Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Reset kernel stack on cpu online from cede state

Cpu hotplug (offline) without dlpar operation will place cpu
in cede state and the extended_cede_processor() function will
return when resumed.

Kernel stack pointer needs to be reset before
start_secondary() is called to continue the online operation.

Added new function start_secondary_resume() to do the above
steps.

Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Cc: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Vaidyanathan Srinivasan and committed by
Benjamin Herrenschmidt
8dbce53c de0b632b

+16 -5
+11
arch/powerpc/kernel/head_64.S
··· 617 617 std r3,0(r1) /* Zero the stack frame pointer */ 618 618 bl .start_secondary 619 619 b . 620 + /* 621 + * Reset stack pointer and call start_secondary 622 + * to continue with online operation when woken up 623 + * from cede in cpu offline. 624 + */ 625 + _GLOBAL(start_secondary_resume) 626 + ld r1,PACAKSAVE(r13) /* Reload kernel stack pointer */ 627 + li r3,0 628 + std r3,0(r1) /* Zero the stack frame pointer */ 629 + bl .start_secondary 630 + b . 620 631 #endif 621 632 622 633 /*
+4 -5
arch/powerpc/platforms/pseries/hotplug-cpu.c
··· 146 146 unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); 147 147 148 148 /* 149 - * NOTE: Calling start_secondary() here for now to 150 - * start new context. 151 - * However, need to do it cleanly by resetting the 152 - * stack pointer. 149 + * Call to start_secondary_resume() will not return. 150 + * Kernel stack will be reset and start_secondary() 151 + * will be called to continue the online operation. 153 152 */ 154 - start_secondary(); 153 + start_secondary_resume(); 155 154 156 155 } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { 157 156
+1
arch/powerpc/platforms/pseries/offline_states.h
··· 35 35 36 36 extern enum cpu_state_vals get_preferred_offline_state(int cpu); 37 37 extern int start_secondary(void); 38 + extern void start_secondary_resume(void); 38 39 #endif