All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] KVM: arm64: Fixes/clarification for GICv4 vLPI injection
@ 2025-02-26 18:31 Oliver Upton
  2025-02-26 18:31 ` [PATCH 1/4] KVM: arm64: vgic-v4: Only attempt vLPI mapping for actual MSIs Oliver Upton
                   ` (5 more replies)
  0 siblings, 6 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

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.

Oliver Upton (4):
  KVM: arm64: vgic-v4: Only attempt vLPI mapping for actual MSIs
  KVM: arm64: vgic-v4: Only WARN for HW IRQ mismatch when unmapping vLPI
  KVM: arm64: vgic-v4: Fall back to software irqbypass if LPI not found
  KVM: arm64: Document ordering requirements for irqbypass

 Documentation/virt/kvm/devices/arm-vgic-its.rst |  5 ++++-
 arch/arm64/kvm/arm.c                            | 12 ++++++++++++
 arch/arm64/kvm/vgic/vgic-v4.c                   | 17 +++++++++++------
 3 files changed, 27 insertions(+), 7 deletions(-)


base-commit: 0ad2507d5d93f39619fc42372c347d6006b64319
-- 
2.39.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [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

end of thread, other threads:[~2025-02-26 21:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 3/4] KVM: arm64: vgic-v4: Fall back to software irqbypass if LPI not found Oliver Upton
2025-02-26 18:31 ` [PATCH 4/4] KVM: arm64: Document ordering requirements for irqbypass 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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.