aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilton Miller <miltonm@bga.com>2011-05-10 15:28:33 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-05-19 00:30:43 -0400
commit3d2cea732d68aa270c360f55d8669820ebce188a (patch)
tree2f43b11f58c81aa6891dae39f91f674842bb7e7e
parentf0e939ae373836400b38e090d78fba6a183976f0 (diff)
powerpc/kexec: Fix memory corruption from unallocated slaves
Commit 1fc711f7ffb01089efc58042cfdbac8573d1b59a (powerpc/kexec: Fix race in kexec shutdown) moved the write to signal the cpu had exited the kernel from before the transition to real mode in kexec_smp_wait to kexec_wait. Unfornately it missed that kexec_wait is used both by cpus leaving the kernel and by secondary slave cpus that were not allocated a paca for what ever reason -- they could be beyond nr_cpus or not described in the current device tree for whatever reason (for example, kexec-load was not refreshed after a cpu hotplug operation). Cpus coming through that path they will write to paca[NR_CPUS] which is beyond the space allocated for the paca data and overwrite memory not allocated to pacas but very likely still real mode accessable). Move the write back to kexec_smp_wait, which is used only by cpus that found their paca, but after the transition to real mode. Signed-off-by: Milton Miller <miltonm@bga.com> Cc: <stable@kernel.org> # (1fc711f was backported to 2.6.32) Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/kernel/misc_64.S13
1 files changed, 8 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 206a321a71d3..e89df59cdc5a 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -462,7 +462,8 @@ _GLOBAL(disable_kernel_fp)
462 * wait for the flag to change, indicating this kernel is going away but 462 * wait for the flag to change, indicating this kernel is going away but
463 * the slave code for the next one is at addresses 0 to 100. 463 * the slave code for the next one is at addresses 0 to 100.
464 * 464 *
465 * This is used by all slaves. 465 * This is used by all slaves, even those that did not find a matching
466 * paca in the secondary startup code.
466 * 467 *
467 * Physical (hardware) cpu id should be in r3. 468 * Physical (hardware) cpu id should be in r3.
468 */ 469 */
@@ -471,10 +472,6 @@ _GLOBAL(kexec_wait)
4711: mflr r5 4721: mflr r5
472 addi r5,r5,kexec_flag-1b 473 addi r5,r5,kexec_flag-1b
473 474
474 li r4,KEXEC_STATE_REAL_MODE
475 stb r4,PACAKEXECSTATE(r13)
476 SYNC
477
47899: HMT_LOW 47599: HMT_LOW
479#ifdef CONFIG_KEXEC /* use no memory without kexec */ 476#ifdef CONFIG_KEXEC /* use no memory without kexec */
480 lwz r4,0(r5) 477 lwz r4,0(r5)
@@ -499,11 +496,17 @@ kexec_flag:
499 * 496 *
500 * get phys id from paca 497 * get phys id from paca
501 * switch to real mode 498 * switch to real mode
499 * mark the paca as no longer used
502 * join other cpus in kexec_wait(phys_id) 500 * join other cpus in kexec_wait(phys_id)
503 */ 501 */
504_GLOBAL(kexec_smp_wait) 502_GLOBAL(kexec_smp_wait)
505 lhz r3,PACAHWCPUID(r13) 503 lhz r3,PACAHWCPUID(r13)
506 bl real_mode 504 bl real_mode
505
506 li r4,KEXEC_STATE_REAL_MODE
507 stb r4,PACAKEXECSTATE(r13)
508 SYNC
509
507 b .kexec_wait 510 b .kexec_wait
508 511
509/* 512/*