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 commitbcef83a00d("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:bcef83a00d("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>
This commit is contained in:
committed by
Michael Ellerman
parent
f077aaf075
commit
bd00a240dc
@@ -411,7 +411,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
|
|||||||
*
|
*
|
||||||
* r13 - PACA
|
* r13 - PACA
|
||||||
* cr3 - gt if waking up with partial/complete hypervisor state loss
|
* cr3 - gt if waking up with partial/complete hypervisor state loss
|
||||||
* cr4 - eq if waking up from complete hypervisor state loss.
|
* cr4 - gt or eq if waking up from complete hypervisor state loss.
|
||||||
*/
|
*/
|
||||||
_GLOBAL(pnv_wakeup_tb_loss)
|
_GLOBAL(pnv_wakeup_tb_loss)
|
||||||
ld r1,PACAR1(r13)
|
ld r1,PACAR1(r13)
|
||||||
@@ -453,7 +453,7 @@ lwarx_loop2:
|
|||||||
* At this stage
|
* At this stage
|
||||||
* cr2 - eq if first thread to wakeup in core
|
* cr2 - eq if first thread to wakeup in core
|
||||||
* cr3- gt if waking up with partial/complete hypervisor state loss
|
* cr3- gt if waking up with partial/complete hypervisor state loss
|
||||||
* cr4 - eq if waking up from complete hypervisor state loss.
|
* cr4 - gt or eq if waking up from complete hypervisor state loss.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ori r15,r15,PNV_CORE_IDLE_LOCK_BIT
|
ori r15,r15,PNV_CORE_IDLE_LOCK_BIT
|
||||||
@@ -481,7 +481,7 @@ first_thread_in_subcore:
|
|||||||
* If waking up from sleep, subcore state is not lost. Hence
|
* If waking up from sleep, subcore state is not lost. Hence
|
||||||
* skip subcore state restore
|
* skip subcore state restore
|
||||||
*/
|
*/
|
||||||
bne cr4,subcore_state_restored
|
blt cr4,subcore_state_restored
|
||||||
|
|
||||||
/* Restore per-subcore state */
|
/* Restore per-subcore state */
|
||||||
ld r4,_SDR1(r1)
|
ld r4,_SDR1(r1)
|
||||||
@@ -526,7 +526,7 @@ timebase_resync:
|
|||||||
* If waking up from sleep, per core state is not lost, skip to
|
* If waking up from sleep, per core state is not lost, skip to
|
||||||
* clear_lock.
|
* clear_lock.
|
||||||
*/
|
*/
|
||||||
bne cr4,clear_lock
|
blt cr4,clear_lock
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First thread in the core to wake up and its waking up with
|
* First thread in the core to wake up and its waking up with
|
||||||
@@ -557,7 +557,7 @@ common_exit:
|
|||||||
* If waking up from sleep, hypervisor state is not lost. Hence
|
* If waking up from sleep, hypervisor state is not lost. Hence
|
||||||
* skip hypervisor state restore.
|
* skip hypervisor state restore.
|
||||||
*/
|
*/
|
||||||
bne cr4,hypervisor_state_restored
|
blt cr4,hypervisor_state_restored
|
||||||
|
|
||||||
/* Waking up from winkle */
|
/* Waking up from winkle */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user