From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gerd Hoffmann Subject: Re: [patch] kvmctl.c: allow custom memory setup. Date: Thu, 18 Oct 2007 13:06:09 +0200 Message-ID: <47173E21.3010502@redhat.com> References: <470C8D28.2060408@qumranet.com> <470F2806.8090902@redhat.com> <4710701C.2040200@qumranet.com> <47134476.1050609@redhat.com> <47134857.9030102@redhat.com> <1192446374.6578.0.camel@izike-woof.qumranet.com> <47134BC0.1000008@redhat.com> <1192447442.6911.5.camel@izike-woof.qumranet.com> <47135284.1060106@redhat.com> <4715DEFC.8010507@redhat.com> <471690D2.2060204@qumranet.com> <47170D95.1050603@redhat.com> <471714FC.6050703@qumranet.com> <47173300.70907@redhat.com> <1192703432.3175.18.camel@izike-woof.qumranet.com> <471737E8.6000708@qumranet.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------020707010900040607040403" Cc: kvm-devel To: Avi Kivity Return-path: In-Reply-To: <471737E8.6000708-atKUWr5tajBWk0Htik3J/w@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Errors-To: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: kvm.vger.kernel.org This is a multi-part message in MIME format. --------------020707010900040607040403 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Avi Kivity wrote: > Izik Eidus wrote: >> On Thu, 2007-10-18 at 12:18 +0200, Gerd Hoffmann wrote: >> >>>>> I don't see how I can pass a pointer to >>>>> kvm_create_userspace_memory() via kvm_create() without >>>>> breaking the libkvm interface. There is no flags field or >>>>> similar which could be used to signal "vm_mem is a valid >>>>> pointer, please use that instead of mmap()'ing anonymous >>>>> memory". >>>>> >>>> There is no need to keep binary compat to libkvm as long as it >>>> is linked statically. >> anyone who use kvmctl, should not call kvm_create_userspace_memory >> directly, instead should call kvm_create()... I'm talking about the kvm_create() interface, dammit. Sure I can modify kvm_create_userspace_memory() without breaking anyone as this isn't part of the public (kvmctl.h) interface. That doesn't buy us much though. I'd have to pass the pointer to kvm_create() somehow so it can be passed down to kvm_create_userspace_memory(). I can't without breaking the public library interface though. > Why not have an API for creating memory slots? It allows much more > flexibility and is more in line with what qemu wants. This *is* what the patch does. It adds a function to add a userspace-memory-backed memory slot: kvm_register_userspace_phys_mem(). That alone doesn't cut it though as there are some more constrains: * kvm_create() builds a standard memory layout, which I want be able to skip. * kvm_create() fails to create a vcpu in case no memory is available, which makes simple approach to just ask kvm_create() for 0 bytes physical memory for the guest unusable. Thats why I went the route to additionally split the job kvm_create() does into multiple, individually callable pieces. So I can first create the vm, then create my custom memory slots (instead of the standard setup built by kvm_create_userspace_memory()), then create the vcpu. cheers, Gerd ps: patch attached again for reference. --------------020707010900040607040403 Content-Type: text/x-patch; name="kvm-user-memory.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="kvm-user-memory.diff" * split kvm_create() into smaller pieces which can be individually called if needed. * add kvm_register_userspace_phys_mem() function. --- user/kvmctl.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- user/kvmctl.h | 8 +++++++ 2 files changed, 64 insertions(+), 5 deletions(-) Index: kvm-46/user/kvmctl.c =================================================================== --- kvm-46.orig/user/kvmctl.c +++ kvm-46/user/kvmctl.c @@ -427,12 +427,9 @@ int kvm_alloc_userspace_memory(kvm_conte return 0; } -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; @@ -442,6 +439,15 @@ int kvm_create(kvm_context_t kvm, unsign return -1; } kvm->vm_fd = fd; + return 0; +} + +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; r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_USER_MEMORY); if (r > 0) @@ -457,18 +463,37 @@ int kvm_create(kvm_context_t kvm, unsign close(zfd); kvm->physical_memory = *vm_mem; + return 0; +} + +void kvm_create_irqchip(kvm_context_t kvm) +{ + int r; kvm->irqchip_in_kernel = 0; 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 printf("Create kernel PIC irqchip failed\n"); } } +} + +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; @@ -558,6 +583,32 @@ 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) +{ + 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", 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 @@ -137,6 +137,11 @@ int kvm_get_shadow_pages(kvm_context_t k int kvm_create(kvm_context_t kvm, unsigned long phys_mem_bytes, void **phys_mem); +int kvm_create_vm(kvm_context_t kvm); +int kvm_create_default_phys_mem(kvm_context_t kvm, unsigned long phys_mem_bytes, + void **vm_mem); +void kvm_create_irqchip(kvm_context_t kvm); + /*! * \brief Create a new virtual cpu * @@ -404,6 +409,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); --------------020707010900040607040403 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ --------------020707010900040607040403 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kvm-devel mailing list kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/kvm-devel --------------020707010900040607040403--