diff mbox

kvm tools: Use mmap to allocate guest RAM

Message ID 1303389242-29657-1-git-send-email-levinsasha928@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sasha Levin April 21, 2011, 12:34 p.m. UTC
Using mmap to allocate the RAM enables us to allocate large blocks of memory for the guest, allowing to boot guests with a large RAM.
Since if we try KVM_SET_USER_MEMORY_REGION with a large memory block KVM used to Oops (now it just fails), we had to move the actual ioctl to after we KVM_CREATE_VCPU.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/include/kvm/kvm.h |    2 +-
 tools/kvm/kvm-run.c         |    5 ++++-
 tools/kvm/kvm.c             |   21 +++++++++++++++++++--
 3 files changed, 24 insertions(+), 4 deletions(-)

Comments

Pekka Enberg April 21, 2011, 12:41 p.m. UTC | #1
On Thu, Apr 21, 2011 at 3:34 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
> Using mmap to allocate the RAM enables us to allocate large blocks of memory for the guest, allowing to boot guests with a large RAM.
> Since if we try KVM_SET_USER_MEMORY_REGION with a large memory block KVM used to Oops (now it just fails), we had to move the actual ioctl to after we KVM_CREATE_VCPU.
>
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>

The changelog seems to be identical with commit
9c2530b7d9b4da8052dfb15f5618b7aa59da6de2 ("kvm tools: Use mmap to
allocate guest RAM") but the diff is different. Hmm?
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index fc76f98..3a44c53 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -25,7 +25,7 @@  struct kvm {
 	struct interrupt_table	interrupt_table;
 };
 
-struct kvm *kvm__init(const char *kvm_dev, unsigned long ram_size);
+struct kvm *kvm__init(const char *kvm_dev, unsigned long ram_size, bool use_backing);
 void kvm__init_ram(struct kvm *self);
 void kvm__delete(struct kvm *self);
 bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index fb8dcae7..a925a98 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -69,6 +69,7 @@  static const char *host_ip_addr;
 static const char *guest_mac;
 static const char *script;
 static bool single_step;
+static bool use_backing;
 static bool readonly_image;
 extern bool ioport_debug;
 extern int  active_console;
@@ -84,6 +85,8 @@  static const struct option options[] = {
 	OPT_GROUP("Basic options:"),
 	OPT_INTEGER('\0', "cpus", &nrcpus, "Number of CPUs"),
 	OPT_U64('m', "mem", &ram_size, "Virtual machine memory size in MiB."),
+	OPT_BOOLEAN('\0', "use-backing", &use_backing,
+			"Use a backing file for virtual RAM"),
 	OPT_STRING('i', "image", &image_filename, "image", "Disk image"),
 	OPT_BOOLEAN('\0', "readonly", &readonly_image,
 			"Don't write changes back to disk image"),
@@ -366,7 +369,7 @@  int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	term_init();
 
-	kvm = kvm__init(kvm_dev, ram_size);
+	kvm = kvm__init(kvm_dev, ram_size, use_backing);
 
 	memset(real_cmdline, 0, sizeof(real_cmdline));
 	strcpy(real_cmdline, "notsc nolapic noacpi pci=conf1 console=ttyS0 ");
diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index eb1a46c..5e312e9 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -170,11 +170,12 @@  void kvm__init_ram(struct kvm *self)
 		die_perror("KVM_SET_USER_MEMORY_REGION ioctl");
 }
 
-struct kvm *kvm__init(const char *kvm_dev, unsigned long ram_size)
+struct kvm *kvm__init(const char *kvm_dev, unsigned long ram_size, bool use_backing)
 {
 	struct kvm_pit_config pit_config = { .flags = 0, };
 	struct kvm *self;
 	int ret;
+	int backfd;
 
 	if (!kvm__cpu_supports_vm())
 		die("Your CPU does not support hardware virtualization");
@@ -214,7 +215,23 @@  struct kvm *kvm__init(const char *kvm_dev, unsigned long ram_size)
 
 	self->ram_size		= ram_size;
 
-	self->ram_start = mmap(NULL, ram_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+	if (use_backing) {
+		char tmp_template[] = "/tmp/kvm_ram.XXXXXX";
+
+		backfd = mkstemp(tmp_template);
+		if (backfd < 0)
+			die("Failed creating RAM backing file");
+
+		unlink(tmp_template);
+
+		if (ftruncate(backfd, ram_size) < 0)
+			die("Failed resizing RAM backing file");
+
+		self->ram_start = mmap(NULL, ram_size, PROT_READ | PROT_WRITE, MAP_SHARED, backfd, 0);
+	} else {
+		self->ram_start = mmap(NULL, ram_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+	}
+
 	if (self->ram_start == MAP_FAILED)
 		die("out of memory");