1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11 /* This file is dual-licensed; see usr/src/contrib/bhyve/LICENSE */
12
13 /*
14 * Copyright 2015 Pluribus Networks Inc.
15 * Copyright 2020 Joyent, Inc.
16 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
17 * Copyright 2021 Oxide Computer Company
18 */
19
20 #include <sys/types.h>
21 #include <sys/conf.h>
22 #include <sys/cpuvar.h>
23 #include <sys/ioccom.h>
24 #include <sys/stat.h>
25 #include <sys/vmsystm.h>
26 #include <sys/ddi.h>
27 #include <sys/mkdev.h>
28 #include <sys/sunddi.h>
29 #include <sys/fs/dv_node.h>
30 #include <sys/cpuset.h>
31 #include <sys/id_space.h>
32 #include <sys/fs/sdev_plugin.h>
33 #include <sys/smt.h>
34 #include <sys/kstat.h>
35
459 if (ddi_copyin(datap, &vcpu, sizeof (vcpu), md)) {
460 return (EFAULT);
461 }
462 if (vcpu < 0 || vcpu > vm_get_maxcpus(sc->vmm_vm)) {
463 return (EINVAL);
464 }
465 vcpu_lock_one(sc, vcpu);
466 lock_type = LOCK_VCPU;
467 break;
468
469 case VM_REINIT:
470 case VM_BIND_PPTDEV:
471 case VM_UNBIND_PPTDEV:
472 case VM_MAP_PPTDEV_MMIO:
473 case VM_UNMAP_PPTDEV_MMIO:
474 case VM_ALLOC_MEMSEG:
475 case VM_MMAP_MEMSEG:
476 case VM_MUNMAP_MEMSEG:
477 case VM_WRLOCK_CYCLE:
478 case VM_PMTMR_LOCATE:
479 case VM_ARC_RESV:
480 vmm_write_lock(sc);
481 lock_type = LOCK_WRITE_HOLD;
482 break;
483
484 case VM_GET_GPA_PMAP:
485 case VM_GET_MEMSEG:
486 case VM_MMAP_GETNEXT:
487 case VM_LAPIC_IRQ:
488 case VM_INJECT_NMI:
489 case VM_IOAPIC_ASSERT_IRQ:
490 case VM_IOAPIC_DEASSERT_IRQ:
491 case VM_IOAPIC_PULSE_IRQ:
492 case VM_LAPIC_MSI:
493 case VM_LAPIC_LOCAL_IRQ:
494 case VM_GET_X2APIC_STATE:
495 case VM_RTC_READ:
496 case VM_RTC_WRITE:
497 case VM_RTC_SETTIME:
498 case VM_RTC_GETTIME:
499 case VM_PPTDEV_DISABLE_MSIX:
1395 break;
1396 }
1397 }
1398 if (de != NULL) {
1399 vdo.offset = de->vde_off;
1400 if (ddi_copyout(&vdo, datap, sizeof (vdo), md) != 0) {
1401 error = EFAULT;
1402 }
1403 } else {
1404 error = ENOENT;
1405 }
1406 break;
1407 }
1408 case VM_WRLOCK_CYCLE: {
1409 /*
1410 * Present a test mechanism to acquire/release the write lock
1411 * on the VM without any other effects.
1412 */
1413 break;
1414 }
1415 case VM_ARC_RESV:
1416 error = vm_arc_resv(sc->vmm_vm, (uint64_t)arg);
1417 break;
1418 default:
1419 error = ENOTTY;
1420 break;
1421 }
1422
1423 /* Release exclusion resources */
1424 switch (lock_type) {
1425 case LOCK_NONE:
1426 break;
1427 case LOCK_VCPU:
1428 vcpu_unlock_one(sc, vcpu);
1429 break;
1430 case LOCK_READ_HOLD:
1431 vmm_read_unlock(sc);
1432 break;
1433 case LOCK_WRITE_HOLD:
1434 vmm_write_unlock(sc);
1435 break;
1436 default:
1437 panic("unexpected lock type");
2172 static int
2173 vmm_is_supported(intptr_t arg)
2174 {
2175 int r;
2176 const char *msg;
2177
2178 if (vmm_is_intel()) {
2179 r = vmx_x86_supported(&msg);
2180 } else if (vmm_is_svm()) {
2181 /*
2182 * HMA already ensured that the features necessary for SVM
2183 * operation were present and online during vmm_attach().
2184 */
2185 r = 0;
2186 } else {
2187 r = ENXIO;
2188 msg = "Unsupported CPU vendor";
2189 }
2190
2191 if (r != 0 && arg != (intptr_t)NULL) {
2192 if (copyoutstr(msg, (char *)arg, strlen(msg), NULL) != 0)
2193 return (EFAULT);
2194 }
2195 return (r);
2196 }
2197
2198 static int
2199 vmm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
2200 int *rvalp)
2201 {
2202 vmm_softc_t *sc;
2203 minor_t minor;
2204
2205 /* The structs in bhyve ioctls assume a 64-bit datamodel */
2206 if (ddi_model_convert_from(mode & FMODELS) != DDI_MODEL_NONE) {
2207 return (ENOTSUP);
2208 }
2209
2210 minor = getminor(dev);
2211
2212 if (minor == VMM_CTL_MINOR) {
|
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11 /* This file is dual-licensed; see usr/src/contrib/bhyve/LICENSE */
12
13 /*
14 * Copyright 2015 Pluribus Networks Inc.
15 * Copyright 2019 Joyent, Inc.
16 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
17 * Copyright 2021 Oxide Computer Company
18 */
19
20 #include <sys/types.h>
21 #include <sys/conf.h>
22 #include <sys/cpuvar.h>
23 #include <sys/ioccom.h>
24 #include <sys/stat.h>
25 #include <sys/vmsystm.h>
26 #include <sys/ddi.h>
27 #include <sys/mkdev.h>
28 #include <sys/sunddi.h>
29 #include <sys/fs/dv_node.h>
30 #include <sys/cpuset.h>
31 #include <sys/id_space.h>
32 #include <sys/fs/sdev_plugin.h>
33 #include <sys/smt.h>
34 #include <sys/kstat.h>
35
459 if (ddi_copyin(datap, &vcpu, sizeof (vcpu), md)) {
460 return (EFAULT);
461 }
462 if (vcpu < 0 || vcpu > vm_get_maxcpus(sc->vmm_vm)) {
463 return (EINVAL);
464 }
465 vcpu_lock_one(sc, vcpu);
466 lock_type = LOCK_VCPU;
467 break;
468
469 case VM_REINIT:
470 case VM_BIND_PPTDEV:
471 case VM_UNBIND_PPTDEV:
472 case VM_MAP_PPTDEV_MMIO:
473 case VM_UNMAP_PPTDEV_MMIO:
474 case VM_ALLOC_MEMSEG:
475 case VM_MMAP_MEMSEG:
476 case VM_MUNMAP_MEMSEG:
477 case VM_WRLOCK_CYCLE:
478 case VM_PMTMR_LOCATE:
479 vmm_write_lock(sc);
480 lock_type = LOCK_WRITE_HOLD;
481 break;
482
483 case VM_GET_GPA_PMAP:
484 case VM_GET_MEMSEG:
485 case VM_MMAP_GETNEXT:
486 case VM_LAPIC_IRQ:
487 case VM_INJECT_NMI:
488 case VM_IOAPIC_ASSERT_IRQ:
489 case VM_IOAPIC_DEASSERT_IRQ:
490 case VM_IOAPIC_PULSE_IRQ:
491 case VM_LAPIC_MSI:
492 case VM_LAPIC_LOCAL_IRQ:
493 case VM_GET_X2APIC_STATE:
494 case VM_RTC_READ:
495 case VM_RTC_WRITE:
496 case VM_RTC_SETTIME:
497 case VM_RTC_GETTIME:
498 case VM_PPTDEV_DISABLE_MSIX:
1394 break;
1395 }
1396 }
1397 if (de != NULL) {
1398 vdo.offset = de->vde_off;
1399 if (ddi_copyout(&vdo, datap, sizeof (vdo), md) != 0) {
1400 error = EFAULT;
1401 }
1402 } else {
1403 error = ENOENT;
1404 }
1405 break;
1406 }
1407 case VM_WRLOCK_CYCLE: {
1408 /*
1409 * Present a test mechanism to acquire/release the write lock
1410 * on the VM without any other effects.
1411 */
1412 break;
1413 }
1414
1415 default:
1416 error = ENOTTY;
1417 break;
1418 }
1419
1420 /* Release exclusion resources */
1421 switch (lock_type) {
1422 case LOCK_NONE:
1423 break;
1424 case LOCK_VCPU:
1425 vcpu_unlock_one(sc, vcpu);
1426 break;
1427 case LOCK_READ_HOLD:
1428 vmm_read_unlock(sc);
1429 break;
1430 case LOCK_WRITE_HOLD:
1431 vmm_write_unlock(sc);
1432 break;
1433 default:
1434 panic("unexpected lock type");
2169 static int
2170 vmm_is_supported(intptr_t arg)
2171 {
2172 int r;
2173 const char *msg;
2174
2175 if (vmm_is_intel()) {
2176 r = vmx_x86_supported(&msg);
2177 } else if (vmm_is_svm()) {
2178 /*
2179 * HMA already ensured that the features necessary for SVM
2180 * operation were present and online during vmm_attach().
2181 */
2182 r = 0;
2183 } else {
2184 r = ENXIO;
2185 msg = "Unsupported CPU vendor";
2186 }
2187
2188 if (r != 0 && arg != (intptr_t)NULL) {
2189 if (copyoutstr(msg, (char *)arg, strlen(msg) + 1, NULL) != 0)
2190 return (EFAULT);
2191 }
2192 return (r);
2193 }
2194
2195 static int
2196 vmm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
2197 int *rvalp)
2198 {
2199 vmm_softc_t *sc;
2200 minor_t minor;
2201
2202 /* The structs in bhyve ioctls assume a 64-bit datamodel */
2203 if (ddi_model_convert_from(mode & FMODELS) != DDI_MODEL_NONE) {
2204 return (ENOTSUP);
2205 }
2206
2207 minor = getminor(dev);
2208
2209 if (minor == VMM_CTL_MINOR) {
|