Skip to content

Commit ff2aa64

Browse files
Sticklyman1936timothy-hayes
authored andcommitted
KVM: arm64: gic-v5: Probe for GICv5
Add in a probe function for GICv5 which enables support for GICv3 guests on a GICv5 host, if FEAT_GCIE_LEGACY is supported by the hardware. Co-authored-by: Timothy Hayes <[email protected]> Signed-off-by: Timothy Hayes <[email protected]> Signed-off-by: Sascha Bischoff <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent c017e49 commit ff2aa64

File tree

4 files changed

+59
-1
lines changed

4 files changed

+59
-1
lines changed

arch/arm64/kvm/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
2323
vgic/vgic-v3.o vgic/vgic-v4.o \
2424
vgic/vgic-mmio.o vgic/vgic-mmio-v2.o \
2525
vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
26-
vgic/vgic-its.o vgic/vgic-debug.o vgic/vgic-v3-nested.o
26+
vgic/vgic-its.o vgic/vgic-debug.o vgic/vgic-v3-nested.o \
27+
vgic/vgic-v5.o
2728

2829
kvm-$(CONFIG_HW_PERF_EVENTS) += pmu-emul.o pmu.o
2930
kvm-$(CONFIG_ARM64_PTR_AUTH) += pauth.o

arch/arm64/kvm/vgic/vgic-init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,9 @@ int kvm_vgic_hyp_init(void)
724724
kvm_info("GIC system register CPU interface enabled\n");
725725
}
726726
break;
727+
case GIC_V5:
728+
ret = vgic_v5_probe(gic_kvm_info);
729+
break;
727730
default:
728731
ret = -ENODEV;
729732
}

arch/arm64/kvm/vgic/vgic-v5.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
3+
#include <kvm/arm_vgic.h>
4+
#include <linux/irqchip/arm-vgic-info.h>
5+
6+
#include "vgic.h"
7+
8+
/*
9+
* Probe for a vGICv5 compatible interrupt controller, returning 0 on success.
10+
* Currently only supports GICv3-based VMs on a GICv5 host, and hence only
11+
* registers a VGIC_V3 device.
12+
*/
13+
int vgic_v5_probe(const struct gic_kvm_info *info)
14+
{
15+
u64 ich_vtr_el2;
16+
int ret;
17+
18+
if (!info->has_gcie_v3_compat)
19+
return -ENODEV;
20+
21+
kvm_vgic_global_state.type = VGIC_V5;
22+
kvm_vgic_global_state.has_gcie_v3_compat = true;
23+
24+
/* We only support v3 compat mode - use vGICv3 limits */
25+
kvm_vgic_global_state.max_gic_vcpus = VGIC_V3_MAX_CPUS;
26+
27+
kvm_vgic_global_state.vcpu_base = 0;
28+
kvm_vgic_global_state.vctrl_base = NULL;
29+
kvm_vgic_global_state.can_emulate_gicv2 = false;
30+
kvm_vgic_global_state.has_gicv4 = false;
31+
kvm_vgic_global_state.has_gicv4_1 = false;
32+
33+
ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_gic_config);
34+
kvm_vgic_global_state.ich_vtr_el2 = (u32)ich_vtr_el2;
35+
36+
/*
37+
* The ListRegs field is 5 bits, but there is an architectural
38+
* maximum of 16 list registers. Just ignore bit 4...
39+
*/
40+
kvm_vgic_global_state.nr_lr = (ich_vtr_el2 & 0xf) + 1;
41+
42+
ret = kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V3);
43+
if (ret) {
44+
kvm_err("Cannot register GICv3-legacy KVM device.\n");
45+
return ret;
46+
}
47+
48+
static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
49+
kvm_info("GCIE legacy system register CPU interface\n");
50+
51+
return 0;
52+
}

arch/arm64/kvm/vgic/vgic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ int vgic_init(struct kvm *kvm);
308308
void vgic_debug_init(struct kvm *kvm);
309309
void vgic_debug_destroy(struct kvm *kvm);
310310

311+
int vgic_v5_probe(const struct gic_kvm_info *info);
312+
311313
static inline int vgic_v3_max_apr_idx(struct kvm_vcpu *vcpu)
312314
{
313315
struct vgic_cpu *cpu_if = &vcpu->arch.vgic_cpu;

0 commit comments

Comments
 (0)