From 109c6e47051f2c7ae2ee10e3fd882b60230e2525 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 18 Oct 2007 17:29:19 +0200 Subject: kvm: libkvm: allow custom memory setup. * split kvm_create() into smaller pieces which can be individually called if needed. * add kvm_register_userspace_phys_mem() function. Signed-off-by: Avi Kivity --- kvm/user/kvmctl.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++----- kvm/user/kvmctl.h | 6 ++++++ 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/kvm/user/kvmctl.c b/kvm/user/kvmctl.c index ff2014e88..18b6fa9a3 100644 --- a/kvm/user/kvmctl.c +++ b/kvm/user/kvmctl.c @@ -436,12 +436,9 @@ int kvm_alloc_userspace_memory(kvm_context_t kvm, unsigned long memory, #endif -int kvm_create(kvm_context_t kvm, unsigned long phys_mem_bytes, void **vm_mem) +int kvm_create_vm(kvm_context_t kvm) { - unsigned long memory = (phys_mem_bytes + PAGE_SIZE - 1) & PAGE_MASK; int fd = kvm->fd; - int zfd; - int r; kvm->vcpu_fd[0] = -1; @@ -451,6 +448,16 @@ int kvm_create(kvm_context_t kvm, unsigned long phys_mem_bytes, void **vm_mem) return -1; } kvm->vm_fd = fd; + return 0; +} + +static int kvm_create_default_phys_mem(kvm_context_t kvm, + unsigned long phys_mem_bytes, + void **vm_mem) +{ + unsigned long memory = (phys_mem_bytes + PAGE_SIZE - 1) & PAGE_MASK; + int zfd; + int r; #ifdef KVM_CAP_USER_MEMORY r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_USER_MEMORY); @@ -468,13 +475,19 @@ int kvm_create(kvm_context_t kvm, unsigned long phys_mem_bytes, void **vm_mem) close(zfd); kvm->physical_memory = *vm_mem; + return 0; +} + +void kvm_create_irqchip(kvm_context_t kvm) +{ + int r; kvm->irqchip_in_kernel = 0; #ifdef KVM_CAP_IRQCHIP if (!kvm->no_irqchip_creation) { r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_IRQCHIP); if (r > 0) { /* kernel irqchip supported */ - r = ioctl(fd, KVM_CREATE_IRQCHIP); + r = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP); if (r >= 0) kvm->irqchip_in_kernel = 1; else @@ -482,6 +495,19 @@ int kvm_create(kvm_context_t kvm, unsigned long phys_mem_bytes, void **vm_mem) } } #endif +} + +int kvm_create(kvm_context_t kvm, unsigned long phys_mem_bytes, void **vm_mem) +{ + int r; + + r = kvm_create_vm(kvm); + if (r < 0) + return r; + r = kvm_create_default_phys_mem(kvm, phys_mem_bytes, vm_mem); + if (r < 0) + return r; + kvm_create_irqchip(kvm); r = kvm_create_vcpu(kvm, 0); if (r < 0) return r; @@ -577,6 +603,32 @@ void *kvm_create_phys_mem(kvm_context_t kvm, unsigned long phys_start, log, writable); } +int kvm_register_userspace_phys_mem(kvm_context_t kvm, + unsigned long phys_start, void *userspace_addr, + unsigned long len, int slot, int log) +{ + struct kvm_userspace_memory_region memory = { + .slot = slot, + .memory_size = len, + .guest_phys_addr = phys_start, + .userspace_addr = (intptr_t)userspace_addr, + .flags = log ? KVM_MEM_LOG_DIRTY_PAGES : 0, + }; + int r; + + if (!kvm->physical_memory) + kvm->physical_memory = userspace_addr - phys_start; + + r = ioctl(kvm->vm_fd, KVM_SET_USER_MEMORY_REGION, &memory); + if (r == -1) { + fprintf(stderr, "create_userspace_phys_mem: %s\n", strerror(errno)); + return -1; + } + + kvm_userspace_memory_region_save_params(kvm, &memory); + return 0; +} + /* destroy/free a whole slot. * phys_start, len and slot are the params passed to kvm_create_phys_mem() */ diff --git a/kvm/user/kvmctl.h b/kvm/user/kvmctl.h index 18ae3b9cc..fd2600da8 100644 --- a/kvm/user/kvmctl.h +++ b/kvm/user/kvmctl.h @@ -146,6 +146,9 @@ int kvm_get_shadow_pages(kvm_context_t kvm , unsigned int *nrshadow_pages); int kvm_create(kvm_context_t kvm, unsigned long phys_mem_bytes, void **phys_mem); +int kvm_create_vm(kvm_context_t kvm); +void kvm_create_irqchip(kvm_context_t kvm); + /*! * \brief Create a new virtual cpu * @@ -413,6 +416,9 @@ void *kvm_create_phys_mem(kvm_context_t, unsigned long phys_start, unsigned long len, int slot, int log, int writable); void kvm_destroy_phys_mem(kvm_context_t, unsigned long phys_start, unsigned long len, int slot); +int kvm_register_userspace_phys_mem(kvm_context_t kvm, + unsigned long phys_start, void *userspace_addr, + unsigned long len, int slot, int log); int kvm_get_dirty_pages(kvm_context_t, int slot, void *buf); -- cgit v1.2.3