1285 error = ioctl(ctx->fd, VM_GET_X2APIC_STATE, &x2apic);
1286 *state = x2apic.state;
1287 return (error);
1288 }
1289
1290 int
1291 vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state state)
1292 {
1293 int error;
1294 struct vm_x2apic x2apic;
1295
1296 bzero(&x2apic, sizeof(x2apic));
1297 x2apic.cpuid = vcpu;
1298 x2apic.state = state;
1299
1300 error = ioctl(ctx->fd, VM_SET_X2APIC_STATE, &x2apic);
1301
1302 return (error);
1303 }
1304
1305 /*
1306 * From Intel Vol 3a:
1307 * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT
1308 */
1309 int
1310 vcpu_reset(struct vmctx *vmctx, int vcpu)
1311 {
1312 int error;
1313 uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx;
1314 uint32_t desc_access, desc_limit;
1315 uint16_t sel;
1316
1317 zero = 0;
1318
1319 rflags = 0x2;
1320 error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RFLAGS, rflags);
1321 if (error)
1322 goto done;
1323
1324 rip = 0xfff0;
1441
1442 /* LDTR */
1443 desc_base = 0;
1444 desc_limit = 0xffff;
1445 desc_access = 0x00000082;
1446 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_LDTR, desc_base,
1447 desc_limit, desc_access);
1448 if (error)
1449 goto done;
1450
1451 sel = 0;
1452 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_LDTR, 0)) != 0)
1453 goto done;
1454
1455 /* XXX cr2, debug registers */
1456
1457 error = 0;
1458 done:
1459 return (error);
1460 }
1461
1462 int
1463 vm_get_gpa_pmap(struct vmctx *ctx, uint64_t gpa, uint64_t *pte, int *num)
1464 {
1465 int error, i;
1466 struct vm_gpa_pte gpapte;
1467
1468 bzero(&gpapte, sizeof(gpapte));
1469 gpapte.gpa = gpa;
1470
1471 error = ioctl(ctx->fd, VM_GET_GPA_PMAP, &gpapte);
1472
1473 if (error == 0) {
1474 *num = gpapte.ptenum;
1475 for (i = 0; i < gpapte.ptenum; i++)
1476 pte[i] = gpapte.pte[i];
1477 }
1478
1479 return (error);
1480 }
1822 {
1823
1824 return (ctx->fd);
1825 }
1826
1827 #ifndef __FreeBSD__
1828 int
1829 vm_pmtmr_set_location(struct vmctx *ctx, uint16_t ioport)
1830 {
1831 return (ioctl(ctx->fd, VM_PMTMR_LOCATE, ioport));
1832 }
1833
1834 int
1835 vm_wrlock_cycle(struct vmctx *ctx)
1836 {
1837 if (ioctl(ctx->fd, VM_WRLOCK_CYCLE, 0) != 0) {
1838 return (errno);
1839 }
1840 return (0);
1841 }
1842 #endif /* __FreeBSD__ */
1843
1844 #ifdef __FreeBSD__
1845 const cap_ioctl_t *
1846 vm_get_ioctls(size_t *len)
1847 {
1848 cap_ioctl_t *cmds;
1849 /* keep in sync with machine/vmm_dev.h */
1850 static const cap_ioctl_t vm_ioctl_cmds[] = { VM_RUN, VM_SUSPEND, VM_REINIT,
1851 VM_ALLOC_MEMSEG, VM_GET_MEMSEG, VM_MMAP_MEMSEG, VM_MMAP_MEMSEG,
1852 VM_MMAP_GETNEXT, VM_SET_REGISTER, VM_GET_REGISTER,
1853 VM_SET_SEGMENT_DESCRIPTOR, VM_GET_SEGMENT_DESCRIPTOR,
1854 VM_SET_REGISTER_SET, VM_GET_REGISTER_SET,
1855 VM_SET_KERNEMU_DEV, VM_GET_KERNEMU_DEV,
1856 VM_INJECT_EXCEPTION, VM_LAPIC_IRQ, VM_LAPIC_LOCAL_IRQ,
1857 VM_LAPIC_MSI, VM_IOAPIC_ASSERT_IRQ, VM_IOAPIC_DEASSERT_IRQ,
1858 VM_IOAPIC_PULSE_IRQ, VM_IOAPIC_PINCOUNT, VM_ISA_ASSERT_IRQ,
1859 VM_ISA_DEASSERT_IRQ, VM_ISA_PULSE_IRQ, VM_ISA_SET_IRQ_TRIGGER,
1860 VM_SET_CAPABILITY, VM_GET_CAPABILITY, VM_BIND_PPTDEV,
1861 VM_UNBIND_PPTDEV, VM_MAP_PPTDEV_MMIO, VM_PPTDEV_MSI,
|
1285 error = ioctl(ctx->fd, VM_GET_X2APIC_STATE, &x2apic);
1286 *state = x2apic.state;
1287 return (error);
1288 }
1289
1290 int
1291 vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state state)
1292 {
1293 int error;
1294 struct vm_x2apic x2apic;
1295
1296 bzero(&x2apic, sizeof(x2apic));
1297 x2apic.cpuid = vcpu;
1298 x2apic.state = state;
1299
1300 error = ioctl(ctx->fd, VM_SET_X2APIC_STATE, &x2apic);
1301
1302 return (error);
1303 }
1304
1305 #ifndef __FreeBSD__
1306 int
1307 vcpu_reset(struct vmctx *vmctx, int vcpu)
1308 {
1309 struct vm_vcpu_reset vvr;
1310
1311 vvr.vcpuid = vcpu;
1312 vvr.kind = VRK_RESET;
1313
1314 return (ioctl(vmctx->fd, VM_RESET_CPU, &vvr));
1315 }
1316 #else /* __FreeBSD__ */
1317 /*
1318 * From Intel Vol 3a:
1319 * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT
1320 */
1321 int
1322 vcpu_reset(struct vmctx *vmctx, int vcpu)
1323 {
1324 int error;
1325 uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx;
1326 uint32_t desc_access, desc_limit;
1327 uint16_t sel;
1328
1329 zero = 0;
1330
1331 rflags = 0x2;
1332 error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RFLAGS, rflags);
1333 if (error)
1334 goto done;
1335
1336 rip = 0xfff0;
1453
1454 /* LDTR */
1455 desc_base = 0;
1456 desc_limit = 0xffff;
1457 desc_access = 0x00000082;
1458 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_LDTR, desc_base,
1459 desc_limit, desc_access);
1460 if (error)
1461 goto done;
1462
1463 sel = 0;
1464 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_LDTR, 0)) != 0)
1465 goto done;
1466
1467 /* XXX cr2, debug registers */
1468
1469 error = 0;
1470 done:
1471 return (error);
1472 }
1473 #endif /* __FreeBSD__ */
1474
1475 int
1476 vm_get_gpa_pmap(struct vmctx *ctx, uint64_t gpa, uint64_t *pte, int *num)
1477 {
1478 int error, i;
1479 struct vm_gpa_pte gpapte;
1480
1481 bzero(&gpapte, sizeof(gpapte));
1482 gpapte.gpa = gpa;
1483
1484 error = ioctl(ctx->fd, VM_GET_GPA_PMAP, &gpapte);
1485
1486 if (error == 0) {
1487 *num = gpapte.ptenum;
1488 for (i = 0; i < gpapte.ptenum; i++)
1489 pte[i] = gpapte.pte[i];
1490 }
1491
1492 return (error);
1493 }
1835 {
1836
1837 return (ctx->fd);
1838 }
1839
1840 #ifndef __FreeBSD__
1841 int
1842 vm_pmtmr_set_location(struct vmctx *ctx, uint16_t ioport)
1843 {
1844 return (ioctl(ctx->fd, VM_PMTMR_LOCATE, ioport));
1845 }
1846
1847 int
1848 vm_wrlock_cycle(struct vmctx *ctx)
1849 {
1850 if (ioctl(ctx->fd, VM_WRLOCK_CYCLE, 0) != 0) {
1851 return (errno);
1852 }
1853 return (0);
1854 }
1855
1856 int
1857 vm_get_run_state(struct vmctx *ctx, int vcpu, enum vcpu_run_state *state,
1858 uint8_t *sipi_vector)
1859 {
1860 struct vm_run_state data;
1861
1862 data.vcpuid = vcpu;
1863 if (ioctl(ctx->fd, VM_GET_RUN_STATE, &data) != 0) {
1864 return (errno);
1865 }
1866
1867 *state = data.state;
1868 *sipi_vector = data.sipi_vector;
1869 return (0);
1870 }
1871
1872 int
1873 vm_set_run_state(struct vmctx *ctx, int vcpu, enum vcpu_run_state state,
1874 uint8_t sipi_vector)
1875 {
1876 struct vm_run_state data;
1877
1878 data.vcpuid = vcpu;
1879 data.state = state;
1880 data.sipi_vector = sipi_vector;
1881 if (ioctl(ctx->fd, VM_SET_RUN_STATE, &data) != 0) {
1882 return (errno);
1883 }
1884
1885 return (0);
1886 }
1887
1888 #endif /* __FreeBSD__ */
1889
1890 #ifdef __FreeBSD__
1891 const cap_ioctl_t *
1892 vm_get_ioctls(size_t *len)
1893 {
1894 cap_ioctl_t *cmds;
1895 /* keep in sync with machine/vmm_dev.h */
1896 static const cap_ioctl_t vm_ioctl_cmds[] = { VM_RUN, VM_SUSPEND, VM_REINIT,
1897 VM_ALLOC_MEMSEG, VM_GET_MEMSEG, VM_MMAP_MEMSEG, VM_MMAP_MEMSEG,
1898 VM_MMAP_GETNEXT, VM_SET_REGISTER, VM_GET_REGISTER,
1899 VM_SET_SEGMENT_DESCRIPTOR, VM_GET_SEGMENT_DESCRIPTOR,
1900 VM_SET_REGISTER_SET, VM_GET_REGISTER_SET,
1901 VM_SET_KERNEMU_DEV, VM_GET_KERNEMU_DEV,
1902 VM_INJECT_EXCEPTION, VM_LAPIC_IRQ, VM_LAPIC_LOCAL_IRQ,
1903 VM_LAPIC_MSI, VM_IOAPIC_ASSERT_IRQ, VM_IOAPIC_DEASSERT_IRQ,
1904 VM_IOAPIC_PULSE_IRQ, VM_IOAPIC_PINCOUNT, VM_ISA_ASSERT_IRQ,
1905 VM_ISA_DEASSERT_IRQ, VM_ISA_PULSE_IRQ, VM_ISA_SET_IRQ_TRIGGER,
1906 VM_SET_CAPABILITY, VM_GET_CAPABILITY, VM_BIND_PPTDEV,
1907 VM_UNBIND_PPTDEV, VM_MAP_PPTDEV_MMIO, VM_PPTDEV_MSI,
|