lkml.org 
[lkml]   [2009]   [Feb]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 17/40] KVM: ia64: stack get/restore patch
    Date
    From: Jes Sorensen <jes@sgi.com>

    Implement KVM_IA64_VCPU_[GS]ET_STACK ioctl calls. This is required
    for live migrations.

    Patch is based on previous implementation that was part of old
    GET/SET_REGS ioctl calls.

    Signed-off-by: Jes Sorensen <jes@sgi.com>
    Signed-off-by: Avi Kivity <avi@redhat.com>
    ---
    arch/ia64/include/asm/kvm.h | 7 +++
    arch/ia64/include/asm/kvm_host.h | 6 ++-
    arch/ia64/kvm/kvm-ia64.c | 92 ++++++++++++++++++++++++++++++++++++-
    include/linux/kvm.h | 3 +
    4 files changed, 104 insertions(+), 4 deletions(-)

    diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/asm/kvm.h
    index be3fdb8..b514578 100644
    --- a/arch/ia64/include/asm/kvm.h
    +++ b/arch/ia64/include/asm/kvm.h
    @@ -214,6 +214,13 @@ struct kvm_sregs {
    struct kvm_fpu {
    };

    +#define KVM_IA64_VCPU_STACK_SHIFT 16
    +#define KVM_IA64_VCPU_STACK_SIZE (1UL << KVM_IA64_VCPU_STACK_SHIFT)
    +
    +struct kvm_ia64_vcpu_stack {
    + unsigned char stack[KVM_IA64_VCPU_STACK_SIZE];
    +};
    +
    struct kvm_debug_exit_arch {
    };

    diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
    index 3486636..7da0c09 100644
    --- a/arch/ia64/include/asm/kvm_host.h
    +++ b/arch/ia64/include/asm/kvm_host.h
    @@ -112,7 +112,11 @@
    #define VCPU_STRUCT_SHIFT 16
    #define VCPU_STRUCT_SIZE (__IA64_UL_CONST(1) << VCPU_STRUCT_SHIFT)

    -#define KVM_STK_OFFSET VCPU_STRUCT_SIZE
    +/*
    + * This must match KVM_IA64_VCPU_STACK_{SHIFT,SIZE} arch/ia64/include/asm/kvm.h
    + */
    +#define KVM_STK_SHIFT 16
    +#define KVM_STK_OFFSET (__IA64_UL_CONST(1)<< KVM_STK_SHIFT)

    #define KVM_VM_STRUCT_SHIFT 19
    #define KVM_VM_STRUCT_SIZE (__IA64_UL_CONST(1) << KVM_VM_STRUCT_SHIFT)
    diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
    index de47467..1477f91 100644
    --- a/arch/ia64/kvm/kvm-ia64.c
    +++ b/arch/ia64/kvm/kvm-ia64.c
    @@ -1421,6 +1421,23 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
    return 0;
    }

    +int kvm_arch_vcpu_ioctl_get_stack(struct kvm_vcpu *vcpu,
    + struct kvm_ia64_vcpu_stack *stack)
    +{
    + memcpy(stack, vcpu, sizeof(struct kvm_ia64_vcpu_stack));
    + return 0;
    +}
    +
    +int kvm_arch_vcpu_ioctl_set_stack(struct kvm_vcpu *vcpu,
    + struct kvm_ia64_vcpu_stack *stack)
    +{
    + memcpy(vcpu + 1, &stack->stack[0] + sizeof(struct kvm_vcpu),
    + sizeof(struct kvm_ia64_vcpu_stack) - sizeof(struct kvm_vcpu));
    +
    + vcpu->arch.exit_data = ((struct kvm_vcpu *)stack)->arch.exit_data;
    + return 0;
    +}
    +
    void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
    {

    @@ -1430,9 +1447,78 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)


    long kvm_arch_vcpu_ioctl(struct file *filp,
    - unsigned int ioctl, unsigned long arg)
    + unsigned int ioctl, unsigned long arg)
    {
    - return -EINVAL;
    + struct kvm_vcpu *vcpu = filp->private_data;
    + void __user *argp = (void __user *)arg;
    + struct kvm_ia64_vcpu_stack *stack = NULL;
    + long r;
    +
    + switch (ioctl) {
    + case KVM_IA64_VCPU_GET_STACK: {
    + struct kvm_ia64_vcpu_stack __user *user_stack;
    + void __user *first_p = argp;
    +
    + r = -EFAULT;
    + if (copy_from_user(&user_stack, first_p, sizeof(void *)))
    + goto out;
    +
    + if (!access_ok(VERIFY_WRITE, user_stack,
    + sizeof(struct kvm_ia64_vcpu_stack))) {
    + printk(KERN_INFO "KVM_IA64_VCPU_GET_STACK: "
    + "Illegal user destination address for stack\n");
    + goto out;
    + }
    + stack = kzalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
    + if (!stack) {
    + r = -ENOMEM;
    + goto out;
    + }
    +
    + r = kvm_arch_vcpu_ioctl_get_stack(vcpu, stack);
    + if (r)
    + goto out;
    +
    + if (copy_to_user(user_stack, stack,
    + sizeof(struct kvm_ia64_vcpu_stack)))
    + goto out;
    +
    + break;
    + }
    + case KVM_IA64_VCPU_SET_STACK: {
    + struct kvm_ia64_vcpu_stack __user *user_stack;
    + void __user *first_p = argp;
    +
    + r = -EFAULT;
    + if (copy_from_user(&user_stack, first_p, sizeof(void *)))
    + goto out;
    +
    + if (!access_ok(VERIFY_READ, user_stack,
    + sizeof(struct kvm_ia64_vcpu_stack))) {
    + printk(KERN_INFO "KVM_IA64_VCPU_SET_STACK: "
    + "Illegal user address for stack\n");
    + goto out;
    + }
    + stack = kmalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
    + if (!stack) {
    + r = -ENOMEM;
    + goto out;
    + }
    + if (copy_from_user(stack, user_stack,
    + sizeof(struct kvm_ia64_vcpu_stack)))
    + goto out;
    +
    + r = kvm_arch_vcpu_ioctl_set_stack(vcpu, stack);
    + break;
    + }
    +
    + default:
    + r = -EINVAL;
    + }
    +
    +out:
    + kfree(stack);
    + return r;
    }

    int kvm_arch_set_memory_region(struct kvm *kvm,
    @@ -1472,7 +1558,7 @@ void kvm_arch_flush_shadow(struct kvm *kvm)
    }

    long kvm_arch_dev_ioctl(struct file *filp,
    - unsigned int ioctl, unsigned long arg)
    + unsigned int ioctl, unsigned long arg)
    {
    return -EINVAL;
    }
    diff --git a/include/linux/kvm.h b/include/linux/kvm.h
    index 429a2ce..28582fc 100644
    --- a/include/linux/kvm.h
    +++ b/include/linux/kvm.h
    @@ -489,6 +489,9 @@ struct kvm_debug_guest {

    #define __KVM_DEPRECATED_DEBUG_GUEST _IOW(KVMIO, 0x87, struct kvm_debug_guest)

    +#define KVM_IA64_VCPU_GET_STACK _IOR(KVMIO, 0x9a, void *)
    +#define KVM_IA64_VCPU_SET_STACK _IOW(KVMIO, 0x9b, void *)
    +
    #define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02)
    #define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03)
    #define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04)
    --
    1.6.0.6


    \
     
     \ /
      Last update: 2009-02-26 15:27    [W:0.030 / U:2.604 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site