Subject: [PATCH] Fix "[v3, 12/32] powerpc/64s/exception: move KVM test to common code"

From: Nicholas Piggin <[email-masked]>
Date: Wed, 1 Apr 2020 11:12:41 +1000

Moving KVM test to the common entry code missed the case of HMI and MCE,
which do not do __GEN_COMMON_ENTRY (because they don't want to switch
to virt mode).

This means a MCE or HMI exception that is taken while KVM is running a
guest context will not be switched out of that context, and KVM won't
be notified. Found by running sigfuz in guest with patched host on
POWER9 DD2.3, which causes some TM related HMI interrupts (which are
expected and supposed to be handled by KVM).

This fix adds a __GEN_REALMODE_COMMON_ENTRY for those handlers to add
the KVM test. This makes them look a little more like other handlers
that all use __GEN_COMMON_ENTRY.

Conflicts with later patches in series:
- powerpc/64s/exception: remove confusing IEARLY option
  Fix: Remove mfspr (H)SRR, keep __GEN_REALMODE_COMMON_ENTRY

- powerpc/64s/exception: trim unused arguments from KVMTEST macro
  Fix: Trim IHSRR IVEC args from the KVMTEST in __GEN_REALMODE_COMMON_ENTRY

Signed-off-by: Nicholas Piggin <[email-masked]>
---
 arch/powerpc/kernel/exceptions-64s.S | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 74809f1b521d..1bc73acceb9a 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -451,7 +451,9 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948)
 
 /*
  * __GEN_COMMON_ENTRY is required to receive the branch from interrupt
- * entry, except in the case of the IEARLY handlers.
+ * entry, except in the case of the real-mode handlers which require
+ * __GEN_REALMODE_COMMON_ENTRY.
+ *
  * This switches to virtual mode and sets MSR[RI].
  */
 .macro __GEN_COMMON_ENTRY name
@@ -487,6 +489,18 @@ DEFINE_FIXED_SYMBOL(\name\()_common_virt)
 	.endif /* IVIRT */
 .endm
 
+/*
+ * Don't switch to virt mode. Used for early MCE and HMI handlers that
+ * want to run in real mode.
+ */
+.macro __GEN_REALMODE_COMMON_ENTRY name
+DEFINE_FIXED_SYMBOL(\name\()_common_real)
+\name\()_common_real:
+	.if IKVM_REAL
+		KVMTEST \name IHSRR IVEC
+	.endif
+.endm
+
 .macro __GEN_COMMON_BODY name
 	.if IMASK
 		lbz	r10,PACAIRQSOFTMASK(r13)
@@ -976,6 +990,8 @@ EXC_COMMON_BEGIN(machine_check_early_common)
 	mfspr	r11,SPRN_SRR0
 	mfspr	r12,SPRN_SRR1
 
+	__GEN_REALMODE_COMMON_ENTRY machine_check_early
+
 	/*
 	 * Switch to mc_emergency stack and handle re-entrancy (we limit
 	 * the nested MCE upto level 4 to avoid stack overflow).
@@ -1831,6 +1847,9 @@ EXC_VIRT_NONE(0x4e60, 0x20)
 EXC_COMMON_BEGIN(hmi_exception_early_common)
 	mfspr	r11,SPRN_HSRR0		/* Save HSRR0 */
 	mfspr	r12,SPRN_HSRR1		/* Save HSRR1 */
+
+	__GEN_REALMODE_COMMON_ENTRY hmi_exception_early
+
 	mr	r10,r1			/* Save r1 */
 	ld	r1,PACAEMERGSP(r13)	/* Use emergency stack for realmode */
 	subi	r1,r1,INT_FRAME_SIZE	/* alloc stack frame		*/
-- 
2.23.0