diff options
| author | Fuad Tabba <fuad.tabba@linux.dev> | 2026-10-13 09:16:45 +0100 |
|---|---|---|
| committer | Marc Zyngier <maz@kernel.org> | 2026-10-17 09:49:59 +0100 |
| commit | de81b28f0b83b22163d7d9a9b708d7aa912e0ef7 (patch) | |
| tree | 6f8b5ca87eb79d158a17d0d4672037fc32902c47 /scripts/basic/split-include.c | |
| parent | b31bce255a009b17c26bcada1f23c15ebc3fbff1 (diff) | |
| download | linux-de81b28f0b83b22163d7d9a9b708d7aa912e0ef7.tar.gz linux-de81b28f0b83b22163d7d9a9b708d7aa912e0ef7.zip | |
KVM: arm64: vgic-its: Don't map an LPI from more than one event
KVM keeps one vgic_irq per LPI. A MAPTI of an LPI whose vgic_irq
already exists reuses it for the new ITE and leaves its target vCPU as
it was. Mapping one LPI from two events is UNPREDICTABLE (IHI 0069H.b,
5.2.10), but nothing stops a guest from 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)
Track in each vgic_irq whether an ITE maps it. Drop a MAPTI of an LPI
that is already mapped, as a failed MAPTI already is. Restoring the ITS
tables keeps the first ITE it reads for each LPI and drops any later
one, so a guest saved with a double mapping still restores. Key the
check on the mapping, not on the vgic_irq. A vgic_irq outlives its ITE
while anything holds a reference to it, such as the vCPU it was last
queued on. A later MAPTI of such an LPI succeeds as before, and now
retargets it to its collection.
Fixes: 196b136498b35 ("KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass")
Suggested-by: Marc Zyngier <maz@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Oliver Upton <oupton@kernel.org>
Link: https://patch.msgid.link/20261013081646.933312-2-fuad.tabba@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
Diffstat (limited to 'scripts/basic/split-include.c')
0 files changed, 0 insertions, 0 deletions
