aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kvm/kvm-ia64.c
diff options
context:
space:
mode:
authorJes Sorensen <jes@sgi.com>2008-12-18 06:17:51 -0500
committerAvi Kivity <avi@redhat.com>2009-03-24 05:02:50 -0400
commite9a999fe1feaddb71bffbacbbd68e0da8ca8b50b (patch)
tree57e8758433e31f8d70251aff9ce32fdd30ad8c18 /arch/ia64/kvm/kvm-ia64.c
parentae675ef01cd86014acf8da5dee87876b71122495 (diff)
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>
Diffstat (limited to 'arch/ia64/kvm/kvm-ia64.c')
-rw-r--r--arch/ia64/kvm/kvm-ia64.c92
1 files changed, 89 insertions, 3 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index de47467a0e61..1477f91617a5 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)
1421 return 0; 1421 return 0;
1422} 1422}
1423 1423
1424int kvm_arch_vcpu_ioctl_get_stack(struct kvm_vcpu *vcpu,
1425 struct kvm_ia64_vcpu_stack *stack)
1426{
1427 memcpy(stack, vcpu, sizeof(struct kvm_ia64_vcpu_stack));
1428 return 0;
1429}
1430
1431int kvm_arch_vcpu_ioctl_set_stack(struct kvm_vcpu *vcpu,
1432 struct kvm_ia64_vcpu_stack *stack)
1433{
1434 memcpy(vcpu + 1, &stack->stack[0] + sizeof(struct kvm_vcpu),
1435 sizeof(struct kvm_ia64_vcpu_stack) - sizeof(struct kvm_vcpu));
1436
1437 vcpu->arch.exit_data = ((struct kvm_vcpu *)stack)->arch.exit_data;
1438 return 0;
1439}
1440
1424void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) 1441void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
1425{ 1442{
1426 1443
@@ -1430,9 +1447,78 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
1430 1447
1431 1448
1432long kvm_arch_vcpu_ioctl(struct file *filp, 1449long kvm_arch_vcpu_ioctl(struct file *filp,
1433 unsigned int ioctl, unsigned long arg) 1450 unsigned int ioctl, unsigned long arg)
1434{ 1451{
1435 return -EINVAL; 1452 struct kvm_vcpu *vcpu = filp->private_data;
1453 void __user *argp = (void __user *)arg;
1454 struct kvm_ia64_vcpu_stack *stack = NULL;
1455 long r;
1456
1457 switch (ioctl) {
1458 case KVM_IA64_VCPU_GET_STACK: {
1459 struct kvm_ia64_vcpu_stack __user *user_stack;
1460 void __user *first_p = argp;
1461
1462 r = -EFAULT;
1463 if (copy_from_user(&user_stack, first_p, sizeof(void *)))
1464 goto out;
1465
1466 if (!access_ok(VERIFY_WRITE, user_stack,
1467 sizeof(struct kvm_ia64_vcpu_stack))) {
1468 printk(KERN_INFO "KVM_IA64_VCPU_GET_STACK: "
1469 "Illegal user destination address for stack\n");
1470 goto out;
1471 }
1472 stack = kzalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
1473 if (!stack) {
1474 r = -ENOMEM;
1475 goto out;
1476 }
1477
1478 r = kvm_arch_vcpu_ioctl_get_stack(vcpu, stack);
1479 if (r)
1480 goto out;
1481
1482 if (copy_to_user(user_stack, stack,
1483 sizeof(struct kvm_ia64_vcpu_stack)))
1484 goto out;
1485
1486 break;
1487 }
1488 case KVM_IA64_VCPU_SET_STACK: {
1489 struct kvm_ia64_vcpu_stack __user *user_stack;
1490 void __user *first_p = argp;
1491
1492 r = -EFAULT;
1493 if (copy_from_user(&user_stack, first_p, sizeof(void *)))
1494 goto out;
1495
1496 if (!access_ok(VERIFY_READ, user_stack,
1497 sizeof(struct kvm_ia64_vcpu_stack))) {
1498 printk(KERN_INFO "KVM_IA64_VCPU_SET_STACK: "
1499 "Illegal user address for stack\n");
1500 goto out;
1501 }
1502 stack = kmalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
1503 if (!stack) {
1504 r = -ENOMEM;
1505 goto out;
1506 }
1507 if (copy_from_user(stack, user_stack,
1508 sizeof(struct kvm_ia64_vcpu_stack)))
1509 goto out;
1510
1511 r = kvm_arch_vcpu_ioctl_set_stack(vcpu, stack);
1512 break;
1513 }
1514
1515 default:
1516 r = -EINVAL;
1517 }
1518
1519out:
1520 kfree(stack);
1521 return r;
1436} 1522}
1437 1523
1438int kvm_arch_set_memory_region(struct kvm *kvm, 1524int kvm_arch_set_memory_region(struct kvm *kvm,
@@ -1472,7 +1558,7 @@ void kvm_arch_flush_shadow(struct kvm *kvm)
1472} 1558}
1473 1559
1474long kvm_arch_dev_ioctl(struct file *filp, 1560long kvm_arch_dev_ioctl(struct file *filp,
1475 unsigned int ioctl, unsigned long arg) 1561 unsigned int ioctl, unsigned long arg)
1476{ 1562{
1477 return -EINVAL; 1563 return -EINVAL;
1478} 1564}