summaryrefslogtreecommitdiff
path: root/virt
diff options
context:
space:
mode:
authorSean Christopherson <seanjc@google.com>2026-09-21 10:44:39 -0700
committerPaolo Bonzini <pbonzini@redhat.com>2026-09-26 00:49:49 -0400
commit8264c0d73f07f6c3e6768d5a41b56c621f912a37 (patch)
treeaf90acc8e0ed54dce2e1cd04fff35e62ca882ac5 /virt
parentc2f24f140c2ee6c00775c2a93c6ac931acec2b60 (diff)
KVM: Reject attempts to lock all vCPUs if vCPU creation is in-progress
Reject locking of all vCPUs if vCPU creation is in-progress, i.e. if the number of "created" vCPUs doesn't match the number of "onlined" vCPUs. It's simply not possible to guarantee that KVM has truly locked all vCPUs if one or more vCPUs are actively being created. Holding kvm->lock does prevent in-flight vCPUs from being fully onlined, but it's infeasible for common KVM to know whether or not that provides sufficient protection. In practice, this is likely a minor bug fix for the ARM and RISC-V usage of kvm_trylock_all_vcpus(), and a glorified nop for everything else. E.g. ARM's kvm_timer_vcpu_init() can race kvm_vm_ioctl_set_counter_offset() with respect to observing KVM_ARCH_FLAG_VM_COUNTER_OFFSET. Opportunistically drop x86's existing manual checks on vCPU creation being in-progress as all of x86's checks immediately precede or follow locking of all vCPUs. Leave arm64 and RISC-V alone for the moment, as their checks aren't as obviously redundant/equivalent. Signed-off-by: Sean Christopherson <seanjc@google.com> Tested-by: Jean-Christophe Guillain <jean-christophe@guillain.net> Tested-by: Naveen N Rao (AMD) <naveen@kernel.org> Message-ID: <20260921174445.911676-2-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/kvm_main.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 85f42289748d..aad8cf00a1c8 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1363,6 +1363,9 @@ int kvm_trylock_all_vcpus(struct kvm *kvm)
lockdep_assert_held(&kvm->lock);
+ if (kvm_is_vcpu_creation_in_progress(kvm))
+ return -EBUSY;
+
kvm_for_each_vcpu(i, vcpu, kvm)
if (!mutex_trylock_nest_lock(&vcpu->mutex, &kvm->lock))
goto out_unlock;
@@ -1386,6 +1389,9 @@ int kvm_lock_all_vcpus(struct kvm *kvm)
lockdep_assert_held(&kvm->lock);
+ if (kvm_is_vcpu_creation_in_progress(kvm))
+ return -EBUSY;
+
kvm_for_each_vcpu(i, vcpu, kvm) {
r = mutex_lock_killable_nest_lock(&vcpu->mutex, &kvm->lock);
if (r)