mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +00:00
[PATCH] kvm: fix GFP_KERNEL allocation in atomic section in kvm_dev_ioctl_create_vcpu()
fix an GFP_KERNEL allocation in atomic section: kvm_dev_ioctl_create_vcpu() called kvm_mmu_init(), which calls alloc_pages(), while holding the vcpu. The fix is to set up the MMU state in two phases: kvm_mmu_create() and kvm_mmu_setup(). (NOTE: free_vcpus does an kvm_mmu_destroy() call so there's no need for any extra teardown branch on allocation/init failure here.) Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Avi Kivity <avi@qumranet.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
55a54f79e0
commit
8018c27b26
3 changed files with 17 additions and 20 deletions
|
@ -319,7 +319,8 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module);
|
|||
void kvm_exit_arch(void);
|
||||
|
||||
void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
|
||||
int kvm_mmu_init(struct kvm_vcpu *vcpu);
|
||||
int kvm_mmu_create(struct kvm_vcpu *vcpu);
|
||||
int kvm_mmu_setup(struct kvm_vcpu *vcpu);
|
||||
|
||||
int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
|
||||
void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
|
||||
|
|
|
@ -522,12 +522,14 @@ static int kvm_dev_ioctl_create_vcpu(struct kvm *kvm, int n)
|
|||
if (r < 0)
|
||||
goto out_free_vcpus;
|
||||
|
||||
r = kvm_mmu_create(vcpu);
|
||||
if (r < 0)
|
||||
goto out_free_vcpus;
|
||||
|
||||
kvm_arch_ops->vcpu_load(vcpu);
|
||||
|
||||
r = kvm_arch_ops->vcpu_setup(vcpu);
|
||||
r = kvm_mmu_setup(vcpu);
|
||||
if (r >= 0)
|
||||
r = kvm_mmu_init(vcpu);
|
||||
|
||||
r = kvm_arch_ops->vcpu_setup(vcpu);
|
||||
vcpu_put(vcpu);
|
||||
|
||||
if (r < 0)
|
||||
|
|
|
@ -639,28 +639,22 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int kvm_mmu_init(struct kvm_vcpu *vcpu)
|
||||
int kvm_mmu_create(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
int r;
|
||||
|
||||
ASSERT(vcpu);
|
||||
ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa));
|
||||
ASSERT(list_empty(&vcpu->free_pages));
|
||||
|
||||
r = alloc_mmu_pages(vcpu);
|
||||
if (r)
|
||||
goto out;
|
||||
return alloc_mmu_pages(vcpu);
|
||||
}
|
||||
|
||||
r = init_kvm_mmu(vcpu);
|
||||
if (r)
|
||||
goto out_free_pages;
|
||||
int kvm_mmu_setup(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
ASSERT(vcpu);
|
||||
ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa));
|
||||
ASSERT(!list_empty(&vcpu->free_pages));
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_pages:
|
||||
free_mmu_pages(vcpu);
|
||||
out:
|
||||
return r;
|
||||
return init_kvm_mmu(vcpu);
|
||||
}
|
||||
|
||||
void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
|
||||
|
|
Loading…
Reference in a new issue