kvm_vgic_v4_set_forwarding() acquires its_lock to safely map guest LPIs to host IRQs for vLPI upgrades. Future per-vCPU direct vLPI injection requires atomically upgrading multiple LPIs while holding its_lock, which would cause recursive locking when calling kvm_vgic_v4_set_forwarding(). Extract the locked portion to kvm_vgic_v4_set_forwarding_locked() to allow callers already holding its_lock to perform vLPI upgrades without recursive locking. No functional change. Signed-off-by: Maximilian Dittgen --- arch/arm64/kvm/vgic/vgic-v4.c | 38 +++++++++++++++++++++-------------- include/kvm/arm_vgic.h | 3 +++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c index fb2e6af96aa9..4a1825a1a5d7 100644 --- a/arch/arm64/kvm/vgic/vgic-v4.c +++ b/arch/arm64/kvm/vgic/vgic-v4.c @@ -483,27 +483,15 @@ int kvm_vgic_v4_map_irq_to_host(struct kvm *kvm, int virq, return 0; } -int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq, - struct kvm_kernel_irq_routing_entry *irq_entry) +int kvm_vgic_v4_set_forwarding_locked(struct kvm *kvm, int virq, + struct kvm_kernel_irq_routing_entry *irq_entry, struct vgic_its *its) { - struct vgic_its *its; struct vgic_irq *irq; struct its_vlpi_map map; unsigned long flags; int ret = 0; - if (!vgic_supports_direct_msis(kvm)) - return 0; - - /* - * Get the ITS, and escape early on error (not a valid - * doorbell for any of our vITSs). - */ - its = vgic_get_its(kvm, irq_entry); - if (IS_ERR(its)) - return 0; - - guard(mutex)(&its->its_lock); + lockdep_assert_held(&its->its_lock); /* * Perform the actual DevID/EventID -> LPI translation. @@ -567,6 +555,26 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq, return ret; } +int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq, + struct kvm_kernel_irq_routing_entry *irq_entry) +{ + struct vgic_its *its; + + if (!vgic_supports_direct_msis(kvm)) + return 0; + + /* + * Get the ITS, and escape early on error (not a valid + * doorbell for any of our vITSs). + */ + its = vgic_get_its(kvm, irq_entry); + if (IS_ERR(its)) + return 0; + + guard(mutex)(&its->its_lock); + return kvm_vgic_v4_set_forwarding_locked(kvm, virq, irq_entry, its); +} + static struct vgic_irq *__vgic_host_irq_get_vlpi(struct kvm *kvm, int host_irq) { struct vgic_irq *irq; diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 02842754627f..18a49c4b83f8 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -454,6 +454,9 @@ int kvm_vgic_v4_map_irq_to_host(struct kvm *kvm, int virq, struct kvm_kernel_irq_routing_entry *irq_entry); int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int irq, struct kvm_kernel_irq_routing_entry *irq_entry); +int kvm_vgic_v4_set_forwarding_locked(struct kvm *kvm, int virq, + struct kvm_kernel_irq_routing_entry *irq_entry, + struct vgic_its *its); void kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int host_irq); -- 2.50.1 (Apple Git-155) Amazon Web Services Development Center Germany GmbH Tamara-Danz-Str. 13 10243 Berlin Geschaeftsfuehrung: Christian Schlaeger, Christof Hellmis Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B Sitz: Berlin Ust-ID: DE 365 538 597