Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

KVM: arm64: gic-v5: Probe for GICv5 device

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@arm.com>
Signed-off-by: Timothy Hayes <timothy.hayes@arm.com>
Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Joey Gouly <joey.gouly@arm.com>
Link: https://patch.msgid.link/20260319154937.3619520-38-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier <maz@kernel.org>

authored by

Sascha Bischoff
Timothy Hayes
and committed by
Marc Zyngier
9b7aa055 a8946fde

+37 -11
+37 -11
arch/arm64/kvm/vgic/vgic-v5.c
··· 39 39 40 40 /* 41 41 * Probe for a vGICv5 compatible interrupt controller, returning 0 on success. 42 - * Currently only supports GICv3-based VMs on a GICv5 host, and hence only 43 - * registers a VGIC_V3 device. 44 42 */ 45 43 int vgic_v5_probe(const struct gic_kvm_info *info) 46 44 { 45 + bool v5_registered = false; 47 46 u64 ich_vtr_el2; 48 47 int ret; 49 48 50 - vgic_v5_get_implemented_ppis(); 51 - 52 - if (!cpus_have_final_cap(ARM64_HAS_GICV5_LEGACY)) 53 - return -ENODEV; 54 - 55 49 kvm_vgic_global_state.type = VGIC_V5; 56 - kvm_vgic_global_state.has_gcie_v3_compat = true; 57 - 58 - /* We only support v3 compat mode - use vGICv3 limits */ 59 - kvm_vgic_global_state.max_gic_vcpus = VGIC_V3_MAX_CPUS; 60 50 61 51 kvm_vgic_global_state.vcpu_base = 0; 62 52 kvm_vgic_global_state.vctrl_base = NULL; ··· 54 64 kvm_vgic_global_state.has_gicv4 = false; 55 65 kvm_vgic_global_state.has_gicv4_1 = false; 56 66 67 + /* 68 + * GICv5 is currently not supported in Protected mode. Skip the 69 + * registration of GICv5 completely to make sure no guests can create a 70 + * GICv5-based guest. 71 + */ 72 + if (is_protected_kvm_enabled()) { 73 + kvm_info("GICv5-based guests are not supported with pKVM\n"); 74 + goto skip_v5; 75 + } 76 + 77 + kvm_vgic_global_state.max_gic_vcpus = VGIC_V5_MAX_CPUS; 78 + 79 + vgic_v5_get_implemented_ppis(); 80 + 81 + ret = kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V5); 82 + if (ret) { 83 + kvm_err("Cannot register GICv5 KVM device.\n"); 84 + goto skip_v5; 85 + } 86 + 87 + v5_registered = true; 88 + kvm_info("GCIE system register CPU interface\n"); 89 + 90 + skip_v5: 91 + /* If we don't support the GICv3 compat mode we're done. */ 92 + if (!cpus_have_final_cap(ARM64_HAS_GICV5_LEGACY)) { 93 + if (!v5_registered) 94 + return -ENODEV; 95 + return 0; 96 + } 97 + 98 + kvm_vgic_global_state.has_gcie_v3_compat = true; 57 99 ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_gic_config); 58 100 kvm_vgic_global_state.ich_vtr_el2 = (u32)ich_vtr_el2; 59 101 ··· 100 78 kvm_err("Cannot register GICv3-legacy KVM device.\n"); 101 79 return ret; 102 80 } 81 + 82 + /* We potentially limit the max VCPUs further than we need to here */ 83 + kvm_vgic_global_state.max_gic_vcpus = min(VGIC_V3_MAX_CPUS, 84 + VGIC_V5_MAX_CPUS); 103 85 104 86 static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif); 105 87 kvm_info("GCIE legacy system register CPU interface\n");