Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[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>

authored by

Ingo Molnar and committed by
Linus Torvalds
8018c27b 55a54f79

+17 -20
+2 -1
drivers/kvm/kvm.h
··· 319 319 void kvm_exit_arch(void); 320 320 321 321 void kvm_mmu_destroy(struct kvm_vcpu *vcpu); 322 - int kvm_mmu_init(struct kvm_vcpu *vcpu); 322 + int kvm_mmu_create(struct kvm_vcpu *vcpu); 323 + int kvm_mmu_setup(struct kvm_vcpu *vcpu); 323 324 324 325 int kvm_mmu_reset_context(struct kvm_vcpu *vcpu); 325 326 void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
+6 -4
drivers/kvm/kvm_main.c
··· 522 522 if (r < 0) 523 523 goto out_free_vcpus; 524 524 525 + r = kvm_mmu_create(vcpu); 526 + if (r < 0) 527 + goto out_free_vcpus; 528 + 525 529 kvm_arch_ops->vcpu_load(vcpu); 526 - 527 - r = kvm_arch_ops->vcpu_setup(vcpu); 530 + r = kvm_mmu_setup(vcpu); 528 531 if (r >= 0) 529 - r = kvm_mmu_init(vcpu); 530 - 532 + r = kvm_arch_ops->vcpu_setup(vcpu); 531 533 vcpu_put(vcpu); 532 534 533 535 if (r < 0)
+9 -15
drivers/kvm/mmu.c
··· 639 639 return -ENOMEM; 640 640 } 641 641 642 - int kvm_mmu_init(struct kvm_vcpu *vcpu) 642 + int kvm_mmu_create(struct kvm_vcpu *vcpu) 643 643 { 644 - int r; 645 - 646 644 ASSERT(vcpu); 647 645 ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa)); 648 646 ASSERT(list_empty(&vcpu->free_pages)); 649 647 650 - r = alloc_mmu_pages(vcpu); 651 - if (r) 652 - goto out; 648 + return alloc_mmu_pages(vcpu); 649 + } 653 650 654 - r = init_kvm_mmu(vcpu); 655 - if (r) 656 - goto out_free_pages; 651 + int kvm_mmu_setup(struct kvm_vcpu *vcpu) 652 + { 653 + ASSERT(vcpu); 654 + ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa)); 655 + ASSERT(!list_empty(&vcpu->free_pages)); 657 656 658 - return 0; 659 - 660 - out_free_pages: 661 - free_mmu_pages(vcpu); 662 - out: 663 - return r; 657 + return init_kvm_mmu(vcpu); 664 658 } 665 659 666 660 void kvm_mmu_destroy(struct kvm_vcpu *vcpu)