aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kvm/kvm-ia64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kvm/kvm-ia64.c')
-rw-r--r--arch/ia64/kvm/kvm-ia64.c129
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;
1287fail: 1304fail:
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
1306int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, 1323int 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
1357void kvm_arch_sync_events(struct kvm *kvm)
1358{
1359}
1360
1340void kvm_arch_destroy_vm(struct kvm *kvm) 1361void 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
1441int 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
1448int 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
1420void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) 1458void 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
1428long kvm_arch_vcpu_ioctl(struct file *filp, 1466long 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
1536out:
1537 kfree(stack);
1538 return r;
1432} 1539}
1433 1540
1434int kvm_arch_set_memory_region(struct kvm *kvm, 1541int kvm_arch_set_memory_region(struct kvm *kvm,
@@ -1468,7 +1575,7 @@ void kvm_arch_flush_shadow(struct kvm *kvm)
1468} 1575}
1469 1576
1470long kvm_arch_dev_ioctl(struct file *filp, 1577long 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)