[PATCH v6 20/39] KVM: arm64: gic-v5: Init Private IRQs (PPIs) for GICv5

Sascha Bischoff Sascha.Bischoff at arm.com
Wed Mar 18 10:34:26 PDT 2026


On Tue, 2026-03-17 at 16:42 +0000, Marc Zyngier wrote:
> On Tue, 17 Mar 2026 11:45:10 +0000,
> Sascha Bischoff <Sascha.Bischoff at arm.com> wrote:
> > 
> > Initialise the private interrupts (PPIs, only) for GICv5. This
> > means
> > that a GICv5-style intid is generated (which encodes the PPI type
> > in
> > the top bits) instead of the 0-based index that is used for older
> > GICs.
> > 
> > Additionally, set all of the GICv5 PPIs to use Level for the
> > handling
> > mode, with the exception of the SW_PPI which uses Edge. This
> > matches
> > the architecturally-defined set in the GICv5 specification (the
> > CTIIRQ
> > handling mode is IMPDEF, so Level has been picked for that).
> > 
> > Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>
> > Reviewed-by: Jonathan Cameron <jonathan.cameron at huawei.com>
> > ---
> >  arch/arm64/kvm/vgic/vgic-init.c | 95 +++++++++++++++++++++++------
> > ----
> >  1 file changed, 66 insertions(+), 29 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/vgic/vgic-init.c
> > b/arch/arm64/kvm/vgic/vgic-init.c
> > index e1be9c5ada7b3..f8d7d5a895e79 100644
> > --- a/arch/arm64/kvm/vgic/vgic-init.c
> > +++ b/arch/arm64/kvm/vgic/vgic-init.c
> > @@ -250,9 +250,64 @@ int kvm_vgic_vcpu_nv_init(struct kvm_vcpu
> > *vcpu)
> >  	return ret;
> >  }
> >  
> > +static void vgic_allocate_private_irq(struct kvm_vcpu *vcpu, int
> > i, u32 type)
> > +{
> > +	struct vgic_irq *irq = &vcpu-
> > >arch.vgic_cpu.private_irqs[i];
> > +
> > +	INIT_LIST_HEAD(&irq->ap_list);
> > +	raw_spin_lock_init(&irq->irq_lock);
> > +	irq->vcpu = NULL;
> > +	irq->target_vcpu = vcpu;
> > +	refcount_set(&irq->refcount, 0);
> > +
> > +	irq->intid = i;
> > +	if (vgic_irq_is_sgi(i)) {
> > +		/* SGIs */
> > +		irq->enabled = 1;
> > +		irq->config = VGIC_CONFIG_EDGE;
> > +	} else {
> > +		/* PPIs */
> > +		irq->config = VGIC_CONFIG_LEVEL;
> > +	}
> > +
> > +	switch (type) {
> > +	case KVM_DEV_TYPE_ARM_VGIC_V3:
> > +		irq->group = 1;
> > +		irq->mpidr = kvm_vcpu_get_mpidr_aff(vcpu);
> > +		break;
> > +	case KVM_DEV_TYPE_ARM_VGIC_V2:
> > +		irq->group = 0;
> > +		irq->targets = BIT(vcpu->vcpu_id);
> > +		break;
> > +	}
> > +}
> > +
> > +static void vgic_v5_allocate_private_irq(struct kvm_vcpu *vcpu,
> > int i, u32 type)
> > +{
> > +	struct vgic_irq *irq = &vcpu-
> > >arch.vgic_cpu.private_irqs[i];
> > +
> > +	INIT_LIST_HEAD(&irq->ap_list);
> > +	raw_spin_lock_init(&irq->irq_lock);
> > +	irq->vcpu = NULL;
> > +	irq->target_vcpu = vcpu;
> > +	refcount_set(&irq->refcount, 0);
> > +
> > +	irq->intid = vgic_v5_make_ppi(i);
> > +
> > +	/* The only Edge architected PPI is the SW_PPI */
> > +	if (i == GICV5_ARCH_PPI_SW_PPI)
> > +		irq->config = VGIC_CONFIG_EDGE;
> > +	else
> > +		irq->config = VGIC_CONFIG_LEVEL;
> > +
> > +	/* Register the GICv5-specific PPI ops */
> > +	vgic_v5_set_ppi_ops(irq);
> 
> I'd definitely expect this to use the generic accessor instead of
> something v5-specific.

I think it is cleaner to use a helper here, as otherwise we need to
expose the instance of struct irq_ops outside of the vgic-v5 code.
We're already handling a special case for vgic-v5 here.

Given my response to the previous patch, this code would be changed
with:

diff --git a/arch/arm64/kvm/vgic/vgic-init.c
b/arch/arm64/kvm/vgic/vgic-init.c
index f8d7d5a895e79..e0366e8c144d5 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -285,6 +285,7 @@ static void vgic_allocate_private_irq(struct
kvm_vcpu *vcpu, int i, u32 type)
 static void vgic_v5_allocate_private_irq(struct kvm_vcpu *vcpu, int i,
u32 type)
 {
        struct vgic_irq *irq = &vcpu->arch.vgic_cpu.private_irqs[i];
+       u32 intid = vgic_v5_make_ppi(i);
 
        INIT_LIST_HEAD(&irq->ap_list);
        raw_spin_lock_init(&irq->irq_lock);
@@ -292,7 +293,7 @@ static void vgic_v5_allocate_private_irq(struct
kvm_vcpu *vcpu, int i, u32 type)
        irq->target_vcpu = vcpu;
        refcount_set(&irq->refcount, 0);
 
-       irq->intid = vgic_v5_make_ppi(i);
+       irq->intid = intid;
 
        /* The only Edge architected PPI is the SW_PPI */
        if (i == GICV5_ARCH_PPI_SW_PPI)
@@ -301,7 +302,7 @@ static void vgic_v5_allocate_private_irq(struct
kvm_vcpu *vcpu, int i, u32 type)
                irq->config = VGIC_CONFIG_LEVEL;
 
        /* Register the GICv5-specific PPI ops */
-       vgic_v5_set_ppi_ops(irq);
+       vgic_v5_set_ppi_ops(vcpu, intid);
 }
 
 static int vgic_allocate_private_irqs_locked(struct kvm_vcpu *vcpu,
u32 type)

Thanks,
Sascha

> 
> Thanks,
> 
> 	M.
> 



More information about the linux-arm-kernel mailing list