[PATCH v1] KVM: arm64: vgic-v4: Don't forward an LPI with no target vCPU
Fuad Tabba
fuad.tabba at linux.dev
Mon Oct 12 01:47:43 PDT 2026
KVM keeps one vgic_irq per LPI. The MAPTI that creates it sets its
target vCPU from that MAPTI's collection, and a later MAPTI of the same
LPI leaves the target alone. Mapping one LPI from two events is
UNPREDICTABLE (IHI 0069H.b, 5.2.10), but nothing stops a guest doing
it. If the first MAPTI names a collection the guest never maps and the
second a mapped one, the LPI translates through the second event with
a NULL target vCPU.
When the VMM routes an assigned device's MSI to that event on a host
with GICv4 enabled, kvm_vgic_v4_set_forwarding() takes the vPE from the
NULL target vCPU and the host oopses:
Unable to handle kernel paging request at virtual address 0000000000001980
[...]
Call trace:
its_build_vmapti_cmd (drivers/irqchip/irq-gic-v3-its.c:943) (P)
its_irq_set_vcpu_affinity (drivers/irqchip/irq-gic-v3-its.c:1380)
irq_set_vcpu_affinity (kernel/irq/manage.c:670)
its_map_vlpi (drivers/irqchip/irq-gic-v4.c:326)
kvm_vgic_v4_set_forwarding (arch/arm64/kvm/vgic/vgic-v4.c:485)
kvm_arch_irq_bypass_add_producer (arch/arm64/kvm/arm.c:2977)
irq_bypass_register_consumer (virt/lib/irqbypass.c:44)
kvm_irqfd (arch/arm64/kvm/../../../virt/kvm/eventfd.c:496)
kvm_vm_ioctl (arch/arm64/kvm/../../../virt/kvm/kvm_main.c:5270)
Leave such an LPI to the software path, which copes with a NULL target,
as kvm_vgic_v4_set_forwarding() already does when the MSI doesn't
translate.
Fixes: 196b136498b35 ("KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass")
Cc: stable at vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba at linux.dev>
---
Tested on QEMU, which emulates the GICv4 ITS, with a local reproducer
that sets up the two MAPTIs and forwards a vfio-pci MSI to the LPI. It
oopses without the fix and passes with it. Not tested on GICv4 hardware.
Based on v7.3-rc3.
arch/arm64/kvm/vgic/vgic-v4.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
index ed236f083f0d7..545e55317c863 100644
--- a/arch/arm64/kvm/vgic/vgic-v4.c
+++ b/arch/arm64/kvm/vgic/vgic-v4.c
@@ -466,6 +466,13 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
if (irq->hw)
goto out_unlock_irq;
+ /*
+ * Silently exit if the LPI has no target vCPU, as one mapped by
+ * multiple ITEs (UNPREDICTABLE) can have.
+ */
+ if (!irq->target_vcpu)
+ goto out_unlock_irq;
+
/*
* Emit the mapping request. If it fails, the ITS probably
* isn't v4 compatible, so let's silently bail out. Holding
base-commit: fd73f4a6659897191fa0d40695fe370925dd3780
--
2.39.5
More information about the linux-arm-kernel
mailing list