diff options
author | Gautham R. Shenoy <ego@linux.vnet.ibm.com> | 2016-09-07 01:16:30 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-09-11 22:45:50 -0400 |
commit | bd00a240dc52e28706fbbe3aceda63e6c291b433 (patch) | |
tree | 0d231a972425c1c380739b652af0e96930a234be | |
parent | f077aaf0754bcba0fffdbd925bc12f09cd1e38aa (diff) |
powerpc/powernv: Fix restore of SPRs upon wake up from hypervisor state loss
pnv_wakeup_tb_loss() currently expects cr4 to be "eq" if the CPU is
waking up from a complete hypervisor state loss. Hence, it currently
restores the SPR contents only if cr4 is "eq".
However, after commit bcef83a00dc4 ("powerpc/powernv: Add platform
support for stop instruction"), on ISA v3.0 CPUs, the function
pnv_restore_hyp_resource() sets cr4 to contain the result of the
comparison between the state the CPU has woken up from and the first
deep stop state before calling pnv_wakeup_tb_loss().
Thus if the CPU woke up from a state that is deeper than the first
deep stop state, cr4 will have "gt" set and hence, pnv_wakeup_tb_loss()
will fail to restore the SPRs on waking up from such a state.
Fix the code in pnv_wakeup_tb_loss() to restore the SPR states when cr4
is "eq" or "gt".
Fixes: bcef83a00dc4 ("powerpc/powernv: Add platform support for stop instruction")
Signed-off-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
Reviewed-by: Shreyas B. Prabhu <shreyasbp@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/kernel/idle_book3s.S | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 2265c6398a17..bd739fed26e3 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S | |||
@@ -411,7 +411,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) | |||
411 | * | 411 | * |
412 | * r13 - PACA | 412 | * r13 - PACA |
413 | * cr3 - gt if waking up with partial/complete hypervisor state loss | 413 | * cr3 - gt if waking up with partial/complete hypervisor state loss |
414 | * cr4 - eq if waking up from complete hypervisor state loss. | 414 | * cr4 - gt or eq if waking up from complete hypervisor state loss. |
415 | */ | 415 | */ |
416 | _GLOBAL(pnv_wakeup_tb_loss) | 416 | _GLOBAL(pnv_wakeup_tb_loss) |
417 | ld r1,PACAR1(r13) | 417 | ld r1,PACAR1(r13) |
@@ -453,7 +453,7 @@ lwarx_loop2: | |||
453 | * At this stage | 453 | * At this stage |
454 | * cr2 - eq if first thread to wakeup in core | 454 | * cr2 - eq if first thread to wakeup in core |
455 | * cr3- gt if waking up with partial/complete hypervisor state loss | 455 | * cr3- gt if waking up with partial/complete hypervisor state loss |
456 | * cr4 - eq if waking up from complete hypervisor state loss. | 456 | * cr4 - gt or eq if waking up from complete hypervisor state loss. |
457 | */ | 457 | */ |
458 | 458 | ||
459 | ori r15,r15,PNV_CORE_IDLE_LOCK_BIT | 459 | ori r15,r15,PNV_CORE_IDLE_LOCK_BIT |
@@ -481,7 +481,7 @@ first_thread_in_subcore: | |||
481 | * If waking up from sleep, subcore state is not lost. Hence | 481 | * If waking up from sleep, subcore state is not lost. Hence |
482 | * skip subcore state restore | 482 | * skip subcore state restore |
483 | */ | 483 | */ |
484 | bne cr4,subcore_state_restored | 484 | blt cr4,subcore_state_restored |
485 | 485 | ||
486 | /* Restore per-subcore state */ | 486 | /* Restore per-subcore state */ |
487 | ld r4,_SDR1(r1) | 487 | ld r4,_SDR1(r1) |
@@ -526,7 +526,7 @@ timebase_resync: | |||
526 | * If waking up from sleep, per core state is not lost, skip to | 526 | * If waking up from sleep, per core state is not lost, skip to |
527 | * clear_lock. | 527 | * clear_lock. |
528 | */ | 528 | */ |
529 | bne cr4,clear_lock | 529 | blt cr4,clear_lock |
530 | 530 | ||
531 | /* | 531 | /* |
532 | * First thread in the core to wake up and its waking up with | 532 | * First thread in the core to wake up and its waking up with |
@@ -557,7 +557,7 @@ common_exit: | |||
557 | * If waking up from sleep, hypervisor state is not lost. Hence | 557 | * If waking up from sleep, hypervisor state is not lost. Hence |
558 | * skip hypervisor state restore. | 558 | * skip hypervisor state restore. |
559 | */ | 559 | */ |
560 | bne cr4,hypervisor_state_restored | 560 | blt cr4,hypervisor_state_restored |
561 | 561 | ||
562 | /* Waking up from winkle */ | 562 | /* Waking up from winkle */ |
563 | 563 | ||