]> git.baikalelectronics.ru Git - kernel.git/commitdiff
KVM: Move wiping of the kvm->vcpus array to common code
authorMarc Zyngier <maz@kernel.org>
Tue, 16 Nov 2021 16:03:57 +0000 (16:03 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 8 Dec 2021 09:24:13 +0000 (04:24 -0500)
All architectures have similar loops iterating over the vcpus,
freeing one vcpu at a time, and eventually wiping the reference
off the vcpus array. They are also inconsistently taking
the kvm->lock mutex when wiping the references from the array.

Make this code common, which will simplify further changes.
The locking is dropped altogether, as this should only be called
when there is no further references on the kvm structure.

Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Message-Id: <20211116160403.4074052-2-maz@kernel.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/arm64/kvm/arm.c
arch/mips/kvm/mips.c
arch/powerpc/kvm/powerpc.c
arch/riscv/kvm/vm.c
arch/s390/kvm/kvm-s390.c
arch/x86/kvm/x86.c
include/linux/kvm_host.h
virt/kvm/kvm_main.c

index e4727dc771bf3a75dbce8384f23313cf623c7c36..362b10cb992c4e4b23e5ec47185ff7b6f70bfad0 100644 (file)
@@ -175,19 +175,11 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
  */
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
-       int i;
-
        bitmap_free(kvm->arch.pmu_filter);
 
        kvm_vgic_destroy(kvm);
 
-       for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-               if (kvm->vcpus[i]) {
-                       kvm_vcpu_destroy(kvm->vcpus[i]);
-                       kvm->vcpus[i] = NULL;
-               }
-       }
-       atomic_set(&kvm->online_vcpus, 0);
+       kvm_destroy_vcpus(kvm);
 }
 
 int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
index aa20d074d38836ed3482cc0cb6915d92fb4a98d6..6aa5e3771d05d094b5141878acf4b9a6abee1888 100644 (file)
@@ -171,25 +171,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        return 0;
 }
 
-void kvm_mips_free_vcpus(struct kvm *kvm)
-{
-       unsigned int i;
-       struct kvm_vcpu *vcpu;
-
-       kvm_for_each_vcpu(i, vcpu, kvm) {
-               kvm_vcpu_destroy(vcpu);
-       }
-
-       mutex_lock(&kvm->lock);
-
-       for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
-               kvm->vcpus[i] = NULL;
-
-       atomic_set(&kvm->online_vcpus, 0);
-
-       mutex_unlock(&kvm->lock);
-}
-
 static void kvm_mips_free_gpa_pt(struct kvm *kvm)
 {
        /* It should always be safe to remove after flushing the whole range */
@@ -199,7 +180,7 @@ static void kvm_mips_free_gpa_pt(struct kvm *kvm)
 
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
-       kvm_mips_free_vcpus(kvm);
+       kvm_destroy_vcpus(kvm);
        kvm_mips_free_gpa_pt(kvm);
 }
 
