]> git.baikalelectronics.ru Git - kernel.git/commitdiff
KVM: x86: inhibit APICv when KVM_GUESTDBG_BLOCKIRQ active
authorMaxim Levitsky <mlevitsk@redhat.com>
Mon, 8 Nov 2021 09:02:45 +0000 (11:02 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 11 Nov 2021 15:56:20 +0000 (10:56 -0500)
KVM_GUESTDBG_BLOCKIRQ relies on interrupts being injected using
standard kvm's inject_pending_event, and not via APICv/AVIC.

Since this is a debug feature, just inhibit APICv/AVIC while
KVM_GUESTDBG_BLOCKIRQ is in use on at least one vCPU.

Fixes: 997520b3b92d5 ("KVM: x86: implement KVM_GUESTDBG_BLOCKIRQ")
Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: Sean Christopherson <seanjc@google.com>
Tested-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20211108090245.166408-1-mlevitsk@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/svm/avic.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c

index 32345241e620c369eb87d6259d0f2ee8276c3012..b71023c64b83a8e8fbe141b9e01e35b37200e308 100644 (file)
@@ -1034,6 +1034,7 @@ struct kvm_x86_msr_filter {
 #define APICV_INHIBIT_REASON_IRQWIN     3
 #define APICV_INHIBIT_REASON_PIT_REINJ  4
 #define APICV_INHIBIT_REASON_X2APIC    5
+#define APICV_INHIBIT_REASON_BLOCKIRQ  6
 
 struct kvm_arch {
        unsigned long n_used_mmu_pages;
index 8052d92069e01f88b750e3c238163182aec68540..affc0ea98d302286303188c91bfdb73bb2cef7e2 100644 (file)
@@ -904,7 +904,8 @@ bool svm_check_apicv_inhibit_reasons(ulong bit)
                          BIT(APICV_INHIBIT_REASON_NESTED) |
                          BIT(APICV_INHIBIT_REASON_IRQWIN) |
                          BIT(APICV_INHIBIT_REASON_PIT_REINJ) |
-                         BIT(APICV_INHIBIT_REASON_X2APIC);
+                         BIT(APICV_INHIBIT_REASON_X2APIC) |
+                         BIT(APICV_INHIBIT_REASON_BLOCKIRQ);
 
        return supported & BIT(bit);
 }
index 71f54d85f104c94d3a8a4bd1d458ab4121bfe755..e4fc9ff7cd9443f5d05d76a8a7d65c0e61ea4f19 100644 (file)
@@ -7565,7 +7565,8 @@ static void hardware_unsetup(void)
 static bool vmx_check_apicv_inhibit_reasons(ulong bit)
 {
        ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
-                         BIT(APICV_INHIBIT_REASON_HYPERV);
+                         BIT(APICV_INHIBIT_REASON_HYPERV) |
+                         BIT(APICV_INHIBIT_REASON_BLOCKIRQ);
 
        return supported & BIT(bit);
 }
index 6bfef1d70ce1f664b47752cec68679fa3d2d5882..d7d2f1bbd83fc08022b8e9429971322d4c079877 100644 (file)
@@ -10753,6 +10753,24 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
        return ret;
 }
 
+static void kvm_arch_vcpu_guestdbg_update_apicv_inhibit(struct kvm *kvm)
+{
+       bool inhibit = false;
+       struct kvm_vcpu *vcpu;
+       int i;
+
+       down_write(&kvm->arch.apicv_update_lock);
+
+       kvm_for_each_vcpu(i, vcpu, kvm) {
+               if (vcpu->guest_debug & KVM_GUESTDBG_BLOCKIRQ) {
+                       inhibit = true;
+                       break;
+               }
+       }
+       __kvm_request_apicv_update(kvm, !inhibit, APICV_INHIBIT_REASON_BLOCKIRQ);
+       up_write(&kvm->arch.apicv_update_lock);
+}
+
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
                                        struct kvm_guest_debug *dbg)
 {
@@ -10805,6 +10823,8 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 
        static_call(kvm_x86_update_exception_bitmap)(vcpu);
 
+       kvm_arch_vcpu_guestdbg_update_apicv_inhibit(vcpu->kvm);
+
        r = 0;
 
 out: