powerpc/64s/exception: machine check fix KVM guest test
authorNicholas Piggin <npiggin@gmail.com>
Fri, 2 Aug 2019 10:56:28 +0000 (20:56 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 30 Aug 2019 00:32:34 +0000 (10:32 +1000)
The machine_check_handle_early hypervisor guest test is skipped if
!HVMODE or MSR[HV]=0, which is wrong for PR or nested hypervisors
that could be running a guest in this state.

Test HSTATE_IN_GUEST up front and use that to branch out to the KVM
handler, then MSR[PR] alone can test for this kernel's userspace.
This matches all other interrupt handling.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190802105709.27696-4-npiggin@gmail.com
arch/powerpc/kernel/exceptions-64s.S

index 8cf4e44d2d764194428e724648259b7299cf7f39..7c28c22fc6a6ca1453694e8292eab2f7d2da1ad7 100644 (file)
@@ -1108,11 +1108,8 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
        bl      machine_check_early
        std     r3,RESULT(r1)   /* Save result */
        ld      r12,_MSR(r1)
-BEGIN_FTR_SECTION
-       b       4f
-END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE)
 
-#ifdef CONFIG_PPC_P7_NAP
+#ifdef CONFIG_PPC_P7_NAP
        /*
         * Check if thread was in power saving mode. We come here when any
         * of the following is true:
@@ -1128,30 +1125,26 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
 #endif
 
-       /*
-        * Check if we are coming from hypervisor userspace. If yes then we
-        * continue in host kernel in V mode to deliver the MC event.
-        */
-       rldicl. r11,r12,4,63            /* See if MC hit while in HV mode. */
-       beq     5f
-4:     andi.   r11,r12,MSR_PR          /* See if coming from user. */
-       bne     9f                      /* continue in V mode if we are. */
-
-5:
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
-BEGIN_FTR_SECTION
        /*
-        * We are coming from kernel context. Check if we are coming from
-        * guest. if yes, then we can continue. We will fall through
-        * do_kvm_200->kvmppc_interrupt to deliver the MC event to guest.
+        * Check if we are coming from guest. If yes, then run the normal
+        * exception handler which will take the do_kvm_200->kvmppc_interrupt
+        * branch to deliver the MC event to guest.
         */
        lbz     r11,HSTATE_IN_GUEST(r13)
        cmpwi   r11,0                   /* Check if coming from guest */
        bne     9f                      /* continue if we are. */
-END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
 #endif
+
+       /*
+        * Check if we are coming from userspace. If yes, then run the normal
+        * exception handler which will deliver the MC event to this kernel.
+        */
+       andi.   r11,r12,MSR_PR          /* See if coming from user. */
+       bne     9f                      /* continue in V mode if we are. */
+
        /*
-        * At this point we are not sure about what context we come from.
+        * At this point we are coming from kernel context.
         * Queue up the MCE event and return from the interrupt.
         * But before that, check if this is an un-recoverable exception.
         * If yes, then stay on emergency stack and panic.