]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: gic: Introduce queue_irq_unlock to irq_ops
authorSascha Bischoff <Sascha.Bischoff@arm.com>
Thu, 19 Mar 2026 15:54:39 +0000 (15:54 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 19 Mar 2026 18:21:28 +0000 (18:21 +0000)
There are times when the default behaviour of vgic_queue_irq_unlock()
is undesirable. This is because some GICs, such a GICv5 which is the
main driver for this change, handle the majority of the interrupt
lifecycle in hardware. In this case, there is no need for a per-VCPU
AP list as the interrupt can be made pending directly. This is done
either via the ICH_PPI_x_EL2 registers for PPIs, or with the VDPEND
system instruction for SPIs and LPIs.

The vgic_queue_irq_unlock() function is made overridable using a new
function pointer in struct irq_ops. vgic_queue_irq_unlock() is
overridden if the function pointer is non-null.

This new irq_op is unused in this change - it is purely providing the
infrastructure itself. The subsequent PPI injection changes provide a
demonstration of the usage of the queue_irq_unlock irq_op.

Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/20260319154937.3619520-20-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/vgic/vgic.c
include/kvm/arm_vgic.h

index 84199d2df80af2512455d5d832f9b73a64a26d42..c46c0e1db436e06e155af2ff09ded26098579cc2 100644 (file)
@@ -404,6 +404,9 @@ bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq,
 
        lockdep_assert_held(&irq->irq_lock);
 
+       if (irq->ops && irq->ops->queue_irq_unlock)
+               return irq->ops->queue_irq_unlock(kvm, irq, flags);
+
 retry:
        vcpu = vgic_target_oracle(irq);
        if (irq->vcpu || !vcpu) {
index fdad0263499babddb984bd63aebd44b847bf7850..e9797c5dbbf0ccf19c7cd938f20394b3ceede195 100644 (file)
@@ -189,6 +189,8 @@ enum vgic_irq_config {
        VGIC_CONFIG_LEVEL
 };
 
+struct vgic_irq;
+
 /*
  * Per-irq ops overriding some common behavious.
  *
@@ -207,6 +209,12 @@ struct irq_ops {
         * peaking into the physical GIC.
         */
        bool (*get_input_level)(int vintid);
+
+       /*
+        * Function pointer to override the queuing of an IRQ.
+        */
+       bool (*queue_irq_unlock)(struct kvm *kvm, struct vgic_irq *irq,
+                               unsigned long flags) __releases(&irq->irq_lock);
 };
 
 struct vgic_irq {