Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9a999fe authored by Jes Sorensen's avatar Jes Sorensen Committed by Avi Kivity
Browse files

KVM: ia64: stack get/restore patch



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: default avatarJes Sorensen <jes@sgi.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent ae675ef0
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -214,6 +214,13 @@ struct kvm_sregs {
struct kvm_fpu {
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 {
struct kvm_debug_exit_arch {
};
};


+5 −1
Original line number Original line Diff line number Diff line
@@ -112,7 +112,11 @@
#define VCPU_STRUCT_SHIFT	16
#define VCPU_STRUCT_SHIFT	16
#define VCPU_STRUCT_SIZE	(__IA64_UL_CONST(1) << VCPU_STRUCT_SHIFT)
#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_SHIFT	19
#define KVM_VM_STRUCT_SIZE	(__IA64_UL_CONST(1) << KVM_VM_STRUCT_SHIFT)
#define KVM_VM_STRUCT_SIZE	(__IA64_UL_CONST(1) << KVM_VM_STRUCT_SHIFT)
+89 −3
Original line number Original line Diff line number Diff line
@@ -1421,6 +1421,23 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
	return 0;
	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)
void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
{
{


@@ -1432,7 +1449,76 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
long kvm_arch_vcpu_ioctl(struct file *filp,
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,
int kvm_arch_set_memory_region(struct kvm *kvm,
+3 −0
Original line number Original line Diff line number Diff line
@@ -489,6 +489,9 @@ struct kvm_debug_guest {


#define __KVM_DEPRECATED_DEBUG_GUEST _IOW(KVMIO,  0x87, 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_INJ_VIRQ         (KVM_TRC_HANDLER + 0x02)
#define KVM_TRC_REDELIVER_EVT    (KVM_TRC_HANDLER + 0x03)
#define KVM_TRC_REDELIVER_EVT    (KVM_TRC_HANDLER + 0x03)
#define KVM_TRC_PEND_INTR        (KVM_TRC_HANDLER + 0x04)
#define KVM_TRC_PEND_INTR        (KVM_TRC_HANDLER + 0x04)