[PATCH v3 0/4] KVM: arm64: Fix vcpu->mutex v. kvm->lock inversion

Oliver Upton oliver.upton at linux.dev
Mon Mar 27 09:47:43 PDT 2023


As it so happens, lock ordering in KVM/arm64 is completely backwards.
There's a significant amount of VM-wide state that needs to be accessed
from the context of a vCPU. Until now, this was accomplished by
acquiring the kvm->lock, but that cannot be nested within vcpu->mutex.

This series fixes the issue with some fine-grained locking for MP state
and a new, dedicated mutex that can nest with both kvm->lock and
vcpu->mutex.

Tested with kvmtool and QEMU scaled up to 64 vCPUs on a kernel w/
lockdep enabled. Applies to kvmarm-fixes-6.3-2.

Please note that these changes will most likely be taken in the 6.4
merge window and not as a fixup during 6.3. After discussing with Marc
we agreed that letting these patches marinade in -next for a while is
probably best as it is quite an overhaul to our locking. Additionally,
there is no evidence of actual deadlocks occurring in the wild, likely
because we _always_ ordered the locks backwards, hence the only breakage
at the moment is lockdep.

Also, Jeremy, I chose to omit your Tested-by tag on the last patch as it
was rather significantly changed from when you last took it for a spin.

v1: http://lore.kernel.org/kvmarm/20230308083947.3760066-1-oliver.upton@linux.dev
v2: https://lore.kernel.org/kvmarm/20230316211412.2651555-1-oliver.upton@linux.dev/

v2 -> v3:
 - Continue to acquire the kvm->lock where we must protect against a
   concurrent vCPU creation (Marc)
 - Plug a few missing WRITE_ONCE() promotions for mp_state (Marc)
 - Hold the mp_state_lock when reading reset_state (Marc)
 - Fix the unguarded write to mp_state in kvm_prepare_system_event()
 - Collect Jeremy's Tested-by tags (thanks!)

v1 -> v2:
 - Add a dedicated lock for serializing writes to MP state
 - Inform lockdep of acquisition order at time of VM/vCPU creation
 - Plug a race with GIC creation (Sean)
 - Use the config_lock in GIC ITS flows as well

Oliver Upton (4):
  KVM: arm64: Avoid vcpu->mutex v. kvm->lock inversion in CPU_ON
  KVM: arm64: Avoid lock inversion when setting the VM register width
  KVM: arm64: Use config_lock to protect data ordered against KVM_RUN
  KVM: arm64: Use config_lock to protect vgic state

 arch/arm64/include/asm/kvm_host.h     |  4 ++
 arch/arm64/kvm/arm.c                  | 53 +++++++++++++++++++++------
 arch/arm64/kvm/guest.c                |  2 +
 arch/arm64/kvm/hypercalls.c           |  4 +-
 arch/arm64/kvm/pmu-emul.c             | 23 +++---------
 arch/arm64/kvm/psci.c                 | 28 ++++++++------
 arch/arm64/kvm/reset.c                | 15 ++++----
 arch/arm64/kvm/vgic/vgic-debug.c      |  8 ++--
 arch/arm64/kvm/vgic/vgic-init.c       | 36 +++++++++++-------
 arch/arm64/kvm/vgic/vgic-its.c        | 18 ++++++---
 arch/arm64/kvm/vgic/vgic-kvm-device.c | 47 ++++++++++++++----------
 arch/arm64/kvm/vgic/vgic-mmio-v3.c    |  4 +-
 arch/arm64/kvm/vgic/vgic-mmio.c       | 12 +++---
 arch/arm64/kvm/vgic/vgic-v4.c         | 11 +++---
 arch/arm64/kvm/vgic/vgic.c            | 12 +++---
 15 files changed, 168 insertions(+), 109 deletions(-)


base-commit: 8c2e8ac8ad4be68409e806ce1cc78fc7a04539f3
-- 
2.40.0.348.gf938b09366-goog




More information about the linux-arm-kernel mailing list