|
@@ -85,6 +85,18 @@ static int vgic_mmio_uaccess_write_v2_misc(struct kvm_vcpu *vcpu,
|
|
|
case GIC_DIST_IIDR:
|
|
|
if (val != vgic_mmio_read_v2_misc(vcpu, addr, len))
|
|
|
return -EINVAL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 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. Doing this by default would break
|
|
|
+ * migration from old kernels to new kernels with legacy
|
|
|
+ * userspace.
|
|
|
+ */
|
|
|
+ vcpu->kvm->arch.vgic.v2_groups_user_writable = true;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
gpa_t addr, unsigned int len,
|
|
|
unsigned long val)
|
|
|
{
|
|
|
- /* Ignore writes from userspace */
|
|
|
+ if (vcpu->kvm->arch.vgic.v2_groups_user_writable)
|
|
|
+ vgic_mmio_write_group(vcpu, addr, len, val);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|