diff options
author | Robert Jarzmik <rjarzmik@free.fr> | 2008-05-02 21:17:06 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-05-04 11:06:05 +0100 |
commit | 649de51b883746d76c5fa1614dd067054c9d702a (patch) | |
tree | 68c3b172063bdf4cc82a727d3d4ca48f63487665 | |
parent | c8df9a53e8d16877fc0b268b002af2a47a14643a (diff) | |
download | op-kernel-dev-649de51b883746d76c5fa1614dd067054c9d702a.zip op-kernel-dev-649de51b883746d76c5fa1614dd067054c9d702a.tar.gz |
[ARM] 5027/1: Fixed random memory corruption on pxa suspend cycle.
Each time a pxa type cpu went in suspend, a portion of
kmalloc memory was corrupted.
The issue was an incorrect length allocation introduced by
the commit 711be5ccfe9a02ba560aa918a008c31ea4760163 for
the save registers array (=> overflow).
Signed-off-by: Robert Jarzmik <rjarzmik@free.fr>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/mach-pxa/pm.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa27x.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa3xx.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/pm.c | 8 | ||||
-rw-r--r-- | include/asm-arm/arch-pxa/pm.h | 2 |
6 files changed, 17 insertions, 23 deletions
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index ec1bbf3..329df21 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -42,7 +42,7 @@ int pxa_pm_enter(suspend_state_t state) if (state != PM_SUSPEND_STANDBY) { pxa_cpu_pm_fns->save(sleep_save); /* before sleeping, calculate and save a checksum */ - for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) + for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) sleep_save_checksum += sleep_save[i]; } @@ -55,7 +55,7 @@ int pxa_pm_enter(suspend_state_t state) if (state != PM_SUSPEND_STANDBY) { /* after sleeping, validate the checksum */ - for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) + for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) checksum += sleep_save[i]; /* if invalid, display message and wait for a hardware reset */ @@ -101,7 +101,8 @@ static int __init pxa_pm_init(void) return -EINVAL; } - sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL); + sleep_save = kmalloc(pxa_cpu_pm_fns->save_count * sizeof(unsigned long), + GFP_KERNEL); if (!sleep_save) { printk(KERN_ERR "failed to alloc memory for pm save\n"); return -ENOMEM; diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index d9b5450..3642f81 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -150,9 +150,7 @@ static struct clk pxa25x_clks[] = { * More ones like CP and general purpose register values are preserved * with the stack pointer in sleep.S. */ -enum { SLEEP_SAVE_START = 0, - - SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, +enum { SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, @@ -162,7 +160,7 @@ enum { SLEEP_SAVE_START = 0, SLEEP_SAVE_CKEN, - SLEEP_SAVE_SIZE + SLEEP_SAVE_COUNT }; @@ -210,7 +208,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) } static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { - .save_size = SLEEP_SAVE_SIZE, + .save_count = SLEEP_SAVE_COUNT, .valid = suspend_valid_only_mem, .save = pxa25x_cpu_pm_save, .restore = pxa25x_cpu_pm_restore, diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7a2449d..505dcca 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -181,9 +181,7 @@ static struct clk pxa27x_clks[] = { * More ones like CP and general purpose register values are preserved * with the stack pointer in sleep.S. */ -enum { SLEEP_SAVE_START = 0, - - SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, +enum { SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, @@ -198,7 +196,7 @@ enum { SLEEP_SAVE_START = 0, SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, - SLEEP_SAVE_SIZE + SLEEP_SAVE_COUNT }; void pxa27x_cpu_pm_save(unsigned long *sleep_save) @@ -269,7 +267,7 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state) } static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { - .save_size = SLEEP_SAVE_SIZE, + .save_count = SLEEP_SAVE_COUNT, .save = pxa27x_cpu_pm_save, .restore = pxa27x_cpu_pm_restore, .valid = pxa27x_cpu_pm_valid, diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index b6a6f5f..644550b 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -256,12 +256,11 @@ static unsigned long wakeup_src; #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] -enum { SLEEP_SAVE_START = 0, - SLEEP_SAVE_CKENA, +enum { SLEEP_SAVE_CKENA, SLEEP_SAVE_CKENB, SLEEP_SAVE_ACCR, - SLEEP_SAVE_SIZE, + SLEEP_SAVE_COUNT, }; static void pxa3xx_cpu_pm_save(unsigned long *sleep_save) @@ -376,7 +375,7 @@ static int pxa3xx_cpu_pm_valid(suspend_state_t state) } static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = { - .save_size = SLEEP_SAVE_SIZE, + .save_count = SLEEP_SAVE_COUNT, .save = pxa3xx_cpu_pm_save, .restore = pxa3xx_cpu_pm_restore, .valid = pxa3xx_cpu_pm_valid, diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index 246c573..1693d44 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c @@ -43,20 +43,18 @@ extern void sa1100_cpu_resume(void); * More ones like CP and general purpose register values are preserved * on the stack and then the stack pointer is stored last in sleep.S. */ -enum { SLEEP_SAVE_SP = 0, - - SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR, +enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR, SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR, SLEEP_SAVE_Ser1SDCR0, - SLEEP_SAVE_SIZE + SLEEP_SAVE_COUNT }; static int sa11x0_pm_enter(suspend_state_t state) { - unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE]; + unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT]; gpio = GPLR; diff --git a/include/asm-arm/arch-pxa/pm.h b/include/asm-arm/arch-pxa/pm.h index 9d9f4b5..261e5bc 100644 --- a/include/asm-arm/arch-pxa/pm.h +++ b/include/asm-arm/arch-pxa/pm.h @@ -10,7 +10,7 @@ #include <linux/suspend.h> struct pxa_cpu_pm_fns { - int save_size; + int save_count; void (*save)(unsigned long *); void (*restore)(unsigned long *); int (*valid)(suspend_state_t state); |