xref: /freebsd-12.1/sys/amd64/vmm/vmm_dev.c (revision 0700a396)
1 /*-
2  * Copyright (c) 2011 NetApp, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/queue.h>
35 #include <sys/lock.h>
36 #include <sys/mutex.h>
37 #include <sys/malloc.h>
38 #include <sys/conf.h>
39 #include <sys/sysctl.h>
40 #include <sys/libkern.h>
41 #include <sys/ioccom.h>
42 #include <sys/mman.h>
43 #include <sys/uio.h>
44 
45 #include <vm/vm.h>
46 #include <vm/pmap.h>
47 #include <vm/vm_map.h>
48 
49 #include <machine/vmparam.h>
50 #include <machine/vmm.h>
51 #include <machine/vmm_instruction_emul.h>
52 #include <machine/vmm_dev.h>
53 
54 #include "vmm_lapic.h"
55 #include "vmm_stat.h"
56 #include "vmm_mem.h"
57 #include "io/ppt.h"
58 #include "io/vatpic.h"
59 #include "io/vioapic.h"
60 #include "io/vhpet.h"
61 #include "io/vrtc.h"
62 
63 struct vmmdev_softc {
64 	struct vm	*vm;		/* vm instance cookie */
65 	struct cdev	*cdev;
66 	SLIST_ENTRY(vmmdev_softc) link;
67 	int		flags;
68 };
69 #define	VSC_LINKED		0x01
70 
71 static SLIST_HEAD(, vmmdev_softc) head;
72 
73 static struct mtx vmmdev_mtx;
74 
75 static MALLOC_DEFINE(M_VMMDEV, "vmmdev", "vmmdev");
76 
77 SYSCTL_DECL(_hw_vmm);
78 
79 static struct vmmdev_softc *
80 vmmdev_lookup(const char *name)
81 {
82 	struct vmmdev_softc *sc;
83 
84 #ifdef notyet	/* XXX kernel is not compiled with invariants */
85 	mtx_assert(&vmmdev_mtx, MA_OWNED);
86 #endif
87 
88 	SLIST_FOREACH(sc, &head, link) {
89 		if (strcmp(name, vm_name(sc->vm)) == 0)
90 			break;
91 	}
92 
93 	return (sc);
94 }
95 
96 static struct vmmdev_softc *
97 vmmdev_lookup2(struct cdev *cdev)
98 {
99 
100 	return (cdev->si_drv1);
101 }
102 
103 static int
104 vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags)
105 {
106 	int error, off, c, prot;
107 	vm_paddr_t gpa;
108 	void *hpa, *cookie;
109 	struct vmmdev_softc *sc;
110 
111 	static char zerobuf[PAGE_SIZE];
112 
113 	error = 0;
114 	sc = vmmdev_lookup2(cdev);
115 	if (sc == NULL)
116 		error = ENXIO;
117 
118 	prot = (uio->uio_rw == UIO_WRITE ? VM_PROT_WRITE : VM_PROT_READ);
119 	while (uio->uio_resid > 0 && error == 0) {
120 		gpa = uio->uio_offset;
121 		off = gpa & PAGE_MASK;
122 		c = min(uio->uio_resid, PAGE_SIZE - off);
123 
124 		/*
125 		 * The VM has a hole in its physical memory map. If we want to
126 		 * use 'dd' to inspect memory beyond the hole we need to
127 		 * provide bogus data for memory that lies in the hole.
128 		 *
129 		 * Since this device does not support lseek(2), dd(1) will
130 		 * read(2) blocks of data to simulate the lseek(2).
131 		 */
132 		hpa = vm_gpa_hold(sc->vm, gpa, c, prot, &cookie);
133 		if (hpa == NULL) {
134 			if (uio->uio_rw == UIO_READ)
135 				error = uiomove(zerobuf, c, uio);
136 			else
137 				error = EFAULT;
138 		} else {
139 			error = uiomove(hpa, c, uio);
140 			vm_gpa_release(cookie);
141 		}
142 	}
143 	return (error);
144 }
145 
146 static int
147 vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
148 	     struct thread *td)
149 {
150 	int error, vcpu, state_changed, size;
151 	cpuset_t *cpuset;
152 	struct vmmdev_softc *sc;
153 	struct vm_memory_segment *seg;
154 	struct vm_register *vmreg;
155 	struct vm_seg_desc *vmsegdesc;
156 	struct vm_run *vmrun;
157 	struct vm_exception *vmexc;
158 	struct vm_lapic_irq *vmirq;
159 	struct vm_lapic_msi *vmmsi;
160 	struct vm_ioapic_irq *ioapic_irq;
161 	struct vm_isa_irq *isa_irq;
162 	struct vm_isa_irq_trigger *isa_irq_trigger;
163 	struct vm_capability *vmcap;
164 	struct vm_pptdev *pptdev;
165 	struct vm_pptdev_mmio *pptmmio;
166 	struct vm_pptdev_msi *pptmsi;
167 	struct vm_pptdev_msix *pptmsix;
168 	struct vm_nmi *vmnmi;
169 	struct vm_stats *vmstats;
170 	struct vm_stat_desc *statdesc;
171 	struct vm_x2apic *x2apic;
172 	struct vm_gpa_pte *gpapte;
173 	struct vm_suspend *vmsuspend;
174 	struct vm_gla2gpa *gg;
175 	struct vm_activate_cpu *vac;
176 	struct vm_cpuset *vm_cpuset;
177 	struct vm_intinfo *vmii;
178 	struct vm_rtc_time *rtctime;
179 	struct vm_rtc_data *rtcdata;
180 
181 	sc = vmmdev_lookup2(cdev);
182 	if (sc == NULL)
183 		return (ENXIO);
184 
185 	error = 0;
186 	vcpu = -1;
187 	state_changed = 0;
188 
189 	/*
190 	 * Some VMM ioctls can operate only on vcpus that are not running.
191 	 */
192 	switch (cmd) {
193 	case VM_RUN:
194 	case VM_GET_REGISTER:
195 	case VM_SET_REGISTER:
196 	case VM_GET_SEGMENT_DESCRIPTOR:
197 	case VM_SET_SEGMENT_DESCRIPTOR:
198 	case VM_INJECT_EXCEPTION:
199 	case VM_GET_CAPABILITY:
200 	case VM_SET_CAPABILITY:
201 	case VM_PPTDEV_MSI:
202 	case VM_PPTDEV_MSIX:
203 	case VM_SET_X2APIC_STATE:
204 	case VM_GLA2GPA:
205 	case VM_ACTIVATE_CPU:
206 	case VM_SET_INTINFO:
207 	case VM_GET_INTINFO:
208 	case VM_RESTART_INSTRUCTION:
209 		/*
210 		 * XXX fragile, handle with care
211 		 * Assumes that the first field of the ioctl data is the vcpu.
212 		 */
213 		vcpu = *(int *)data;
214 		if (vcpu < 0 || vcpu >= VM_MAXCPU) {
215 			error = EINVAL;
216 			goto done;
217 		}
218 
219 		error = vcpu_set_state(sc->vm, vcpu, VCPU_FROZEN, true);
220 		if (error)
221 			goto done;
222 
223 		state_changed = 1;
224 		break;
225 
226 	case VM_MAP_PPTDEV_MMIO:
227 	case VM_BIND_PPTDEV:
228 	case VM_UNBIND_PPTDEV:
229 	case VM_MAP_MEMORY:
230 	case VM_REINIT:
231 		/*
232 		 * ioctls that operate on the entire virtual machine must
233 		 * prevent all vcpus from running.
234 		 */
235 		error = 0;
236 		for (vcpu = 0; vcpu < VM_MAXCPU; vcpu++) {
237 			error = vcpu_set_state(sc->vm, vcpu, VCPU_FROZEN, true);
238 			if (error)
239 				break;
240 		}
241 
242 		if (error) {
243 			while (--vcpu >= 0)
244 				vcpu_set_state(sc->vm, vcpu, VCPU_IDLE, false);
245 			goto done;
246 		}
247 
248 		state_changed = 2;
249 		break;
250 
251 	default:
252 		break;
253 	}
254 
255 	switch(cmd) {
256 	case VM_RUN:
257 		vmrun = (struct vm_run *)data;
258 		error = vm_run(sc->vm, vmrun);
259 		break;
260 	case VM_SUSPEND:
261 		vmsuspend = (struct vm_suspend *)data;
262 		error = vm_suspend(sc->vm, vmsuspend->how);
263 		break;
264 	case VM_REINIT:
265 		error = vm_reinit(sc->vm);
266 		break;
267 	case VM_STAT_DESC: {
268 		statdesc = (struct vm_stat_desc *)data;
269 		error = vmm_stat_desc_copy(statdesc->index,
270 					statdesc->desc, sizeof(statdesc->desc));
271 		break;
272 	}
273 	case VM_STATS: {
274 		CTASSERT(MAX_VM_STATS >= MAX_VMM_STAT_ELEMS);
275 		vmstats = (struct vm_stats *)data;
276 		getmicrotime(&vmstats->tv);
277 		error = vmm_stat_copy(sc->vm, vmstats->cpuid,
278 				      &vmstats->num_entries, vmstats->statbuf);
279 		break;
280 	}
281 	case VM_PPTDEV_MSI:
282 		pptmsi = (struct vm_pptdev_msi *)data;
283 		error = ppt_setup_msi(sc->vm, pptmsi->vcpu,
284 				      pptmsi->bus, pptmsi->slot, pptmsi->func,
285 				      pptmsi->addr, pptmsi->msg,
286 				      pptmsi->numvec);
287 		break;
288 	case VM_PPTDEV_MSIX:
289 		pptmsix = (struct vm_pptdev_msix *)data;
290 		error = ppt_setup_msix(sc->vm, pptmsix->vcpu,
291 				       pptmsix->bus, pptmsix->slot,
292 				       pptmsix->func, pptmsix->idx,
293 				       pptmsix->addr, pptmsix->msg,
294 				       pptmsix->vector_control);
295 		break;
296 	case VM_MAP_PPTDEV_MMIO:
297 		pptmmio = (struct vm_pptdev_mmio *)data;
298 		error = ppt_map_mmio(sc->vm, pptmmio->bus, pptmmio->slot,
299 				     pptmmio->func, pptmmio->gpa, pptmmio->len,
300 				     pptmmio->hpa);
301 		break;
302 	case VM_BIND_PPTDEV:
303 		pptdev = (struct vm_pptdev *)data;
304 		error = vm_assign_pptdev(sc->vm, pptdev->bus, pptdev->slot,
305 					 pptdev->func);
306 		break;
307 	case VM_UNBIND_PPTDEV:
308 		pptdev = (struct vm_pptdev *)data;
309 		error = vm_unassign_pptdev(sc->vm, pptdev->bus, pptdev->slot,
310 					   pptdev->func);
311 		break;
312 	case VM_INJECT_EXCEPTION:
313 		vmexc = (struct vm_exception *)data;
314 		error = vm_inject_exception(sc->vm, vmexc->cpuid,
315 		    vmexc->vector, vmexc->error_code_valid, vmexc->error_code,
316 		    vmexc->restart_instruction);
317 		break;
318 	case VM_INJECT_NMI:
319 		vmnmi = (struct vm_nmi *)data;
320 		error = vm_inject_nmi(sc->vm, vmnmi->cpuid);
321 		break;
322 	case VM_LAPIC_IRQ:
323 		vmirq = (struct vm_lapic_irq *)data;
324 		error = lapic_intr_edge(sc->vm, vmirq->cpuid, vmirq->vector);
325 		break;
326 	case VM_LAPIC_LOCAL_IRQ:
327 		vmirq = (struct vm_lapic_irq *)data;
328 		error = lapic_set_local_intr(sc->vm, vmirq->cpuid,
329 		    vmirq->vector);
330 		break;
331 	case VM_LAPIC_MSI:
332 		vmmsi = (struct vm_lapic_msi *)data;
333 		error = lapic_intr_msi(sc->vm, vmmsi->addr, vmmsi->msg);
334 		break;
335 	case VM_IOAPIC_ASSERT_IRQ:
336 		ioapic_irq = (struct vm_ioapic_irq *)data;
337 		error = vioapic_assert_irq(sc->vm, ioapic_irq->irq);
338 		break;
339 	case VM_IOAPIC_DEASSERT_IRQ:
340 		ioapic_irq = (struct vm_ioapic_irq *)data;
341 		error = vioapic_deassert_irq(sc->vm, ioapic_irq->irq);
342 		break;
343 	case VM_IOAPIC_PULSE_IRQ:
344 		ioapic_irq = (struct vm_ioapic_irq *)data;
345 		error = vioapic_pulse_irq(sc->vm, ioapic_irq->irq);
346 		break;
347 	case VM_IOAPIC_PINCOUNT:
348 		*(int *)data = vioapic_pincount(sc->vm);
349 		break;
350 	case VM_ISA_ASSERT_IRQ:
351 		isa_irq = (struct vm_isa_irq *)data;
352 		error = vatpic_assert_irq(sc->vm, isa_irq->atpic_irq);
353 		if (error == 0 && isa_irq->ioapic_irq != -1)
354 			error = vioapic_assert_irq(sc->vm,
355 			    isa_irq->ioapic_irq);
356 		break;
357 	case VM_ISA_DEASSERT_IRQ:
358 		isa_irq = (struct vm_isa_irq *)data;
359 		error = vatpic_deassert_irq(sc->vm, isa_irq->atpic_irq);
360 		if (error == 0 && isa_irq->ioapic_irq != -1)
361 			error = vioapic_deassert_irq(sc->vm,
362 			    isa_irq->ioapic_irq);
363 		break;
364 	case VM_ISA_PULSE_IRQ:
365 		isa_irq = (struct vm_isa_irq *)data;
366 		error = vatpic_pulse_irq(sc->vm, isa_irq->atpic_irq);
367 		if (error == 0 && isa_irq->ioapic_irq != -1)
368 			error = vioapic_pulse_irq(sc->vm, isa_irq->ioapic_irq);
369 		break;
370 	case VM_ISA_SET_IRQ_TRIGGER:
371 		isa_irq_trigger = (struct vm_isa_irq_trigger *)data;
372 		error = vatpic_set_irq_trigger(sc->vm,
373 		    isa_irq_trigger->atpic_irq, isa_irq_trigger->trigger);
374 		break;
375 	case VM_MAP_MEMORY:
376 		seg = (struct vm_memory_segment *)data;
377 		error = vm_malloc(sc->vm, seg->gpa, seg->len);
378 		break;
379 	case VM_GET_MEMORY_SEG:
380 		seg = (struct vm_memory_segment *)data;
381 		seg->len = 0;
382 		(void)vm_gpabase2memseg(sc->vm, seg->gpa, seg);
383 		error = 0;
384 		break;
385 	case VM_GET_REGISTER:
386 		vmreg = (struct vm_register *)data;
387 		error = vm_get_register(sc->vm, vmreg->cpuid, vmreg->regnum,
388 					&vmreg->regval);
389 		break;
390 	case VM_SET_REGISTER:
391 		vmreg = (struct vm_register *)data;
392 		error = vm_set_register(sc->vm, vmreg->cpuid, vmreg->regnum,
393 					vmreg->regval);
394 		break;
395 	case VM_SET_SEGMENT_DESCRIPTOR:
396 		vmsegdesc = (struct vm_seg_desc *)data;
397 		error = vm_set_seg_desc(sc->vm, vmsegdesc->cpuid,
398 					vmsegdesc->regnum,
399 					&vmsegdesc->desc);
400 		break;
401 	case VM_GET_SEGMENT_DESCRIPTOR:
402 		vmsegdesc = (struct vm_seg_desc *)data;
403 		error = vm_get_seg_desc(sc->vm, vmsegdesc->cpuid,
404 					vmsegdesc->regnum,
405 					&vmsegdesc->desc);
406 		break;
407 	case VM_GET_CAPABILITY:
408 		vmcap = (struct vm_capability *)data;
409 		error = vm_get_capability(sc->vm, vmcap->cpuid,
410 					  vmcap->captype,
411 					  &vmcap->capval);
412 		break;
413 	case VM_SET_CAPABILITY:
414 		vmcap = (struct vm_capability *)data;
415 		error = vm_set_capability(sc->vm, vmcap->cpuid,
416 					  vmcap->captype,
417 					  vmcap->capval);
418 		break;
419 	case VM_SET_X2APIC_STATE:
420 		x2apic = (struct vm_x2apic *)data;
421 		error = vm_set_x2apic_state(sc->vm,
422 					    x2apic->cpuid, x2apic->state);
423 		break;
424 	case VM_GET_X2APIC_STATE:
425 		x2apic = (struct vm_x2apic *)data;
426 		error = vm_get_x2apic_state(sc->vm,
427 					    x2apic->cpuid, &x2apic->state);
428 		break;
429 	case VM_GET_GPA_PMAP:
430 		gpapte = (struct vm_gpa_pte *)data;
431 		pmap_get_mapping(vmspace_pmap(vm_get_vmspace(sc->vm)),
432 				 gpapte->gpa, gpapte->pte, &gpapte->ptenum);
433 		error = 0;
434 		break;
435 	case VM_GET_HPET_CAPABILITIES:
436 		error = vhpet_getcap((struct vm_hpet_cap *)data);
437 		break;
438 	case VM_GLA2GPA: {
439 		CTASSERT(PROT_READ == VM_PROT_READ);
440 		CTASSERT(PROT_WRITE == VM_PROT_WRITE);
441 		CTASSERT(PROT_EXEC == VM_PROT_EXECUTE);
442 		gg = (struct vm_gla2gpa *)data;
443 		error = vmm_gla2gpa(sc->vm, gg->vcpuid, &gg->paging, gg->gla,
444 		    gg->prot, &gg->gpa);
445 		KASSERT(error == 0 || error == 1 || error == -1,
446 		    ("%s: vmm_gla2gpa unknown error %d", __func__, error));
447 		if (error >= 0) {
448 			/*
449 			 * error = 0: the translation was successful
450 			 * error = 1: a fault was injected into the guest
451 			 */
452 			gg->fault = error;
453 			error = 0;
454 		} else {
455 			error = EFAULT;
456 		}
457 		break;
458 	}
459 	case VM_ACTIVATE_CPU:
460 		vac = (struct vm_activate_cpu *)data;
461 		error = vm_activate_cpu(sc->vm, vac->vcpuid);
462 		break;
463 	case VM_GET_CPUS:
464 		error = 0;
465 		vm_cpuset = (struct vm_cpuset *)data;
466 		size = vm_cpuset->cpusetsize;
467 		if (size < sizeof(cpuset_t) || size > CPU_MAXSIZE / NBBY) {
468 			error = ERANGE;
469 			break;
470 		}
471 		cpuset = malloc(size, M_TEMP, M_WAITOK | M_ZERO);
472 		if (vm_cpuset->which == VM_ACTIVE_CPUS)
473 			*cpuset = vm_active_cpus(sc->vm);
474 		else if (vm_cpuset->which == VM_SUSPENDED_CPUS)
475 			*cpuset = vm_suspended_cpus(sc->vm);
476 		else
477 			error = EINVAL;
478 		if (error == 0)
479 			error = copyout(cpuset, vm_cpuset->cpus, size);
480 		free(cpuset, M_TEMP);
481 		break;
482 	case VM_SET_INTINFO:
483 		vmii = (struct vm_intinfo *)data;
484 		error = vm_exit_intinfo(sc->vm, vmii->vcpuid, vmii->info1);
485 		break;
486 	case VM_GET_INTINFO:
487 		vmii = (struct vm_intinfo *)data;
488 		error = vm_get_intinfo(sc->vm, vmii->vcpuid, &vmii->info1,
489 		    &vmii->info2);
490 		break;
491 	case VM_RTC_WRITE:
492 		rtcdata = (struct vm_rtc_data *)data;
493 		error = vrtc_nvram_write(sc->vm, rtcdata->offset,
494 		    rtcdata->value);
495 		break;
496 	case VM_RTC_READ:
497 		rtcdata = (struct vm_rtc_data *)data;
498 		error = vrtc_nvram_read(sc->vm, rtcdata->offset,
499 		    &rtcdata->value);
500 		break;
501 	case VM_RTC_SETTIME:
502 		rtctime = (struct vm_rtc_time *)data;
503 		error = vrtc_set_time(sc->vm, rtctime->secs);
504 		break;
505 	case VM_RTC_GETTIME:
506 		error = 0;
507 		rtctime = (struct vm_rtc_time *)data;
508 		rtctime->secs = vrtc_get_time(sc->vm);
509 		break;
510 	case VM_RESTART_INSTRUCTION:
511 		error = vm_restart_instruction(sc->vm, vcpu);
512 		break;
513 	default:
514 		error = ENOTTY;
515 		break;
516 	}
517 
518 	if (state_changed == 1) {
519 		vcpu_set_state(sc->vm, vcpu, VCPU_IDLE, false);
520 	} else if (state_changed == 2) {
521 		for (vcpu = 0; vcpu < VM_MAXCPU; vcpu++)
522 			vcpu_set_state(sc->vm, vcpu, VCPU_IDLE, false);
523 	}
524 
525 done:
526 	/* Make sure that no handler returns a bogus value like ERESTART */
527 	KASSERT(error >= 0, ("vmmdev_ioctl: invalid error return %d", error));
528 	return (error);
529 }
530 
531 static int
532 vmmdev_mmap_single(struct cdev *cdev, vm_ooffset_t *offset,
533 		   vm_size_t size, struct vm_object **object, int nprot)
534 {
535 	int error;
536 	struct vmmdev_softc *sc;
537 
538 	sc = vmmdev_lookup2(cdev);
539 	if (sc != NULL && (nprot & PROT_EXEC) == 0)
540 		error = vm_get_memobj(sc->vm, *offset, size, offset, object);
541 	else
542 		error = EINVAL;
543 
544 	return (error);
545 }
546 
547 static void
548 vmmdev_destroy(void *arg)
549 {
550 
551 	struct vmmdev_softc *sc = arg;
552 
553 	if (sc->cdev != NULL)
554 		destroy_dev(sc->cdev);
555 
556 	if (sc->vm != NULL)
557 		vm_destroy(sc->vm);
558 
559 	if ((sc->flags & VSC_LINKED) != 0) {
560 		mtx_lock(&vmmdev_mtx);
561 		SLIST_REMOVE(&head, sc, vmmdev_softc, link);
562 		mtx_unlock(&vmmdev_mtx);
563 	}
564 
565 	free(sc, M_VMMDEV);
566 }
567 
568 static int
569 sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
570 {
571 	int error;
572 	char buf[VM_MAX_NAMELEN];
573 	struct vmmdev_softc *sc;
574 	struct cdev *cdev;
575 
576 	strlcpy(buf, "beavis", sizeof(buf));
577 	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
578 	if (error != 0 || req->newptr == NULL)
579 		return (error);
580 
581 	mtx_lock(&vmmdev_mtx);
582 	sc = vmmdev_lookup(buf);
583 	if (sc == NULL || sc->cdev == NULL) {
584 		mtx_unlock(&vmmdev_mtx);
585 		return (EINVAL);
586 	}
587 
588 	/*
589 	 * The 'cdev' will be destroyed asynchronously when 'si_threadcount'
590 	 * goes down to 0 so we should not do it again in the callback.
591 	 */
592 	cdev = sc->cdev;
593 	sc->cdev = NULL;
594 	mtx_unlock(&vmmdev_mtx);
595 
596 	/*
597 	 * Schedule the 'cdev' to be destroyed:
598 	 *
599 	 * - any new operations on this 'cdev' will return an error (ENXIO).
600 	 *
601 	 * - when the 'si_threadcount' dwindles down to zero the 'cdev' will
602 	 *   be destroyed and the callback will be invoked in a taskqueue
603 	 *   context.
604 	 */
605 	destroy_dev_sched_cb(cdev, vmmdev_destroy, sc);
606 
607 	return (0);
608 }
609 SYSCTL_PROC(_hw_vmm, OID_AUTO, destroy, CTLTYPE_STRING | CTLFLAG_RW,
610 	    NULL, 0, sysctl_vmm_destroy, "A", NULL);
611 
612 static struct cdevsw vmmdevsw = {
613 	.d_name		= "vmmdev",
614 	.d_version	= D_VERSION,
615 	.d_ioctl	= vmmdev_ioctl,
616 	.d_mmap_single	= vmmdev_mmap_single,
617 	.d_read		= vmmdev_rw,
618 	.d_write	= vmmdev_rw,
619 };
620 
621 static int
622 sysctl_vmm_create(SYSCTL_HANDLER_ARGS)
623 {
624 	int error;
625 	struct vm *vm;
626 	struct cdev *cdev;
627 	struct vmmdev_softc *sc, *sc2;
628 	char buf[VM_MAX_NAMELEN];
629 
630 	strlcpy(buf, "beavis", sizeof(buf));
631 	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
632 	if (error != 0 || req->newptr == NULL)
633 		return (error);
634 
635 	mtx_lock(&vmmdev_mtx);
636 	sc = vmmdev_lookup(buf);
637 	mtx_unlock(&vmmdev_mtx);
638 	if (sc != NULL)
639 		return (EEXIST);
640 
641 	error = vm_create(buf, &vm);
642 	if (error != 0)
643 		return (error);
644 
645 	sc = malloc(sizeof(struct vmmdev_softc), M_VMMDEV, M_WAITOK | M_ZERO);
646 	sc->vm = vm;
647 
648 	/*
649 	 * Lookup the name again just in case somebody sneaked in when we
650 	 * dropped the lock.
651 	 */
652 	mtx_lock(&vmmdev_mtx);
653 	sc2 = vmmdev_lookup(buf);
654 	if (sc2 == NULL) {
655 		SLIST_INSERT_HEAD(&head, sc, link);
656 		sc->flags |= VSC_LINKED;
657 	}
658 	mtx_unlock(&vmmdev_mtx);
659 
660 	if (sc2 != NULL) {
661 		vmmdev_destroy(sc);
662 		return (EEXIST);
663 	}
664 
665 	error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &vmmdevsw, NULL,
666 			   UID_ROOT, GID_WHEEL, 0600, "vmm/%s", buf);
667 	if (error != 0) {
668 		vmmdev_destroy(sc);
669 		return (error);
670 	}
671 
672 	mtx_lock(&vmmdev_mtx);
673 	sc->cdev = cdev;
674 	sc->cdev->si_drv1 = sc;
675 	mtx_unlock(&vmmdev_mtx);
676 
677 	return (0);
678 }
679 SYSCTL_PROC(_hw_vmm, OID_AUTO, create, CTLTYPE_STRING | CTLFLAG_RW,
680 	    NULL, 0, sysctl_vmm_create, "A", NULL);
681 
682 void
683 vmmdev_init(void)
684 {
685 	mtx_init(&vmmdev_mtx, "vmm device mutex", NULL, MTX_DEF);
686 }
687 
688 int
689 vmmdev_cleanup(void)
690 {
691 	int error;
692 
693 	if (SLIST_EMPTY(&head))
694 		error = 0;
695 	else
696 		error = EBUSY;
697 
698 	return (error);
699 }
700