From nobody Tue Nov 05 01:40:53 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 4Xj9ys3Sgrz5cqV7; Tue, 05 Nov 2024 01:40:53 +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 4Xj9ys2sLLz4vdv; Tue, 5 Nov 2024 01:40:53 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1730770853; 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=OOuI5vj/axtKT2MhzWqNdqcV2VbhBj2FNAaunpJ1nHU=; b=fY9ma3FzYw0/pY4vZ1e2Nz5zo/4KaWM/+fcS/3hy+MoPKlXZTYNx0MCUet4rxrzR1gy09q 1AzRiLZadIYgyBuwqS47PC1yuhC1WwBXxYxbkPfPrg3ZFZmvuzso//jkQczOBS88N5aet+ swwK+zdt7ObmsD4PTcqPuifgB5U1zqQ5BUX4OftHobGfR33SrnEXUrct9nL4c1zKTD6Ahx 1FXNf3M4xkZzTnQmG6P+26Sz5mlJl0VTjxKWz3mVCxJPdr2d0x7JSVvcyejnH0kFBTZZvq grgrZU+e8lDLwdVpSSSdy6ZNA2d8Tte2CltK9vlBQFl2W1jLWFEEVO6fSoleEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1730770853; 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=OOuI5vj/axtKT2MhzWqNdqcV2VbhBj2FNAaunpJ1nHU=; b=JvW6N6lQfn9A2JQb+h7c7v2lNjv6JupLmBze+ul4/70mp3X51kMNGt+A8k+j32RTz/ZeB8 9dzNILH8KGq3x0UJIwyCGiH32udJO+Ojum6GJeKDp0nL7A4v8/feVjqkmhjlyft8Oafwzq y2S7MG4XOPqUDnSH6DGUKPOyyz395btSHCYES7xAy8LfBMbrdNC2IJyaJTwW41XmNueFJo JWrwg3qirck+803ptVYhKjPHNcupzg2J03gxBE1RiiHHzX8TMLj0dzPoQ/zkJ5zewIKi2c DoNLeKIVQ2RNjbRQrrFDfE+XA1YgYDUgBZQj+DchZE152RNSEL/GGZDo2jPvlA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1730770853; a=rsa-sha256; cv=none; b=iBW4gQkz+Lw5P2U+RSzEWw1CTC+k4d6bDu/E6Hrne41vP2m91RjyNkUcmUvSJnS4IXXElG p2eb1/bOxZS00JM27mXh5MPOFqmJcH32HGDCIbAU5wEg/Afxf5sMBmu76oMg8AWiODbKmG b3o7oAog7LmWTGPKxNJvL/UnGQEzqANZf/OjUtr6dtUa2Uq0ib4jkx6qEZ+zUBDHBaScMC MVf+RZ2QI9P33b5DDStqQ+OIZQ9+mYtCDdPPtc3Ov7CVXxVTd3cWhVaARfPbgAlcryaFBR lZu4IpO2OOo9LXgB6lQu+o9QKMU+GHGf6CsjnTb9SMK7qWCMwEkcADB8pyG1Hg== 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 4Xj9ys1zmxzxnV; Tue, 5 Nov 2024 01:40:53 +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 4A51er9r062757; Tue, 5 Nov 2024 01:40:53 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4A51erMd062754; Tue, 5 Nov 2024 01:40:53 GMT (envelope-from git) Date: Tue, 5 Nov 2024 01:40:53 GMT Message-Id: <202411050140.4A51erMd062754@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: 99127fd10362 - main - libvmmapi: Use the vmmctl device file to create and destroy 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: 99127fd103624de593c7d1d885387e7d3667d73d Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=99127fd103624de593c7d1d885387e7d3667d73d commit 99127fd103624de593c7d1d885387e7d3667d73d Author: Mark Johnston AuthorDate: 2024-11-05 01:36:33 +0000 Commit: Mark Johnston CommitDate: 2024-11-05 01:40:41 +0000 libvmmapi: Use the vmmctl device file to create and destroy VMs This deprecates the vm_create() and vm_open() interfaces and introduces vm_openf(), which takes flags controlling its behaviour. In particular, it will optionally create a VM first, and it can optionally reinitialize an existing VM. This enables some simplification of existing consumers. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D47030 --- lib/libvmmapi/internal.h | 3 +- lib/libvmmapi/vmmapi.c | 104 +++++++++++++++++++++++++++++++++++------------ lib/libvmmapi/vmmapi.h | 3 ++ 3 files changed, 83 insertions(+), 27 deletions(-) diff --git a/lib/libvmmapi/internal.h b/lib/libvmmapi/internal.h index 42be9ec59770..aa7b1d8e6a93 100644 --- a/lib/libvmmapi/internal.h +++ b/lib/libvmmapi/internal.h @@ -16,7 +16,8 @@ enum { }; struct vmctx { - int fd; + int fd; /* device file descriptor */ + int ctlfd; /* vmm control descriptor */ struct { vm_paddr_t base; vm_size_t size; diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index 0cf051567110..5042a1f3914e 100644 --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -50,11 +51,12 @@ #include #include -#include #ifdef WITH_VMMAPI_SNAPSHOT #include #endif +#include + #include "vmmapi.h" #include "internal.h" @@ -78,58 +80,104 @@ #define PROT_RW (PROT_READ | PROT_WRITE) #define PROT_ALL (PROT_READ | PROT_WRITE | PROT_EXEC) -#define CREATE(x) sysctlbyname("hw.vmm.create", NULL, NULL, (x), strlen((x))) -#define DESTROY(x) sysctlbyname("hw.vmm.destroy", NULL, NULL, (x), strlen((x))) - static int vm_device_open(const char *name) { - int fd, len; - char *vmfile; + char devpath[PATH_MAX]; - len = strlen("/dev/vmm/") + strlen(name) + 1; - vmfile = malloc(len); - assert(vmfile != NULL); - snprintf(vmfile, len, "/dev/vmm/%s", name); + assert(strlen(name) <= VM_MAX_NAMELEN); + (void)snprintf(devpath, sizeof(devpath), "/dev/vmm/%s", name); + return (open(devpath, O_RDWR)); +} - /* Open the device file */ - fd = open(vmfile, O_RDWR, 0); +static int +vm_ctl_create(const char *name, int ctlfd) +{ + struct vmmctl_vm_create vmc; - free(vmfile); - return (fd); + memset(&vmc, 0, sizeof(vmc)); + if (strlcpy(vmc.name, name, sizeof(vmc.name)) >= sizeof(vmc.name)) { + errno = ENAMETOOLONG; + return (-1); + } + return (ioctl(ctlfd, VMMCTL_VM_CREATE, &vmc)); } int vm_create(const char *name) { + int error, fd; + /* Try to load vmm(4) module before creating a guest. */ - if (modfind("vmm") < 0) - kldload("vmm"); - return (CREATE(name)); + if (modfind("vmm") < 0) { + error = kldload("vmm"); + if (error != 0) + return (-1); + } + + fd = open("/dev/vmmctl", O_RDWR, 0); + if (fd < 0) + return (fd); + error = vm_ctl_create(name, fd); + if (error != 0) { + error = errno; + (void)close(fd); + errno = error; + return (-1); + } + (void)close(fd); + return (0); } struct vmctx * vm_open(const char *name) +{ + return (vm_openf(name, 0)); +} + +struct vmctx * +vm_openf(const char *name, int flags) { struct vmctx *vm; int saved_errno; + bool created; + + created = false; vm = malloc(sizeof(struct vmctx) + strlen(name) + 1); assert(vm != NULL); - vm->fd = -1; + vm->fd = vm->ctlfd = -1; vm->memflags = 0; vm->name = (char *)(vm + 1); strcpy(vm->name, name); memset(vm->memsegs, 0, sizeof(vm->memsegs)); - if ((vm->fd = vm_device_open(vm->name)) < 0) + if ((vm->ctlfd = open("/dev/vmmctl", O_RDWR, 0)) < 0) + goto err; + + vm->fd = vm_device_open(vm->name); + if (vm->fd < 0 && errno == ENOENT) { + if (flags & VMMAPI_OPEN_CREATE) { + if (vm_ctl_create(vm->name, vm->ctlfd) != 0) + goto err; + vm->fd = vm_device_open(vm->name); + created = true; + } + } + if (vm->fd < 0) + goto err; + + if (!created && (flags & VMMAPI_OPEN_REINIT) != 0 && vm_reinit(vm) != 0) goto err; return (vm); err: saved_errno = errno; - free(vm); + if (created) + vm_destroy(vm); + else + vm_close(vm); errno = saved_errno; return (NULL); } @@ -139,20 +187,24 @@ vm_close(struct vmctx *vm) { assert(vm != NULL); - close(vm->fd); + if (vm->fd >= 0) + (void)close(vm->fd); + if (vm->ctlfd >= 0) + (void)close(vm->ctlfd); free(vm); } void vm_destroy(struct vmctx *vm) { - assert(vm != NULL); + struct vmmctl_vm_destroy vmd; - if (vm->fd >= 0) - close(vm->fd); - DESTROY(vm->name); + memset(&vmd, 0, sizeof(vmd)); + (void)strlcpy(vmd.name, vm->name, sizeof(vmd.name)); + if (ioctl(vm->ctlfd, VMMCTL_VM_DESTROY, &vmd) != 0) + warn("ioctl(VMMCTL_VM_DESTROY)"); - free(vm); + vm_close(vm); } struct vcpu * diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h index 0ea1d5824271..440064ad13cb 100644 --- a/lib/libvmmapi/vmmapi.h +++ b/lib/libvmmapi/vmmapi.h @@ -117,6 +117,9 @@ int vm_munmap_memseg(struct vmctx *ctx, vm_paddr_t gpa, size_t len); int vm_create(const char *name); struct vmctx *vm_open(const char *name); +#define VMMAPI_OPEN_CREATE 0x01 /* create if the VM does not exist */ +#define VMMAPI_OPEN_REINIT 0x02 /* reinitialize the VM if it exists */ +struct vmctx *vm_openf(const char *name, int flags); void vm_close(struct vmctx *ctx); void vm_destroy(struct vmctx *ctx); int vm_limit_rights(struct vmctx *ctx);