Skip to content

Commit 9bce50b

Browse files
author
Gavin Shan
committed
KVM: arm64: Unmap vLPIs affected by changes to GSI routing information
JIRA: https://issues.redhat.com/browse/RHEL-93666 KVM's interrupt infrastructure is dodgy at best, allowing for some ugly 'off label' usage of the various UAPIs. In one example, userspace can change the routing entry of a particular "GSI" after configuring irqbypass with KVM_IRQFD. KVM/arm64 is oblivious to this, and winds up preserving the stale translation in cases where vLPIs are configured. Honor userspace's intentions and tear down the vLPI mapping if affected by a "GSI" routing change. Make no attempt to reconstruct vLPIs if the new target is an MSI and just fall back to software injection. Tested-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me> Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Link: https://lore.kernel.org/r/20250523194722.4066715-5-oliver.upton@linux.dev Signed-off-by: Marc Zyngier <maz@kernel.org> (cherry picked from commit 4bf3693) Signed-off-by: Gavin Shan <gshan@redhat.com>
1 parent 5c929e4 commit 9bce50b

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

arch/arm64/kvm/arm.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,6 +2741,7 @@ int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
27412741
return kvm_vgic_v4_set_forwarding(irqfd->kvm, prod->irq,
27422742
&irqfd->irq_entry);
27432743
}
2744+
27442745
void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
27452746
struct irq_bypass_producer *prod)
27462747
{
@@ -2754,6 +2755,28 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
27542755
kvm_vgic_v4_unset_forwarding(irqfd->kvm, prod->irq);
27552756
}
27562757

2758+
bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old,
2759+
struct kvm_kernel_irq_routing_entry *new)
2760+
{
2761+
if (new->type != KVM_IRQ_ROUTING_MSI)
2762+
return true;
2763+
2764+
return memcmp(&old->msi, &new->msi, sizeof(new->msi));
2765+
}
2766+
2767+
int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
2768+
uint32_t guest_irq, bool set)
2769+
{
2770+
/*
2771+
* Remapping the vLPI requires taking the its_lock mutex to resolve
2772+
* the new translation. We're in spinlock land at this point, so no
2773+
* chance of resolving the translation.
2774+
*
2775+
* Unmap the vLPI and fall back to software LPI injection.
2776+
*/
2777+
return kvm_vgic_v4_unset_forwarding(kvm, host_irq);
2778+
}
2779+
27572780
void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *cons)
27582781
{
27592782
struct kvm_kernel_irqfd *irqfd =

0 commit comments

Comments
 (0)