Skip to content

Commit 8095185

Browse files
author
Sebastian Ott
committed
KVM: arm64: Unmap vLPIs affected by changes to GSI routing information
JIRA: https://issues.redhat.com/browse/RHEL-92805 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 <[email protected]> Signed-off-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]> (cherry picked from commit 4bf3693) Signed-off-by: Sebastian Ott <[email protected]>
1 parent 71e3e0c commit 8095185

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
@@ -2766,6 +2766,7 @@ int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
27662766
return kvm_vgic_v4_set_forwarding(irqfd->kvm, prod->irq,
27672767
&irqfd->irq_entry);
27682768
}
2769+
27692770
void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
27702771
struct irq_bypass_producer *prod)
27712772
{
@@ -2779,6 +2780,28 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
27792780
kvm_vgic_v4_unset_forwarding(irqfd->kvm, prod->irq);
27802781
}
27812782

2783+
bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old,
2784+
struct kvm_kernel_irq_routing_entry *new)
2785+
{
2786+
if (new->type != KVM_IRQ_ROUTING_MSI)
2787+
return true;
2788+
2789+
return memcmp(&old->msi, &new->msi, sizeof(new->msi));
2790+
}
2791+
2792+
int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
2793+
uint32_t guest_irq, bool set)
2794+
{
2795+
/*
2796+
* Remapping the vLPI requires taking the its_lock mutex to resolve
2797+
* the new translation. We're in spinlock land at this point, so no
2798+
* chance of resolving the translation.
2799+
*
2800+
* Unmap the vLPI and fall back to software LPI injection.
2801+
*/
2802+
return kvm_vgic_v4_unset_forwarding(kvm, host_irq);
2803+
}
2804+
27822805
void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *cons)
27832806
{
27842807
struct kvm_kernel_irqfd *irqfd =

0 commit comments

Comments
 (0)