* make kvm_create() skip all memory setup in case phys_mem_bytes == 0 * add kvm_register_userspace_phys_mem() to register any userspace memory as guest physical memory. Signed-off-by: Gerd Hoffmann --- user/kvmctl.c | 53 +++++++++++++++++++++++++++++++++++++++++------------ user/kvmctl.h | 3 +++ 2 files changed, 44 insertions(+), 12 deletions(-) Index: kvm-46/user/kvmctl.c =================================================================== --- kvm-46.orig/user/kvmctl.c +++ kvm-46/user/kvmctl.c @@ -443,20 +443,22 @@ int kvm_create(kvm_context_t kvm, unsign } kvm->vm_fd = fd; - r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_USER_MEMORY); - if (r > 0) - r = kvm_alloc_userspace_memory(kvm, memory, vm_mem); - else - r = kvm_alloc_kernel_memory(kvm, memory, vm_mem); - if (r < 0) - return r; + if (phys_mem_bytes) { + r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_USER_MEMORY); + if (r > 0) + r = kvm_alloc_userspace_memory(kvm, memory, vm_mem); + else + r = kvm_alloc_kernel_memory(kvm, memory, vm_mem); + if (r < 0) + return r; - zfd = open("/dev/zero", O_RDONLY); - mmap(*vm_mem + 0xa8000, 0x8000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_FIXED, zfd, 0); - close(zfd); + zfd = open("/dev/zero", O_RDONLY); + mmap(*vm_mem + 0xa8000, 0x8000, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_FIXED, zfd, 0); + close(zfd); - kvm->physical_memory = *vm_mem; + kvm->physical_memory = *vm_mem; + } kvm->irqchip_in_kernel = 0; if (!kvm->no_irqchip_creation) { @@ -558,6 +560,33 @@ void *kvm_create_phys_mem(kvm_context_t 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) +{ + int r; + 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, + }; + + 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", 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() */ Index: kvm-46/user/kvmctl.h =================================================================== --- kvm-46.orig/user/kvmctl.h +++ kvm-46/user/kvmctl.h @@ -404,6 +404,9 @@ void *kvm_create_phys_mem(kvm_context_t, 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);