Re: [PATCH v4 10/36] KVM: arm64: gic-v5: Detect implemented PPIs on boot
From: Sascha Bischoff <hidden>
Date: 2026-01-30 12:34:40
Also in:
kvm, kvmarm
On Fri, 2026-01-30 at 11:03 +0000, Marc Zyngier wrote:
On Wed, 28 Jan 2026 18:01:54 +0000, Sascha Bischoff [off-list ref] wrote:quoted
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 <redacted> --- arch/arm64/kvm/vgic/vgic-init.c | 4 ++++ arch/arm64/kvm/vgic/vgic-v5.c | 33 ++++++++++++++++++++++++++++++ arch/arm64/kvm/vgic/vgic.h | 1 + include/kvm/arm_vgic.h | 5 +++++ include/linux/irqchip/arm-gic-v5.h | 10 +++++++++ 5 files changed, 53 insertions(+)diff --git a/arch/arm64/kvm/vgic/vgic-init.cb/arch/arm64/kvm/vgic/vgic-init.c index 86c149537493..653364299154 100644--- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c@@ -750,5 +750,9 @@ int kvm_vgic_hyp_init(void)} kvm_info("vgic interrupt IRQ%d\n", kvm_vgic_global_state.maint_irq); + + /* Always safe to call */ + vgic_v5_get_implemented_ppis();What is the reason for calling this from the generic code, while it is v5-specific? I'd have expected this to be entirely contained in the v5 subsystem.
At this point, I don't think that there is a reason anymore. Previously, it somehow made more sense to me to do it like this (although, I do fail to see why I thought that was the case at the time). I've just reworked this to be called as part of probe (and made it static in the process).
quoted
+ return 0; }diff --git a/arch/arm64/kvm/vgic/vgic-v5.cb/arch/arm64/kvm/vgic/vgic-v5.c index 23d0a495d855..9bd5a85ba203 100644--- a/arch/arm64/kvm/vgic/vgic-v5.c +++ b/arch/arm64/kvm/vgic/vgic-v5.c@@ -8,6 +8,8 @@#include "vgic.h" +static struct vgic_v5_ppi_caps *ppi_caps; + /* * Probe for a vGICv5 compatible interrupt controller, returning 0 on success. * Currently only supports GICv3-based VMs on a GICv5 host, and hence only@@ -53,3 +55,34 @@ int vgic_v5_probe(const struct gic_kvm_info*info) return 0; } + +/* + * Not all PPIs are guaranteed to be implemented for GICv5. Deterermine which + * ones are, and generate a mask. + */ +void vgic_v5_get_implemented_ppis(void) +{ + if (!cpus_have_final_cap(ARM64_HAS_GICV5_CPUIF)) + return; + + /* Never freed again */ + ppi_caps = kzalloc(sizeof(*ppi_caps), GFP_KERNEL); + if (!ppi_caps) + return;Maybe we can spare the call by statically allocating the PPI structure? Just the code calling kzalloc() costs us more than the 128 bits required by the structure.
Yeah, it doesn't really save us anything. I've dropped the dynamic allocation and made it static instead. Thanks, Sascha
Thanks, M.