Commit 01954dfd authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Sasha Levin

KVM: fix spin_lock_init order on x86

[ Upstream commit e9ad4ec8 ]

Moving the initialization earlier is needed in 4.6 because
kvm_arch_init_vm is now using mmu_lock, causing lockdep to
complain:

[  284.440294] INFO: trying to register non-static key.
[  284.445259] the code is fine but needs lockdep annotation.
[  284.450736] turning off the locking correctness validator.
...
[  284.528318]  [<ffffffff810aecc3>] lock_acquire+0xd3/0x240
[  284.533733]  [<ffffffffa0305aa0>] ? kvm_page_track_register_notifier+0x20/0x60 [kvm]
[  284.541467]  [<ffffffff81715581>] _raw_spin_lock+0x41/0x80
[  284.546960]  [<ffffffffa0305aa0>] ? kvm_page_track_register_notifier+0x20/0x60 [kvm]
[  284.554707]  [<ffffffffa0305aa0>] kvm_page_track_register_notifier+0x20/0x60 [kvm]
[  284.562281]  [<ffffffffa02ece70>] kvm_mmu_init_vm+0x20/0x30 [kvm]
[  284.568381]  [<ffffffffa02dbf7a>] kvm_arch_init_vm+0x1ea/0x200 [kvm]
[  284.574740]  [<ffffffffa02bff3f>] kvm_dev_ioctl+0xbf/0x4d0 [kvm]

However, it also helps fixing a preexisting problem, which is why this
patch is also good for stable kernels: kvm_create_vm was incrementing
current->mm->mm_count but not decrementing it at the out_err label (in
case kvm_init_mmu_notifier failed).  The new initialization order makes
it possible to add the required mmdrop without adding a new error label.

Cc: stable@vger.kernel.org
Reported-by: default avatarBorislav Petkov <bp@alien8.de>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarSasha Levin <sasha.levin@oracle.com>
parent 7a335391
...@@ -457,6 +457,16 @@ static struct kvm *kvm_create_vm(unsigned long type) ...@@ -457,6 +457,16 @@ static struct kvm *kvm_create_vm(unsigned long type)
if (!kvm) if (!kvm)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
spin_lock_init(&kvm->mmu_lock);
atomic_inc(&current->mm->mm_count);
kvm->mm = current->mm;
kvm_eventfd_init(kvm);
mutex_init(&kvm->lock);
mutex_init(&kvm->irq_lock);
mutex_init(&kvm->slots_lock);
atomic_set(&kvm->users_count, 1);
INIT_LIST_HEAD(&kvm->devices);
r = kvm_arch_init_vm(kvm, type); r = kvm_arch_init_vm(kvm, type);
if (r) if (r)
goto out_err_no_disable; goto out_err_no_disable;
...@@ -494,16 +504,6 @@ static struct kvm *kvm_create_vm(unsigned long type) ...@@ -494,16 +504,6 @@ static struct kvm *kvm_create_vm(unsigned long type)
goto out_err; goto out_err;
} }
spin_lock_init(&kvm->mmu_lock);
kvm->mm = current->mm;
atomic_inc(&kvm->mm->mm_count);
kvm_eventfd_init(kvm);
mutex_init(&kvm->lock);
mutex_init(&kvm->irq_lock);
mutex_init(&kvm->slots_lock);
atomic_set(&kvm->users_count, 1);
INIT_LIST_HEAD(&kvm->devices);
r = kvm_init_mmu_notifier(kvm); r = kvm_init_mmu_notifier(kvm);
if (r) if (r)
goto out_err; goto out_err;
...@@ -525,6 +525,7 @@ static struct kvm *kvm_create_vm(unsigned long type) ...@@ -525,6 +525,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
kfree(kvm->buses[i]); kfree(kvm->buses[i]);
kvfree(kvm->memslots); kvfree(kvm->memslots);
kvm_arch_free_vm(kvm); kvm_arch_free_vm(kvm);
mmdrop(current->mm);
return ERR_PTR(r); return ERR_PTR(r);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment