Skip to content

Commit b489edc

Browse files
christofferdall-armMarc Zyngier
authored andcommitted
KVM: arm/arm64: vgic: Return error on incompatible uaccess GICD_IIDR writes
If userspace attempts to write a GICD_IIDR that does not match the kernel version, return an error to userspace. The intention is to allow implementation changes inside KVM while avoiding silently breaking migration resulting in guests not running without any clear indication of what went wrong. Reviewed-by: Andrew Jones <[email protected]> Signed-off-by: Christoffer Dall <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent c6e0917 commit b489edc

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@ static void vgic_mmio_write_v2_misc(struct kvm_vcpu *vcpu,
7575
}
7676
}
7777

78+
static int vgic_mmio_uaccess_write_v2_misc(struct kvm_vcpu *vcpu,
79+
gpa_t addr, unsigned int len,
80+
unsigned long val)
81+
{
82+
switch (addr & 0x0c) {
83+
case GIC_DIST_IIDR:
84+
if (val != vgic_mmio_read_v2_misc(vcpu, addr, len))
85+
return -EINVAL;
86+
}
87+
88+
vgic_mmio_write_v2_misc(vcpu, addr, len, val);
89+
return 0;
90+
}
91+
7892
static void vgic_mmio_write_sgir(struct kvm_vcpu *source_vcpu,
7993
gpa_t addr, unsigned int len,
8094
unsigned long val)
@@ -367,9 +381,10 @@ static void vgic_mmio_write_apr(struct kvm_vcpu *vcpu,
367381
}
368382

369383
static const struct vgic_register_region vgic_v2_dist_registers[] = {
370-
REGISTER_DESC_WITH_LENGTH(GIC_DIST_CTRL,
371-
vgic_mmio_read_v2_misc, vgic_mmio_write_v2_misc, 12,
372-
VGIC_ACCESS_32bit),
384+
REGISTER_DESC_WITH_LENGTH_UACCESS(GIC_DIST_CTRL,
385+
vgic_mmio_read_v2_misc, vgic_mmio_write_v2_misc,
386+
NULL, vgic_mmio_uaccess_write_v2_misc,
387+
12, VGIC_ACCESS_32bit),
373388
REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_IGROUP,
374389
vgic_mmio_read_raz, vgic_mmio_write_wi, NULL, NULL, 1,
375390
VGIC_ACCESS_32bit),

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,20 @@ static void vgic_mmio_write_v3_misc(struct kvm_vcpu *vcpu,
113113
}
114114
}
115115

116+
static int vgic_mmio_uaccess_write_v3_misc(struct kvm_vcpu *vcpu,
117+
gpa_t addr, unsigned int len,
118+
unsigned long val)
119+
{
120+
switch (addr & 0x0c) {
121+
case GICD_IIDR:
122+
if (val != vgic_mmio_read_v3_misc(vcpu, addr, len))
123+
return -EINVAL;
124+
}
125+
126+
vgic_mmio_write_v3_misc(vcpu, addr, len, val);
127+
return 0;
128+
}
129+
116130
static unsigned long vgic_mmio_read_irouter(struct kvm_vcpu *vcpu,
117131
gpa_t addr, unsigned int len)
118132
{
@@ -449,9 +463,10 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
449463
}
450464

451465
static const struct vgic_register_region vgic_v3_dist_registers[] = {
452-
REGISTER_DESC_WITH_LENGTH(GICD_CTLR,
453-
vgic_mmio_read_v3_misc, vgic_mmio_write_v3_misc, 16,
454-
VGIC_ACCESS_32bit),
466+
REGISTER_DESC_WITH_LENGTH_UACCESS(GICD_CTLR,
467+
vgic_mmio_read_v3_misc, vgic_mmio_write_v3_misc,
468+
NULL, vgic_mmio_uaccess_write_v3_misc,
469+
16, VGIC_ACCESS_32bit),
455470
REGISTER_DESC_WITH_LENGTH(GICD_STATUSR,
456471
vgic_mmio_read_rao, vgic_mmio_write_wi, 4,
457472
VGIC_ACCESS_32bit),

0 commit comments

Comments
 (0)