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

Sascha Bischoff
2026-03-18T17:35:33Z

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@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@arm.com>
> > Reviewed-by: Jonathan Cameron <jonathan.cameron@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.
>