[PATCH v2 31/39] KVM: arm64: gic-v5: Add GICv5 SPI injection to irqfd
Vladimir Murzin
vladimir.murzin at arm.com
Thu Jun 4 03:51:44 PDT 2026
Hi Sascha,
On 5/21/26 15:59, Sascha Bischoff wrote:
> Now that there is support for GICv5 SPIs in KVM, update
> vgic_irqfd_set_irq() to translate irqchip pins into GICv5 SPI IntIDs
> before injecting them.
>
> Also adjust IRQCHIP route validation for GICv5: use the configured SPI
> count, fall back to the default SPI count before VGIC init, and cap
> the accepted pin range to the generic irq routing table size.
>
> Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>
> ---
> arch/arm64/kvm/vgic/vgic-irqfd.c | 20 +++++++++++++++++---
> 1 file changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kvm/vgic/vgic-irqfd.c b/arch/arm64/kvm/vgic/vgic-irqfd.c
> index b9b86e3a6c862..3644516811214 100644
> --- a/arch/arm64/kvm/vgic/vgic-irqfd.c
> +++ b/arch/arm64/kvm/vgic/vgic-irqfd.c
> @@ -19,7 +19,12 @@ static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e,
> struct kvm *kvm, int irq_source_id,
> int level, bool line_status)
> {
> - unsigned int spi_id = e->irqchip.pin + VGIC_NR_PRIVATE_IRQS;
> + unsigned int spi_id;
> +
> + if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V5)
> + spi_id = vgic_v5_make_spi(e->irqchip.pin);
> + else
> + spi_id = e->irqchip.pin + VGIC_NR_PRIVATE_IRQS;
>
> if (!vgic_valid_spi(kvm, spi_id))
> return -EINVAL;
> @@ -39,15 +44,24 @@ int kvm_set_routing_entry(struct kvm *kvm,
> struct kvm_kernel_irq_routing_entry *e,
> const struct kvm_irq_routing_entry *ue)
> {
> + unsigned int nr_pins = KVM_IRQCHIP_NUM_PINS;
> int r = -EINVAL;
>
> + if (vgic_is_v5(kvm)) {
> + nr_pins = kvm->arch.vgic.nr_spis;
> + if (!nr_pins)
> + nr_pins = VGIC_V5_DEFAULT_NR_SPIS;
> +
> + nr_pins = min(nr_pins, KVM_IRQCHIP_NUM_PINS);
> + }
> +
I have a few questions about these checks.
IIUC, there are two paths that can lead us here:
vgic_init()
-> kvm_vgic_setup_default_irq_routing()
-> kvm_set_irq_routing()
-> setup_routing_entry()
-> kvm_set_routing_entry()
where vgic_init() sets nr_spis to the default value if it has not
been configured already.
And:
kvm_vm_ioctl(KVM_SET_GSI_ROUTING)
-> kvm_set_irq_routing()
-> setup_routing_entry()
-> kvm_set_routing_entry()
where nr_spis would still be 0 if KVM_SET_GSI_ROUTING is used
before the vGIC is initialized. In that case, how much harm
processing with nr_spis set to 0? Wouldn't the routing be
overwritten once the vGIC is initialized anyway?
Also, IIUC, this is not specific to vGICv5 and appears to be
equally applicable to vGICv2/v3. If so, shouldn't we apply the
same validation logic to the non-vGICv5 cases as well?
Finally, it seems the core already enforces KVM_MAX_IRQ_ROUTES,
and we lower that limit to KVM_IRQCHIP_NUM_PINS. IIUC, nr_spis
limit for vGICv5 is FIELD_MAX(GICV5_IRS_IDR5_SPI_RANGE) which
exceeds both core and our private limit.
Would it be simpler/cleaner to reject nr_spis values provided
through KVM_DEV_ARM_VGIC_GRP_NR_IRQS rather than allowing them
and later capping the accepted pin range?
Thanks
Vladimir
> switch (ue->type) {
> case KVM_IRQ_ROUTING_IRQCHIP:
> e->set = vgic_irqfd_set_irq;
> e->irqchip.irqchip = ue->u.irqchip.irqchip;
> e->irqchip.pin = ue->u.irqchip.pin;
> - if ((e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) ||
> - (e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
> + if (e->irqchip.pin >= nr_pins ||
> + e->irqchip.irqchip >= KVM_NR_IRQCHIPS)
> goto out;
> break;
> case KVM_IRQ_ROUTING_MSI:
> -- 2.34.1
>
More information about the linux-arm-kernel
mailing list