]> git.baikalelectronics.ru Git - kernel.git/commitdiff
KVM: Move kvm_arch_vcpu_precreate() under kvm->lock
authorZeng Guang <guang.zeng@intel.com>
Tue, 19 Apr 2022 15:44:09 +0000 (23:44 +0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 8 Jun 2022 08:47:28 +0000 (04:47 -0400)
kvm_arch_vcpu_precreate() targets to handle arch specific VM resource
to be prepared prior to the actual creation of vCPU. For example, x86
platform may need do per-VM allocation based on max_vcpu_ids at the
first vCPU creation. It probably leads to concurrency control on this
allocation as multiple vCPU creation could happen simultaneously. From
the architectual point of view, it's necessary to execute
kvm_arch_vcpu_precreate() under protect of kvm->lock.

Currently only arm64, x86 and s390 have non-nop implementations at the
stage of vCPU pre-creation. Remove the lock acquiring in s390's design
and make sure all architecture can run kvm_arch_vcpu_precreate() safely
under kvm->lock without recrusive lock issue.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Zeng Guang <guang.zeng@intel.com>
Message-Id: <20220419154409.11842-1-guang.zeng@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/s390/kvm/kvm-s390.c
arch/x86/kvm/x86.c
virt/kvm/kvm_main.c

index ff457a77e22b80d9cb219bb0138fd5edd4ff9f05..72bd5c9b961728db88862dcbf16552398c76329a 100644 (file)
@@ -3238,9 +3238,7 @@ static int sca_can_add_vcpu(struct kvm *kvm, unsigned int id)
        if (!sclp.has_esca || !sclp.has_64bscao)
                return false;
 
-       mutex_lock(&kvm->lock);
        rc = kvm->arch.use_esca ? 0 : sca_switch_to_extended(kvm);
-       mutex_unlock(&kvm->lock);
 
        return rc == 0 && id < KVM_S390_ESCA_CPU_SLOTS;
 }
index 501606e026888a00e3c48a503c5e9a1ea9483097..9c2e2b6d1767273c9f5d9b161b2a9d37e4242cfc 100644 (file)
@@ -11242,7 +11242,7 @@ static int sync_regs(struct kvm_vcpu *vcpu)
 
 int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
 {
-       if (kvm_check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0)
+       if (kvm_check_tsc_unstable() && kvm->created_vcpus)
                pr_warn_once("kvm: SMP vm created on host with unstable TSC; "
                             "guest TSC will not be reliable\n");
 
index 7f79abdbd68d25aad1d45e57ade14c5ff76c6d22..6dbdcbda02917ceabe99cba7ae262d6118ec3dcb 100644 (file)
@@ -3768,13 +3768,15 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
                return -EINVAL;
        }
 
+       r = kvm_arch_vcpu_precreate(kvm, id);
+       if (r) {
+               mutex_unlock(&kvm->lock);
+               return r;
+       }
+
        kvm->created_vcpus++;
        mutex_unlock(&kvm->lock);
 
-       r = kvm_arch_vcpu_precreate(kvm, id);
-       if (r)
-               goto vcpu_decrement;
-
        vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL_ACCOUNT);
        if (!vcpu) {
                r = -ENOMEM;