]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: x86: Explicitly check for in-kernel PIC when getting ExtINT
authorSean Christopherson <seanjc@google.com>
Wed, 11 Jun 2025 21:35:51 +0000 (14:35 -0700)
committerSean Christopherson <seanjc@google.com>
Fri, 20 Jun 2025 20:52:48 +0000 (13:52 -0700)
Explicitly check for an in-kernel PIC when checking for a pending ExtINT
in the PIC.  Effectively swapping the split vs. full irqchip logic will
allow guarding the in-kernel I/O APIC (and PIC) emulation with a Kconfig,
and also makes it more obvious that kvm_pic_read_irq() won't result in a
NULL pointer dereference.

Opportunistically add WARNs in the fallthrough path, mostly to document
that the userspace ExtINT logic is only relevant to split IRQ chips.

Acked-by: Kai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/r/20250611213557.294358-13-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/irq.c

index b696161ec0786a8bafa8af88cc9a1e5b842d9692..fb3bad0f496576e9fde760a31579e39135a14c5b 100644 (file)
@@ -42,6 +42,14 @@ static int pending_userspace_extint(struct kvm_vcpu *v)
        return v->arch.pending_external_vector != -1;
 }
 
+static int get_userspace_extint(struct kvm_vcpu *vcpu)
+{
+       int vector = vcpu->arch.pending_external_vector;
+
+       vcpu->arch.pending_external_vector = -1;
+       return vector;
+}
+
 /*
  * check if there is pending interrupt from
  * non-APIC source without intack.
@@ -68,10 +76,11 @@ int kvm_cpu_has_extint(struct kvm_vcpu *v)
        if (!kvm_apic_accept_pic_intr(v))
                return 0;
 
-       if (irqchip_split(v->kvm))
-               return pending_userspace_extint(v);
-       else
+       if (pic_in_kernel(v->kvm))
                return v->kvm->arch.vpic->output;
+
+       WARN_ON_ONCE(!irqchip_split(v->kvm));
+       return pending_userspace_extint(v);
 }
 
 /*
@@ -127,13 +136,11 @@ int kvm_cpu_get_extint(struct kvm_vcpu *v)
                return v->kvm->arch.xen.upcall_vector;
 #endif
 
-       if (irqchip_split(v->kvm)) {
-               int vector = v->arch.pending_external_vector;
-
-               v->arch.pending_external_vector = -1;
-               return vector;
-       } else
+       if (pic_in_kernel(v->kvm))
                return kvm_pic_read_irq(v->kvm); /* PIC */
+
+       WARN_ON_ONCE(!irqchip_split(v->kvm));
+       return get_userspace_extint(v);
 }
 EXPORT_SYMBOL_GPL(kvm_cpu_get_extint);