Skip to content

Commit 6a85245

Browse files
pfedinAlex Shi
authored andcommitted
arm/arm64: KVM: Detect vGIC presence at runtime
Before commit 662d971 ("arm/arm64: KVM: Kill CONFIG_KVM_ARM_{VGIC,TIMER}") is was possible to compile the kernel without vGIC and vTimer support. Commit message says about possibility to detect vGIC support in runtime, but this has never been implemented. This patch introduces runtime check, restoring the lost functionality. It again allows to use KVM on hardware without vGIC. Interrupt controller has to be emulated in userspace in this case. -ENODEV return code from probe function means there's no GIC at all. -ENXIO happens when, for example, there is GIC node in the device tree, but it does not specify vGIC resources. Any other error code is still treated as full stop because it might mean some really serious problems. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> (cherry picked from commit c7da6fa43cb1c5e649da0f478a491feb9208cae7) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent 1a1549b commit 6a85245

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

arch/arm/kvm/arm.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ static u32 kvm_next_vmid;
6363
static unsigned int kvm_vmid_bits __read_mostly;
6464
static DEFINE_SPINLOCK(kvm_vmid_lock);
6565

66+
static bool vgic_present;
67+
6668
static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
6769
{
6870
BUG_ON(preemptible());
@@ -134,7 +136,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
134136
kvm->arch.vmid_gen = 0;
135137

136138
/* The maximum number of VCPUs is limited by the host's GIC model */
137-
kvm->arch.max_vcpus = kvm_vgic_get_max_vcpus();
139+
kvm->arch.max_vcpus = vgic_present ?
140+
kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
138141

139142
return ret;
140143
out_free_stage2_pgd:
@@ -172,6 +175,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
172175
int r;
173176
switch (ext) {
174177
case KVM_CAP_IRQCHIP:
178+
r = vgic_present;
179+
break;
175180
case KVM_CAP_IOEVENTFD:
176181
case KVM_CAP_DEVICE_CTRL:
177182
case KVM_CAP_USER_MEMORY:
@@ -914,6 +919,8 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
914919

915920
switch (dev_id) {
916921
case KVM_ARM_DEVICE_VGIC_V2:
922+
if (!vgic_present)
923+
return -ENXIO;
917924
return kvm_vgic_addr(kvm, type, &dev_addr->addr, true);
918925
default:
919926
return -ENODEV;
@@ -928,6 +935,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
928935

929936
switch (ioctl) {
930937
case KVM_CREATE_IRQCHIP: {
938+
if (!vgic_present)
939+
return -ENXIO;
931940
return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
932941
}
933942
case KVM_ARM_SET_DEVICE_ADDR: {
@@ -1118,8 +1127,17 @@ static int init_hyp_mode(void)
11181127
* Init HYP view of VGIC
11191128
*/
11201129
err = kvm_vgic_hyp_init();
1121-
if (err)
1130+
switch (err) {
1131+
case 0:
1132+
vgic_present = true;
1133+
break;
1134+
case -ENODEV:
1135+
case -ENXIO:
1136+
vgic_present = false;
1137+
break;
1138+
default:
11221139
goto out_free_context;
1140+
}
11231141

11241142
/*
11251143
* Init HYP architected timer support

0 commit comments

Comments
 (0)