linux/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 KVM: arm64: Generate hyp_constants.h for the host 2021-12-06 08:37:03 +00:00
Kconfig Merge branch kvm-arm64/s2-ptdump into kvmarm-master/next 2024-09-12 08:38:02 +01:00
Makefile Merge branch kvm-arm64/s2-ptdump into kvmarm-master/next 2024-09-12 08:38:02 +01:00
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 KVM: arm64: Support trace filtering for guests 2025-01-12 12:50:11 +00:00
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 KVM: arm64: Manage software step state at load/put 2024-12-20 09:04:06 +00:00
handle_exit.c KVM: arm64: nv: Honor MDCR_EL2.TDE routing for debug exceptions 2024-12-20 09:04:11 +00:00
hypercalls.c Merge branch kvm-arm64/psci-1.3 into kvmarm/next 2024-11-11 18:36:46 +00:00
inject_fault.c KVM: arm64: Fix typos 2024-02-24 09:13:33 +00:00
mmio.c KVM: arm64: Don't retire aborted MMIO instruction 2024-10-26 14:37:49 +00:00
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 KVM: arm64: nv: Work around lack of pauth support in old toolchains 2024-04-23 19:27:11 +01:00
pkvm.c KVM: arm64: Introduce the EL1 pKVM MMU 2024-12-20 09:44:00 +00:00
pmu-emul.c KVM: arm64: Only apply PMCR_EL0.P to the guest range of counters 2024-12-18 13:22:25 -08:00
pmu.c perf: arm_pmuv3: Add support for Armv9.4 PMU instruction counter 2024-08-16 13:09:12 +01:00
psci.c KVM: arm64: Add support for PSCI v1.2 and v1.3 2024-10-24 16:38:07 -07:00
ptdump.c KVM: arm64: Register ptdump with debugfs on guest creation 2024-09-10 21:32:51 +01:00
pvtime.c KVM: MMU: Make the definition of 'INVALID_GPA' common 2023-01-19 21:48:38 +00:00
reset.c KVM: arm64: Convert the SVE guest vcpu flag to a vm flag 2024-12-20 13:54:09 +00:00
stacktrace.c arm64: kvm: Introduce nvhe stack size constants 2025-01-08 11:25:28 +00:00
sys_regs.c KVM/arm64 fixes for 6.14, take #1 2025-02-04 11:14:53 -05:00
sys_regs.h Merge branch kvm-arm64/visibility-cleanups into kvmarm-master/next 2024-09-12 08:38:17 +01:00
trace.h
trace_arm.h KVM: arm64: Add tracepoint for MMIO accesses where ISV==0 2023-10-30 20:17:22 +00:00
trace_handle_exit.h KVM: arm64: Remove debug tracepoints 2024-12-20 09:01:25 +00:00
trng.c
va_layout.c arm64: alternatives: kvm: prepare for cap changes 2022-09-16 17:15:02 +01:00
vgic-sys-reg-v3.c KVM: arm64: vgic-v3: Convert userspace accessors over to FIELD_GET/FIELD_PREP 2022-07-17 11:55:33 +01:00
vmid.c KVM: arm64: Ensure a VMID is allocated before programming VTTBR_EL2 2025-02-20 16:29:28 +00:00