[PATCH v2 33/36] KVM: arm64: gic-v5: Probe for GICv5 device
Sascha Bischoff
Sascha.Bischoff at arm.com
Fri Dec 19 07:52:47 PST 2025
The basic GICv5 PPI support is now complete. Allow probing for a
native GICv5 rather than just the legacy support.
The implementation doesn't support protected VMs with GICv5 at this
time. Therefore, if KVM has protected mode enabled the native GICv5
init is skipped, but legacy VMs are allowed if the hardware supports
it.
At this stage the GICv5 KVM implementation only supports PPIs, and
doesn't interact with the host IRS at all. This means that there is no
need to check how many concurrent VMs or vCPUs per VM are supported by
the IRS - the PPI support only requires the CPUIF. The support is
artificially limited to VGIC_V5_MAX_CPUS, i.e. 512, vCPUs per VM.
With this change it becomes possible to run basic GICv5-based VMs,
provided that they only use PPIs.
Co-authored-by: Timothy Hayes <timothy.hayes at arm.com>
Signed-off-by: Timothy Hayes <timothy.hayes at arm.com>
Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>
---
arch/arm64/kvm/vgic/vgic-v5.c | 39 +++++++++++++++++++++++++++--------
1 file changed, 30 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
index 97d67c1d16541..bf72982d6a2e8 100644
--- a/arch/arm64/kvm/vgic/vgic-v5.c
+++ b/arch/arm64/kvm/vgic/vgic-v5.c
@@ -12,22 +12,13 @@ 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
- * registers a VGIC_V3 device.
*/
int vgic_v5_probe(const struct gic_kvm_info *info)
{
u64 ich_vtr_el2;
int ret;
- if (!cpus_have_final_cap(ARM64_HAS_GICV5_LEGACY))
- return -ENODEV;
-
kvm_vgic_global_state.type = VGIC_V5;
- kvm_vgic_global_state.has_gcie_v3_compat = true;
-
- /* We only support v3 compat mode - use vGICv3 limits */
- kvm_vgic_global_state.max_gic_vcpus = VGIC_V3_MAX_CPUS;
kvm_vgic_global_state.vcpu_base = 0;
kvm_vgic_global_state.vctrl_base = NULL;
@@ -35,6 +26,32 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
kvm_vgic_global_state.has_gicv4 = false;
kvm_vgic_global_state.has_gicv4_1 = false;
+ /*
+ * GICv5 is currently not supported in Protected mode. Skip the
+ * registration of GICv5 completely to make sure no guests can create a
+ * GICv5-based guest.
+ */
+ if (is_protected_kvm_enabled()) {
+ kvm_info("GICv5-based guests are not supported with pKVM\n");
+ goto skip_v5;
+ }
+
+ kvm_vgic_global_state.max_gic_vcpus = VGIC_V5_MAX_CPUS;
+
+ ret = kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V5);
+ if (ret) {
+ kvm_err("Cannot register GICv5 KVM device.\n");
+ goto skip_v5;
+ }
+
+ kvm_info("GCIE system register CPU interface\n");
+
+skip_v5:
+ /* If we don't support the GICv3 compat mode we're done. */
+ if (!cpus_have_final_cap(ARM64_HAS_GICV5_LEGACY))
+ return 0;
+
+ kvm_vgic_global_state.has_gcie_v3_compat = true;
ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_gic_config);
kvm_vgic_global_state.ich_vtr_el2 = (u32)ich_vtr_el2;
@@ -50,6 +67,10 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
return ret;
}
+ /* We potentially limit the max VCPUs further than we need to here */
+ kvm_vgic_global_state.max_gic_vcpus = min(VGIC_V3_MAX_CPUS,
+ VGIC_V5_MAX_CPUS);
+
static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
kvm_info("GCIE legacy system register CPU interface\n");
--
2.34.1
More information about the linux-arm-kernel
mailing list