* [PATCH 1/4] KVM: arm64: vgic-v4: Only attempt vLPI mapping for actual MSIs
2025-02-26 18:31 [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection Oliver Upton
@ 2025-02-26 18:31 ` Oliver Upton
2025-02-26 18:31 ` [PATCH 2/4] KVM: arm64: vgic-v4: Only WARN for HW IRQ mismatch when unmapping vLPI Oliver Upton
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Oliver Upton @ 2025-02-26 18:31 UTC (permalink / raw)
To: kvmarm
Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose, Oliver Upton,
Sudheer Dantuluri
Some 'creative' VMMs out there may assign a VFIO MSI eventfd to an SPI
routing entry.
And yes, I can already hear you shouting about possibly driving a level
interrupt with an edge-sensitive one. You know who you are.
This works for the most part, and interrupt injection winds up taking
the software path. However, when running on GICv4-enabled hardware, KVM
erroneously attempts to setup LPI forwarding, even though the KVM
routing isn't an MSI.
Thanks to misuse of a union, the MSI destination is unlikely to match any
ITS in the VM and kvm_vgic_v4_set_forwarding() bails early. Later on when
the VM is being torn down, this half-configured state triggers the
WARN_ON() in kvm_vgic_v4_unset_forwarding() due to the fact that no HW
IRQ was ever assigned.
Avoid the whole mess by preventing SPI routing entries from getting into
the LPI forwarding helpers.
Reported-by: Sudheer Dantuluri <dantuluris@google.com>
Tested-by: Sudheer Dantuluri <dantuluris@google.com>
Fixes: 196b136498b3 ("KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass")
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/arm.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index b8e55a441282..36d8dd80b431 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -2717,6 +2717,14 @@ int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
{
struct kvm_kernel_irqfd *irqfd =
container_of(cons, struct kvm_kernel_irqfd, consumer);
+ struct kvm_kernel_irq_routing_entry *irq_entry = &irqfd->irq_entry;
+
+ /*
+ * The only thing we have a chance of directly-injecting is LPIs. Maybe
+ * one day...
+ */
+ if (irq_entry->type != KVM_IRQ_ROUTING_MSI)
+ return 0;
return kvm_vgic_v4_set_forwarding(irqfd->kvm, prod->irq,
&irqfd->irq_entry);
@@ -2726,6 +2734,10 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
{
struct kvm_kernel_irqfd *irqfd =
container_of(cons, struct kvm_kernel_irqfd, consumer);
+ struct kvm_kernel_irq_routing_entry *irq_entry = &irqfd->irq_entry;
+
+ if (irq_entry->type != KVM_IRQ_ROUTING_MSI)
+ return;
kvm_vgic_v4_unset_forwarding(irqfd->kvm, prod->irq,
&irqfd->irq_entry);
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/4] KVM: arm64: vgic-v4: Only WARN for HW IRQ mismatch when unmapping vLPI
2025-02-26 18:31 [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection Oliver Upton
2025-02-26 18:31 ` [PATCH 1/4] KVM: arm64: vgic-v4: Only attempt vLPI mapping for actual MSIs Oliver Upton
@ 2025-02-26 18:31 ` Oliver Upton
2025-02-26 18:31 ` [PATCH 3/4] KVM: arm64: vgic-v4: Fall back to software irqbypass if LPI not found Oliver Upton
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Oliver Upton @ 2025-02-26 18:31 UTC (permalink / raw)
To: kvmarm
Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose, Oliver Upton,
Sudheer Dantuluri
The VMM or guest can easily screw up GICv4 vLPI injection by
misconfiguring the MSI or the virtual ITS. Don't fuss over it; limit the
WARN in vgic_v4_unset_forwarding() to fire in the worrying case where an
unrelated HW IRQ was mapped to a vLPI.
Reported-by: Sudheer Dantuluri <dantuluris@google.com>
Tested-by: Sudheer Dantuluri <dantuluris@google.com>
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/vgic/vgic-v4.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
index eedecbbbcf31..3e1de40720e0 100644
--- a/arch/arm64/kvm/vgic/vgic-v4.c
+++ b/arch/arm64/kvm/vgic/vgic-v4.c
@@ -512,7 +512,7 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int virq,
if (ret)
goto out;
- WARN_ON(!(irq->hw && irq->host_irq == virq));
+ WARN_ON(irq->hw && irq->host_irq != virq);
if (irq->hw) {
atomic_dec(&irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count);
irq->hw = false;
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/4] KVM: arm64: vgic-v4: Fall back to software irqbypass if LPI not found
2025-02-26 18:31 [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection Oliver Upton
2025-02-26 18:31 ` [PATCH 1/4] KVM: arm64: vgic-v4: Only attempt vLPI mapping for actual MSIs Oliver Upton
2025-02-26 18:31 ` [PATCH 2/4] KVM: arm64: vgic-v4: Only WARN for HW IRQ mismatch when unmapping vLPI Oliver Upton
@ 2025-02-26 18:31 ` Oliver Upton
2025-02-26 18:31 ` [PATCH 4/4] KVM: arm64: Document ordering requirements for irqbypass Oliver Upton
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Oliver Upton @ 2025-02-26 18:31 UTC (permalink / raw)
To: kvmarm
Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose, Oliver Upton,
Sudheer Dantuluri
Continuing with the theme of broken VMMs and guests, irqbypass
registration can fail if the virtual ITS lacks a translation for the
MSI. Either the guest hasn't mapped it or userspace may have forgotten
to restore the ITS.
Exit silently and allow irqbypass configuration to succeed. As a reward
for ingenuity, LPIs are demoted to software injection.
Tested-by: Sudheer Dantuluri <dantuluris@google.com>
Fixes: 196b136498b3 ("KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass")
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/vgic/vgic-v4.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
index 3e1de40720e0..9f51d58b5f8a 100644
--- a/arch/arm64/kvm/vgic/vgic-v4.c
+++ b/arch/arm64/kvm/vgic/vgic-v4.c
@@ -415,7 +415,7 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
struct vgic_irq *irq;
struct its_vlpi_map map;
unsigned long flags;
- int ret;
+ int ret = 0;
if (!vgic_supports_direct_msis(kvm))
return 0;
@@ -430,10 +430,15 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
mutex_lock(&its->its_lock);
- /* Perform the actual DevID/EventID -> LPI translation. */
- ret = vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid,
- irq_entry->msi.data, &irq);
- if (ret)
+ /*
+ * Perform the actual DevID/EventID -> LPI translation.
+ *
+ * Silently exit if translation fails as the guest (or userspace!) has
+ * managed to do something stupid. Emulated LPI injection will still
+ * work if the guest figures itself out at a later time.
+ */
+ if (vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid,
+ irq_entry->msi.data, &irq))
goto out;
/* Silently exit if the vLPI is already mapped */
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/4] KVM: arm64: Document ordering requirements for irqbypass
2025-02-26 18:31 [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection Oliver Upton
` (2 preceding siblings ...)
2025-02-26 18:31 ` [PATCH 3/4] KVM: arm64: vgic-v4: Fall back to software irqbypass if LPI not found Oliver Upton
@ 2025-02-26 18:31 ` Oliver Upton
2025-02-26 18:58 ` [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection Marc Zyngier
2025-02-26 21:27 ` Oliver Upton
5 siblings, 0 replies; 7+ messages in thread
From: Oliver Upton @ 2025-02-26 18:31 UTC (permalink / raw)
To: kvmarm; +Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose, Oliver Upton
One of the not-so-obvious requirements for restoring a VM is ensuring
that the vITS has been restored _before_ creating any irqbypass mappings.
This is because KVM needs to get the guest translation for MSIs to
correctly assemble the vLPI mapping getting installed in the physical
ITS.
Document the restore ordering requirements necessary for GICv4 vLPI
injection to work.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
Documentation/virt/kvm/devices/arm-vgic-its.rst | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Documentation/virt/kvm/devices/arm-vgic-its.rst b/Documentation/virt/kvm/devices/arm-vgic-its.rst
index e053124f77c4..f0171aff1126 100644
--- a/Documentation/virt/kvm/devices/arm-vgic-its.rst
+++ b/Documentation/virt/kvm/devices/arm-vgic-its.rst
@@ -126,7 +126,8 @@ KVM_DEV_ARM_VGIC_GRP_ITS_REGS
ITS Restore Sequence:
---------------------
-The following ordering must be followed when restoring the GIC and the ITS:
+The following ordering must be followed when restoring the GIC, ITS, and
+KVM_IRQFD assignments:
a) restore all guest memory and create vcpus
b) restore all redistributors
@@ -139,6 +140,8 @@ d) restore the ITS in the following order:
3. Load the ITS table data (KVM_DEV_ARM_ITS_RESTORE_TABLES)
4. Restore GITS_CTLR
+e) restore KVM_IRQFD assignments for MSIs
+
Then vcpus can be started.
ITS Table ABI REV0:
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection
2025-02-26 18:31 [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection Oliver Upton
` (3 preceding siblings ...)
2025-02-26 18:31 ` [PATCH 4/4] KVM: arm64: Document ordering requirements for irqbypass Oliver Upton
@ 2025-02-26 18:58 ` Marc Zyngier
2025-02-26 21:27 ` Oliver Upton
5 siblings, 0 replies; 7+ messages in thread
From: Marc Zyngier @ 2025-02-26 18:58 UTC (permalink / raw)
To: Oliver Upton; +Cc: kvmarm, Joey Gouly, Suzuki K Poulose
On Wed, 26 Feb 2025 18:31:20 +0000,
Oliver Upton <oliver.upton@linux.dev> wrote:
>
> Small batch of fixes for vLPI injection issues that can happen when
> userspace is being mean:
>
> - MSI interrupt sources could be mapped to non-MSI GSI routing entries.
> KVM doesn't account for the routing type and blindly attempts to map
> a vLPI.
>
> - KVM_IRQFD mappings could be installed before the ITS has been
> restored, leading to kvm_vgic_v4_set_forwarding() failing due to the
> missing guest translation
>
> Prevent userspace from triggering a WARN() because of these issues and
> gracefully fall back to software vLPI routing/injection should irqbypass
> fail.
>
> I've thrown in some documentation on the restore ordering necessary to get
> GICv4 vLPI injection working correctly as well.
>
> Marc, I'm planning to take these for 6.15.
Go for it.
Acked-by: Marc Zyngier <maz@kernel.org>
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection
2025-02-26 18:31 [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection Oliver Upton
` (4 preceding siblings ...)
2025-02-26 18:58 ` [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection Marc Zyngier
@ 2025-02-26 21:27 ` Oliver Upton
5 siblings, 0 replies; 7+ messages in thread
From: Oliver Upton @ 2025-02-26 21:27 UTC (permalink / raw)
To: kvmarm, Oliver Upton; +Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose
On Wed, 26 Feb 2025 10:31:20 -0800, Oliver Upton wrote:
> Small batch of fixes for vLPI injection issues that can happen when
> userspace is being mean:
>
> - MSI interrupt sources could be mapped to non-MSI GSI routing entries.
> KVM doesn't account for the routing type and blindly attempts to map
> a vLPI.
>
> [...]
Applied to next, thanks!
[1/4] KVM: arm64: vgic-v4: Only attempt vLPI mapping for actual MSIs
https://git.kernel.org/kvmarm/kvmarm/c/a0d7e2fc61ab
[2/4] KVM: arm64: vgic-v4: Only WARN for HW IRQ mismatch when unmapping vLPI
https://git.kernel.org/kvmarm/kvmarm/c/d0b79563fd60
[3/4] KVM: arm64: vgic-v4: Fall back to software irqbypass if LPI not found
https://git.kernel.org/kvmarm/kvmarm/c/5c57533eb8c1
[4/4] KVM: arm64: Document ordering requirements for irqbypass
https://git.kernel.org/kvmarm/kvmarm/c/d766d87cf4a0
--
Best,
Oliver
^ permalink raw reply [flat|nested] 7+ messages in thread