mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-09-05 13:11:44 +00:00
kvm tools: Use mmap to allocate guest RAM
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> Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
@@ -26,6 +26,7 @@ struct kvm {
|
||||
};
|
||||
|
||||
struct kvm *kvm__init(const char *kvm_dev, unsigned long ram_size);
|
||||
void kvm__init_ram(struct kvm *self);
|
||||
void kvm__delete(struct kvm *self);
|
||||
bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
|
||||
const char *initrd_filename, const char *kernel_cmdline);
|
||||
|
||||
@@ -437,7 +437,11 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (single_step)
|
||||
kvm_cpu__enable_singlestep(kvm_cpus[i]);
|
||||
}
|
||||
|
||||
kvm__init_ram(kvm);
|
||||
|
||||
for (i = 0; i < nrcpus; i++) {
|
||||
if (pthread_create(&kvm_cpus[i]->thread, NULL, kvm_cpu_thread, kvm_cpus[i]) != 0)
|
||||
die("unable to create KVM VCPU thread");
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ void kvm__delete(struct kvm *self)
|
||||
{
|
||||
kvm__stop_timer(self);
|
||||
|
||||
free(self->ram_start);
|
||||
munmap(self->ram_start, self->ram_size);
|
||||
free(self);
|
||||
}
|
||||
|
||||
@@ -153,12 +153,27 @@ static bool kvm__cpu_supports_vm(void)
|
||||
return regs.ecx & (1 << feature);
|
||||
}
|
||||
|
||||
struct kvm *kvm__init(const char *kvm_dev, unsigned long ram_size)
|
||||
void kvm__init_ram(struct kvm *self)
|
||||
{
|
||||
struct kvm_userspace_memory_region mem;
|
||||
int ret;
|
||||
|
||||
mem = (struct kvm_userspace_memory_region) {
|
||||
.slot = 0,
|
||||
.guest_phys_addr = 0x0UL,
|
||||
.memory_size = self->ram_size,
|
||||
.userspace_addr = (unsigned long) self->ram_start,
|
||||
};
|
||||
|
||||
ret = ioctl(self->vm_fd, KVM_SET_USER_MEMORY_REGION, &mem);
|
||||
if (ret < 0)
|
||||
die_perror("KVM_SET_USER_MEMORY_REGION ioctl");
|
||||
}
|
||||
|
||||
struct kvm *kvm__init(const char *kvm_dev, unsigned long ram_size)
|
||||
{
|
||||
struct kvm_pit_config pit_config = { .flags = 0, };
|
||||
struct kvm *self;
|
||||
long page_size;
|
||||
int ret;
|
||||
|
||||
if (!kvm__cpu_supports_vm())
|
||||
@@ -199,21 +214,10 @@ struct kvm *kvm__init(const char *kvm_dev, unsigned long ram_size)
|
||||
|
||||
self->ram_size = ram_size;
|
||||
|
||||
page_size = sysconf(_SC_PAGESIZE);
|
||||
if (posix_memalign(&self->ram_start, page_size, self->ram_size) != 0)
|
||||
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");
|
||||
|
||||
mem = (struct kvm_userspace_memory_region) {
|
||||
.slot = 0,
|
||||
.guest_phys_addr = 0x0UL,
|
||||
.memory_size = self->ram_size,
|
||||
.userspace_addr = (unsigned long) self->ram_start,
|
||||
};
|
||||
|
||||
ret = ioctl(self->vm_fd, KVM_SET_USER_MEMORY_REGION, &mem);
|
||||
if (ret < 0)
|
||||
die_perror("KVM_SET_USER_MEMORY_REGION ioctl");
|
||||
|
||||
ret = ioctl(self->vm_fd, KVM_CREATE_IRQCHIP);
|
||||
if (ret < 0)
|
||||
die_perror("KVM_CREATE_IRQCHIP ioctl");
|
||||
|
||||
Reference in New Issue
Block a user