KVM: x86: Use kvm_queue_exception_e() to queue #DF
authorSean Christopherson <seanjc@google.com>
Tue, 30 Aug 2022 23:16:03 +0000 (23:16 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 26 Sep 2022 16:03:08 +0000 (12:03 -0400)
Queue #DF by recursing on kvm_multiple_exception() by way of
kvm_queue_exception_e() instead of open coding the behavior.  This will
allow KVM to Just Work when a future commit moves exception interception
checks (for L2 => L1) into kvm_multiple_exception().

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Link: https://lore.kernel.org/r/20220830231614.3580124-17-seanjc@google.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/x86.c

index b156dde..4ac067b 100644 (file)
@@ -667,25 +667,22 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
        }
        class1 = exception_class(prev_nr);
        class2 = exception_class(nr);
-       if ((class1 == EXCPT_CONTRIBUTORY && class2 == EXCPT_CONTRIBUTORY)
-               || (class1 == EXCPT_PF && class2 != EXCPT_BENIGN)) {
+       if ((class1 == EXCPT_CONTRIBUTORY && class2 == EXCPT_CONTRIBUTORY) ||
+           (class1 == EXCPT_PF && class2 != EXCPT_BENIGN)) {
                /*
-                * Generate double fault per SDM Table 5-5.  Set
-                * exception.pending = true so that the double fault
-                * can trigger a nested vmexit.
+                * Synthesize #DF.  Clear the previously injected or pending
+                * exception so as not to incorrectly trigger shutdown.
                 */
-               vcpu->arch.exception.pending = true;
                vcpu->arch.exception.injected = false;
-               vcpu->arch.exception.has_error_code = true;
-               vcpu->arch.exception.vector = DF_VECTOR;
-               vcpu->arch.exception.error_code = 0;
-               vcpu->arch.exception.has_payload = false;
-               vcpu->arch.exception.payload = 0;
-       } else
+               vcpu->arch.exception.pending = false;
+
+               kvm_queue_exception_e(vcpu, DF_VECTOR, 0);
+       } else {
                /* replace previous exception with a new one in a hope
                   that instruction re-execution will regenerate lost
                   exception */
                goto queue;
+       }
 }
 
 void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr)