aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powernv/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/powernv/smp.c')
-rw-r--r--arch/powerpc/platforms/powernv/smp.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index 4753958cd509..b716f666e48a 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -149,6 +149,7 @@ static int pnv_smp_cpu_disable(void)
149static void pnv_smp_cpu_kill_self(void) 149static void pnv_smp_cpu_kill_self(void)
150{ 150{
151 unsigned int cpu; 151 unsigned int cpu;
152 unsigned long srr1;
152 153
153 /* Standard hot unplug procedure */ 154 /* Standard hot unplug procedure */
154 local_irq_disable(); 155 local_irq_disable();
@@ -165,13 +166,25 @@ static void pnv_smp_cpu_kill_self(void)
165 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); 166 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
166 while (!generic_check_cpu_restart(cpu)) { 167 while (!generic_check_cpu_restart(cpu)) {
167 ppc64_runlatch_off(); 168 ppc64_runlatch_off();
168 power7_nap(1); 169 srr1 = power7_nap(1);
169 ppc64_runlatch_on(); 170 ppc64_runlatch_on();
170 171
171 /* Clear the IPI that woke us up */ 172 /*
172 icp_native_flush_interrupt(); 173 * If the SRR1 value indicates that we woke up due to
173 local_paca->irq_happened &= PACA_IRQ_HARD_DIS; 174 * an external interrupt, then clear the interrupt.
174 mb(); 175 * We clear the interrupt before checking for the
176 * reason, so as to avoid a race where we wake up for
177 * some other reason, find nothing and clear the interrupt
178 * just as some other cpu is sending us an interrupt.
179 * If we returned from power7_nap as a result of
180 * having finished executing in a KVM guest, then srr1
181 * contains 0.
182 */
183 if ((srr1 & SRR1_WAKEMASK) == SRR1_WAKEEE) {
184 icp_native_flush_interrupt();
185 local_paca->irq_happened &= PACA_IRQ_HARD_DIS;
186 smp_mb();
187 }
175 188
176 if (cpu_core_split_required()) 189 if (cpu_core_split_required())
177 continue; 190 continue;