Re: [PATCH v5 09/36] KVM: arm64: gic-v5: Detect implemented PPIs on boot

Sascha Bischoff
2026-03-03T17:23:44Z

On Tue, 2026-03-03 at 15:10 +0000, Marc Zyngier wrote:
> On Thu, 26 Feb 2026 15:57:45 +0000,
> Sascha Bischoff <Sascha.Bischoff@arm.com> wrote:
> >
> > As part of booting the system and initialising KVM, create and
> > populate a mask of the implemented PPIs. This mask allows future
> > PPI
> > operations (such as save/restore or state, or syncing back into the
> > shadow state) to only consider PPIs that are actually implemented
> > on
> > the host.
> >
> > The set of implemented virtual PPIs matches the set of implemented
> > physical PPIs for a GICv5 host. Therefore, this mask represents all
> > PPIs that could ever by used by a GICv5-based guest on a specific
> > host.
> >
> > Only architected PPIs are currently supported in KVM with
> > GICv5. Moreover, as KVM only supports a subset of all possible PPIS
> > (Timers, PMU, GICv5 SW_PPI) the PPI mask only includes these PPIs,
> > if
> > present. The timers are always assumed to be present; if we have
> > KVM
> > we have EL2, which means that we have the EL1 & EL2 Timer PPIs. If
> > we
> > have a PMU (v3), then the PMUIRQ is present. The GICv5 SW_PPI is
> > always assumed to be present.
> >
> > Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
> > Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
> > ---
> >  arch/arm64/kvm/vgic/vgic-v5.c      | 30
> > ++++++++++++++++++++++++++++++
> >  include/kvm/arm_vgic.h             |  5 +++++
> >  include/linux/irqchip/arm-gic-v5.h | 10 ++++++++++
> >  3 files changed, 45 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/vgic/vgic-v5.c
> > b/arch/arm64/kvm/vgic/vgic-v5.c
> > index 9d9aa5774e634..2c51b9ba4f118 100644
> > --- a/arch/arm64/kvm/vgic/vgic-v5.c
> > +++ b/arch/arm64/kvm/vgic/vgic-v5.c
> > @@ -8,6 +8,34 @@
> >
> >  #include "vgic.h"
> >
> > +static struct vgic_v5_ppi_caps ppi_caps;
> > +
> > +/*
> > + * Not all PPIs are guaranteed to be implemented for GICv5.
> > Deterermine which
> > + * ones are, and generate a mask.
> > + */
> > +static void vgic_v5_get_implemented_ppis(void)
> > +{
> > + if (!cpus_have_final_cap(ARM64_HAS_GICV5_CPUIF))
> > + return;
> > +
> > + /*
> > + * If we have KVM, we have EL2, which means that we have
> > support for the
> > + * EL1 and EL2 P & V timers.
>
> nit: please spell out physical and virtual.

Done.

>
> > + */
> > + ppi_caps.impl_ppi_mask[0] |=
> > BIT_ULL(GICV5_ARCH_PPI_CNTHP);
> > + ppi_caps.impl_ppi_mask[0] |= BIT_ULL(GICV5_ARCH_PPI_CNTV);
> > + ppi_caps.impl_ppi_mask[0] |=
> > BIT_ULL(GICV5_ARCH_PPI_CNTHV);
> > + ppi_caps.impl_ppi_mask[0] |= BIT_ULL(GICV5_ARCH_PPI_CNTP);
> > +
> > + /* The SW_PPI should be available */
> > + ppi_caps.impl_ppi_mask[0] |=
> > BIT_ULL(GICV5_ARCH_PPI_SW_PPI);
> > +
> > + /* The PMUIRQ is available if we have the PMU */
> > + if (system_supports_pmuv3())
> > + ppi_caps.impl_ppi_mask[0] |=
> > BIT_ULL(GICV5_ARCH_PPI_PMUIRQ);
> > +}
> > +
> >  /*
> >   * Probe for a vGICv5 compatible interrupt controller, returning 0
> > on success.
> >   * Currently only supports GICv3-based VMs on a GICv5 host, and
> > hence only
> > @@ -18,6 +46,8 @@ int vgic_v5_probe(const struct gic_kvm_info
> > *info)
> >   u64 ich_vtr_el2;
> >   int ret;
> >
> > + vgic_v5_get_implemented_ppis();
> > +
> >   if (!cpus_have_final_cap(ARM64_HAS_GICV5_LEGACY))
> >   return -ENODEV;
> >
> > diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> > index f12b47e589abc..9e4798333b46c 100644
> > --- a/include/kvm/arm_vgic.h
> > +++ b/include/kvm/arm_vgic.h
> > @@ -410,6 +410,11 @@ struct vgic_v3_cpu_if {
> >   unsigned int used_lrs;
> >  };
> >
> > +/* What PPI capabilities does a GICv5 host have */
> > +struct vgic_v5_ppi_caps {
> > + u64 impl_ppi_mask[2];
> > +};
> > +
> >  struct vgic_cpu {
> >   /* CPU vif control registers for world switch */
> >   union {
> > diff --git a/include/linux/irqchip/arm-gic-v5.h
> > b/include/linux/irqchip/arm-gic-v5.h
> > index b78488df6c989..1dc05afcab53e 100644
> > --- a/include/linux/irqchip/arm-gic-v5.h
> > +++ b/include/linux/irqchip/arm-gic-v5.h
> > @@ -24,6 +24,16 @@
> >  #define GICV5_HWIRQ_TYPE_LPI UL(0x2)
> >  #define GICV5_HWIRQ_TYPE_SPI UL(0x3)
> >
> > +/*
> > + * Architected PPIs
> > + */
> > +#define GICV5_ARCH_PPI_SW_PPI 0x3
> > +#define GICV5_ARCH_PPI_PMUIRQ 0x17
> > +#define GICV5_ARCH_PPI_CNTHP 0x1a
> > +#define GICV5_ARCH_PPI_CNTV 0x1b
> > +#define GICV5_ARCH_PPI_CNTHV 0x1c
> > +#define GICV5_ARCH_PPI_CNTP 0x1e
>
> Could you dump all the architected PPI numbers from R_XDVCM here,
> even
> if they are not directly relevant to KVM? I'm pretty sure someone
> will
> find them useful at some point...

Also done.

Thanks,
Sascha

>
> Thanks,
>
> M.
>