aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/smp.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-02-10 02:45:24 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-04-01 00:37:09 -0400
commitfa3f82c8bb7acbe049ea71f258b3ae0a33d9d40b (patch)
tree9c5e71195c7948c139ea37d8d0e0287f062910f9 /arch/powerpc/kernel/smp.c
parent963e5d3b76d657f1ebcf3561446d2ba1872bbfa2 (diff)
powerpc/smp: soft-replugged CPUs must go back to start_secondary
Various thing are torn down when a CPU is hot-unplugged. That CPU is expected to go back to start_secondary when re-plugged to re initialize everything, such as clock sources, maps, ... Some implementations just return from cpu_die() callback in the idle loop when the CPU is "re-plugged". This is not enough. We fix it using a little asm trampoline which resets the stack and calls back into start_secondary as if we were all fresh from boot. The trampoline already existed on ppc64, but we add it for ppc32 Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r--arch/powerpc/kernel/smp.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 981360509172..1c9956c43801 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -502,7 +502,7 @@ static struct device_node *cpu_to_l2cache(int cpu)
502} 502}
503 503
504/* Activate a secondary processor. */ 504/* Activate a secondary processor. */
505int __devinit start_secondary(void *unused) 505void __devinit start_secondary(void *unused)
506{ 506{
507 unsigned int cpu = smp_processor_id(); 507 unsigned int cpu = smp_processor_id();
508 struct device_node *l2_cache; 508 struct device_node *l2_cache;
@@ -558,7 +558,8 @@ int __devinit start_secondary(void *unused)
558 local_irq_enable(); 558 local_irq_enable();
559 559
560 cpu_idle(); 560 cpu_idle();
561 return 0; 561
562 BUG();
562} 563}
563 564
564int setup_profiling_timer(unsigned int multiplier) 565int setup_profiling_timer(unsigned int multiplier)
@@ -660,5 +661,9 @@ void cpu_die(void)
660{ 661{
661 if (ppc_md.cpu_die) 662 if (ppc_md.cpu_die)
662 ppc_md.cpu_die(); 663 ppc_md.cpu_die();
664
665 /* If we return, we re-enter start_secondary */
666 start_secondary_resume();
663} 667}
668
664#endif 669#endif