Commit cd9140ad authored by Sean Christopherson's avatar Sean Christopherson
Browse files

KVM: x86: Explicitly check for in-kernel PIC when getting ExtINT



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: default avatarKai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/r/20250611213557.294358-13-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 2c31aa74
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -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);