diff options
Diffstat (limited to 'arch/ia64/kvm/kvm-ia64.c')
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 129 |
1 files changed, 118 insertions, 11 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 4e586f6110aa..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 | } |
@@ -1337,6 +1354,10 @@ static void kvm_release_vm_pages(struct kvm *kvm) | |||
1337 | } | 1354 | } |
1338 | } | 1355 | } |
1339 | 1356 | ||
1357 | void kvm_arch_sync_events(struct kvm *kvm) | ||
1358 | { | ||
1359 | } | ||
1360 | |||
1340 | void kvm_arch_destroy_vm(struct kvm *kvm) | 1361 | void kvm_arch_destroy_vm(struct kvm *kvm) |
1341 | { | 1362 | { |
1342 | kvm_iommu_unmap_guest(kvm); | 1363 | kvm_iommu_unmap_guest(kvm); |
@@ -1417,6 +1438,23 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
1417 | return 0; | 1438 | return 0; |
1418 | } | 1439 | } |
1419 | 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 | |||
1420 | void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | 1458 | void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) |
1421 | { | 1459 | { |
1422 | 1460 | ||
@@ -1426,9 +1464,78 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | |||
1426 | 1464 | ||
1427 | 1465 | ||
1428 | long kvm_arch_vcpu_ioctl(struct file *filp, | 1466 | long kvm_arch_vcpu_ioctl(struct file *filp, |
1429 | unsigned int ioctl, unsigned long arg) | 1467 | unsigned int ioctl, unsigned long arg) |
1430 | { | 1468 | { |
1431 | 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; | ||
1432 | } | 1539 | } |
1433 | 1540 | ||
1434 | int kvm_arch_set_memory_region(struct kvm *kvm, | 1541 | int kvm_arch_set_memory_region(struct kvm *kvm, |
@@ -1468,7 +1575,7 @@ void kvm_arch_flush_shadow(struct kvm *kvm) | |||
1468 | } | 1575 | } |
1469 | 1576 | ||
1470 | long kvm_arch_dev_ioctl(struct file *filp, | 1577 | long kvm_arch_dev_ioctl(struct file *filp, |
1471 | unsigned int ioctl, unsigned long arg) | 1578 | unsigned int ioctl, unsigned long arg) |
1472 | { | 1579 | { |
1473 | return -EINVAL; | 1580 | return -EINVAL; |
1474 | } | 1581 | } |
@@ -1733,7 +1840,7 @@ struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | |||
1733 | struct kvm_vcpu *lvcpu = kvm->vcpus[0]; | 1840 | struct kvm_vcpu *lvcpu = kvm->vcpus[0]; |
1734 | int i; | 1841 | int i; |
1735 | 1842 | ||
1736 | for (i = 1; i < KVM_MAX_VCPUS; i++) { | 1843 | for (i = 1; i < kvm->arch.online_vcpus; i++) { |
1737 | if (!kvm->vcpus[i]) | 1844 | if (!kvm->vcpus[i]) |
1738 | continue; | 1845 | continue; |
1739 | if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp) | 1846 | if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp) |