Print this page
13275 bhyve needs richer INIT/SIPI support
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Approved by: Gordon Ross <gordon.w.ross@gmail.com>


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,