diff options
Diffstat (limited to 'arch/ia64/kvm/kvm-ia64.c')
| -rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 125 |
1 files changed, 114 insertions, 11 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 28f982045f29..076b00d1dbff 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
| @@ -182,7 +182,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
| 182 | switch (ext) { | 182 | switch (ext) { |
| 183 | case KVM_CAP_IRQCHIP: | 183 | case KVM_CAP_IRQCHIP: |
| 184 | case KVM_CAP_MP_STATE: | 184 | case KVM_CAP_MP_STATE: |
| 185 | 185 | case KVM_CAP_IRQ_INJECT_STATUS: | |
| 186 | r = 1; | 186 | r = 1; |
| 187 | break; | 187 | break; |
| 188 | case KVM_CAP_COALESCED_MMIO: | 188 | case KVM_CAP_COALESCED_MMIO: |
| @@ -314,7 +314,7 @@ static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id, | |||
| 314 | union ia64_lid lid; | 314 | union ia64_lid lid; |
| 315 | int i; | 315 | int i; |
| 316 | 316 | ||
| 317 | for (i = 0; i < KVM_MAX_VCPUS; i++) { | 317 | for (i = 0; i < kvm->arch.online_vcpus; i++) { |
| 318 | if (kvm->vcpus[i]) { | 318 | if (kvm->vcpus[i]) { |
| 319 | lid.val = VCPU_LID(kvm->vcpus[i]); | 319 | lid.val = VCPU_LID(kvm->vcpus[i]); |
| 320 | if (lid.id == id && lid.eid == eid) | 320 | if (lid.id == id && lid.eid == eid) |
| @@ -388,7 +388,7 @@ static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 388 | 388 | ||
| 389 | call_data.ptc_g_data = p->u.ptc_g_data; | 389 | call_data.ptc_g_data = p->u.ptc_g_data; |
| 390 | 390 | ||
| 391 | for (i = 0; i < KVM_MAX_VCPUS; i++) { | 391 | for (i = 0; i < kvm->arch.online_vcpus; i++) { |
| 392 | if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state == | 392 | if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state == |
| 393 | KVM_MP_STATE_UNINITIALIZED || | 393 | KVM_MP_STATE_UNINITIALIZED || |
| 394 | vcpu == kvm->vcpus[i]) | 394 | vcpu == kvm->vcpus[i]) |
| @@ -788,6 +788,8 @@ struct kvm *kvm_arch_create_vm(void) | |||
| 788 | return ERR_PTR(-ENOMEM); | 788 | return ERR_PTR(-ENOMEM); |
| 789 | kvm_init_vm(kvm); | 789 | kvm_init_vm(kvm); |
| 790 | 790 | ||
| 791 | kvm->arch.online_vcpus = 0; | ||
| 792 | |||
| 791 | return kvm; | 793 | return kvm; |
| 792 | 794 | ||
| 793 | } | 795 | } |
| @@ -919,7 +921,13 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 919 | r = kvm_ioapic_init(kvm); | 921 | r = kvm_ioapic_init(kvm); |
| 920 | if (r) | 922 | if (r) |
| 921 | goto out; | 923 | goto out; |
| 924 | r = kvm_setup_default_irq_routing(kvm); | ||
| 925 | if (r) { | ||
| 926 | kfree(kvm->arch.vioapic); | ||
| 927 | goto out; | ||
| 928 | } | ||
| 922 | break; | 929 | break; |
| 930 | case KVM_IRQ_LINE_STATUS: | ||
| 923 | case KVM_IRQ_LINE: { | 931 | case KVM_IRQ_LINE: { |
| 924 | struct kvm_irq_level irq_event; | 932 | struct kvm_irq_level irq_event; |
| 925 | 933 | ||
| @@ -927,10 +935,17 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 927 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) | 935 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) |
| 928 | goto out; | 936 | goto out; |
| 929 | if (irqchip_in_kernel(kvm)) { | 937 | if (irqchip_in_kernel(kvm)) { |
| 938 | __s32 status; | ||
| 930 | mutex_lock(&kvm->lock); | 939 | mutex_lock(&kvm->lock); |
| 931 | kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, | 940 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, |
| 932 | irq_event.irq, irq_event.level); | 941 | irq_event.irq, irq_event.level); |
| 933 | mutex_unlock(&kvm->lock); | 942 | mutex_unlock(&kvm->lock); |
| 943 | if (ioctl == KVM_IRQ_LINE_STATUS) { | ||
| 944 | irq_event.status = status; | ||
| 945 | if (copy_to_user(argp, &irq_event, | ||
| 946 | sizeof irq_event)) | ||
| 947 | goto out; | ||
| 948 | } | ||
| 934 | r = 0; | 949 | r = 0; |
| 935 | } | 950 | } |
| 936 | break; | 951 | break; |
| @@ -1149,7 +1164,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
| 1149 | 1164 | ||
| 1150 | /*Initialize itc offset for vcpus*/ | 1165 | /*Initialize itc offset for vcpus*/ |
| 1151 | itc_offset = 0UL - ia64_getreg(_IA64_REG_AR_ITC); | 1166 | itc_offset = 0UL - ia64_getreg(_IA64_REG_AR_ITC); |
| 1152 | for (i = 0; i < KVM_MAX_VCPUS; i++) { | 1167 | for (i = 0; i < kvm->arch.online_vcpus; i++) { |
| 1153 | v = (struct kvm_vcpu *)((char *)vcpu + | 1168 | v = (struct kvm_vcpu *)((char *)vcpu + |
| 1154 | sizeof(struct kvm_vcpu_data) * i); | 1169 | sizeof(struct kvm_vcpu_data) * i); |
| 1155 | v->arch.itc_offset = itc_offset; | 1170 | v->arch.itc_offset = itc_offset; |
| @@ -1283,6 +1298,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
| 1283 | goto fail; | 1298 | goto fail; |
| 1284 | } | 1299 | } |
| 1285 | 1300 | ||
| 1301 | kvm->arch.online_vcpus++; | ||
| 1302 | |||
| 1286 | return vcpu; | 1303 | return vcpu; |
| 1287 | fail: | 1304 | fail: |
| 1288 | return ERR_PTR(r); | 1305 | return ERR_PTR(r); |
| @@ -1303,8 +1320,8 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | |||
| 1303 | return -EINVAL; | 1320 | return -EINVAL; |
| 1304 | } | 1321 | } |
| 1305 | 1322 | ||
| 1306 | int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, | 1323 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
| 1307 | struct kvm_debug_guest *dbg) | 1324 | struct kvm_guest_debug *dbg) |
| 1308 | { | 1325 | { |
| 1309 | return -EINVAL; | 1326 | return -EINVAL; |
| 1310 | } | 1327 | } |
| @@ -1421,6 +1438,23 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
| 1421 | return 0; | 1438 | return 0; |
| 1422 | } | 1439 | } |
| 1423 | 1440 | ||
| 1441 | int kvm_arch_vcpu_ioctl_get_stack(struct kvm_vcpu *vcpu, | ||
| 1442 | struct kvm_ia64_vcpu_stack *stack) | ||
| 1443 | { | ||
| 1444 | memcpy(stack, vcpu, sizeof(struct kvm_ia64_vcpu_stack)); | ||
| 1445 | return 0; | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | int kvm_arch_vcpu_ioctl_set_stack(struct kvm_vcpu *vcpu, | ||
| 1449 | struct kvm_ia64_vcpu_stack *stack) | ||
| 1450 | { | ||
| 1451 | memcpy(vcpu + 1, &stack->stack[0] + sizeof(struct kvm_vcpu), | ||
| 1452 | sizeof(struct kvm_ia64_vcpu_stack) - sizeof(struct kvm_vcpu)); | ||
| 1453 | |||
| 1454 | vcpu->arch.exit_data = ((struct kvm_vcpu *)stack)->arch.exit_data; | ||
| 1455 | return 0; | ||
| 1456 | } | ||
| 1457 | |||
| 1424 | void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | 1458 | void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) |
| 1425 | { | 1459 | { |
| 1426 | 1460 | ||
| @@ -1430,9 +1464,78 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | |||
| 1430 | 1464 | ||
| 1431 | 1465 | ||
| 1432 | long kvm_arch_vcpu_ioctl(struct file *filp, | 1466 | long kvm_arch_vcpu_ioctl(struct file *filp, |
| 1433 | unsigned int ioctl, unsigned long arg) | 1467 | unsigned int ioctl, unsigned long arg) |
| 1434 | { | 1468 | { |
| 1435 | return -EINVAL; | 1469 | struct kvm_vcpu *vcpu = filp->private_data; |
| 1470 | void __user *argp = (void __user *)arg; | ||
| 1471 | struct kvm_ia64_vcpu_stack *stack = NULL; | ||
| 1472 | long r; | ||
| 1473 | |||
| 1474 | switch (ioctl) { | ||
| 1475 | case KVM_IA64_VCPU_GET_STACK: { | ||
| 1476 | struct kvm_ia64_vcpu_stack __user *user_stack; | ||
| 1477 | void __user *first_p = argp; | ||
| 1478 | |||
| 1479 | r = -EFAULT; | ||
| 1480 | if (copy_from_user(&user_stack, first_p, sizeof(void *))) | ||
| 1481 | goto out; | ||
| 1482 | |||
| 1483 | if (!access_ok(VERIFY_WRITE, user_stack, | ||
| 1484 | sizeof(struct kvm_ia64_vcpu_stack))) { | ||
| 1485 | printk(KERN_INFO "KVM_IA64_VCPU_GET_STACK: " | ||
| 1486 | "Illegal user destination address for stack\n"); | ||
| 1487 | goto out; | ||
| 1488 | } | ||
| 1489 | stack = kzalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL); | ||
| 1490 | if (!stack) { | ||
| 1491 | r = -ENOMEM; | ||
| 1492 | goto out; | ||
| 1493 | } | ||
| 1494 | |||
| 1495 | r = kvm_arch_vcpu_ioctl_get_stack(vcpu, stack); | ||
| 1496 | if (r) | ||
| 1497 | goto out; | ||
| 1498 | |||
| 1499 | if (copy_to_user(user_stack, stack, | ||
| 1500 | sizeof(struct kvm_ia64_vcpu_stack))) | ||
| 1501 | goto out; | ||
| 1502 | |||
| 1503 | break; | ||
| 1504 | } | ||
| 1505 | case KVM_IA64_VCPU_SET_STACK: { | ||
| 1506 | struct kvm_ia64_vcpu_stack __user *user_stack; | ||
| 1507 | void __user *first_p = argp; | ||
| 1508 | |||
| 1509 | r = -EFAULT; | ||
| 1510 | if (copy_from_user(&user_stack, first_p, sizeof(void *))) | ||
| 1511 | goto out; | ||
| 1512 | |||
| 1513 | if (!access_ok(VERIFY_READ, user_stack, | ||
| 1514 | sizeof(struct kvm_ia64_vcpu_stack))) { | ||
| 1515 | printk(KERN_INFO "KVM_IA64_VCPU_SET_STACK: " | ||
| 1516 | "Illegal user address for stack\n"); | ||
| 1517 | goto out; | ||
| 1518 | } | ||
| 1519 | stack = kmalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL); | ||
| 1520 | if (!stack) { | ||
| 1521 | r = -ENOMEM; | ||
| 1522 | goto out; | ||
| 1523 | } | ||
| 1524 | if (copy_from_user(stack, user_stack, | ||
| 1525 | sizeof(struct kvm_ia64_vcpu_stack))) | ||
| 1526 | goto out; | ||
| 1527 | |||
| 1528 | r = kvm_arch_vcpu_ioctl_set_stack(vcpu, stack); | ||
| 1529 | break; | ||
| 1530 | } | ||
| 1531 | |||
| 1532 | default: | ||
| 1533 | r = -EINVAL; | ||
| 1534 | } | ||
| 1535 | |||
| 1536 | out: | ||
| 1537 | kfree(stack); | ||
| 1538 | return r; | ||
| 1436 | } | 1539 | } |
| 1437 | 1540 | ||
| 1438 | int kvm_arch_set_memory_region(struct kvm *kvm, | 1541 | int kvm_arch_set_memory_region(struct kvm *kvm, |
| @@ -1472,7 +1575,7 @@ void kvm_arch_flush_shadow(struct kvm *kvm) | |||
| 1472 | } | 1575 | } |
| 1473 | 1576 | ||
| 1474 | long kvm_arch_dev_ioctl(struct file *filp, | 1577 | long kvm_arch_dev_ioctl(struct file *filp, |
| 1475 | unsigned int ioctl, unsigned long arg) | 1578 | unsigned int ioctl, unsigned long arg) |
| 1476 | { | 1579 | { |
| 1477 | return -EINVAL; | 1580 | return -EINVAL; |
| 1478 | } | 1581 | } |
| @@ -1737,7 +1840,7 @@ struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | |||
| 1737 | struct kvm_vcpu *lvcpu = kvm->vcpus[0]; | 1840 | struct kvm_vcpu *lvcpu = kvm->vcpus[0]; |
| 1738 | int i; | 1841 | int i; |
| 1739 | 1842 | ||
| 1740 | for (i = 1; i < KVM_MAX_VCPUS; i++) { | 1843 | for (i = 1; i < kvm->arch.online_vcpus; i++) { |
| 1741 | if (!kvm->vcpus[i]) | 1844 | if (!kvm->vcpus[i]) |
| 1742 | continue; | 1845 | continue; |
| 1743 | if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp) | 1846 | if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp) |
