public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Andrew Honig <ahonig@google.com>
To: kvm@vger.kernel.org
Cc: ahonig@google.com
Subject: [PATCH] KVM: x86: Fix memory leak in vmx.c
Date: Thu, 4 Apr 2013 12:39:47 -0700 (PDT)	[thread overview]
Message-ID: <alpine.DEB.2.02.1304041235060.7867@ahonig-virtual-machine> (raw)

If userspace creates and destroys multiple VMs within the same process
we leak 20k of memory in the userspace process context per VM.  This
patch frees the memory in kvm_arch_destroy_vm.  If the process exits
without closing the VM file descriptor or the file descriptor has been
shared with another process then we don't need to free the memory.

Messing with user space memory from an fd is not ideal, but other changes
would require user space changes and this is consistent with how the
memory is currently allocated.

Tested: Test ran several VMs and ran against test program meant to 
demonstrate the leak (www.spinics.net/lists/kvm/msg83734.html).

Signed-off-by: Andrew Honig <ahonig@google.com>

---
 arch/x86/include/asm/kvm_host.h |    3 +++
 arch/x86/kvm/vmx.c              |    3 +++
 arch/x86/kvm/x86.c              |   11 +++++++++++
 3 files changed, 17 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4979778..975a74d 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -553,6 +553,9 @@ struct kvm_arch {
 	struct page *ept_identity_pagetable;
 	bool ept_identity_pagetable_done;
 	gpa_t ept_identity_map_addr;
+	unsigned long ept_ptr;
+	unsigned long apic_ptr;
+	unsigned long tss_ptr;
 
 	unsigned long irq_sources_bitmap;
 	s64 kvmclock_offset;
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 6667042..8aa5d81 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3703,6 +3703,7 @@ static int alloc_apic_access_page(struct kvm *kvm)
 	}
 
 	kvm->arch.apic_access_page = page;
+	kvm->arch.apic_ptr = kvm_userspace_mem.userspace_addr;
 out:
 	mutex_unlock(&kvm->slots_lock);
 	return r;
@@ -3733,6 +3734,7 @@ static int alloc_identity_pagetable(struct kvm *kvm)
 	}
 
 	kvm->arch.ept_identity_pagetable = page;
+	kvm->arch.ept_ptr = kvm_userspace_mem.userspace_addr;
 out:
 	mutex_unlock(&kvm->slots_lock);
 	return r;
@@ -4366,6 +4368,7 @@ static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
 	if (ret)
 		return ret;
 	kvm->arch.tss_addr = addr;
+	kvm->arch.tss_ptr = tss_mem.userspace_addr;
 	if (!init_rmode_tss(kvm))
 		return  -ENOMEM;
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f19ac0a..411ff2a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6812,6 +6812,16 @@ void kvm_arch_sync_events(struct kvm *kvm)
 
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
+	if (current->mm == kvm->mm) {
+		/*
+		 * Free pages allocated on behalf of userspace, unless the
+		 * the memory map has changed due to process exit or fd
+		 * copying.
+		 */
+		vm_munmap(kvm->arch.apic_ptr, PAGE_SIZE);
+		vm_munmap(kvm->arch.ept_ptr, PAGE_SIZE);
+		vm_munmap(kvm->arch.tss_ptr, PAGE_SIZE * 3);
+	}
 	kvm_iommu_unmap_guest(kvm);
 	kfree(kvm->arch.vpic);
 	kfree(kvm->arch.vioapic);
@@ -6929,6 +6939,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
 			return PTR_ERR((void *)userspace_addr);
 
 		memslot->userspace_addr = userspace_addr;
+		mem->userspace_addr = userspace_addr;
 	}
 
 	return 0;
-- 
1.7.10.4


             reply	other threads:[~2013-04-04 19:39 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-04 19:39 Andrew Honig [this message]
2013-04-08  9:24 ` [PATCH] KVM: x86: Fix memory leak in vmx.c Gleb Natapov
2013-04-08 17:11   ` Andrew Honig
2013-04-08 17:53     ` Gleb Natapov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.02.1304041235060.7867@ahonig-virtual-machine \
    --to=ahonig@google.com \
    --cc=kvm@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox