diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2010-03-09 00:55:19 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-04-26 10:48:04 -0400 |
commit | dee49b4925d922229656f4d3c15da33ae5d036ed (patch) | |
tree | c4e1d1d5fe2861499e8a22c0c8fd690af720a5f8 | |
parent | 68f35500d733ed5cc3153c09f685e0abcfce4956 (diff) |
KVM: SVM: Fix memory leaks that happen when svm_create_vcpu() fails
(Cherry-picked from commit b7af40433870aa0636932ad39b0c48a0cb319057)
svm_create_vcpu() does not free the pages allocated during the creation
when it fails to complete the allocations. This patch fixes it.
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | arch/x86/kvm/svm.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1d9b33843c80..d42e191b17fa 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -698,29 +698,28 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
698 | if (err) | 698 | if (err) |
699 | goto free_svm; | 699 | goto free_svm; |
700 | 700 | ||
701 | err = -ENOMEM; | ||
701 | page = alloc_page(GFP_KERNEL); | 702 | page = alloc_page(GFP_KERNEL); |
702 | if (!page) { | 703 | if (!page) |
703 | err = -ENOMEM; | ||
704 | goto uninit; | 704 | goto uninit; |
705 | } | ||
706 | 705 | ||
707 | err = -ENOMEM; | ||
708 | msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); | 706 | msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); |
709 | if (!msrpm_pages) | 707 | if (!msrpm_pages) |
710 | goto uninit; | 708 | goto free_page1; |
711 | 709 | ||
712 | nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); | 710 | nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); |
713 | if (!nested_msrpm_pages) | 711 | if (!nested_msrpm_pages) |
714 | goto uninit; | 712 | goto free_page2; |
715 | |||
716 | svm->msrpm = page_address(msrpm_pages); | ||
717 | svm_vcpu_init_msrpm(svm->msrpm); | ||
718 | 713 | ||
719 | hsave_page = alloc_page(GFP_KERNEL); | 714 | hsave_page = alloc_page(GFP_KERNEL); |
720 | if (!hsave_page) | 715 | if (!hsave_page) |
721 | goto uninit; | 716 | goto free_page3; |
717 | |||
722 | svm->nested.hsave = page_address(hsave_page); | 718 | svm->nested.hsave = page_address(hsave_page); |
723 | 719 | ||
720 | svm->msrpm = page_address(msrpm_pages); | ||
721 | svm_vcpu_init_msrpm(svm->msrpm); | ||
722 | |||
724 | svm->nested.msrpm = page_address(nested_msrpm_pages); | 723 | svm->nested.msrpm = page_address(nested_msrpm_pages); |
725 | 724 | ||
726 | svm->vmcb = page_address(page); | 725 | svm->vmcb = page_address(page); |
@@ -737,6 +736,12 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
737 | 736 | ||
738 | return &svm->vcpu; | 737 | return &svm->vcpu; |
739 | 738 | ||
739 | free_page3: | ||
740 | __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER); | ||
741 | free_page2: | ||
742 | __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER); | ||
743 | free_page1: | ||
744 | __free_page(page); | ||
740 | uninit: | 745 | uninit: |
741 | kvm_vcpu_uninit(&svm->vcpu); | 746 | kvm_vcpu_uninit(&svm->vcpu); |
742 | free_svm: | 747 | free_svm: |