KVM: PPC: Book3S HV: Don't attempt to recover machine checks for FWNMI enabled guests
authorNicholas Piggin <npiggin@gmail.com>
Sat, 28 Nov 2020 07:07:23 +0000 (17:07 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 3 Dec 2020 14:01:23 +0000 (01:01 +1100)
Guests that can deal with machine checks would actually prefer the
hypervisor not to try recover for them. For example if SLB multi-hits
are recovered by the hypervisor by clearing the SLB then the guest
will not be able to log the contents and debug its programming error.

If guests don't register for FWNMI, they may not be so capable and so
the hypervisor will continue to recover for those.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20201128070728.825934-4-npiggin@gmail.com
arch/powerpc/kvm/book3s_hv_ras.c

index 6028628..d4bca93 100644 (file)
@@ -65,10 +65,9 @@ static void reload_slb(struct kvm_vcpu *vcpu)
  * On POWER7, see if we can handle a machine check that occurred inside
  * the guest in real mode, without switching to the host partition.
  */
  * On POWER7, see if we can handle a machine check that occurred inside
  * the guest in real mode, without switching to the host partition.
  */
-static void kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)
+static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)
 {
        unsigned long srr1 = vcpu->arch.shregs.msr;
 {
        unsigned long srr1 = vcpu->arch.shregs.msr;
-       struct machine_check_event mce_evt;
        long handled = 1;
 
        if (srr1 & SRR1_MC_LDSTERR) {
        long handled = 1;
 
        if (srr1 & SRR1_MC_LDSTERR) {
@@ -106,6 +105,21 @@ static void kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)
                handled = 0;
        }
 
                handled = 0;
        }
 
+       return handled;
+}
+
+void kvmppc_realmode_machine_check(struct kvm_vcpu *vcpu)
+{
+       struct machine_check_event mce_evt;
+       long handled;
+
+       if (vcpu->kvm->arch.fwnmi_enabled) {
+               /* FWNMI guests handle their own recovery */
+               handled = 0;
+       } else {
+               handled = kvmppc_realmode_mc_power7(vcpu);
+       }
+
        /*
         * Now get the event and stash it in the vcpu struct so it can
         * be handled by the primary thread in virtual mode.  We can't
        /*
         * Now get the event and stash it in the vcpu struct so it can
         * be handled by the primary thread in virtual mode.  We can't
@@ -122,11 +136,6 @@ static void kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)
        vcpu->arch.mce_evt = mce_evt;
 }
 
        vcpu->arch.mce_evt = mce_evt;
 }
 
-void kvmppc_realmode_machine_check(struct kvm_vcpu *vcpu)
-{
-       kvmppc_realmode_mc_power7(vcpu);
-}
-
 /* Check if dynamic split is in force and return subcore size accordingly. */
 static inline int kvmppc_cur_subcore_size(void)
 {
 /* Check if dynamic split is in force and return subcore size accordingly. */
 static inline int kvmppc_cur_subcore_size(void)
 {