index a72920f4f221fab998e4bb6c50c0739d8c9c63a9..98f5d90ebf5aa3b4404c81c62070b81beee82216 100644 (file)
@@ -463,9 +463,6 @@ err_out:
 
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
-       unsigned int i;
-       struct kvm_vcpu *vcpu;
-
 #ifdef CONFIG_KVM_XICS
        /*
         * We call kick_all_cpus_sync() to ensure that all
@@ -476,14 +473,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
                kick_all_cpus_sync();
 #endif
 
-       kvm_for_each_vcpu(i, vcpu, kvm)
-               kvm_vcpu_destroy(vcpu);
+       kvm_destroy_vcpus(kvm);
 
        mutex_lock(&kvm->lock);
-       for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
-               kvm->vcpus[i] = NULL;
-
-       atomic_set(&kvm->online_vcpus, 0);
 
        kvmppc_core_destroy_vm(kvm);
 
index fb18af34a4b52f1275763a829324bca84a358bbc..7619691d89530babeba749e8a3b5af463d2f8424 100644 (file)
@@ -46,15 +46,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
-       int i;
-
-       for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-               if (kvm->vcpus[i]) {
-                       kvm_vcpu_destroy(kvm->vcpus[i]);
-                       kvm->vcpus[i] = NULL;
-               }
-       }
-       atomic_set(&kvm->online_vcpus, 0);
+       kvm_destroy_vcpus(kvm);
 }
 
 int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
index 14a18ba5ff2c8b8e810b06c5979ef654d48e4121..6eeb59af5d7446f75315ba0b56263ade523e9b94 100644 (file)
@@ -2821,27 +2821,11 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
        free_page((unsigned long)(vcpu->arch.sie_block));
 }
 
-static void kvm_free_vcpus(struct kvm *kvm)
-{
-       unsigned int i;
-       struct kvm_vcpu *vcpu;
-
-       kvm_for_each_vcpu(i, vcpu, kvm)
-               kvm_vcpu_destroy(vcpu);
-
-       mutex_lock(&kvm->lock);
-       for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
-               kvm->vcpus[i] = NULL;
-
-       atomic_set(&kvm->online_vcpus, 0);
-       mutex_unlock(&kvm->lock);
-}
-
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
        u16 rc, rrc;
 
-       kvm_free_vcpus(kvm);
+       kvm_destroy_vcpus(kvm);
        sca_dispose(kvm);
        kvm_s390_gisa_destroy(kvm);
        /*
index e0aa4dd53c7fc98957d0a916df12f37fda9c2f39..0e6d11a726cd94743c1cac3ecfd970fcabad10cd 100644 (file)
@@ -11423,15 +11423,8 @@ static void kvm_free_vcpus(struct kvm *kvm)
                kvm_clear_async_pf_completion_queue(vcpu);
                kvm_unload_vcpu_mmu(vcpu);
        }
-       kvm_for_each_vcpu(i, vcpu, kvm)
-               kvm_vcpu_destroy(vcpu);
-
-       mutex_lock(&kvm->lock);
-       for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
-               kvm->vcpus[i] = NULL;
 
-       atomic_set(&kvm->online_vcpus, 0);
-       mutex_unlock(&kvm->lock);
+       kvm_destroy_vcpus(kvm);
 }
 
 void kvm_arch_sync_events(struct kvm *kvm)
index c310648cc8f1abd8581f245871920b4e08a960f9..e2f9f8f67c58763af82f4c307662633c57672361 100644 (file)
@@ -733,7 +733,7 @@ static inline struct kvm_vcpu *kvm_get_vcpu_by_id(struct kvm *kvm, int id)
                if (WARN_ON_ONCE(!memslot->npages)) {                   \
                } else
 
-void kvm_vcpu_destroy(struct kvm_vcpu *vcpu);
+void kvm_destroy_vcpus(struct kvm *kvm);
 
 void vcpu_load(struct kvm_vcpu *vcpu);
 void vcpu_put(struct kvm_vcpu *vcpu);
index 72c4e6b393896aa9f4a7fa3531151ee8df3d1268..0a504c7988dcb56cd14e9a9d3449fa2c1edbad0e 100644 (file)
@@ -435,7 +435,7 @@ static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
        vcpu->last_used_slot = 0;
 }
 
-void kvm_vcpu_destroy(struct kvm_vcpu *vcpu)
+static void kvm_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
        kvm_dirty_ring_free(&vcpu->dirty_ring);
        kvm_arch_vcpu_destroy(vcpu);
@@ -450,7 +450,20 @@ void kvm_vcpu_destroy(struct kvm_vcpu *vcpu)
        free_page((unsigned long)vcpu->run);
        kmem_cache_free(kvm_vcpu_cache, vcpu);
 }
-EXPORT_SYMBOL_GPL(kvm_vcpu_destroy);
+
+void kvm_destroy_vcpus(struct kvm *kvm)
+{
+       unsigned int i;
+       struct kvm_vcpu *vcpu;
+
+       kvm_for_each_vcpu(i, vcpu, kvm) {
+               kvm_vcpu_destroy(vcpu);
+               kvm->vcpus[i] = NULL;
+       }
+
+       atomic_set(&kvm->online_vcpus, 0);
+}
+EXPORT_SYMBOL_GPL(kvm_destroy_vcpus);
 
 #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
 static inline struct kvm *mmu_notifier_to_kvm(struct mmu_notifier *mn)