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@xxxxxxxxx> --- 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(-) 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"); -- 1.7.5.rc1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html