Skip to content

Commit 32f8777

Browse files
christofferdall-armMarc Zyngier
authored andcommitted
KVM: arm/arm64: vgic: Let userspace opt-in to writable v2 IGROUPR
Simply letting IGROUPR be writable from userspace would break migration from old kernels to newer kernels, because old kernels incorrectly report interrupt groups as group 1. This would not be a big problem if userspace wrote GICD_IIDR as read from the kernel, because we could detect the incompatibility and return an error to userspace. Unfortunately, this is not the case with current userspace implementations and simply letting IGROUPR be writable from userspace for an emulated GICv2 silently breaks migration and causes the destination VM to no longer run after migration. We now encourage userspace to write the read and expected value of GICD_IIDR as the first part of a GIC register restore, and if we observe a write to GICD_IIDR we know that userspace has been updated and has had a chance to cope with older kernels (VGICv2 IIDR.Revision == 0) incorrectly reporting interrupts as group 1, and therefore we now allow groups to be user writable. Reviewed-by: Andrew Jones <[email protected]> Signed-off-by: Christoffer Dall <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent d53c2c2 commit 32f8777

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

include/kvm/arm_vgic.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ struct vgic_dist {
221221
/* Implementation revision as reported in the GICD_IIDR */
222222
u32 implementation_rev;
223223

224+
/* Userspace can write to GICv2 IGROUPR */
225+
bool v2_groups_user_writable;
226+
224227
/* Do injected MSIs require an additional device ID? */
225228
bool msis_require_devid;
226229

virt/kvm/arm/vgic/vgic-mmio-v2.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ static int vgic_mmio_uaccess_write_v2_misc(struct kvm_vcpu *vcpu,
8585
case GIC_DIST_IIDR:
8686
if (val != vgic_mmio_read_v2_misc(vcpu, addr, len))
8787
return -EINVAL;
88+
89+
/*
90+
* If we observe a write to GICD_IIDR we know that userspace
91+
* has been updated and has had a chance to cope with older
92+
* kernels (VGICv2 IIDR.Revision == 0) incorrectly reporting
93+
* interrupts as group 1, and therefore we now allow groups to
94+
* be user writable. Doing this by default would break
95+
* migration from old kernels to new kernels with legacy
96+
* userspace.
97+
*/
98+
vcpu->kvm->arch.vgic.v2_groups_user_writable = true;
99+
return 0;
88100
}
89101

90102
vgic_mmio_write_v2_misc(vcpu, addr, len, val);
@@ -95,7 +107,9 @@ static int vgic_mmio_uaccess_write_v2_group(struct kvm_vcpu *vcpu,
95107
gpa_t addr, unsigned int len,
96108
unsigned long val)
97109
{
98-
/* Ignore writes from userspace */
110+
if (vcpu->kvm->arch.vgic.v2_groups_user_writable)
111+
vgic_mmio_write_group(vcpu, addr, len, val);
112+
99113
return 0;
100114
}
101115

0 commit comments

Comments
 (0)