# HG changeset patch
# User Hollis Blanchard <[EMAIL PROTECTED]>
# Date 1202189668 21600
# Node ID e6e0239e8df55c6af4e0b2959350215aaa119254
# Parent  7dd50dab9096c8e0125792e3f48083c3f47fceab
The ioctl accepts a core name as input and calls kvm_vm_ioctl_create_vcpu()
with the corresponding "guest operations" structure. That structure, which
will be extended with additional core-specific function pointers, is saved into
the new vcpu by kvm_arch_vcpu_create().

Signed-off-by: Hollis Blanchard <[EMAIL PROTECTED]>

---
3 files changed, 87 insertions(+), 3 deletions(-)
arch/powerpc/kvm/powerpc.c     |   77 ++++++++++++++++++++++++++++++++++++++--
include/asm-powerpc/kvm_host.h |    5 ++
include/linux/kvm.h            |    8 ++++


diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -460,13 +460,22 @@ int kvm_arch_set_memory_region(struct kv
        return 0;
 }
 
+/* XXX Make modules register kvmppc_core_spec pointers at init. */
+static struct kvmppc_core_spec kvmppc_supported_guests[] = {
+       {
+               .name = "ppc440",
+               .vcpu_size = sizeof(struct kvm_vcpu),
+       },
+};
+
 struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id,
                                       void *opaque)
 {
+       struct kvmppc_core_spec *s = opaque;
        struct kvm_vcpu *vcpu;
        int err;
 
-       vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
+       vcpu = vmalloc(s->vcpu_size);
        if (!vcpu) {
                err = -ENOMEM;
                goto out;
@@ -479,7 +488,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
        return vcpu;
 
 free_vcpu:
-       kmem_cache_free(kvm_vcpu_cache, vcpu);
+       vfree(vcpu);
 out:
        return ERR_PTR(err);
 }
@@ -487,7 +496,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu 
 void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
 {
        kvm_vcpu_uninit(vcpu);
-       kmem_cache_free(kvm_vcpu_cache, vcpu);
+       vfree(vcpu);
 }
 
 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
@@ -800,12 +809,74 @@ int kvm_vm_ioctl_get_dirty_log(struct kv
        return -ENOTSUPP;
 }
 
+static struct kvmppc_core_spec *kvmppc_guest_type(char *coretype)
+{
+       struct kvmppc_core_spec *c = kvmppc_supported_guests;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(kvmppc_supported_guests); i++,c++)
+               if (strcmp(c->name, coretype))
+                       return c;
+
+       return 0;
+}
+
+static long kvmppc_arch_vcpu_create_type(struct kvm *kvm,
+                                  struct kvm_vcpu_create_type __user 
*user_type)
+{
+       struct kvm_vcpu_create_type type;
+       struct kvmppc_core_spec *s;
+       char *coretype;
+       long r;
+
+       if (copy_from_user(&type, user_type, sizeof(type))) {
+               r = -EFAULT;
+               goto out;
+       }
+
+       if (type.typelen > 32) {
+               r = -E2BIG;
+               goto out;
+       }
+
+       coretype = vmalloc(type.typelen);
+       if (!coretype) {
+               r = -ENOMEM;
+               goto out;
+       }
+
+       if (copy_from_user(coretype, type.type, type.typelen)) {
+               r = -EFAULT;
+               goto out_free;
+       }
+       coretype[type.typelen-1] = '\0';
+
+       s = kvmppc_guest_type(coretype);
+       if (!s) {
+               r = -ENOTSUPP;
+               goto out_free;
+       }
+
+       r = kvm_vm_ioctl_create_vcpu(kvm, type.id, s);
+
+out_free:
+       vfree(coretype);
+out:
+       return r;
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
                        unsigned int ioctl, unsigned long arg)
 {
+       struct kvm *kvm = filp->private_data;
+       void __user *argp = (void __user *)arg;
        long r;
 
        switch (ioctl) {
+       case KVM_CREATE_VCPU_TYPE: {
+               r = kvmppc_arch_vcpu_create_type(kvm, argp);
+               break;
+       }
        default:
                r = -EINVAL;
        }
diff --git a/include/asm-powerpc/kvm_host.h b/include/asm-powerpc/kvm_host.h
--- a/include/asm-powerpc/kvm_host.h
+++ b/include/asm-powerpc/kvm_host.h
@@ -49,6 +49,11 @@ struct tlbe {
 };
 
 struct kvm_arch {
+};
+
+struct kvmppc_core_spec {
+       const char *name;
+       unsigned int vcpu_size;
 };
 
 struct kvm_vcpu_arch {
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -211,6 +211,12 @@ struct kvm_vapic_addr {
        __u64 vapic_addr;
 };
 
+struct kvm_vcpu_create_type {
+       __u32 id;
+       __u32 typelen;
+       char type[0];
+};
+
 #define KVMIO 0xAE
 
 /*
@@ -257,6 +263,8 @@ struct kvm_vapic_addr {
 #define KVM_GET_DIRTY_LOG         _IOW(KVMIO, 0x42, struct kvm_dirty_log)
 #define KVM_SET_MEMORY_ALIAS      _IOW(KVMIO, 0x43, struct kvm_memory_alias)
 #define KVM_GET_SUPPORTED_CPUID   _IOWR(KVMIO, 0x48, struct kvm_cpuid2)
+#define KVM_CREATE_VCPU_TYPE      _IOW(KVMIO,  0x49, struct 
kvm_vcpu_create_type)
+
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP       _IO(KVMIO,  0x60)
 #define KVM_IRQ_LINE             _IOW(KVMIO, 0x61, struct kvm_irq_level)

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to