linux/arch/arm/kvm
Christoffer Dall 9765097ba2 KVM: arm/arm64: Fix VMID alloc race by reverting to lock-less
commit fb544d1ca6 upstream.

We recently addressed a VMID generation race by introducing a read/write
lock around accesses and updates to the vmid generation values.

However, kvm_arch_vcpu_ioctl_run() also calls need_new_vmid_gen() but
does so without taking the read lock.

As far as I can tell, this can lead to the same kind of race:

  VM 0, VCPU 0			VM 0, VCPU 1
  ------------			------------
  update_vttbr (vmid 254)
  				update_vttbr (vmid 1) // roll over
				read_lock(kvm_vmid_lock);
				force_vm_exit()
  local_irq_disable
  need_new_vmid_gen == false //because vmid gen matches

  enter_guest (vmid 254)
  				kvm_arch.vttbr = <PGD>:<VMID 1>
				read_unlock(kvm_vmid_lock);

  				enter_guest (vmid 1)

Which results in running two VCPUs in the same VM with different VMIDs
and (even worse) other VCPUs from other VMs could now allocate clashing
VMID 254 from the new generation as long as VCPU 0 is not exiting.

Attempt to solve this by making sure vttbr is updated before another CPU
can observe the updated VMID generation.

Fixes: f0cf47d939 "KVM: arm/arm64: Close VMID generation race"
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
[bwh: Backported to 3.16:
 - Use ACCESS_ONCE() instead of {READ,WRITE}_ONCE()
 - Adjust filename]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
History 2019-04-04 16:13:57 +01:00
..
arm.c KVM: arm/arm64: Fix VMID alloc race by reverting to lock-less 2019-04-04 16:13:57 +01:00
coproc.c KVM: ARM/arm64: avoid returning negative error code as bool 2015-05-20 13:25:43 +01:00
coproc.h ARM: KVM: trap VM system registers until MMU and caches are ON 2014-03-03 01:15:24 +00:00
coproc_a7.c ARM: KVM: trap VM system registers until MMU and caches are ON 2014-03-03 01:15:24 +00:00
coproc_a15.c ARM: KVM: trap VM system registers until MMU and caches are ON 2014-03-03 01:15:24 +00:00
emulate.c arm/arm64: KVM: set right LR register value for 32 bit guest when inject abort 2018-01-01 20:51:57 +00:00
guest.c arm/arm64: KVM: Fix ioctl error handling 2016-03-24 10:00:58 +00:00
handle_exit.c arm: KVM: Fix SMCCC handling of unimplemented SMC/HVC calls 2018-06-16 22:22:06 +01:00
init.S arm: KVM: Allow unaligned accesses at HYP 2017-09-15 18:30:04 +01:00
interrupts.S arm: KVM: force execution of HCPTR access on VM exit 2015-07-15 10:00:39 +01:00
interrupts_head.S arm: KVM: Disable virtual timer even if the guest is not using it 2015-10-06 11:52:29 +01:00
Kconfig ARM: KVM: disable KVM in Kconfig on big-endian systems 2014-04-26 04:20:03 -07:00
Makefile KVM: ARM: Add support for Cortex-A7 2013-10-12 17:45:30 -07:00
mmio.c KVM: Fix stack-out-of-bounds read in write_mmio 2018-01-01 20:52:11 +00:00
mmu.c KVM: arm/arm64: Skip updating PTE entry if no change 2018-12-16 22:08:44 +00:00
perf.c ARM: KVM: add support for minimal host vs guest profiling 2013-04-28 21:44:01 -07:00
psci.c KVM: arm/arm64: fix races in kvm_psci_vcpu_on 2017-08-26 02:14:36 +01:00
reset.c Updates for KVM/ARM, take 3 supporting more than 4 CPUs. 2013-11-11 12:02:27 +01:00
trace.h ARM: KVM: Simplify tracepoint text 2013-08-30 15:47:53 -07:00