aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/include/asm/kvm.h7
-rw-r--r--arch/ia64/include/asm/kvm_host.h6
-rw-r--r--arch/ia64/kvm/kvm-ia64.c92
-rw-r--r--include/linux/kvm.h3
4 files changed, 104 insertions, 4 deletions
diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/asm/kvm.h
index be3fdb891214..b5145784233e 100644
--- a/arch/ia64/include/asm/kvm.h
+++ b/arch/ia64/include/asm/kvm.h
@@ -214,6 +214,13 @@ struct kvm_sregs {
214struct kvm_fpu { 214struct kvm_fpu {
215}; 215};
216 216
217#define KVM_IA64_VCPU_STACK_SHIFT 16
218#define KVM_IA64_VCPU_STACK_SIZE (1UL << KVM_IA64_VCPU_STACK_SHIFT)
219
220struct kvm_ia64_vcpu_stack {
221 unsigned char stack[KVM_IA64_VCPU_STACK_SIZE];
222};
223
217struct kvm_debug_exit_arch { 224struct kvm_debug_exit_arch {
218}; 225};
219 226
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index 348663661659..7da0c0963226 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -112,7 +112,11 @@
112#define VCPU_STRUCT_SHIFT 16 112#define VCPU_STRUCT_SHIFT 16
113#define VCPU_STRUCT_SIZE (__IA64_UL_CONST(1) << VCPU_STRUCT_SHIFT) 113#define VCPU_STRUCT_SIZE (__IA64_UL_CONST(1) << VCPU_STRUCT_SHIFT)
114 114
115#define KVM_STK_OFFSET VCPU_STRUCT_SIZE 115/*
116 * This must match KVM_IA64_VCPU_STACK_{SHIFT,SIZE} arch/ia64/include/asm/kvm.h
117 */
118#define KVM_STK_SHIFT 16
119#define KVM_STK_OFFSET (__IA64_UL_CONST(1)<< KVM_STK_SHIFT)
116 120
117#define KVM_VM_STRUCT_SHIFT 19 121#define KVM_VM_STRUCT_SHIFT 19
118#define KVM_VM_STRUCT_SIZE (__IA64_UL_CONST(1) << KVM_VM_STRUCT_SHIFT) 122#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 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}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 429a2ce202f9..28582fcd3f79 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -489,6 +489,9 @@ struct kvm_debug_guest {
489 489
490#define __KVM_DEPRECATED_DEBUG_GUEST _IOW(KVMIO, 0x87, struct kvm_debug_guest) 490#define __KVM_DEPRECATED_DEBUG_GUEST _IOW(KVMIO, 0x87, struct kvm_debug_guest)
491 491
492#define KVM_IA64_VCPU_GET_STACK _IOR(KVMIO, 0x9a, void *)
493#define KVM_IA64_VCPU_SET_STACK _IOW(KVMIO, 0x9b, void *)
494
492#define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02) 495#define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02)
493#define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03) 496#define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03)
494#define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04) 497#define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04)