KVM: PPC: Book3S HV: Make sure we don't re-enter guest without XIVE loaded

"Linux Kernel Mailing List" <[email protected]> Sat, 10 Feb 2018 22:00:25 +0000 (UTC)
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/43ff3f65234061e08d234bdef5a9aadc19832b74
Commit:     43ff3f65234061e08d234bdef5a9aadc19832b74
Parent:     5855564c8ab2d9cefca7b2933bd19818eb795e40
Refname:    refs/heads/master
Author:     Paul Mackerras <[email protected]>
AuthorDate: Thu Jan 11 14:31:43 2018 +1100
Committer:  Paul Mackerras <[email protected]>
CommitDate: Wed Jan 17 11:18:48 2018 +1100

    KVM: PPC: Book3S HV: Make sure we don't re-enter guest without XIVE loaded
    
    This fixes a bug where it is possible to enter a guest on a POWER9
    system without having the XIVE (interrupt controller) context loaded.
    This can happen because we unload the XIVE context from the CPU
    before doing the real-mode handling for machine checks.  After the
    real-mode handler runs, it is possible that we re-enter the guest
    via a fast path which does not load the XIVE context.
    
    To fix this, we move the unloading of the XIVE context to come after
    the real-mode machine check handler is called.
    
    Fixes: 5af50993850a ("KVM: PPC: Book3S HV: Native usage of the XIVE interrupt controller")
    Cc: [email protected] # v4.11+
    Signed-off-by: Paul Mackerras <[email protected]>
---
 arch/powerpc/kvm/book3s_hv_rmhandlers.S | 40 ++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index c8ffd69adfec..76332a3f6c0d 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1423,6 +1423,26 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 	blt	deliver_guest_interrupt
 
 guest_exit_cont:		/* r9 = vcpu, r12 = trap, r13 = paca */
+	/* Save more register state  */
+	mfdar	r6
+	mfdsisr	r7
+	std	r6, VCPU_DAR(r9)
+	stw	r7, VCPU_DSISR(r9)
+	/* don't overwrite fault_dar/fault_dsisr if HDSI */
+	cmpwi	r12,BOOK3S_INTERRUPT_H_DATA_STORAGE
+	beq	mc_cont
+	std	r6, VCPU_FAULT_DAR(r9)
+	stw	r7, VCPU_FAULT_DSISR(r9)
+
+	/* See if it is a machine check */
+	cmpwi	r12, BOOK3S_INTERRUPT_MACHINE_CHECK
+	beq	machine_check_realmode
+mc_cont:
+#ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING
+	addi	r3, r9, VCPU_TB_RMEXIT
+	mr	r4, r9
+	bl	kvmhv_accumulate_time
+#endif
 #ifdef CONFIG_KVM_XICS
 	/* We are exiting, pull the VP from the XIVE */
 	lwz	r0, VCPU_XIVE_PUSHED(r9)
@@ -1460,26 +1480,6 @@ guest_exit_cont:		/* r9 = vcpu, r12 = trap, r13 = paca */
 	eieio
 1:
 #endif /* CONFIG_KVM_XICS */
-	/* Save more register state  */
-	mfdar	r6
-	mfdsisr	r7
-	std	r6, VCPU_DAR(r9)
-	stw	r7, VCPU_DSISR(r9)
-	/* don't overwrite fault_dar/fault_dsisr if HDSI */
-	cmpwi	r12,BOOK3S_INTERRUPT_H_DATA_STORAGE
-	beq	mc_cont
-	std	r6, VCPU_FAULT_DAR(r9)
-	stw	r7, VCPU_FAULT_DSISR(r9)