mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
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: Jes Sorensen <jes@sgi.com> Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
ae675ef01c
commit
e9a999fe1f
4 changed files with 104 additions and 4 deletions
|
@ -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 {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1430,9 +1447,78 @@ 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,
|
||||||
|
@ -1472,7 +1558,7 @@ void kvm_arch_flush_shadow(struct kvm *kvm)
|
||||||
}
|
}
|
||||||
|
|
||||||
long kvm_arch_dev_ioctl(struct file *filp,
|
long kvm_arch_dev_ioctl(struct file *filp,
|
||||||
unsigned int ioctl, unsigned long arg)
|
unsigned int ioctl, unsigned long arg)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue