git: 063a8bd908dd - main - vmm: Factor most of sysctl_vmm_destroy() into a separate function

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Wed, 28 Aug 2024 19:12:43 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=063a8bd908ddaae9f0ba8c7711dfe837a14f21e7

commit 063a8bd908ddaae9f0ba8c7711dfe837a14f21e7
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-08-28 18:57:12 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-08-28 18:57:12 +0000

    vmm: Factor most of sysctl_vmm_destroy() into a separate function
    
    This will make it easy to share code with an ioctl handler which creates
    VMs.  No functional change intended.
    
    Reviewed by:    corvink, jhb
    Differential Revision:  https://reviews.freebsd.org/D46445
---
 sys/dev/vmm/vmm_dev.c | 72 ++++++++++++++++++++++++++-------------------------
 1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c
index 94546efd03c9..6bdcb51777d4 100644
--- a/sys/dev/vmm/vmm_dev.c
+++ b/sys/dev/vmm/vmm_dev.c
@@ -732,12 +732,24 @@ vmmdev_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t mapsize,
 }
 
 static void
-vmmdev_destroy(void *arg)
+vmmdev_destroy(struct vmmdev_softc *sc)
 {
-	struct vmmdev_softc *sc = arg;
 	struct devmem_softc *dsc;
 	int error __diagused;
 
+	/*
+	 * Destroy all cdevs:
+	 *
+	 * - any new operations on the 'cdev' will return an error (ENXIO).
+	 *
+	 * - the 'devmem' cdevs are destroyed before the virtual machine 'cdev'
+	 */
+	SLIST_FOREACH(dsc, &sc->devmem, link) {
+		KASSERT(dsc->cdev != NULL, ("devmem cdev already destroyed"));
+		destroy_dev(dsc->cdev);
+		devmem_destroy(dsc);
+	}
+
 	vm_disable_vcpu_creation(sc->vm);
 	error = vcpu_lock_all(sc);
 	KASSERT(error == 0, ("%s: error %d freezing vcpus", __func__, error));
@@ -769,31 +781,16 @@ vmmdev_destroy(void *arg)
 }
 
 static int
-sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
+vmmdev_lookup_and_destroy(const char *name, struct ucred *cred)
 {
-	struct devmem_softc *dsc;
-	struct vmmdev_softc *sc;
 	struct cdev *cdev;
-	char *buf;
-	int error, buflen;
-
-	error = vmm_priv_check(req->td->td_ucred);
-	if (error)
-		return (error);
-
-	buflen = VM_MAX_NAMELEN + 1;
-	buf = malloc(buflen, M_VMMDEV, M_WAITOK | M_ZERO);
-	strlcpy(buf, "beavis", buflen);
-	error = sysctl_handle_string(oidp, buf, buflen, req);
-	if (error != 0 || req->newptr == NULL)
-		goto out;
+	struct vmmdev_softc *sc;
 
 	mtx_lock(&vmmdev_mtx);
-	sc = vmmdev_lookup(buf);
+	sc = vmmdev_lookup(name);
 	if (sc == NULL || sc->cdev == NULL) {
 		mtx_unlock(&vmmdev_mtx);
-		error = EINVAL;
-		goto out;
+		return (EINVAL);
 	}
 
 	/*
@@ -804,23 +801,28 @@ sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
 	sc->cdev = NULL;
 	mtx_unlock(&vmmdev_mtx);
 
-	/*
-	 * Destroy all cdevs:
-	 *
-	 * - any new operations on the 'cdev' will return an error (ENXIO).
-	 *
-	 * - the 'devmem' cdevs are destroyed before the virtual machine 'cdev'
-	 */
-	SLIST_FOREACH(dsc, &sc->devmem, link) {
-		KASSERT(dsc->cdev != NULL, ("devmem cdev already destroyed"));
-		destroy_dev(dsc->cdev);
-		devmem_destroy(dsc);
-	}
 	destroy_dev(cdev);
 	vmmdev_destroy(sc);
-	error = 0;
 
-out:
+	return (0);
+}
+
+static int
+sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
+{
+	char *buf;
+	int error, buflen;
+
+	error = vmm_priv_check(req->td->td_ucred);
+	if (error)
+		return (error);
+
+	buflen = VM_MAX_NAMELEN + 1;
+	buf = malloc(buflen, M_VMMDEV, M_WAITOK | M_ZERO);
+	strlcpy(buf, "beavis", buflen);
+	error = sysctl_handle_string(oidp, buf, buflen, req);
+	if (error == 0 && req->newptr != NULL)
+		error = vmmdev_lookup_and_destroy(buf, req->td->td_ucred);
 	free(buf, M_VMMDEV);
 	return (error);
 }