KVM: SVM: Fix memory leaks that happen when svm_create_vcpu() fails

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>
This commit is contained in:
Takuya Yoshikawa 2010-03-09 14:55:19 +09:00 committed by Avi Kivity
parent 7567cae105
commit b7af404338

View File

@ -706,29 +706,28 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
if (err) if (err)
goto free_svm; goto free_svm;
page = alloc_page(GFP_KERNEL);
if (!page) {
err = -ENOMEM;
goto uninit;
}
err = -ENOMEM; err = -ENOMEM;
page = alloc_page(GFP_KERNEL);
if (!page)
goto uninit;
msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
if (!msrpm_pages) if (!msrpm_pages)
goto uninit; goto free_page1;
nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
if (!nested_msrpm_pages) if (!nested_msrpm_pages)
goto uninit; goto free_page2;
svm->msrpm = page_address(msrpm_pages);
svm_vcpu_init_msrpm(svm->msrpm);
hsave_page = alloc_page(GFP_KERNEL); hsave_page = alloc_page(GFP_KERNEL);
if (!hsave_page) if (!hsave_page)
goto uninit; goto free_page3;
svm->nested.hsave = page_address(hsave_page); 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->nested.msrpm = page_address(nested_msrpm_pages);
svm->vmcb = page_address(page); svm->vmcb = page_address(page);
@ -744,6 +743,12 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
return &svm->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: uninit:
kvm_vcpu_uninit(&svm->vcpu); kvm_vcpu_uninit(&svm->vcpu);
free_svm: free_svm: