kvm: Allocate memslots and buses before calling kvm_arch_init_vm
authorJim Mattson <jmattson@google.com>
Thu, 24 Oct 2019 23:03:26 +0000 (16:03 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 25 Oct 2019 11:32:33 +0000 (13:32 +0200)
This reorganization will allow us to call kvm_arch_destroy_vm in the
event that kvm_create_vm fails after calling kvm_arch_init_vm.

Suggested-by: Junaid Shahid <junaids@google.com>
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Junaid Shahid <junaids@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
virt/kvm/kvm_main.c

index 67ef3f2..ec14dae 100644 (file)
@@ -627,8 +627,9 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
 
 static struct kvm *kvm_create_vm(unsigned long type)
 {
-       int r, i;
        struct kvm *kvm = kvm_arch_alloc_vm();
+       int r = -ENOMEM;
+       int i;
 
        if (!kvm)
                return ERR_PTR(-ENOMEM);
@@ -643,6 +644,25 @@ static struct kvm *kvm_create_vm(unsigned long type)
        refcount_set(&kvm->users_count, 1);
        INIT_LIST_HEAD(&kvm->devices);
 
+       BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
+
+       for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
+               struct kvm_memslots *slots = kvm_alloc_memslots();
+
+               if (!slots)
+                       goto out_err_no_disable;
+               /* Generations must be different for each address space. */
+               slots->generation = i;
+               rcu_assign_pointer(kvm->memslots[i], slots);
+       }
+
+       for (i = 0; i < KVM_NR_BUSES; i++) {
+               rcu_assign_pointer(kvm->buses[i],
+                       kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT));
+               if (!kvm->buses[i])
+                       goto out_err_no_disable;
+       }
+
        r = kvm_arch_init_vm(kvm, type);
        if (r)
                goto out_err_no_disable;
@@ -655,28 +675,10 @@ static struct kvm *kvm_create_vm(unsigned long type)
        INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list);
 #endif
 
-       BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
-
-       r = -ENOMEM;
-       for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
-               struct kvm_memslots *slots = kvm_alloc_memslots();
-               if (!slots)
-                       goto out_err_no_srcu;
-               /* Generations must be different for each address space. */
-               slots->generation = i;
-               rcu_assign_pointer(kvm->memslots[i], slots);
-       }
-
        if (init_srcu_struct(&kvm->srcu))
                goto out_err_no_srcu;
        if (init_srcu_struct(&kvm->irq_srcu))
                goto out_err_no_irq_srcu;
-       for (i = 0; i < KVM_NR_BUSES; i++) {
-               rcu_assign_pointer(kvm->buses[i],
-                       kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT));
-               if (!kvm->buses[i])
-                       goto out_err;
-       }
 
        r = kvm_init_mmu_notifier(kvm);
        if (r)