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.
* 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);
-------------------------------------------------------------------------
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/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel