kvm: call kvm_arch_destroy_vm if vm creation fails
In kvm_create_vm(), if we've successfully called kvm_arch_init_vm(), but
then fail later in the function, we need to call kvm_arch_destroy_vm()
so that it can do any necessary cleanup (like freeing memory).
Fixes: 44a95dae1d
("KVM: x86: Detect and Initialize AVIC support")
Signed-off-by: John Sperbeck <jsperbeck@google.com>
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Junaid Shahid <junaids@google.com>
[Remove dependency on "kvm: Don't clear reference count on
kvm_create_vm() error path" which was not committed. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9121923c45
commit
a97b0e773e
|
@ -641,7 +641,6 @@ static struct kvm *kvm_create_vm(unsigned long type)
|
|||
mutex_init(&kvm->lock);
|
||||
mutex_init(&kvm->irq_lock);
|
||||
mutex_init(&kvm->slots_lock);
|
||||
refcount_set(&kvm->users_count, 1);
|
||||
INIT_LIST_HEAD(&kvm->devices);
|
||||
|
||||
BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
|
||||
|
@ -650,7 +649,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
|
|||
struct kvm_memslots *slots = kvm_alloc_memslots();
|
||||
|
||||
if (!slots)
|
||||
goto out_err_no_disable;
|
||||
goto out_err_no_arch_destroy_vm;
|
||||
/* Generations must be different for each address space. */
|
||||
slots->generation = i;
|
||||
rcu_assign_pointer(kvm->memslots[i], slots);
|
||||
|
@ -660,12 +659,13 @@ static struct kvm *kvm_create_vm(unsigned long type)
|
|||
rcu_assign_pointer(kvm->buses[i],
|
||||
kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT));
|
||||
if (!kvm->buses[i])
|
||||
goto out_err_no_disable;
|
||||
goto out_err_no_arch_destroy_vm;
|
||||
}
|
||||
|
||||
refcount_set(&kvm->users_count, 1);
|
||||
r = kvm_arch_init_vm(kvm, type);
|
||||
if (r)
|
||||
goto out_err_no_disable;
|
||||
goto out_err_no_arch_destroy_vm;
|
||||
|
||||
r = hardware_enable_all();
|
||||
if (r)
|
||||
|
@ -699,7 +699,9 @@ static struct kvm *kvm_create_vm(unsigned long type)
|
|||
out_err_no_srcu:
|
||||
hardware_disable_all();
|
||||
out_err_no_disable:
|
||||
refcount_set(&kvm->users_count, 0);
|
||||
kvm_arch_destroy_vm(kvm);
|
||||
WARN_ON_ONCE(!refcount_dec_and_test(&kvm->users_count));
|
||||
out_err_no_arch_destroy_vm:
|
||||
for (i = 0; i < KVM_NR_BUSES; i++)
|
||||
kfree(kvm_get_bus(kvm, i));
|
||||
for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
|
||||
|
|
Loading…
Reference in New Issue
Block a user