git: e3333648b75d - main - vmm: Start reconciling amd64 and arm64 copies of vmm_dev.c

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Wed, 08 May 2024 16:11:18 UTC
The branch main has been updated by markj:

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

commit e3333648b75dc9703e54129dff56ae5b4d6f91c5
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-05-08 16:02:38 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-05-08 16:11:03 +0000

    vmm: Start reconciling amd64 and arm64 copies of vmm_dev.c
    
    Most of the code in vmm_dev.c and vmm.c can and should be shared between
    amd64 and arm64 (and eventually riscv) rather than being duplicated.  To
    the end of adding a shared implementation in sys/dev/vmm, this patch
    eliminates most of the differences between the two copies of vmm_dev.c.
    
    - Remove an unneeded cdefs.h include.
    - Simplify the amd64 implementation of vcpu_unlock_one().
    - Simplify the arm64 implementation of vcpu_lock_one().
    - Pass buffer sizes to alloc_memseg() and get_memseg() on arm64.  On
      amd64 this is needed for compat ioctls, but these functions should be
      merged.
    - Make devmem_mmap_single() stricter on arm64.
    
    Reviewed by:    corvink, jhb
    Differential Revision:  https://reviews.freebsd.org/D44995
---
 sys/amd64/vmm/vmm_dev.c | 15 +++++++--------
 sys/arm64/vmm/vmm_dev.c | 29 +++++++++++++++--------------
 2 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
index 5214cd3f1447..46cddce4e4b8 100644
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -26,7 +26,6 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
 #include "opt_bhyve_snapshot.h"
 
 #include <sys/param.h>
@@ -163,14 +162,14 @@ vcpu_lock_one(struct vcpu *vcpu)
 }
 
 static void
-vcpu_unlock_one(struct vmmdev_softc *sc, int vcpuid, struct vcpu *vcpu)
+vcpu_unlock_one(struct vcpu *vcpu)
 {
 	enum vcpu_state state;
 
 	state = vcpu_get_state(vcpu, NULL);
 	if (state != VCPU_FROZEN) {
-		panic("vcpu %s(%d) has invalid state %d", vm_name(sc->vm),
-		    vcpuid, state);
+		panic("vcpu %s(%d) has invalid state %d",
+		    vm_name(vcpu_vm(vcpu)), vcpu_vcpuid(vcpu), state);
 	}
 
 	vcpu_set_state(vcpu, VCPU_IDLE, false);
@@ -200,7 +199,7 @@ vcpu_lock_all(struct vmmdev_softc *sc)
 			vcpu = vm_vcpu(sc->vm, j);
 			if (vcpu == NULL)
 				continue;
-			vcpu_unlock_one(sc, j, vcpu);
+			vcpu_unlock_one(vcpu);
 		}
 		vm_unlock_vcpus(sc->vm);
 	}
@@ -219,7 +218,7 @@ vcpu_unlock_all(struct vmmdev_softc *sc)
 		vcpu = vm_vcpu(sc->vm, i);
 		if (vcpu == NULL)
 			continue;
-		vcpu_unlock_one(sc, i, vcpu);
+		vcpu_unlock_one(vcpu);
 	}
 	vm_unlock_vcpus(sc->vm);
 }
@@ -1086,7 +1085,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
 
 done:
 	if (vcpus_locked == SINGLE)
-		vcpu_unlock_one(sc, vcpuid, vcpu);
+		vcpu_unlock_one(vcpu);
 	else if (vcpus_locked == ALL)
 		vcpu_unlock_all(sc);
 	if (memsegs_locked)
@@ -1231,7 +1230,7 @@ sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
 	 * is scheduled for destruction.
 	 */
 	cdev = sc->cdev;
-	sc->cdev = NULL;		
+	sc->cdev = NULL;
 	mtx_unlock(&vmmdev_mtx);
 
 	/*
diff --git a/sys/arm64/vmm/vmm_dev.c b/sys/arm64/vmm/vmm_dev.c
index 9f405384f2b3..946c6760f7c1 100644
--- a/sys/arm64/vmm/vmm_dev.c
+++ b/sys/arm64/vmm/vmm_dev.c
@@ -102,10 +102,7 @@ vmm_priv_check(struct ucred *ucred)
 static int
 vcpu_lock_one(struct vcpu *vcpu)
 {
-	int error;
-
-	error = vcpu_set_state(vcpu, VCPU_FROZEN, true);
-	return (error);
+	return (vcpu_set_state(vcpu, VCPU_FROZEN, true));
 }
 
 static void
@@ -252,8 +249,10 @@ vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags)
 	return (error);
 }
 
+CTASSERT(sizeof(((struct vm_memseg *)0)->name) >= VM_MAX_SUFFIXLEN + 1);
+
 static int
-get_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg)
+get_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg, size_t len)
 {
 	struct devmem_softc *dsc;
 	int error;
@@ -270,17 +269,16 @@ get_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg)
 		}
 		KASSERT(dsc != NULL, ("%s: devmem segment %d not found",
 		    __func__, mseg->segid));
-		error = copystr(dsc->name, mseg->name, sizeof(mseg->name),
-		    NULL);
+		error = copystr(dsc->name, mseg->name, len, NULL);
 	} else {
-		bzero(mseg->name, sizeof(mseg->name));
+		bzero(mseg->name, len);
 	}
 
 	return (error);
 }
 
 static int
-alloc_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg)
+alloc_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg, size_t len)
 {
 	char *name;
 	int error;
@@ -296,8 +294,8 @@ alloc_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg)
 	 */
 	if (VM_MEMSEG_NAME(mseg)) {
 		sysmem = false;
-		name = malloc(sizeof(mseg->name), M_VMMDEV, M_WAITOK);
-		error = copystr(mseg->name, name, sizeof(mseg->name), NULL);
+		name = malloc(len, M_VMMDEV, M_WAITOK);
+		error = copystr(mseg->name, name, len, NULL);
 		if (error)
 			goto done;
 	}
@@ -545,10 +543,12 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
 		error = vm_munmap_memseg(sc->vm, mu->gpa, mu->len);
 		break;
 	case VM_ALLOC_MEMSEG:
-		error = alloc_memseg(sc, (struct vm_memseg *)data);
+		error = alloc_memseg(sc, (struct vm_memseg *)data,
+		    sizeof(((struct vm_memseg *)0)->name));
 		break;
 	case VM_GET_MEMSEG:
-		error = get_memseg(sc, (struct vm_memseg *)data);
+		error = get_memseg(sc, (struct vm_memseg *)data,
+		    sizeof(((struct vm_memseg *)0)->name));
 		break;
 	case VM_GET_REGISTER:
 		vmreg = (struct vm_register *)data;
@@ -994,7 +994,8 @@ devmem_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t len,
 	if (seglen >= last)
 		vm_object_reference(*objp);
 	else
-		error = 0;
+		error = EINVAL;
+
 	vm_unlock_memsegs(dsc->sc->vm);
 	return (error);
 }