| From 55a5d6db91054b446d633f61e0c0ad23e3944aec Mon Sep 17 00:00:00 2001 |
| From: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> |
| Date: Tue, 9 Mar 2010 14:55:19 +0900 |
| Subject: KVM: SVM: Fix memory leaks that happen when svm_create_vcpu() fails |
| |
| From: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> |
| |
| (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> |
| |
| --- |
| arch/x86/kvm/svm.c | 25 +++++++++++++++---------- |
| 1 file changed, 15 insertions(+), 10 deletions(-) |
| |
| --- a/arch/x86/kvm/svm.c |
| +++ b/arch/x86/kvm/svm.c |
| @@ -694,29 +694,28 @@ static struct kvm_vcpu *svm_create_vcpu( |
| if (err) |
| goto free_svm; |
| |
| + err = -ENOMEM; |
| page = alloc_page(GFP_KERNEL); |
| - if (!page) { |
| - err = -ENOMEM; |
| + if (!page) |
| goto uninit; |
| - } |
| |
| - err = -ENOMEM; |
| msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); |
| if (!msrpm_pages) |
| - goto uninit; |
| + goto free_page1; |
| |
| nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); |
| if (!nested_msrpm_pages) |
| - goto uninit; |
| - |
| - svm->msrpm = page_address(msrpm_pages); |
| - svm_vcpu_init_msrpm(svm->msrpm); |
| + goto free_page2; |
| |
| hsave_page = alloc_page(GFP_KERNEL); |
| if (!hsave_page) |
| - goto uninit; |
| + goto free_page3; |
| + |
| svm->nested.hsave = page_address(hsave_page); |
| |
| + svm->msrpm = page_address(msrpm_pages); |
| + svm_vcpu_init_msrpm(svm->msrpm); |
| + |
| svm->nested.msrpm = page_address(nested_msrpm_pages); |
| |
| svm->vmcb = page_address(page); |
| @@ -733,6 +732,12 @@ static struct kvm_vcpu *svm_create_vcpu( |
| |
| return &svm->vcpu; |
| |
| +free_page3: |
| + __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER); |
| +free_page2: |
| + __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER); |
| +free_page1: |
| + __free_page(page); |
| uninit: |
| kvm_vcpu_uninit(&svm->vcpu); |
| free_svm: |