summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Mattson <jmattson@google.com>2019-10-24 16:03:26 -0700
committerPaolo Bonzini <pbonzini@redhat.com>2019-10-25 13:32:33 +0200
commit9121923c457d1d8667a6e3a67302c29e5c5add6b (patch)
tree821962f16d7e52fa2ce92eb0a942390bb614d01e
parent671ddc700fd08b94967b1e2a937020e30c838609 (diff)
downloadlinux-9121923c457d1d8667a6e3a67302c29e5c5add6b.tar.bz2
kvm: Allocate memslots and buses before calling kvm_arch_init_vm
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>
-rw-r--r--virt/kvm/kvm_main.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 67ef3f2e19e8..ec14dae2f538 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -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)