linux/virt/kvm
Isaku Yamahata 0bf50497f0 KVM: Drop kvm_count_lock and instead protect kvm_usage_count with kvm_lock
Drop kvm_count_lock and instead protect kvm_usage_count with kvm_lock now
that KVM hooks CPU hotplug during the ONLINE phase, which can sleep.
Previously, KVM hooked the STARTING phase, which is not allowed to sleep
and thus could not take kvm_lock (a mutex).  This effectively allows the
task that's initiating hardware enabling/disabling to preempted and/or
migrated.

Note, the Documentation/virt/kvm/locking.rst statement that kvm_count_lock
is "raw" because hardware enabling/disabling needs to be atomic with
respect to migration is wrong on multiple fronts.  First, while regular
spinlocks can be preempted, the task holding the lock cannot be migrated.
Second, preventing migration is not required.  on_each_cpu() disables
preemption, which ensures that cpus_hardware_enabled correctly reflects
hardware state.  The task may be preempted/migrated between bumping
kvm_usage_count and invoking on_each_cpu(), but that's perfectly ok as
kvm_usage_count is still protected, e.g. other tasks that call
hardware_enable_all() will be blocked until the preempted/migrated owner
exits its critical section.

KVM does have lockless accesses to kvm_usage_count in the suspend/resume
flows, but those are safe because all tasks must be frozen prior to
suspending CPUs, and a task cannot be frozen while it holds one or more
locks (userspace tasks are frozen via a fake signal).

Preemption doesn't need to be explicitly disabled in the hotplug path.
The hotplug thread is pinned to the CPU that's being hotplugged, and KVM
only cares about having a stable CPU, i.e. to ensure hardware is enabled
on the correct CPU.  Lockep, i.e. check_preemption_disabled(), plays nice
with this state too, as is_percpu_thread() is true for the hotplug thread.

Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20221130230934.1014142-45-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-12-29 15:48:34 -05:00
..
async_pf.c KVM: Add helpers to wake/query blocking vCPU 2021-12-08 04:24:54 -05:00
async_pf.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 504 2019-06-19 17:09:56 +02:00
binary_stats.c KVM: stats: remove dead stores 2021-08-13 03:35:15 -04:00
coalesced_mmio.c KVM: mmio: Fix use-after-free Read in kvm_vm_ioctl_unregister_coalesced_mmio 2021-07-14 12:17:56 -04:00
coalesced_mmio.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
dirty_ring.c KVM: Support dirty ring in conjunction with bitmap 2022-11-10 13:11:58 +00:00
eventfd.c KVM: eventfd: Fix false positive RCU usage warning 2022-05-20 09:10:33 -04:00
irqchip.c KVM: replace direct irq.h inclusion 2022-11-09 12:31:37 -05:00
Kconfig KVM: Support dirty ring in conjunction with bitmap 2022-11-10 13:11:58 +00:00
kvm_main.c KVM: Drop kvm_count_lock and instead protect kvm_usage_count with kvm_lock 2022-12-29 15:48:34 -05:00
kvm_mm.h kvm: Remove the unused macro KVM_MMU_READ_{,UN}LOCK() 2022-12-27 06:00:51 -05:00
Makefile.kvm KVM: Reinstate gfn_to_pfn_cache with invalidation support 2022-01-07 10:44:44 -05:00
pfncache.c KVM: Skip unnecessary "unmap" if gpc is already valid during refresh 2022-11-30 19:25:24 +00:00
vfio.c vfio: Hold a reference to the iommu_group in kvm for SPAPR 2022-10-07 08:10:52 -06:00
vfio.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00