linux-mainline/arch/arm64/kvm
Oliver Upton fa808ed4e1 KVM: arm64: Ensure a VMID is allocated before programming VTTBR_EL2
Vladimir reports that a race condition to attach a VMID to a stage-2 MMU
sometimes results in a vCPU entering the guest with a VMID of 0:

| CPU1                                            |   CPU2
|                                                 |
|                                                 | kvm_arch_vcpu_ioctl_run
|                                                 |   vcpu_load             <= load VTTBR_EL2
|                                                 |                            kvm_vmid->id = 0
|                                                 |
| kvm_arch_vcpu_ioctl_run                         |
|   vcpu_load             <= load VTTBR_EL2       |
|                            with kvm_vmid->id = 0|
|   kvm_arm_vmid_update   <= allocates fresh      |
|                            kvm_vmid->id and     |
|                            reload VTTBR_EL2     |
|                                                 |
|                                                 |   kvm_arm_vmid_update <= observes that kvm_vmid->id
|                                                 |                          already allocated,
|                                                 |                          skips reload VTTBR_EL2

Oh yeah, it's as bad as it looks. Remember that VHE loads the stage-2
MMU eagerly but a VMID only gets attached to the MMU later on in the
KVM_RUN loop.

Even in the "best case" where VTTBR_EL2 correctly gets reprogrammed
before entering the EL1&0 regime, there is a period of time where
hardware is configured with VMID 0. That's completely insane. So, rather
than decorating the 'late' binding with another hack, just allocate the
damn thing up front.

Attaching a VMID from vcpu_load() is still rollover safe since
(surprise!) it'll always get called after a vCPU was preempted.

Excuse me while I go find a brown paper bag.

Cc: stable@vger.kernel.org
Fixes: 934bf871f0 ("KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe()")
Reported-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20250219220737.130842-1-oliver.upton@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
2025-02-20 16:29:28 +00:00
..
hyp KVM/arm64 fixes for 6.14, take #2 2025-02-14 18:32:47 -05:00
vgic KVM: arm64: vgic: Hoist SGI/PPI alloc from vgic_init() to kvm_create_vgic() 2025-02-13 18:03:54 +00:00
.gitignore
arch_timer.c KVM: arm64: timer: Drop warning on failed interrupt signalling 2025-02-13 18:03:54 +00:00
arm.c KVM: arm64: Ensure a VMID is allocated before programming VTTBR_EL2 2025-02-20 16:29:28 +00:00
at.c arm64 updates for 6.14 2025-01-20 21:21:49 -08:00
debug.c
emulate-nested.c Merge branch kvm-arm64/nv-timers into kvmarm-master/next 2025-01-17 11:04:53 +00:00
fpsimd.c KVM: arm64: Simplify warning in kvm_arch_vcpu_load_fp() 2025-02-13 17:55:13 +00:00
guest.c
handle_exit.c
hypercalls.c
inject_fault.c
Kconfig
Makefile
mmio.c
mmu.c Merge branch kvm-arm64/misc-6.14 into kvmarm-master/next 2025-01-17 11:06:50 +00:00
nested.c KVM: arm64: Fix nested S2 MMU structures reallocation 2025-02-04 15:02:16 +00:00
pauth.c
pkvm.c
pmu-emul.c
pmu.c
psci.c
ptdump.c
pvtime.c
reset.c
stacktrace.c
sys_regs.c KVM/arm64 fixes for 6.14, take #1 2025-02-04 11:14:53 -05:00
sys_regs.h
trace_arm.h
trace_handle_exit.h
trace.h
trng.c
va_layout.c
vgic-sys-reg-v3.c
vmid.c KVM: arm64: Ensure a VMID is allocated before programming VTTBR_EL2 2025-02-20 16:29:28 +00:00