Merge tag 'kvm-x86-svm-6.4' of https://github.com/kvm-x86/linux into HEAD
[platform/kernel/linux-rpi.git] / arch / x86 / kvm / x86.c
index 6a41bdb..523c39a 100644 (file)
@@ -5185,7 +5185,7 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
        events->interrupt.shadow = static_call(kvm_x86_get_interrupt_shadow)(vcpu);
 
        events->nmi.injected = vcpu->arch.nmi_injected;
-       events->nmi.pending = vcpu->arch.nmi_pending != 0;
+       events->nmi.pending = kvm_get_nr_pending_nmis(vcpu);
        events->nmi.masked = static_call(kvm_x86_get_nmi_mask)(vcpu);
 
        /* events->sipi_vector is never valid when reporting to user space */
@@ -5272,8 +5272,11 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
                                                events->interrupt.shadow);
 
        vcpu->arch.nmi_injected = events->nmi.injected;
-       if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING)
-               vcpu->arch.nmi_pending = events->nmi.pending;
+       if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING) {
+               vcpu->arch.nmi_pending = 0;
+               atomic_set(&vcpu->arch.nmi_queued, events->nmi.pending);
+               kvm_make_request(KVM_REQ_NMI, vcpu);
+       }
        static_call(kvm_x86_set_nmi_mask)(vcpu, events->nmi.masked);
 
        if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR &&
@@ -10210,19 +10213,46 @@ out:
 
 static void process_nmi(struct kvm_vcpu *vcpu)
 {
-       unsigned limit = 2;
+       unsigned int limit;
 
        /*
-        * x86 is limited to one NMI running, and one NMI pending after it.
-        * If an NMI is already in progress, limit further NMIs to just one.
-        * Otherwise, allow two (and we'll inject the first one immediately).
+        * x86 is limited to one NMI pending, but because KVM can't react to
+        * incoming NMIs as quickly as bare metal, e.g. if the vCPU is
+        * scheduled out, KVM needs to play nice with two queued NMIs showing
+        * up at the same time.  To handle this scenario, allow two NMIs to be
+        * (temporarily) pending so long as NMIs are not blocked and KVM is not
+        * waiting for a previous NMI injection to complete (which effectively
+        * blocks NMIs).  KVM will immediately inject one of the two NMIs, and
+        * will request an NMI window to handle the second NMI.
         */
        if (static_call(kvm_x86_get_nmi_mask)(vcpu) || vcpu->arch.nmi_injected)
                limit = 1;
+       else
+               limit = 2;
+
+       /*
+        * Adjust the limit to account for pending virtual NMIs, which aren't
+        * tracked in vcpu->arch.nmi_pending.
+        */
+       if (static_call(kvm_x86_is_vnmi_pending)(vcpu))
+               limit--;
 
        vcpu->arch.nmi_pending += atomic_xchg(&vcpu->arch.nmi_queued, 0);
        vcpu->arch.nmi_pending = min(vcpu->arch.nmi_pending, limit);
-       kvm_make_request(KVM_REQ_EVENT, vcpu);
+
+       if (vcpu->arch.nmi_pending &&
+           (static_call(kvm_x86_set_vnmi_pending)(vcpu)))
+               vcpu->arch.nmi_pending--;
+
+       if (vcpu->arch.nmi_pending)
+               kvm_make_request(KVM_REQ_EVENT, vcpu);
+}
+
+/* Return total number of NMIs pending injection to the VM */
+int kvm_get_nr_pending_nmis(struct kvm_vcpu *vcpu)
+{
+       return vcpu->arch.nmi_pending +
+              static_call(kvm_x86_is_vnmi_pending)(vcpu);
 }
 
 void kvm_make_scan_ioapic_request_mask(struct kvm *kvm,