# 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