From nobody Tue Nov 05 01:40:50 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Xj9yq3D8Vz5cqcG; Tue, 05 Nov 2024 01:40:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Xj9yq1FZ6z3wfC; Tue, 5 Nov 2024 01:40:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1730770851; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=uup+6Z8gu1lyBEm/81xl9v1/12AemxtsP1Kn9bNaaFU=; b=NxBx9va8YzUqh0dnkqY3WyT0EQDUsUK7zdZCwlMpV0oykWs1Y2nnGsCENvlPEjJc/6P3gF dZ1QZJlFm5TBeYowV1ct3xeYsVfwPml0jvWcCRaFO0VqpOz8t9NUWxR0teluuw6DNIpWxw JevpLxfOr2RBp13wx2/y9MosX3azVMvV8XOKmBHYPDi4wRfJpt/YeoO+Ctb2NP8DxY/dre MQZVJ8G6KdpeVrtr4ChxT4yZ0p1ZP4u2GkSQAIBk7BbWm0jcMrjfHUeCgDkLtiMV0henzB UHQRuuyIlVdJavQcFDAX5FIW59jAFyGBryB8+KWWQ7ehURGINEQr0L6Kdedsig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1730770851; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=uup+6Z8gu1lyBEm/81xl9v1/12AemxtsP1Kn9bNaaFU=; b=YP6U6QIeTMUFs854qYYGGWi5HvrxQLd8kyBL6pJl2arN8y73+x8egYAQNhB+8Tipc4mtlL cgk3UU3wg8moAvkBOm0DjTwDFfroaLyBgjzymzpVbXLg5LBM5bwTsYEG6P83lX5a2M4g3X c9wNwSN83OfJ5DPWVeaP0r9mX/Ag6rfakqDvRKSqgRHP/KhBDnmHf7GmdamhswFHVawgzw j+0TRbKy4mVXcJGCDMwLx72vV70QcaoorVfv4sKXfixihAn6yCt6fOC107mfgdsWgJ1drd 6/toSNFD5zhOrRgA86PvQxl5/DSoOmx7l7+hUVgKpHU6KwC/7bhzc63J3/hZTA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1730770851; a=rsa-sha256; cv=none; b=rhJxtoIA/Jxc41JXvBz7gbnCWVO/JAoOJ3uMOaihmsLWAHVOKwAd2az+nPamCSROkt7ARO w6Nm3SnoAsDJFiOKaT75ubAY8Iva55aU+x/z8Ld4OFxwek0Fc9xwPTWYKoa9CxSoMTdQBQ 9M6TwOEWPytzxuGis+yycnYZ5mBLwpkTAxy4fWdlhjgeHTC5v3NFXYJYS0wKOtXvWwc2FE o12kYEITL5kknC2y7ybZ+KVuPA1gD0HIte0nHyQtssantmGVWZb/5fCJm9HvFH/2cRZDDT yCm+ozZQiQpyOJwEOWzrxk0Lr5VbGus+6VICsQiuQXSXHyrbod/uVQG/XfTdhw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Xj9yp74VdzxKb; Tue, 5 Nov 2024 01:40:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4A51eofB062655; Tue, 5 Nov 2024 01:40:50 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4A51eoLC062652; Tue, 5 Nov 2024 01:40:50 GMT (envelope-from git) Date: Tue, 5 Nov 2024 01:40:50 GMT Message-Id: <202411050140.4A51eoLC062652@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: a97f683fe3c4 - main - vmm: Add a device file interface for creating and destroying VMs List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a97f683fe3c425b425cf8cc466319f54ea957c20 Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=a97f683fe3c425b425cf8cc466319f54ea957c20 commit a97f683fe3c425b425cf8cc466319f54ea957c20 Author: Mark Johnston AuthorDate: 2024-11-05 01:36:06 +0000 Commit: Mark Johnston CommitDate: 2024-11-05 01:40:41 +0000 vmm: Add a device file interface for creating and destroying VMs This supersedes the sysctl interface, which has the limitations of being root-only and not supporting automatic resource destruction, i.e., we cannot easily destroy VMs automatically when bhyve terminates. For now, two ioctls are implemented VMMCTL_VM_CREATE and VMMCTL_VM_DESTROY. Eventually I would like to support tying a VM's lifetime to that of the descriptor, so that it is automatically destroyed when the descriptor is closed. However, this will require some work in bhyve: when the guest wants to reboot, bhyve exits with a status that indicates that it is to be restarted. This is incompatible with the idea of tying a VM's lifetime to that of a descriptor, since we want to avoid creating and destroying a VM across each reboot (as this involves freeing all of the guest memory, among other things). One possible design would be to decompose bhyve into two processes, a parent which handles reboots, and a child which runs in capability mode and handles guest execution. In any case, this gets us closer to addressing the shortcomings mentioned above. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D47028 --- sys/amd64/vmm/vmm.c | 4 ++- sys/arm64/vmm/vmm.c | 4 ++- sys/dev/vmm/vmm_dev.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++- sys/dev/vmm/vmm_dev.h | 15 +++++++++- 4 files changed, 99 insertions(+), 4 deletions(-) diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 07d3f74b8365..77e0adda86f5 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -465,7 +465,9 @@ vmm_handler(module_t mod, int what, void *arg) switch (what) { case MOD_LOAD: if (vmm_is_hw_supported()) { - vmmdev_init(); + error = vmmdev_init(); + if (error != 0) + break; error = vmm_init(); if (error == 0) vmm_initialized = 1; diff --git a/sys/arm64/vmm/vmm.c b/sys/arm64/vmm/vmm.c index 4127fad5cd59..2f4f3a2b59ea 100644 --- a/sys/arm64/vmm/vmm.c +++ b/sys/arm64/vmm/vmm.c @@ -362,7 +362,9 @@ vmm_handler(module_t mod, int what, void *arg) switch (what) { case MOD_LOAD: /* TODO: if (vmm_is_hw_supported()) { */ - vmmdev_init(); + error = vmmdev_init(); + if (error != 0) + break; error = vmm_init(); if (error == 0) vmm_initialized = true; diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c index a43d642b3925..4bea4360a51c 100644 --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -917,11 +918,88 @@ SYSCTL_PROC(_hw_vmm, OID_AUTO, create, NULL, 0, sysctl_vmm_create, "A", NULL); -void +static int +vmmctl_open(struct cdev *cdev, int flags, int fmt, struct thread *td) +{ + int error; + + error = vmm_priv_check(td->td_ucred); + if (error != 0) + return (error); + + if ((flags & FWRITE) == 0) + return (EPERM); + + return (0); +} + +static int +vmmctl_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, + struct thread *td) +{ + int error; + + switch (cmd) { + case VMMCTL_VM_CREATE: { + struct vmmctl_vm_create *vmc; + + vmc = (struct vmmctl_vm_create *)data; + vmc->name[VM_MAX_NAMELEN] = '\0'; + for (size_t i = 0; i < nitems(vmc->reserved); i++) { + if (vmc->reserved[i] != 0) { + error = EINVAL; + return (error); + } + } + + error = vmmdev_create(vmc->name, td->td_ucred); + break; + } + case VMMCTL_VM_DESTROY: { + struct vmmctl_vm_destroy *vmd; + + vmd = (struct vmmctl_vm_destroy *)data; + vmd->name[VM_MAX_NAMELEN] = '\0'; + for (size_t i = 0; i < nitems(vmd->reserved); i++) { + if (vmd->reserved[i] != 0) { + error = EINVAL; + return (error); + } + } + + error = vmmdev_lookup_and_destroy(vmd->name, td->td_ucred); + break; + } + default: + error = ENOTTY; + break; + } + + return (error); +} + +static struct cdevsw vmmctlsw = { + .d_name = "vmmctl", + .d_version = D_VERSION, + .d_open = vmmctl_open, + .d_ioctl = vmmctl_ioctl, +}; + +int vmmdev_init(void) { + struct cdev *cdev; + int error; + + error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &vmmctlsw, NULL, + UID_ROOT, GID_WHEEL, 0600, "vmmctl"); + if (error) + return (error); + pr_allow_flag = prison_add_allow(NULL, "vmm", NULL, "Allow use of vmm in a jail."); + + return (0); } int diff --git a/sys/dev/vmm/vmm_dev.h b/sys/dev/vmm/vmm_dev.h index a2dc4d11f359..410066c49cf2 100644 --- a/sys/dev/vmm/vmm_dev.h +++ b/sys/dev/vmm/vmm_dev.h @@ -18,7 +18,7 @@ struct thread; struct vm; struct vcpu; -void vmmdev_init(void); +int vmmdev_init(void); int vmmdev_cleanup(void); int vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data, int fflag, struct thread *td); @@ -54,4 +54,17 @@ extern const size_t vmmdev_machdep_ioctl_count; #endif /* _KERNEL */ +struct vmmctl_vm_create { + char name[VM_MAX_NAMELEN + 1]; + int reserved[16]; +}; + +struct vmmctl_vm_destroy { + char name[VM_MAX_NAMELEN + 1]; + int reserved[16]; +}; + +#define VMMCTL_VM_CREATE _IOWR('V', 0, struct vmmctl_vm_create) +#define VMMCTL_VM_DESTROY _IOWR('V', 1, struct vmmctl_vm_destroy) + #endif /* _DEV_VMM_DEV_H_ */