From 73a98491f956970e5755ae565866cd809697967e Mon Sep 17 00:00:00 2001 From: dv Date: Tue, 25 Apr 2023 12:46:13 +0000 Subject: [PATCH] vmm(4)/vmd(8): pull struct members out of vmm ioctl create struct. The object sent to vmm(4) contained file paths and details the kernel does not need for cpu virtualization as device emulation is in userland. Effectively, "pull up" the struct members from the vm_create_params struct to the parent vmop_create_params struct. This allows us to clean up some of vmd(8) and simplify things for switching to having vmctl(8) open the "kernel" file (SeaBIOS, bsd.rd, etc.) to allow users to boot recovery ramdisk kernels. ok mlarkin@ --- sys/arch/amd64/include/vmmvar.h | 11 +--- usr.sbin/vmctl/vmctl.c | 21 ++++---- usr.sbin/vmd/config.c | 48 +++++++++--------- usr.sbin/vmd/loadfile.h | 4 +- usr.sbin/vmd/loadfile_elf.c | 9 ++-- usr.sbin/vmd/parse.y | 79 ++++++++++++++--------------- usr.sbin/vmd/virtio.c | 80 ++++++++++++++--------------- usr.sbin/vmd/virtio.h | 17 +++---- usr.sbin/vmd/vm.c | 89 +++++++++++++++++---------------- usr.sbin/vmd/vmd.c | 78 ++++++++++++++--------------- usr.sbin/vmd/vmd.h | 13 +++-- usr.sbin/vmd/vmm.c | 10 ++-- 12 files changed, 227 insertions(+), 232 deletions(-) diff --git a/sys/arch/amd64/include/vmmvar.h b/sys/arch/amd64/include/vmmvar.h index 4e020bcafc9..b01979676b0 100644 --- a/sys/arch/amd64/include/vmmvar.h +++ b/sys/arch/amd64/include/vmmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmmvar.h,v 1.89 2023/01/30 02:32:01 dv Exp $ */ +/* $OpenBSD: vmmvar.h,v 1.90 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2014 Mike Larkin * @@ -25,10 +25,7 @@ #define VMM_MAX_MEM_RANGES 16 #define VMM_MAX_DISKS_PER_VM 4 -#define VMM_MAX_PATH_DISK 128 -#define VMM_MAX_PATH_CDROM 128 #define VMM_MAX_NAME_LEN 64 -#define VMM_MAX_KERNEL_PATH 128 #define VMM_MAX_VCPUS 512 #define VMM_MAX_VCPUS_PER_VM 64 #define VMM_MAX_VM_MEM_SIZE 32L * 1024 * 1024 * 1024 /* 32 GiB */ @@ -473,14 +470,8 @@ struct vm_create_params { /* Input parameters to VMM_IOC_CREATE */ size_t vcp_nmemranges; size_t vcp_ncpus; - size_t vcp_ndisks; - size_t vcp_nnics; struct vm_mem_range vcp_memranges[VMM_MAX_MEM_RANGES]; - char vcp_disks[VMM_MAX_DISKS_PER_VM][VMM_MAX_PATH_DISK]; - char vcp_cdrom[VMM_MAX_PATH_CDROM]; char vcp_name[VMM_MAX_NAME_LEN]; - char vcp_kernel[VMM_MAX_KERNEL_PATH]; - uint8_t vcp_macs[VMM_MAX_NICS_PER_VM][6]; /* Output parameter from VMM_IOC_CREATE */ uint32_t vcp_id; diff --git a/usr.sbin/vmctl/vmctl.c b/usr.sbin/vmctl/vmctl.c index 9567bac93ed..ae2ecd29a9f 100644 --- a/usr.sbin/vmctl/vmctl.c +++ b/usr.sbin/vmctl/vmctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmctl.c,v 1.84 2023/01/28 14:40:53 dv Exp $ */ +/* $OpenBSD: vmctl.c,v 1.85 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2014 Mike Larkin @@ -128,14 +128,15 @@ vm_start(uint32_t start_id, const char *name, size_t memsize, int nnics, vcp->vcp_memranges[0].vmr_size = memsize; vcp->vcp_ncpus = 1; - vcp->vcp_ndisks = ndisks; - vcp->vcp_nnics = nnics; vcp->vcp_id = start_id; + vmc->vmc_ndisks = ndisks; + vmc->vmc_nnics = nnics; + for (i = 0 ; i < ndisks; i++) { - if (strlcpy(vcp->vcp_disks[i], disks[i], - sizeof(vcp->vcp_disks[i])) >= - sizeof(vcp->vcp_disks[i])) + if (strlcpy(vmc->vmc_disks[i], disks[i], + sizeof(vmc->vmc_disks[i])) >= + sizeof(vmc->vmc_disks[i])) errx(1, "disk path too long"); vmc->vmc_disktypes[i] = disktypes[i]; } @@ -175,12 +176,12 @@ vm_start(uint32_t start_id, const char *name, size_t memsize, int nnics, errx(1, "vm name too long"); } if (kernel != NULL) - if (strlcpy(vcp->vcp_kernel, kernel, - sizeof(vcp->vcp_kernel)) >= sizeof(vcp->vcp_kernel)) + if (strlcpy(vmc->vmc_kernel, kernel, + sizeof(vmc->vmc_kernel)) >= sizeof(vmc->vmc_kernel)) errx(1, "kernel name too long"); if (iso != NULL) - if (strlcpy(vcp->vcp_cdrom, iso, - sizeof(vcp->vcp_cdrom)) >= sizeof(vcp->vcp_cdrom)) + if (strlcpy(vmc->vmc_cdrom, iso, + sizeof(vmc->vmc_cdrom)) >= sizeof(vmc->vmc_cdrom)) errx(1, "cdrom name too long"); if (instance != NULL) if (strlcpy(vmc->vmc_instance, instance, diff --git a/usr.sbin/vmd/config.c b/usr.sbin/vmd/config.c index cc88551b63e..e40cc654016 100644 --- a/usr.sbin/vmd/config.c +++ b/usr.sbin/vmd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.69 2023/04/02 02:04:10 dv Exp $ */ +/* $OpenBSD: config.c,v 1.70 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -268,13 +268,13 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) for (j = 0; j < VM_MAX_BASE_PER_DISK; j++) diskfds[i][j] = -1; - tapfds = reallocarray(NULL, vcp->vcp_nnics, sizeof(*tapfds)); + tapfds = reallocarray(NULL, vmc->vmc_nnics, sizeof(*tapfds)); if (tapfds == NULL) { ret = errno; log_warn("%s: can't allocate tap fds", __func__); return (ret); } - for (i = 0; i < vcp->vcp_nnics; i++) + for (i = 0; i < vmc->vmc_nnics; i++) tapfds[i] = -1; vm->vm_peerid = peerid; @@ -285,12 +285,12 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) */ if (!(vm->vm_state & VM_STATE_RECEIVED)) { - if (strlen(vcp->vcp_kernel)) { + if (strlen(vmc->vmc_kernel)) { /* Open external kernel for child */ - if ((kernfd = open(vcp->vcp_kernel, O_RDONLY)) == -1) { + if ((kernfd = open(vmc->vmc_kernel, O_RDONLY)) == -1) { ret = errno; log_warn("%s: can't open kernel or BIOS " - "boot image %s", __func__, vcp->vcp_kernel); + "boot image %s", __func__, vmc->vmc_kernel); goto fail; } } @@ -312,18 +312,18 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) vmc->vmc_checkaccess & VMOP_CREATE_KERNEL, uid, R_OK) == -1) { log_warnx("vm \"%s\" no read access to kernel %s", - vcp->vcp_name, vcp->vcp_kernel); + vcp->vcp_name, vmc->vmc_kernel); ret = EPERM; goto fail; } } /* Open CDROM image for child */ - if (strlen(vcp->vcp_cdrom)) { + if (strlen(vmc->vmc_cdrom)) { /* Stat cdrom to ensure it is a regular file */ if ((cdromfd = - open(vcp->vcp_cdrom, O_RDONLY)) == -1) { - log_warn("can't open cdrom %s", vcp->vcp_cdrom); + open(vmc->vmc_cdrom, O_RDONLY)) == -1) { + log_warn("can't open cdrom %s", vmc->vmc_cdrom); ret = VMD_CDROM_MISSING; goto fail; } @@ -332,17 +332,17 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) vmc->vmc_checkaccess & VMOP_CREATE_CDROM, uid, R_OK) == -1) { log_warnx("vm \"%s\" no read access to cdrom %s", - vcp->vcp_name, vcp->vcp_cdrom); + vcp->vcp_name, vmc->vmc_cdrom); ret = EPERM; goto fail; } } /* Open disk images for child */ - for (i = 0 ; i < vcp->vcp_ndisks; i++) { - if (strlcpy(path, vcp->vcp_disks[i], sizeof(path)) + for (i = 0 ; i < vmc->vmc_ndisks; i++) { + if (strlcpy(path, vmc->vmc_disks[i], sizeof(path)) >= sizeof(path)) - log_warnx("disk path %s too long", vcp->vcp_disks[i]); + log_warnx("disk path %s too long", vmc->vmc_disks[i]); memset(vmc->vmc_diskbases, 0, sizeof(vmc->vmc_diskbases)); oflags = O_RDWR|O_EXLOCK|O_NONBLOCK; aflags = R_OK|W_OK; @@ -350,7 +350,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) /* Stat disk[i] to ensure it is a regular file */ if ((diskfds[i][j] = open(path, oflags)) == -1) { log_warn("can't open disk %s", - vcp->vcp_disks[i]); + vmc->vmc_disks[i]); ret = VMD_DISK_MISSING; goto fail; } @@ -378,7 +378,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) if (n == -1) { log_warnx("vm \"%s\" unable to read " "base for disk %s", vcp->vcp_name, - vcp->vcp_disks[i]); + vmc->vmc_disks[i]); goto fail; } (void)strlcpy(path, base, sizeof(path)); @@ -386,7 +386,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) } /* Open network interfaces */ - for (i = 0 ; i < vcp->vcp_nnics; i++) { + for (i = 0 ; i < vmc->vmc_nnics; i++) { vif = &vm->vm_ifs[i]; /* Check if the user has requested a specific tap(4) */ @@ -474,12 +474,12 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) IMSG_VMDOP_START_VM_REQUEST, vm->vm_vmid, kernfd, vmc, sizeof(*vmc)); - if (strlen(vcp->vcp_cdrom)) + if (strlen(vmc->vmc_cdrom)) proc_compose_imsg(ps, PROC_VMM, -1, IMSG_VMDOP_START_VM_CDROM, vm->vm_vmid, cdromfd, NULL, 0); - for (i = 0; i < vcp->vcp_ndisks; i++) { + for (i = 0; i < vmc->vmc_ndisks; i++) { for (j = 0; j < VM_MAX_BASE_PER_DISK; j++) { if (diskfds[i][j] == -1) break; @@ -488,7 +488,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) diskfds[i][j], &i, sizeof(i)); } } - for (i = 0; i < vcp->vcp_nnics; i++) { + for (i = 0; i < vmc->vmc_nnics; i++) { proc_compose_imsg(ps, PROC_VMM, -1, IMSG_VMDOP_START_VM_IF, vm->vm_vmid, tapfds[i], &i, sizeof(i)); @@ -524,12 +524,12 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid) close(kernfd); if (cdromfd != -1) close(cdromfd); - for (i = 0; i < vcp->vcp_ndisks; i++) + for (i = 0; i < vmc->vmc_ndisks; i++) for (j = 0; j < VM_MAX_BASE_PER_DISK; j++) if (diskfds[i][j] != -1) close(diskfds[i][j]); if (tapfds != NULL) { - for (i = 0; i < vcp->vcp_nnics; i++) + for (i = 0; i < vmc->vmc_nnics; i++) close(tapfds[i]); free(tapfds); } @@ -591,7 +591,7 @@ config_getdisk(struct privsep *ps, struct imsg *imsg) IMSG_SIZE_CHECK(imsg, &n); memcpy(&n, imsg->data, sizeof(n)); - if (n >= vm->vm_params.vmc_params.vcp_ndisks || imsg->fd == -1) { + if (n >= vm->vm_params.vmc_ndisks || imsg->fd == -1) { log_warnx("invalid disk id"); errno = EINVAL; return (-1); @@ -620,7 +620,7 @@ config_getif(struct privsep *ps, struct imsg *imsg) IMSG_SIZE_CHECK(imsg, &n); memcpy(&n, imsg->data, sizeof(n)); - if (n >= vm->vm_params.vmc_params.vcp_nnics || + if (n >= vm->vm_params.vmc_nnics || vm->vm_ifs[n].vif_fd != -1 || imsg->fd == -1) { log_warnx("invalid interface id"); goto fail; diff --git a/usr.sbin/vmd/loadfile.h b/usr.sbin/vmd/loadfile.h index 609d336bdee..f0167aa6caf 100644 --- a/usr.sbin/vmd/loadfile.h +++ b/usr.sbin/vmd/loadfile.h @@ -1,5 +1,5 @@ /* $NetBSD: loadfile.h,v 1.1 1999/04/28 09:08:50 christos Exp $ */ -/* $OpenBSD: loadfile.h,v 1.16 2021/12/30 08:12:23 claudio Exp $ */ +/* $OpenBSD: loadfile.h,v 1.17 2023/04/25 12:46:13 dv Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -80,7 +80,7 @@ #define PML2_PAGE 0x13000 #define NPTE_PG (PAGE_SIZE / sizeof(uint64_t)) -int loadfile_elf(gzFile, struct vm_create_params *, struct vcpu_reg_state *, +int loadfile_elf(gzFile, struct vmd_vm *, struct vcpu_reg_state *, unsigned int); size_t mread(gzFile, paddr_t, size_t); diff --git a/usr.sbin/vmd/loadfile_elf.c b/usr.sbin/vmd/loadfile_elf.c index 44578830e3b..864344c88e0 100644 --- a/usr.sbin/vmd/loadfile_elf.c +++ b/usr.sbin/vmd/loadfile_elf.c @@ -1,5 +1,5 @@ /* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */ -/* $OpenBSD: loadfile_elf.c,v 1.46 2023/04/19 12:58:16 jsg Exp $ */ +/* $OpenBSD: loadfile_elf.c,v 1.47 2023/04/25 12:46:13 dv Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -262,8 +262,8 @@ push_pt_64(void) * various error codes returned from gzread(3) or loadelf functions */ int -loadfile_elf(gzFile fp, struct vm_create_params *vcp, - struct vcpu_reg_state *vrs, unsigned int bootdevice) +loadfile_elf(gzFile fp, struct vmd_vm *vm, struct vcpu_reg_state *vrs, + unsigned int bootdevice) { int r, is_i386 = 0; uint32_t bootargsz; @@ -271,6 +271,7 @@ loadfile_elf(gzFile fp, struct vm_create_params *vcp, u_long marks[MARK_MAX]; bios_memmap_t memmap[VMM_MAX_MEM_RANGES + 1]; bios_bootmac_t bm, *bootmac = NULL; + struct vm_create_params *vcp = &vm->vm_params.vmc_params; if ((r = gzread(fp, &hdr, sizeof(hdr))) != sizeof(hdr)) return 1; @@ -303,7 +304,7 @@ loadfile_elf(gzFile fp, struct vm_create_params *vcp, if (bootdevice == VMBOOTDEV_NET) { bootmac = &bm; - memcpy(bootmac, vcp->vcp_macs[0], ETHER_ADDR_LEN); + memcpy(bootmac, vm->vm_params.vmc_macs[0], ETHER_ADDR_LEN); } n = create_bios_memmap(vcp, memmap); bootargsz = push_bootargs(memmap, n, bootmac); diff --git a/usr.sbin/vmd/parse.y b/usr.sbin/vmd/parse.y index e5ede6e70ff..b3e53eb9dec 100644 --- a/usr.sbin/vmd/parse.y +++ b/usr.sbin/vmd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.64 2023/04/24 15:12:14 kn Exp $ */ +/* $OpenBSD: parse.y,v 1.65 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2007-2016 Reyk Floeter @@ -97,8 +97,8 @@ static struct vmop_create_params vmc; static struct vm_create_params *vcp; static struct vmd_switch *vsw; static char vsw_type[IF_NAMESIZE]; -static int vcp_disable; -static size_t vcp_nnics; +static int vmc_disable; +static size_t vmc_nnics; static int errors; extern struct vmd *env; extern const char *vmd_descsw[]; @@ -246,7 +246,7 @@ switch : SWITCH string { vsw->sw_name = $2; vsw->sw_flags = VMIFF_UP; - vcp_disable = 0; + vmc_disable = 0; } '{' optnl switch_opts_l '}' { if (strnlen(vsw->sw_ifname, sizeof(vsw->sw_ifname)) == 0) { @@ -256,7 +256,7 @@ switch : SWITCH string { YYERROR; } - if (vcp_disable) { + if (vmc_disable) { log_debug("%s:%d: switch \"%s\"" " skipped (disabled)", file->name, yylval.lineno, vsw->sw_name); @@ -275,7 +275,7 @@ switch_opts_l : switch_opts_l switch_opts nl ; switch_opts : disable { - vcp_disable = $1; + vmc_disable = $1; } | GROUP string { if (priv_validgroup($2) == -1) { @@ -326,8 +326,8 @@ vm : VM string vm_instance { memset(&vmc, 0, sizeof(vmc)); vcp = &vmc.vmc_params; - vcp_disable = 0; - vcp_nnics = 0; + vmc_disable = 0; + vmc_nnics = 0; if ($3 != NULL) { /* This is an instance of a pre-configured VM */ @@ -367,8 +367,8 @@ vm : VM string vm_instance { int ret; /* configured interfaces vs. number of interfaces */ - if (vcp_nnics > vcp->vcp_nnics) - vcp->vcp_nnics = vcp_nnics; + if (vmc_nnics > vmc.vmc_nnics) + vmc.vmc_nnics = vmc_nnics; if (!env->vmd_noaction) { ret = vm_register(&env->vmd_ps, &vmc, @@ -385,7 +385,7 @@ vm : VM string vm_instance { vcp->vcp_name, strerror(errno)); YYERROR; } else { - if (vcp_disable) + if (vmc_disable) vm->vm_state |= VM_STATE_DISABLED; else vm->vm_state |= VM_STATE_WAITING; @@ -393,7 +393,7 @@ vm : VM string vm_instance { "registered (%s)", file->name, yylval.lineno, vcp->vcp_name, - vcp_disable ? + vmc_disable ? "disabled" : "enabled"); } vm->vm_from_config = 1; @@ -410,7 +410,7 @@ vm_opts_l : vm_opts_l vm_opts nl ; vm_opts : disable { - vcp_disable = $1; + vmc_disable = $1; } | DISK string image_format { if (parse_disk($2, $3) != 0) { @@ -425,9 +425,9 @@ vm_opts : disable { unsigned int i; char type[IF_NAMESIZE]; - i = vcp_nnics; - if (++vcp_nnics > VM_MAX_NICS_PER_VM) { - yyerror("too many interfaces: %zu", vcp_nnics); + i = vmc_nnics; + if (++vmc_nnics > VM_MAX_NICS_PER_VM) { + yyerror("too many interfaces: %zu", vmc_nnics); free($3); YYERROR; } @@ -458,7 +458,7 @@ vm_opts : disable { | BOOT string { char path[PATH_MAX]; - if (vcp->vcp_kernel[0] != '\0') { + if (vmc.vmc_kernel[0] != '\0') { yyerror("kernel specified more than once"); free($2); YYERROR; @@ -471,9 +471,9 @@ vm_opts : disable { YYERROR; } free($2); - if (strlcpy(vcp->vcp_kernel, path, - sizeof(vcp->vcp_kernel)) >= - sizeof(vcp->vcp_kernel)) { + if (strlcpy(vmc.vmc_kernel, path, + sizeof(vmc.vmc_kernel)) >= + sizeof(vmc.vmc_kernel)) { yyerror("kernel name too long"); YYERROR; } @@ -483,15 +483,15 @@ vm_opts : disable { vmc.vmc_bootdevice = $3; } | CDROM string { - if (vcp->vcp_cdrom[0] != '\0') { + if (vmc.vmc_cdrom[0] != '\0') { yyerror("cdrom specified more than once"); free($2); YYERROR; } - if (strlcpy(vcp->vcp_cdrom, $2, - sizeof(vcp->vcp_cdrom)) >= - sizeof(vcp->vcp_cdrom)) { + if (strlcpy(vmc.vmc_cdrom, $2, + sizeof(vmc.vmc_cdrom)) >= + sizeof(vmc.vmc_cdrom)) { yyerror("cdrom name too long"); free($2); YYERROR; @@ -500,7 +500,7 @@ vm_opts : disable { vmc.vmc_flags |= VMOP_CREATE_CDROM; } | NIFS NUMBER { - if (vcp->vcp_nnics != 0) { + if (vmc.vmc_nnics != 0) { yyerror("interfaces specified more than once"); YYERROR; } @@ -508,7 +508,7 @@ vm_opts : disable { yyerror("too many interfaces: %lld", $2); YYERROR; } - vcp->vcp_nnics = (size_t)$2; + vmc.vmc_nnics = (size_t)$2; vmc.vmc_flags |= VMOP_CREATE_NETWORK; } | MEMORY NUMBER { @@ -664,7 +664,7 @@ iface_opts_c : iface_opts_c iface_opts optcomma ; iface_opts : SWITCH string { - unsigned int i = vcp_nnics; + unsigned int i = vmc_nnics; /* No need to check if the switch exists */ if (strlcpy(vmc.vmc_ifswitch[i], $2, @@ -677,7 +677,7 @@ iface_opts : SWITCH string { free($2); } | GROUP string { - unsigned int i = vcp_nnics; + unsigned int i = vmc_nnics; if (priv_validgroup($2) == -1) { yyerror("invalid group name: %s", $2); @@ -692,22 +692,22 @@ iface_opts : SWITCH string { } | locked LLADDR lladdr { if ($1) - vmc.vmc_ifflags[vcp_nnics] |= VMIFF_LOCKED; - memcpy(vcp->vcp_macs[vcp_nnics], $3, ETHER_ADDR_LEN); + vmc.vmc_ifflags[vmc_nnics] |= VMIFF_LOCKED; + memcpy(vmc.vmc_macs[vmc_nnics], $3, ETHER_ADDR_LEN); } | RDOMAIN NUMBER { if ($2 < 0 || $2 > RT_TABLEID_MAX) { yyerror("invalid rdomain: %lld", $2); YYERROR; } - vmc.vmc_ifflags[vcp_nnics] |= VMIFF_RDOMAIN; - vmc.vmc_ifrdomain[vcp_nnics] = $2; + vmc.vmc_ifflags[vmc_nnics] |= VMIFF_RDOMAIN; + vmc.vmc_ifrdomain[vmc_nnics] = $2; } | updown { if ($1) - vmc.vmc_ifflags[vcp_nnics] |= VMIFF_UP; + vmc.vmc_ifflags[vmc_nnics] |= VMIFF_UP; else - vmc.vmc_ifflags[vcp_nnics] &= ~VMIFF_UP; + vmc.vmc_ifflags[vmc_nnics] &= ~VMIFF_UP; } ; @@ -1350,7 +1350,7 @@ parse_disk(char *word, int type) int fd; ssize_t len; - if (vcp->vcp_ndisks >= VM_MAX_DISKS_PER_VM) { + if (vmc.vmc_ndisks >= VM_MAX_DISKS_PER_VM) { log_warnx("too many disks"); return (-1); } @@ -1377,14 +1377,15 @@ parse_disk(char *word, int type) } } - if (strlcpy(vcp->vcp_disks[vcp->vcp_ndisks], path, - VM_MAX_PATH_DISK) >= VM_MAX_PATH_DISK) { + if (strlcpy(vmc.vmc_disks[vmc.vmc_ndisks], path, + sizeof(vmc.vmc_disks[vmc.vmc_ndisks])) >= + sizeof(vmc.vmc_disks[vmc.vmc_ndisks])) { log_warnx("disk path too long"); return (-1); } - vmc.vmc_disktypes[vcp->vcp_ndisks] = type; + vmc.vmc_disktypes[vmc.vmc_ndisks] = type; - vcp->vcp_ndisks++; + vmc.vmc_ndisks++; return (0); } diff --git a/usr.sbin/vmd/virtio.c b/usr.sbin/vmd/virtio.c index 7371d823e4a..62616958a0c 100644 --- a/usr.sbin/vmd/virtio.c +++ b/usr.sbin/vmd/virtio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio.c,v 1.100 2023/04/22 19:47:35 dv Exp $ */ +/* $OpenBSD: virtio.c,v 1.101 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2015 Mike Larkin @@ -1737,17 +1737,17 @@ virtio_init(struct vmd_vm *vm, int child_cdrom, viornd.irq = pci_get_dev_irq(id); viornd.vm_id = vcp->vcp_id; - if (vcp->vcp_nnics > 0) { - vionet = calloc(vcp->vcp_nnics, sizeof(struct vionet_dev)); + if (vmc->vmc_nnics > 0) { + vionet = calloc(vmc->vmc_nnics, sizeof(struct vionet_dev)); if (vionet == NULL) { log_warn("%s: calloc failure allocating vionets", __progname); return; } - nr_vionet = vcp->vcp_nnics; + nr_vionet = vmc->vmc_nnics; /* Virtio network */ - for (i = 0; i < vcp->vcp_nnics; i++) { + for (i = 0; i < vmc->vmc_nnics; i++) { if (pci_add_device(&id, PCI_VENDOR_QUMRANET, PCI_PRODUCT_QUMRANET_VIO_NET, PCI_CLASS_SYSTEM, PCI_SUBCLASS_SYSTEM_MISC, @@ -1804,7 +1804,7 @@ virtio_init(struct vmd_vm *vm, int child_cdrom, } /* MAC address has been assigned by the parent */ - memcpy(&vionet[i].mac, &vcp->vcp_macs[i], 6); + memcpy(&vionet[i].mac, &vmc->vmc_macs[i], 6); vionet[i].cfg.device_feature = VIRTIO_NET_F_MAC; vionet[i].lockedmac = @@ -1825,9 +1825,9 @@ virtio_init(struct vmd_vm *vm, int child_cdrom, } } - if (vcp->vcp_ndisks > 0) { - nr_vioblk = vcp->vcp_ndisks; - vioblk = calloc(vcp->vcp_ndisks, sizeof(struct vioblk_dev)); + if (vmc->vmc_ndisks > 0) { + nr_vioblk = vmc->vmc_ndisks; + vioblk = calloc(vmc->vmc_ndisks, sizeof(struct vioblk_dev)); if (vioblk == NULL) { log_warn("%s: calloc failure allocating vioblks", __progname); @@ -1835,7 +1835,7 @@ virtio_init(struct vmd_vm *vm, int child_cdrom, } /* One virtio block device for each disk defined in vcp */ - for (i = 0; i < vcp->vcp_ndisks; i++) { + for (i = 0; i < vmc->vmc_ndisks; i++) { if (pci_add_device(&id, PCI_VENDOR_QUMRANET, PCI_PRODUCT_QUMRANET_VIO_BLOCK, PCI_CLASS_MASS_STORAGE, @@ -1876,7 +1876,7 @@ virtio_init(struct vmd_vm *vm, int child_cdrom, } /* vioscsi cdrom */ - if (strlen(vcp->vcp_cdrom)) { + if (strlen(vmc->vmc_cdrom)) { vioscsi = calloc(1, sizeof(struct vioscsi_dev)); if (vioscsi == NULL) { log_warn("%s: calloc failure allocating vioscsi", @@ -1968,10 +1968,9 @@ void vionet_set_hostmac(struct vmd_vm *vm, unsigned int idx, uint8_t *addr) { struct vmop_create_params *vmc = &vm->vm_params; - struct vm_create_params *vcp = &vmc->vmc_params; struct vionet_dev *dev; - if (idx > vcp->vcp_nnics) + if (idx > vmc->vmc_nnics) fatalx("vionet_set_hostmac"); dev = &vionet[idx]; @@ -2013,7 +2012,7 @@ vmmci_restore(int fd, uint32_t vm_id) } int -viornd_restore(int fd, struct vm_create_params *vcp) +viornd_restore(int fd, struct vmd_vm *vm) { void *hva = NULL; @@ -2027,7 +2026,7 @@ viornd_restore(int fd, struct vm_create_params *vcp) __progname); return (-1); } - viornd.vm_id = vcp->vcp_id; + viornd.vm_id = vm->vm_params.vmc_params.vcp_id; viornd.irq = pci_get_dev_irq(viornd.pci_id); hva = hvaddr_mem(viornd.vq[0].q_gpa, vring_size(VIORND_QUEUE_SIZE)); @@ -2047,9 +2046,9 @@ vionet_restore(int fd, struct vmd_vm *vm, int *child_taps) int ret; void *hva = NULL; - nr_vionet = vcp->vcp_nnics; - if (vcp->vcp_nnics > 0) { - vionet = calloc(vcp->vcp_nnics, sizeof(struct vionet_dev)); + nr_vionet = vmc->vmc_nnics; + if (vmc->vmc_nnics > 0) { + vionet = calloc(vmc->vmc_nnics, sizeof(struct vionet_dev)); if (vionet == NULL) { log_warn("%s: calloc failure allocating vionets", __progname); @@ -2057,15 +2056,15 @@ vionet_restore(int fd, struct vmd_vm *vm, int *child_taps) } log_debug("%s: receiving vionet", __func__); if (atomicio(read, fd, vionet, - vcp->vcp_nnics * sizeof(struct vionet_dev)) != - vcp->vcp_nnics * sizeof(struct vionet_dev)) { + vmc->vmc_nnics * sizeof(struct vionet_dev)) != + vmc->vmc_nnics * sizeof(struct vionet_dev)) { log_warnx("%s: error reading vionet from fd", __func__); return (-1); } /* Virtio network */ - for (i = 0; i < vcp->vcp_nnics; i++) { + for (i = 0; i < vmc->vmc_nnics; i++) { if (pci_set_bar_fn(vionet[i].pci_id, 0, virtio_net_io, &vionet[i])) { log_warnx("%s: can't set bar fn for virtio net " @@ -2108,15 +2107,14 @@ vionet_restore(int fd, struct vmd_vm *vm, int *child_taps) } int -vioblk_restore(int fd, struct vmop_create_params *vmc, +vioblk_restore(int fd, struct vmd_vm *vm, int child_disks[][VM_MAX_BASE_PER_DISK]) { - struct vm_create_params *vcp = &vmc->vmc_params; uint8_t i; void *hva = NULL; - nr_vioblk = vcp->vcp_ndisks; - vioblk = calloc(vcp->vcp_ndisks, sizeof(struct vioblk_dev)); + nr_vioblk = vm->vm_params.vmc_ndisks; + vioblk = calloc(vm->vm_params.vmc_ndisks, sizeof(struct vioblk_dev)); if (vioblk == NULL) { log_warn("%s: calloc failure allocating vioblks", __progname); return (-1); @@ -2128,7 +2126,7 @@ vioblk_restore(int fd, struct vmop_create_params *vmc, log_warnx("%s: error reading vioblk from fd", __func__); return (-1); } - for (i = 0; i < vcp->vcp_ndisks; i++) { + for (i = 0; i < vm->vm_params.vmc_ndisks; i++) { if (pci_set_bar_fn(vioblk[i].pci_id, 0, virtio_blk_io, &vioblk[i])) { log_warnx("%s: can't set bar fn for virtio block " @@ -2136,13 +2134,13 @@ vioblk_restore(int fd, struct vmop_create_params *vmc, return (-1); } if (virtio_init_disk(&vioblk[i].file, &vioblk[i].sz, - child_disks[i], vmc->vmc_diskbases[i], - vmc->vmc_disktypes[i]) == -1) { + child_disks[i], vm->vm_params.vmc_diskbases[i], + vm->vm_params.vmc_disktypes[i]) == -1) { log_warnx("%s: unable to determine disk format", __func__); return (-1); } - vioblk[i].vm_id = vcp->vcp_id; + vioblk[i].vm_id = vm->vm_params.vmc_params.vcp_id; vioblk[i].irq = pci_get_dev_irq(vioblk[i].pci_id); hva = hvaddr_mem(vioblk[i].vq[0].q_gpa, @@ -2155,12 +2153,12 @@ vioblk_restore(int fd, struct vmop_create_params *vmc, } int -vioscsi_restore(int fd, struct vm_create_params *vcp, int child_cdrom) +vioscsi_restore(int fd, struct vmd_vm *vm, int child_cdrom) { void *hva = NULL; unsigned int i; - if (!strlen(vcp->vcp_cdrom)) + if (!strlen(vm->vm_params.vmc_cdrom)) return (0); vioscsi = calloc(1, sizeof(struct vioscsi_dev)); @@ -2188,7 +2186,7 @@ vioscsi_restore(int fd, struct vm_create_params *vcp, int child_cdrom) log_warnx("%s: unable to determine iso format", __func__); return (-1); } - vioscsi->vm_id = vcp->vcp_id; + vioscsi->vm_id = vm->vm_params.vmc_params.vcp_id; vioscsi->irq = pci_get_dev_irq(vioscsi->pci_id); /* vioscsi uses 3 virtqueues. */ @@ -2207,23 +2205,21 @@ int virtio_restore(int fd, struct vmd_vm *vm, int child_cdrom, int child_disks[][VM_MAX_BASE_PER_DISK], int *child_taps) { - struct vmop_create_params *vmc = &vm->vm_params; - struct vm_create_params *vcp = &vmc->vmc_params; int ret; - if ((ret = viornd_restore(fd, vcp)) == -1) + if ((ret = viornd_restore(fd, vm)) == -1) return ret; - if ((ret = vioblk_restore(fd, vmc, child_disks)) == -1) + if ((ret = vioblk_restore(fd, vm, child_disks)) == -1) return ret; - if ((ret = vioscsi_restore(fd, vcp, child_cdrom)) == -1) + if ((ret = vioscsi_restore(fd, vm, child_cdrom)) == -1) return ret; if ((ret = vionet_restore(fd, vm, child_taps)) == -1) return ret; - if ((ret = vmmci_restore(fd, vcp->vcp_id)) == -1) + if ((ret = vmmci_restore(fd, vm->vm_params.vmc_params.vcp_id)) == -1) return ret; return (0); @@ -2340,10 +2336,10 @@ virtio_dump(int fd) } void -virtio_stop(struct vm_create_params *vcp) +virtio_stop(struct vmd_vm *vm) { uint8_t i; - for (i = 0; i < vcp->vcp_nnics; i++) { + for (i = 0; i < vm->vm_params.vmc_nnics; i++) { if (event_del(&vionet[i].event)) { log_warn("could not initialize vionet event " "handler"); @@ -2353,10 +2349,10 @@ virtio_stop(struct vm_create_params *vcp) } void -virtio_start(struct vm_create_params *vcp) +virtio_start(struct vmd_vm *vm) { uint8_t i; - for (i = 0; i < vcp->vcp_nnics; i++) { + for (i = 0; i < vm->vm_params.vmc_nnics; i++) { if (event_add(&vionet[i].event, NULL)) { log_warn("could not initialize vionet event " "handler"); diff --git a/usr.sbin/vmd/virtio.h b/usr.sbin/vmd/virtio.h index 14cd659d73a..f090ed5c383 100644 --- a/usr.sbin/vmd/virtio.h +++ b/usr.sbin/vmd/virtio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio.h,v 1.43 2022/12/23 19:25:22 dv Exp $ */ +/* $OpenBSD: virtio.h,v 1.44 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2015 Mike Larkin @@ -284,15 +284,17 @@ struct ioinfo { /* virtio.c */ void virtio_init(struct vmd_vm *, int, int[][VM_MAX_BASE_PER_DISK], int *); +void virtio_stop(struct vmd_vm *); +void virtio_start(struct vmd_vm *); void virtio_shutdown(struct vmd_vm *); int virtio_dump(int); -int virtio_restore(int, struct vmd_vm *, int, - int[][VM_MAX_BASE_PER_DISK], int *); +int virtio_restore(int, struct vmd_vm *, int, int[][VM_MAX_BASE_PER_DISK], + int *); uint32_t vring_size(uint32_t); int virtio_rnd_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t); int viornd_dump(int); -int viornd_restore(int, struct vm_create_params *); +int viornd_restore(int, struct vmd_vm *); void viornd_update_qs(void); void viornd_update_qa(void); int viornd_notifyq(void); @@ -305,8 +307,7 @@ int virtio_raw_init(struct virtio_backing *, off_t *, int*, size_t); int virtio_blk_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t); int vioblk_dump(int); -int vioblk_restore(int, struct vmop_create_params *, - int[][VM_MAX_BASE_PER_DISK]); +int vioblk_restore(int, struct vmd_vm *, int[][VM_MAX_BASE_PER_DISK]); void vioblk_update_qs(struct vioblk_dev *); void vioblk_update_qa(struct vioblk_dev *); int vioblk_notifyq(struct vioblk_dev *); @@ -332,7 +333,7 @@ void vmmci_timeout(int, short, void *); const char *vioblk_cmd_name(uint32_t); int vioscsi_dump(int); -int vioscsi_restore(int, struct vm_create_params *, int); +int vioscsi_restore(int, struct vmd_vm *, int); /* dhcp.c */ ssize_t dhcp_request(struct vionet_dev *, char *, size_t, char **); @@ -342,7 +343,5 @@ int vioscsi_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t); void vioscsi_update_qs(struct vioscsi_dev *); void vioscsi_update_qa(struct vioscsi_dev *); int vioscsi_notifyq(struct vioscsi_dev *); -void virtio_stop(struct vm_create_params *vcp); -void virtio_start(struct vm_create_params *vcp); #endif /* _VIRTIO_H_ */ diff --git a/usr.sbin/vmd/vm.c b/usr.sbin/vmd/vm.c index 62782a2cc1f..319cee8d6e3 100644 --- a/usr.sbin/vmd/vm.c +++ b/usr.sbin/vmd/vm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm.c,v 1.85 2023/04/23 12:11:37 dv Exp $ */ +/* $OpenBSD: vm.c,v 1.86 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2015 Mike Larkin @@ -82,7 +82,7 @@ int vcpu_exit(struct vm_run_params *); int vcpu_reset(uint32_t, uint32_t, struct vcpu_reg_state *); void create_memory_map(struct vm_create_params *); int alloc_guest_mem(struct vm_create_params *); -int vmm_create_vm(struct vm_create_params *); +static int vmm_create_vm(struct vmd_vm *); void init_emulated_hw(struct vmop_create_params *, int, int[][VM_MAX_BASE_PER_DISK], int *); void restore_emulated_hw(struct vm_create_params *, int, int *, @@ -92,15 +92,15 @@ int vcpu_exit_eptviolation(struct vm_run_params *); uint8_t vcpu_exit_pci(struct vm_run_params *); int vcpu_pic_intr(uint32_t, uint32_t, uint8_t); int loadfile_bios(gzFile, off_t, struct vcpu_reg_state *); -int send_vm(int, struct vm_create_params *); +static int send_vm(int, struct vmd_vm *); int dump_send_header(int); -int dump_vmr(int , struct vm_mem_range *); -int dump_mem(int, struct vm_create_params *); +static int dump_vmr(int , struct vm_mem_range *); +static int dump_mem(int, struct vmd_vm *); void restore_vmr(int, struct vm_mem_range *); void restore_mem(int, struct vm_create_params *); int restore_vm_params(int, struct vm_create_params *); -void pause_vm(struct vm_create_params *); -void unpause_vm(struct vm_create_params *); +static void pause_vm(struct vmd_vm *); +static void unpause_vm(struct vmd_vm *); int translate_gva(struct vm_exit*, uint64_t, uint64_t *, int); @@ -387,7 +387,7 @@ start_vm(struct vmd_vm *vm, int fd) } /* We've allocated guest memory, so now create the vm in vmm(4). */ - ret = vmm_create_vm(vcp); + ret = vmm_create_vm(vm); if (ret) { /* Let the vmm process know we failed by sending a 0 vm id. */ vcp->vcp_id = 0; @@ -437,7 +437,7 @@ start_vm(struct vmd_vm *vm, int fd) fatalx("failed to open kernel - exiting"); /* Load kernel image */ - ret = loadfile_elf(fp, vcp, &vrs, vmc->vmc_bootdevice); + ret = loadfile_elf(fp, vm, &vrs, vmc->vmc_bootdevice); /* * Try BIOS as a fallback (only if it was provided as an image @@ -492,7 +492,7 @@ start_vm(struct vmd_vm *vm, int fd) restore_mem(vm->vm_receive_fd, vcp); if (restore_vm_params(vm->vm_receive_fd, vcp)) fatal("restore vm params failed"); - unpause_vm(vcp); + unpause_vm(vm); } else init_emulated_hw(vmc, vm->vm_cdrom, vm->vm_disks, nicfds); @@ -567,7 +567,7 @@ vm_dispatch_vmm(int fd, short event, void *arg) case IMSG_VMDOP_PAUSE_VM: vmr.vmr_result = 0; vmr.vmr_id = vm->vm_vmid; - pause_vm(&vm->vm_params.vmc_params); + pause_vm(vm); imsg_compose_event(&vm->vm_iev, IMSG_VMDOP_PAUSE_VM_RESPONSE, imsg.hdr.peerid, imsg.hdr.pid, -1, &vmr, @@ -576,7 +576,7 @@ vm_dispatch_vmm(int fd, short event, void *arg) case IMSG_VMDOP_UNPAUSE_VM: vmr.vmr_result = 0; vmr.vmr_id = vm->vm_vmid; - unpause_vm(&vm->vm_params.vmc_params); + unpause_vm(vm); imsg_compose_event(&vm->vm_iev, IMSG_VMDOP_UNPAUSE_VM_RESPONSE, imsg.hdr.peerid, imsg.hdr.pid, -1, &vmr, @@ -584,8 +584,7 @@ vm_dispatch_vmm(int fd, short event, void *arg) break; case IMSG_VMDOP_SEND_VM_REQUEST: vmr.vmr_id = vm->vm_vmid; - vmr.vmr_result = send_vm(imsg.fd, - &vm->vm_params.vmc_params); + vmr.vmr_result = send_vm(imsg.fd, vm); imsg_compose_event(&vm->vm_iev, IMSG_VMDOP_SEND_VM_RESPONSE, imsg.hdr.peerid, imsg.hdr.pid, -1, &vmr, @@ -642,7 +641,7 @@ vm_shutdown(unsigned int cmd) } int -send_vm(int fd, struct vm_create_params *vcp) +send_vm(int fd, struct vmd_vm *vm) { struct vm_rwregs_params vrp; struct vm_rwvmparams_params vpp; @@ -658,7 +657,7 @@ send_vm(int fd, struct vm_create_params *vcp) goto err; } - pause_vm(vcp); + pause_vm(vm); vmc = calloc(1, sizeof(struct vmop_create_params)); if (vmc == NULL) { @@ -671,18 +670,18 @@ send_vm(int fd, struct vm_create_params *vcp) memcpy(&vmc->vmc_params, ¤t_vm->vm_params, sizeof(struct vmop_create_params)); vmc->vmc_flags = flags; - vrp.vrwp_vm_id = vcp->vcp_id; + vrp.vrwp_vm_id = vm->vm_params.vmc_params.vcp_id; vrp.vrwp_mask = VM_RWREGS_ALL; vpp.vpp_mask = VM_RWVMPARAMS_ALL; - vpp.vpp_vm_id = vcp->vcp_id; + vpp.vpp_vm_id = vm->vm_params.vmc_params.vcp_id; - sz = atomicio(vwrite, fd, vmc,sizeof(struct vmop_create_params)); + sz = atomicio(vwrite, fd, vmc, sizeof(struct vmop_create_params)); if (sz != sizeof(struct vmop_create_params)) { ret = -1; goto err; } - for (i = 0; i < vcp->vcp_ncpus; i++) { + for (i = 0; i < vm->vm_params.vmc_params.vcp_ncpus; i++) { vrp.vrwp_vcpu_id = i; if ((ret = ioctl(env->vmd_fd, VMM_IOC_READREGS, &vrp))) { log_warn("%s: readregs failed", __func__); @@ -712,10 +711,10 @@ send_vm(int fd, struct vm_create_params *vcp) goto err; if ((ret = virtio_dump(fd))) goto err; - if ((ret = dump_mem(fd, vcp))) + if ((ret = dump_mem(fd, vm))) goto err; - for (i = 0; i < vcp->vcp_ncpus; i++) { + for (i = 0; i < vm->vm_params.vmc_params.vcp_ncpus; i++) { vpp.vpp_vcpu_id = i; if ((ret = ioctl(env->vmd_fd, VMM_IOC_READVMPARAMS, &vpp))) { log_warn("%s: readvmparams failed", __func__); @@ -731,7 +730,7 @@ send_vm(int fd, struct vm_create_params *vcp) } } - vtp.vtp_vm_id = vcp->vcp_id; + vtp.vtp_vm_id = vm->vm_params.vmc_params.vcp_id; if (ioctl(env->vmd_fd, VMM_IOC_TERM, &vtp) == -1) { log_warnx("%s: term IOC error: %d, %d", __func__, errno, ENOENT); @@ -739,7 +738,7 @@ send_vm(int fd, struct vm_create_params *vcp) err: close(fd); if (ret) - unpause_vm(vcp); + unpause_vm(vm); return ret; } @@ -784,14 +783,14 @@ dump_send_header(int fd) { } int -dump_mem(int fd, struct vm_create_params *vcp) +dump_mem(int fd, struct vmd_vm *vm) { unsigned int i; int ret; struct vm_mem_range *vmr; - for (i = 0; i < vcp->vcp_nmemranges; i++) { - vmr = &vcp->vcp_memranges[i]; + for (i = 0; i < vm->vm_params.vmc_params.vcp_nmemranges; i++) { + vmr = &vm->vm_params.vmc_params.vcp_memranges[i]; ret = dump_vmr(fd, vmr); if (ret) return ret; @@ -868,24 +867,25 @@ restore_vmr(int fd, struct vm_mem_range *vmr) } } -void -pause_vm(struct vm_create_params *vcp) +static void +pause_vm(struct vmd_vm *vm) { unsigned int n; int ret; - if (current_vm->vm_state & VM_STATE_PAUSED) + if (vm->vm_state & VM_STATE_PAUSED) return; current_vm->vm_state |= VM_STATE_PAUSED; - ret = pthread_barrier_init(&vm_pause_barrier, NULL, vcp->vcp_ncpus + 1); + ret = pthread_barrier_init(&vm_pause_barrier, NULL, + vm->vm_params.vmc_params.vcp_ncpus + 1); if (ret) { log_warnx("%s: cannot initialize pause barrier (%d)", __progname, ret); return; } - for (n = 0; n < vcp->vcp_ncpus; n++) { + for (n = 0; n < vm->vm_params.vmc_params.vcp_ncpus; n++) { ret = pthread_cond_broadcast(&vcpu_run_cond[n]); if (ret) { log_warnx("%s: can't broadcast vcpu run cond (%d)", @@ -910,19 +910,19 @@ pause_vm(struct vm_create_params *vcp) i8253_stop(); mc146818_stop(); ns8250_stop(); - virtio_stop(vcp); + virtio_stop(vm); } -void -unpause_vm(struct vm_create_params *vcp) +static void +unpause_vm(struct vmd_vm *vm) { unsigned int n; int ret; - if (!(current_vm->vm_state & VM_STATE_PAUSED)) + if (!(vm->vm_state & VM_STATE_PAUSED)) return; current_vm->vm_state &= ~VM_STATE_PAUSED; - for (n = 0; n < vcp->vcp_ncpus; n++) { + for (n = 0; n < vm->vm_params.vmc_params.vcp_ncpus; n++) { ret = pthread_cond_broadcast(&vcpu_unpause_cond[n]); if (ret) { log_warnx("%s: can't broadcast vcpu unpause cond (%d)", @@ -934,7 +934,7 @@ unpause_vm(struct vm_create_params *vcp) i8253_start(); mc146818_start(); ns8250_start(); - virtio_start(vcp); + virtio_start(vm); } /* @@ -1121,16 +1121,17 @@ alloc_guest_mem(struct vm_create_params *vcp) * structures for the VM, but does not start the VM's vcpu(s). * * Parameters: - * vcp: vm_create_params struct containing the VM's desired creation - * configuration + * vm: pointer to the vm object * * Return values: * 0: success * !0 : ioctl to vmm(4) failed */ -int -vmm_create_vm(struct vm_create_params *vcp) +static int +vmm_create_vm(struct vmd_vm *vm) { + struct vm_create_params *vcp = &vm->vm_params.vmc_params; + /* Sanity check arguments */ if (vcp->vcp_ncpus > VMM_MAX_VCPUS_PER_VM) return (EINVAL); @@ -1139,10 +1140,10 @@ vmm_create_vm(struct vm_create_params *vcp) vcp->vcp_nmemranges > VMM_MAX_MEM_RANGES) return (EINVAL); - if (vcp->vcp_ndisks > VM_MAX_DISKS_PER_VM) + if (vm->vm_params.vmc_ndisks > VM_MAX_DISKS_PER_VM) return (EINVAL); - if (vcp->vcp_nnics > VM_MAX_NICS_PER_VM) + if (vm->vm_params.vmc_nnics > VM_MAX_NICS_PER_VM) return (EINVAL); if (ioctl(env->vmd_fd, VMM_IOC_CREATE, vcp) == -1) diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c index 4d6f4a9a439..1246c91eb61 100644 --- a/usr.sbin/vmd/vmd.c +++ b/usr.sbin/vmd/vmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.c,v 1.143 2023/04/24 15:12:14 kn Exp $ */ +/* $OpenBSD: vmd.c,v 1.144 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -1354,14 +1354,14 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc, if (vcp->vcp_ncpus > VMM_MAX_VCPUS_PER_VM) { log_warnx("invalid number of CPUs"); goto fail; - } else if (vcp->vcp_ndisks > VM_MAX_DISKS_PER_VM) { + } else if (vmc->vmc_ndisks > VM_MAX_DISKS_PER_VM) { log_warnx("invalid number of disks"); goto fail; - } else if (vcp->vcp_nnics > VM_MAX_NICS_PER_VM) { + } else if (vmc->vmc_nnics > VM_MAX_NICS_PER_VM) { log_warnx("invalid number of interfaces"); goto fail; - } else if (strlen(vcp->vcp_kernel) == 0 && - vcp->vcp_ndisks == 0 && strlen(vcp->vcp_cdrom) == 0) { + } else if (strlen(vmc->vmc_kernel) == 0 && + vmc->vmc_ndisks == 0 && strlen(vmc->vmc_cdrom) == 0) { log_warnx("no kernel or disk/cdrom specified"); goto fail; } else if (strlen(vcp->vcp_name) == 0) { @@ -1397,7 +1397,7 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc, vm->vm_disks[i][j] = -1; for (i = 0; i < VM_MAX_NICS_PER_VM; i++) vm->vm_ifs[i].vif_fd = -1; - for (i = 0; i < vcp->vcp_nnics; i++) { + for (i = 0; i < vmc->vmc_nnics; i++) { if ((sw = switch_getbyname(vmc->vmc_ifswitch[i])) != NULL) { /* inherit per-interface flags from the switch */ vmc->vmc_ifflags[i] |= (sw->sw_flags & VMIFF_OPTMASK); @@ -1410,14 +1410,14 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc, * from the kernel, incremented by one to differentiate * the source. */ - if (memcmp(zero_mac, &vcp->vcp_macs[i], ETHER_ADDR_LEN) == 0) { + if (memcmp(zero_mac, &vmc->vmc_macs[i], ETHER_ADDR_LEN) == 0) { rng = arc4random(); - vcp->vcp_macs[i][0] = 0xfe; - vcp->vcp_macs[i][1] = 0xe1; - vcp->vcp_macs[i][2] = 0xba + 1; - vcp->vcp_macs[i][3] = 0xd0 | ((i + 1) & 0xf); - vcp->vcp_macs[i][4] = rng; - vcp->vcp_macs[i][5] = rng >> 8; + vmc->vmc_macs[i][0] = 0xfe; + vmc->vmc_macs[i][1] = 0xe1; + vmc->vmc_macs[i][2] = 0xba + 1; + vmc->vmc_macs[i][3] = 0xd0 | ((i + 1) & 0xf); + vmc->vmc_macs[i][4] = rng; + vmc->vmc_macs[i][5] = rng >> 8; } } vm->vm_kernel = -1; @@ -1505,17 +1505,17 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent, /* disks cannot be inherited */ if (vm_checkinsflag(vmcp, VMOP_CREATE_DISK, uid) != 0 && - vcp->vcp_ndisks) { + vmc->vmc_ndisks) { log_warnx("vm \"%s\" no permission to set disks", name); return (EPERM); } - for (i = 0; i < vcp->vcp_ndisks; i++) { + for (i = 0; i < vmc->vmc_ndisks; i++) { /* Check if this disk is already used in the parent */ - for (j = 0; j < vcpp->vcp_ndisks; j++) { - if (strcmp(vcp->vcp_disks[i], - vcpp->vcp_disks[j]) == 0) { + for (j = 0; j < vmcp->vmc_ndisks; j++) { + if (strcmp(vmc->vmc_disks[i], + vmcp->vmc_disks[j]) == 0) { log_warnx("vm \"%s\" disk %s cannot be reused", - name, vcp->vcp_disks[i]); + name, vmc->vmc_disks[i]); return (EBUSY); } } @@ -1523,15 +1523,15 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent, } /* interfaces */ - if (vcp->vcp_nnics > 0 && + if (vmc->vmc_nnics > 0 && vm_checkinsflag(vmcp, VMOP_CREATE_NETWORK, uid) != 0 && - vcp->vcp_nnics != vcpp->vcp_nnics) { + vmc->vmc_nnics != vmcp->vmc_nnics) { log_warnx("vm \"%s\" no permission to set interfaces", name); return (EPERM); } - for (i = 0; i < vcpp->vcp_nnics; i++) { + for (i = 0; i < vmcp->vmc_nnics; i++) { /* Interface got overwritten */ - if (i < vcp->vcp_nnics) + if (i < vmc->vmc_nnics) continue; /* Copy interface from parent */ @@ -1542,17 +1542,17 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent, sizeof(vmc->vmc_ifswitch[i])); (void)strlcpy(vmc->vmc_ifgroup[i], vmcp->vmc_ifgroup[i], sizeof(vmc->vmc_ifgroup[i])); - memcpy(vcp->vcp_macs[i], vcpp->vcp_macs[i], - sizeof(vcp->vcp_macs[i])); + memcpy(vmc->vmc_macs[i], vmcp->vmc_macs[i], + sizeof(vmc->vmc_macs[i])); vmc->vmc_ifrdomain[i] = vmcp->vmc_ifrdomain[i]; - vcp->vcp_nnics++; - } - for (i = 0; i < vcp->vcp_nnics; i++) { - for (j = 0; j < vcpp->vcp_nnics; j++) { - if (memcmp(zero_mac, vcp->vcp_macs[i], - sizeof(vcp->vcp_macs[i])) != 0 && - memcmp(vcpp->vcp_macs[i], vcp->vcp_macs[i], - sizeof(vcp->vcp_macs[i])) != 0) { + vmc->vmc_nnics++; + } + for (i = 0; i < vmc->vmc_nnics; i++) { + for (j = 0; j < vmcp->vmc_nnics; j++) { + if (memcmp(zero_mac, vmc->vmc_macs[i], + sizeof(vmc->vmc_macs[i])) != 0 && + memcmp(vmcp->vmc_macs[i], vmc->vmc_macs[i], + sizeof(vmc->vmc_macs[i])) != 0) { log_warnx("vm \"%s\" lladdr cannot be reused", name); return (EBUSY); @@ -1568,28 +1568,28 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent, } /* kernel */ - if (strlen(vcp->vcp_kernel) > 0) { + if (strlen(vmc->vmc_kernel) > 0) { if (vm_checkinsflag(vmcp, VMOP_CREATE_KERNEL, uid) != 0) { log_warnx("vm \"%s\" no permission to set boot image", name); return (EPERM); } vmc->vmc_checkaccess |= VMOP_CREATE_KERNEL; - } else if (strlcpy(vcp->vcp_kernel, vcpp->vcp_kernel, - sizeof(vcp->vcp_kernel)) >= sizeof(vcp->vcp_kernel)) { + } else if (strlcpy(vmc->vmc_kernel, vmcp->vmc_kernel, + sizeof(vmc->vmc_kernel)) >= sizeof(vmc->vmc_kernel)) { log_warnx("vm \"%s\" kernel name too long", name); return (EINVAL); } /* cdrom */ - if (strlen(vcp->vcp_cdrom) > 0) { + if (strlen(vmc->vmc_cdrom) > 0) { if (vm_checkinsflag(vmcp, VMOP_CREATE_CDROM, uid) != 0) { log_warnx("vm \"%s\" no permission to set cdrom", name); return (EPERM); } vmc->vmc_checkaccess |= VMOP_CREATE_CDROM; - } else if (strlcpy(vcp->vcp_cdrom, vcpp->vcp_cdrom, - sizeof(vcp->vcp_cdrom)) >= sizeof(vcp->vcp_cdrom)) { + } else if (strlcpy(vmc->vmc_cdrom, vmcp->vmc_cdrom, + sizeof(vmc->vmc_cdrom)) >= sizeof(vmc->vmc_cdrom)) { log_warnx("vm \"%s\" cdrom name too long", name); return (EINVAL); } diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h index 5e0eb8dfe8e..00becd961c4 100644 --- a/usr.sbin/vmd/vmd.h +++ b/usr.sbin/vmd/vmd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.h,v 1.117 2023/04/23 12:11:37 dv Exp $ */ +/* $OpenBSD: vmd.h,v 1.118 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2015 Mike Larkin @@ -55,9 +55,6 @@ #define VM_MAX_BASE_PER_DISK 4 #define VM_TTYNAME_MAX 16 #define VM_MAX_DISKS_PER_VM 4 -#define VM_MAX_PATH_DISK 128 -#define VM_MAX_PATH_CDROM 128 -#define VM_MAX_KERNEL_PATH 128 #define VM_MAX_NICS_PER_VM 4 #define VM_PCI_MMIO_BAR_SIZE 0x00010000 @@ -216,15 +213,23 @@ struct vmop_create_params { #define VMIFF_RDOMAIN 0x08 #define VMIFF_OPTMASK (VMIFF_LOCKED|VMIFF_LOCAL|VMIFF_RDOMAIN) + size_t vmc_ndisks; + char vmc_disks[VM_MAX_DISKS_PER_VM][PATH_MAX]; unsigned int vmc_disktypes[VM_MAX_DISKS_PER_VM]; unsigned int vmc_diskbases[VM_MAX_DISKS_PER_VM]; #define VMDF_RAW 0x01 #define VMDF_QCOW2 0x02 + char vmc_cdrom[PATH_MAX]; + char vmc_kernel[PATH_MAX]; + + size_t vmc_nnics; char vmc_ifnames[VM_MAX_NICS_PER_VM][IF_NAMESIZE]; char vmc_ifswitch[VM_MAX_NICS_PER_VM][VM_NAME_MAX]; char vmc_ifgroup[VM_MAX_NICS_PER_VM][IF_NAMESIZE]; unsigned int vmc_ifrdomain[VM_MAX_NICS_PER_VM]; + uint8_t vmc_macs[VM_MAX_NICS_PER_VM][6]; + struct vmop_owner vmc_owner; /* instance template params */ diff --git a/usr.sbin/vmd/vmm.c b/usr.sbin/vmd/vmm.c index e5d4e3ab73d..df4ae5ac73f 100644 --- a/usr.sbin/vmd/vmm.c +++ b/usr.sbin/vmd/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.109 2023/04/23 12:11:37 dv Exp $ */ +/* $OpenBSD: vmm.c,v 1.110 2023/04/25 12:46:13 dv Exp $ */ /* * Copyright (c) 2015 Mike Larkin @@ -680,13 +680,13 @@ vmm_start_vm(struct imsg *imsg, uint32_t *id, pid_t *pid) } /* As the parent/vmm process, we no longer need these fds. */ - for (i = 0 ; i < vcp->vcp_ndisks; i++) { + for (i = 0 ; i < vm->vm_params.vmc_ndisks; i++) { for (j = 0; j < VM_MAX_BASE_PER_DISK; j++) { if (close_fd(vm->vm_disks[i][j]) == 0) vm->vm_disks[i][j] = -1; } } - for (i = 0 ; i < vcp->vcp_nnics; i++) { + for (i = 0 ; i < vm->vm_params.vmc_nnics; i++) { if (close_fd(vm->vm_ifs[i].vif_fd) == 0) vm->vm_ifs[i].vif_fd = -1; } @@ -752,11 +752,11 @@ vmm_start_vm(struct imsg *imsg, uint32_t *id, pid_t *pid) } /* Toggle all fds to not close on exec. */ - for (i = 0 ; i < vcp->vcp_ndisks; i++) + for (i = 0 ; i < vm->vm_params.vmc_ndisks; i++) for (j = 0; j < VM_MAX_BASE_PER_DISK; j++) if (vm->vm_disks[i][j] != -1) fcntl(vm->vm_disks[i][j], F_SETFD, 0); - for (i = 0 ; i < vcp->vcp_nnics; i++) + for (i = 0 ; i < vm->vm_params.vmc_nnics; i++) fcntl(vm->vm_ifs[i].vif_fd, F_SETFD, 0); if (vm->vm_kernel != -1) fcntl(vm->vm_kernel, F_SETFD, 0); -- 2.20.1