[RFC PATCH 03/13] KVM: arm64: Refactor out locked section of kvm_vgic_v4_set_forwarding()

Maximilian Dittgen mdittgen at amazon.de
Thu Nov 20 06:02:52 PST 2025


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 <mdittgen at amazon.com>
---
 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




More information about the linux-arm-kernel mailing list