powerpc/kvm: make hypervisor state restore a function
In the current code, when the thread wakes up in reset vector, some of the state restore code and check for whether a thread needs to branch to kvm is duplicated. Reorder the code such that this duplication is avoided. At a higher level this is what the change looks like- Before this patch - power7_wakeup_tb_loss: restore hypervisor state if (thread needed by kvm) goto kvm_start_guest restore nvgprs, cr, pc rfid to process context power7_wakeup_loss: restore nvgprs, cr, pc rfid to process context reset vector: if (waking from deep idle states) goto power7_wakeup_tb_loss else if (thread needed by kvm) goto kvm_start_guest goto power7_wakeup_loss After this patch - power7_wakeup_tb_loss: restore hypervisor state return power7_restore_hyp_resource(): if (waking from deep idle states) goto power7_wakeup_tb_loss return power7_wakeup_loss: restore nvgprs, cr, pc rfid to process context reset vector: power7_restore_hyp_resource() if (thread needed by kvm) goto kvm_start_guest goto power7_wakeup_loss Reviewed-by: Paul Mackerras <paulus@samba.org> Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com> Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
bfd1b7ae5e
commit
1706567117
@ -107,25 +107,9 @@ BEGIN_FTR_SECTION
|
|||||||
beq 9f
|
beq 9f
|
||||||
|
|
||||||
cmpwi cr3,r13,2
|
cmpwi cr3,r13,2
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if last bit of HSPGR0 is set. This indicates whether we are
|
|
||||||
* waking up from winkle.
|
|
||||||
*/
|
|
||||||
GET_PACA(r13)
|
GET_PACA(r13)
|
||||||
clrldi r5,r13,63
|
bl power7_restore_hyp_resource
|
||||||
clrrdi r13,r13,1
|
|
||||||
cmpwi cr4,r5,1
|
|
||||||
mtspr SPRN_HSPRG0,r13
|
|
||||||
|
|
||||||
lbz r0,PACA_THREAD_IDLE_STATE(r13)
|
|
||||||
cmpwi cr2,r0,PNV_THREAD_NAP
|
|
||||||
bgt cr2,8f /* Either sleep or Winkle */
|
|
||||||
|
|
||||||
/* Waking up from nap should not cause hypervisor state loss */
|
|
||||||
bgt cr3,.
|
|
||||||
|
|
||||||
/* Waking up from nap */
|
|
||||||
li r0,PNV_THREAD_RUNNING
|
li r0,PNV_THREAD_RUNNING
|
||||||
stb r0,PACA_THREAD_IDLE_STATE(r13) /* Clear thread state */
|
stb r0,PACA_THREAD_IDLE_STATE(r13) /* Clear thread state */
|
||||||
|
|
||||||
@ -143,13 +127,9 @@ BEGIN_FTR_SECTION
|
|||||||
|
|
||||||
/* Return SRR1 from power7_nap() */
|
/* Return SRR1 from power7_nap() */
|
||||||
mfspr r3,SPRN_SRR1
|
mfspr r3,SPRN_SRR1
|
||||||
beq cr3,2f
|
blt cr3,2f
|
||||||
b power7_wakeup_noloss
|
b power7_wakeup_loss
|
||||||
2: b power7_wakeup_loss
|
2: b power7_wakeup_noloss
|
||||||
|
|
||||||
/* Fast Sleep wakeup on PowerNV */
|
|
||||||
8: GET_PACA(r13)
|
|
||||||
b power7_wakeup_tb_loss
|
|
||||||
|
|
||||||
9:
|
9:
|
||||||
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
|
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
|
||||||
|
@ -276,6 +276,39 @@ ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_ARCH_207S, 66); \
|
|||||||
20: nop;
|
20: nop;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called from reset vector. Check whether we have woken up with
|
||||||
|
* hypervisor state loss. If yes, restore hypervisor state and return
|
||||||
|
* back to reset vector.
|
||||||
|
*
|
||||||
|
* r13 - Contents of HSPRG0
|
||||||
|
* cr3 - set to gt if waking up with partial/complete hypervisor state loss
|
||||||
|
*/
|
||||||
|
_GLOBAL(power7_restore_hyp_resource)
|
||||||
|
/*
|
||||||
|
* Check if last bit of HSPGR0 is set. This indicates whether we are
|
||||||
|
* waking up from winkle.
|
||||||
|
*/
|
||||||
|
clrldi r5,r13,63
|
||||||
|
clrrdi r13,r13,1
|
||||||
|
cmpwi cr4,r5,1
|
||||||
|
mtspr SPRN_HSPRG0,r13
|
||||||
|
|
||||||
|
lbz r0,PACA_THREAD_IDLE_STATE(r13)
|
||||||
|
cmpwi cr2,r0,PNV_THREAD_NAP
|
||||||
|
bgt cr2,power7_wakeup_tb_loss /* Either sleep or Winkle */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We fall through here if PACA_THREAD_IDLE_STATE shows we are waking
|
||||||
|
* up from nap. At this stage CR3 shouldn't contains 'gt' since that
|
||||||
|
* indicates we are waking with hypervisor state loss from nap.
|
||||||
|
*/
|
||||||
|
bgt cr3,.
|
||||||
|
|
||||||
|
blr /* Return back to System Reset vector from where
|
||||||
|
power7_restore_hyp_resource was invoked */
|
||||||
|
|
||||||
|
|
||||||
_GLOBAL(power7_wakeup_tb_loss)
|
_GLOBAL(power7_wakeup_tb_loss)
|
||||||
ld r2,PACATOC(r13);
|
ld r2,PACATOC(r13);
|
||||||
ld r1,PACAR1(r13)
|
ld r1,PACAR1(r13)
|
||||||
@ -284,11 +317,13 @@ _GLOBAL(power7_wakeup_tb_loss)
|
|||||||
* and they are restored before switching to the process context. Hence
|
* and they are restored before switching to the process context. Hence
|
||||||
* until they are restored, they are free to be used.
|
* until they are restored, they are free to be used.
|
||||||
*
|
*
|
||||||
* Save SRR1 in a NVGPR as it might be clobbered in opal_call_realmode
|
* Save SRR1 and LR in NVGPRs as they might be clobbered in
|
||||||
* (called in CHECK_HMI_INTERRUPT). SRR1 is required to determine the
|
* opal_call_realmode (called in CHECK_HMI_INTERRUPT). SRR1 is required
|
||||||
* wakeup reason if we branch to kvm_start_guest.
|
* to determine the wakeup reason if we branch to kvm_start_guest. LR
|
||||||
|
* is required to return back to reset vector after hypervisor state
|
||||||
|
* restore is complete.
|
||||||
*/
|
*/
|
||||||
|
mflr r17
|
||||||
mfspr r16,SPRN_SRR1
|
mfspr r16,SPRN_SRR1
|
||||||
BEGIN_FTR_SECTION
|
BEGIN_FTR_SECTION
|
||||||
CHECK_HMI_INTERRUPT
|
CHECK_HMI_INTERRUPT
|
||||||
@ -438,33 +473,10 @@ common_exit:
|
|||||||
|
|
||||||
hypervisor_state_restored:
|
hypervisor_state_restored:
|
||||||
|
|
||||||
li r5,PNV_THREAD_RUNNING
|
|
||||||
stb r5,PACA_THREAD_IDLE_STATE(r13)
|
|
||||||
|
|
||||||
mtspr SPRN_SRR1,r16
|
mtspr SPRN_SRR1,r16
|
||||||
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
|
mtlr r17
|
||||||
li r0,KVM_HWTHREAD_IN_KERNEL
|
blr /* Return back to System Reset vector from where
|
||||||
stb r0,HSTATE_HWTHREAD_STATE(r13)
|
power7_restore_hyp_resource was invoked */
|
||||||
/* Order setting hwthread_state vs. testing hwthread_req */
|
|
||||||
sync
|
|
||||||
lbz r0,HSTATE_HWTHREAD_REQ(r13)
|
|
||||||
cmpwi r0,0
|
|
||||||
beq 6f
|
|
||||||
b kvm_start_guest
|
|
||||||
6:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
REST_NVGPRS(r1)
|
|
||||||
REST_GPR(2, r1)
|
|
||||||
ld r3,_CCR(r1)
|
|
||||||
ld r4,_MSR(r1)
|
|
||||||
ld r5,_NIP(r1)
|
|
||||||
addi r1,r1,INT_FRAME_SIZE
|
|
||||||
mtcr r3
|
|
||||||
mfspr r3,SPRN_SRR1 /* Return SRR1 */
|
|
||||||
mtspr SPRN_SRR1,r4
|
|
||||||
mtspr SPRN_SRR0,r5
|
|
||||||
rfid
|
|
||||||
|
|
||||||
fastsleep_workaround_at_exit:
|
fastsleep_workaround_at_exit:
|
||||||
li r3,1
|
li r3,1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user