From: Sascha Bischoff Date: Thu, 19 Mar 2026 15:54:39 +0000 (+0000) Subject: KVM: arm64: gic: Introduce queue_irq_unlock to irq_ops X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4a9a32d3538a9d800067be113b0196271a478c6a;p=thirdparty%2Fkernel%2Flinux.git KVM: arm64: gic: Introduce queue_irq_unlock to irq_ops 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 Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/20260319154937.3619520-20-sascha.bischoff@arm.com Signed-off-by: Marc Zyngier --- diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index 84199d2df80af..c46c0e1db436e 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -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) { diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index fdad0263499ba..e9797c5dbbf0c 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -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 {