Skip to content

Commit 23bde34

Browse files
Zenghui YuMarc Zyngier
authored andcommitted
KVM: arm64: vgic-v3: Drop the reporting of GICR_TYPER.Last for userspace
It was recently reported that if GICR_TYPER is accessed before the RD base address is set, we'll suffer from the unset @rdreg dereferencing. Oops... gpa_t last_rdist_typer = rdreg->base + GICR_TYPER + (rdreg->free_index - 1) * KVM_VGIC_V3_REDIST_SIZE; It's "expected" that users will access registers in the redistributor if the RD has been properly configured (e.g., the RD base address is set). But it hasn't yet been covered by the existing documentation. Per discussion on the list [1], the reporting of the GICR_TYPER.Last bit for userspace never actually worked. And it's difficult for us to emulate it correctly given that userspace has the flexibility to access it any time. Let's just drop the reporting of the Last bit for userspace for now (userspace should have full knowledge about it anyway) and it at least prevents kernel from panic ;-) [1] https://lore.kernel.org/kvmarm/[email protected]/ Fixes: ba7b3f1 ("KVM: arm/arm64: Revisit Redistributor TYPER last bit computation") Reported-by: Keqian Zhu <[email protected]> Signed-off-by: Zenghui Yu <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Eric Auger <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: [email protected]
1 parent 7bab16a commit 23bde34

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

arch/arm64/kvm/vgic/vgic-mmio-v3.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,23 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu,
273273
return extract_bytes(value, addr & 7, len);
274274
}
275275

276+
static unsigned long vgic_uaccess_read_v3r_typer(struct kvm_vcpu *vcpu,
277+
gpa_t addr, unsigned int len)
278+
{
279+
unsigned long mpidr = kvm_vcpu_get_mpidr_aff(vcpu);
280+
int target_vcpu_id = vcpu->vcpu_id;
281+
u64 value;
282+
283+
value = (u64)(mpidr & GENMASK(23, 0)) << 32;
284+
value |= ((target_vcpu_id & 0xffff) << 8);
285+
286+
if (vgic_has_its(vcpu->kvm))
287+
value |= GICR_TYPER_PLPIS;
288+
289+
/* reporting of the Last bit is not supported for userspace */
290+
return extract_bytes(value, addr & 7, len);
291+
}
292+
276293
static unsigned long vgic_mmio_read_v3r_iidr(struct kvm_vcpu *vcpu,
277294
gpa_t addr, unsigned int len)
278295
{
@@ -593,8 +610,9 @@ static const struct vgic_register_region vgic_v3_rd_registers[] = {
593610
REGISTER_DESC_WITH_LENGTH(GICR_IIDR,
594611
vgic_mmio_read_v3r_iidr, vgic_mmio_write_wi, 4,
595612
VGIC_ACCESS_32bit),
596-
REGISTER_DESC_WITH_LENGTH(GICR_TYPER,
597-
vgic_mmio_read_v3r_typer, vgic_mmio_write_wi, 8,
613+
REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_TYPER,
614+
vgic_mmio_read_v3r_typer, vgic_mmio_write_wi,
615+
vgic_uaccess_read_v3r_typer, vgic_mmio_uaccess_write_wi, 8,
598616
VGIC_ACCESS_64bit | VGIC_ACCESS_32bit),
599617
REGISTER_DESC_WITH_LENGTH(GICR_WAKER,
600618
vgic_mmio_read_raz, vgic_mmio_write_wi, 4,

0 commit comments

Comments
 (0)