|
@@ -276,6 +276,39 @@ ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_ARCH_207S, 66); \
|
|
|
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)
|
|
|
ld r2,PACATOC(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
|
|
|
* until they are restored, they are free to be used.
|
|
|
*
|
|
|
- * Save SRR1 in a NVGPR as it might be clobbered in opal_call_realmode
|
|
|
- * (called in CHECK_HMI_INTERRUPT). SRR1 is required to determine the
|
|
|
- * wakeup reason if we branch to kvm_start_guest.
|
|
|
+ * Save SRR1 and LR in NVGPRs as they might be clobbered in
|
|
|
+ * opal_call_realmode (called in CHECK_HMI_INTERRUPT). SRR1 is required
|
|
|
+ * 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
|
|
|
BEGIN_FTR_SECTION
|
|
|
CHECK_HMI_INTERRUPT
|
|
@@ -438,33 +473,10 @@ common_exit:
|
|
|
|
|
|
hypervisor_state_restored:
|
|
|
|
|
|
- li r5,PNV_THREAD_RUNNING
|
|
|
- stb r5,PACA_THREAD_IDLE_STATE(r13)
|
|
|
-
|
|
|
mtspr SPRN_SRR1,r16
|
|
|
-#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
|
|
|
- li r0,KVM_HWTHREAD_IN_KERNEL
|
|
|
- stb r0,HSTATE_HWTHREAD_STATE(r13)
|
|
|
- /* 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
|
|
|
+ mtlr r17
|
|
|
+ blr /* Return back to System Reset vector from where
|
|
|
+ power7_restore_hyp_resource was invoked */
|
|
|
|
|
|
fastsleep_workaround_at_exit:
|
|
|
li r3,1
|