Skip to content

Commit f26e6af

Browse files
committed
KVM: arm64: vgic-v3: Allow access to GICD_IIDR prior to initialization
KVM allows userspace to write GICD_IIDR for backwards-compatibility with older kernels, where new implementation revisions have new features. Unfortunately this is allowed to happen at runtime, and ripping features out from underneath a running guest is a terrible idea. While we can't do anything about the ABI, prepare for more ID-like registers by allowing access to GICD_IIDR prior to VGIC initialization. Hoist initializaiton of the default value to kvm_vgic_create() and discard the incorrect comment that assumed userspace could access the register before initialization (until now). Subsequent changes will allow the VMM to further provision the GIC feature set, e.g. the presence of nASSGIcap. Reviewed-by: Eric Auger <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent ef364c5 commit f26e6af

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
157157

158158
kvm->arch.vgic.in_kernel = true;
159159
kvm->arch.vgic.vgic_model = type;
160+
kvm->arch.vgic.implementation_rev = KVM_VGIC_IMP_REV_LATEST;
160161

161162
kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
162163

@@ -408,15 +409,7 @@ int vgic_init(struct kvm *kvm)
408409
goto out;
409410

410411
vgic_debug_init(kvm);
411-
412-
/*
413-
* If userspace didn't set the GIC implementation revision,
414-
* default to the latest and greatest. You know want it.
415-
*/
416-
if (!dist->implementation_rev)
417-
dist->implementation_rev = KVM_VGIC_IMP_REV_LATEST;
418412
dist->initialized = true;
419-
420413
out:
421414
return ret;
422415
}

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Copyright (C) 2015 ARM Ltd.
66
* Author: Marc Zyngier <[email protected]>
77
*/
8+
#include <linux/irqchip/arm-gic-v3.h>
89
#include <linux/kvm_host.h>
910
#include <kvm/arm_vgic.h>
1011
#include <linux/uaccess.h>
@@ -503,6 +504,23 @@ int vgic_v3_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,
503504
return 0;
504505
}
505506

507+
/*
508+
* Allow access to certain ID-like registers prior to VGIC initialization,
509+
* thereby allowing the VMM to provision the features / sizing of the VGIC.
510+
*/
511+
static bool reg_allowed_pre_init(struct kvm_device_attr *attr)
512+
{
513+
if (attr->group != KVM_DEV_ARM_VGIC_GRP_DIST_REGS)
514+
return false;
515+
516+
switch (attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK) {
517+
case GICD_IIDR:
518+
return true;
519+
default:
520+
return false;
521+
}
522+
}
523+
506524
/*
507525
* vgic_v3_attr_regs_access - allows user space to access VGIC v3 state
508526
*
@@ -552,7 +570,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
552570

553571
mutex_lock(&dev->kvm->arch.config_lock);
554572

555-
if (!vgic_initialized(dev->kvm)) {
573+
if (!(vgic_initialized(dev->kvm) || reg_allowed_pre_init(attr))) {
556574
ret = -EBUSY;
557575
goto out;
558576
}

0 commit comments

Comments
 (0)