Commit cae72dcc authored by Maxim Levitsky's avatar Maxim Levitsky Committed by Paolo Bonzini
Browse files

KVM: x86: inhibit APICv when KVM_GUESTDBG_BLOCKIRQ active



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: 61e5f69e ("KVM: x86: implement KVM_GUESTDBG_BLOCKIRQ")

Reported-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: default avatarSean Christopherson <seanjc@google.com>
Tested-by: default avatarSean Christopherson <seanjc@google.com>
Message-Id: <20211108090245.166408-1-mlevitsk@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent e6cd31f1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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);
}
+2 −1
Original line number Diff line number Diff line
@@ -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);
}
+20 −0
Original line number Diff line number Diff line
@@ -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: