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

From: Marc Zyngier <[email-masked]>
Date: Tue, 03 Mar 2026 15:10:13 +0000

On Thu, 26 Feb 2026 15:57:45 +0000,
Sascha Bischoff <[email-masked]> 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 <[email-masked]>
> Reviewed-by: Jonathan Cameron <[email-masked]>
> ---
>  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.

> +	 */
> +	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...

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.