aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorSam Bobroff <sam.bobroff@au1.ibm.com>2015-05-01 02:50:34 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2015-05-01 02:55:11 -0400
commit0aab3747091db309b8a484cfd382a41644552aa3 (patch)
tree8047000536b9c951ec8072c9a14b0cf3fbd8c4f7 /arch/powerpc
parentd91dafc02f42e23c1a906202ebde5d7c49ef058d (diff)
powerpc/powernv: Restore non-volatile CRs after nap
Patches 7cba160ad "powernv/cpuidle: Redesign idle states management" and 77b54e9f2 "powernv/powerpc: Add winkle support for offline cpus" use non-volatile condition registers (cr2, cr3 and cr4) early in the system reset interrupt handler (system_reset_pSeries()) before it has been determined if state loss has occurred. If state loss has not occurred, control returns via the power7_wakeup_noloss() path which does not restore those condition registers, leaving them corrupted. Fix this by restoring the condition registers in the power7_wakeup_noloss() case. This is apparent when running a KVM guest on hardware that does not support winkle or sleep and the guest makes use of secondary threads. In practice this means Power7 machines, though some early unreleased Power8 machines may also be susceptible. The secondary CPUs are taken off line before the guest is started and they call pnv_smp_cpu_kill_self(). This checks support for sleep states (in this case there is no support) and power7_nap() is called. When the CPU is woken, power7_nap() returns and because the CPU is still off line, the main while loop executes again. The sleep states support test is executed again, but because the tested values cannot have changed, the compiler has optimized the test away and instead we rely on the result of the first test, which has been left in cr3 and/or cr4. With the result overwritten, the wrong branch is taken and power7_winkle() is called on a CPU that does not support it, leading to it stalling. Fixes: 7cba160ad789 ("powernv/cpuidle: Redesign idle states management") Fixes: 77b54e9f213f ("powernv/powerpc: Add winkle support for offline cpus") [mpe: Massage change log a bit more] Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/idle_power7.S2
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index eeaa0d5f69d5..ccde8f084ce4 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -501,9 +501,11 @@ BEGIN_FTR_SECTION
501 CHECK_HMI_INTERRUPT 501 CHECK_HMI_INTERRUPT
502END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) 502END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
503 ld r1,PACAR1(r13) 503 ld r1,PACAR1(r13)
504 ld r6,_CCR(r1)
504 ld r4,_MSR(r1) 505 ld r4,_MSR(r1)
505 ld r5,_NIP(r1) 506 ld r5,_NIP(r1)
506 addi r1,r1,INT_FRAME_SIZE 507 addi r1,r1,INT_FRAME_SIZE
508 mtcr r6
507 mtspr SPRN_SRR1,r4 509 mtspr SPRN_SRR1,r4
508 mtspr SPRN_SRR0,r5 510 mtspr SPRN_SRR0,r5
509 rfid 511 rfid