| 977 | } |
| 978 | |
| 979 | static int |
| 980 | sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS) |
| 981 | { |
| 982 | struct devmem_softc *dsc; |
| 983 | struct vmmdev_softc *sc; |
| 984 | struct cdev *cdev; |
| 985 | char *buf; |
| 986 | int error, buflen; |
| 987 | |
| 988 | error = vmm_priv_check(req->td->td_ucred); |
| 989 | if (error) |
| 990 | return (error); |
| 991 | |
| 992 | buflen = VM_MAX_NAMELEN + 1; |
| 993 | buf = malloc(buflen, M_VMMDEV, M_WAITOK | M_ZERO); |
| 994 | strlcpy(buf, "beavis", buflen); |
| 995 | error = sysctl_handle_string(oidp, buf, buflen, req); |
| 996 | if (error != 0 || req->newptr == NULL) |
| 997 | goto out; |
| 998 | |
| 999 | mtx_lock(&vmmdev_mtx); |
| 1000 | sc = vmmdev_lookup(buf); |
| 1001 | if (sc == NULL || sc->cdev == NULL) { |
| 1002 | mtx_unlock(&vmmdev_mtx); |
| 1003 | error = EINVAL; |
| 1004 | goto out; |
| 1005 | } |
| 1006 | |
| 1007 | /* |
| 1008 | * The 'cdev' will be destroyed asynchronously when 'si_threadcount' |
| 1009 | * goes down to 0 so we should not do it again in the callback. |
| 1010 | * |
| 1011 | * Setting 'sc->cdev' to NULL is also used to indicate that the VM |
| 1012 | * is scheduled for destruction. |
| 1013 | */ |
| 1014 | cdev = sc->cdev; |
| 1015 | sc->cdev = NULL; |
| 1016 | mtx_unlock(&vmmdev_mtx); |
| 1017 | |
| 1018 | /* |
| 1019 | * Schedule all cdevs to be destroyed: |
| 1020 | * |
| 1021 | * - any new operations on the 'cdev' will return an error (ENXIO). |
| 1022 | * |
| 1023 | * - when the 'si_threadcount' dwindles down to zero the 'cdev' will |
| 1024 | * be destroyed and the callback will be invoked in a taskqueue |
| 1025 | * context. |
| 1026 | * |
| 1027 | * - the 'devmem' cdevs are destroyed before the virtual machine 'cdev' |
| 1028 | */ |
| 1029 | SLIST_FOREACH(dsc, &sc->devmem, link) { |
| 1030 | KASSERT(dsc->cdev != NULL, ("devmem cdev already destroyed")); |
| 1031 | destroy_dev_sched_cb(dsc->cdev, devmem_destroy, dsc); |
| 1032 | } |
| 1033 | destroy_dev_sched_cb(cdev, vmmdev_destroy, sc); |
| 1034 | error = 0; |
| 1035 | |
| 1036 | out: |
nothing calls this directly
no test coverage detected