Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
Re: declutter vmd/vmctl by pulling vmm structs out of vmd structs
To:
Dave Voutila <dv@sisu.io>
Cc:
tech@openbsd.org
Date:
Mon, 29 Dec 2025 11:53:12 +0100

Download raw body.

Thread
On Sat, Dec 27, 2025 at 10:31:23AM -0500, Dave Voutila wrote:
> This looks like deck chair shuffling, but this is to set up for
> switching vmm(4) from using magic identifiers (a monotonically
> incrementing uint32_t) passed in ioctl's to files[1] to not only clean
> up the vmm api a bit, but make virtual machine lifetime management
> simpler.
> 
> This diff:
> 
>  - cleans up how vm identifiers are used, specifically vmm(4)
>    vs. vmd(8), making use of explcit naming (vmm_id for kernel ids
>    vs. vm_id for vmd ids) to prevent future confusion.
> 
>  - makes vmctl(8) not depend on any vmm(4) kernel structs and only on
>    the vmd(8)-defined structs by removing the vmm structs embedded in
>    vmd structs.
> 
>  - is net-negative!?
> 
> Right now I'm mostly looking for testers to check for any
> regressions. No behavioral change is expected from this diff.
> 
> I don't have an AMD SEV machine, so testing on that would be
> appreciated.

I have tested in on AMD with all variatios of SEV.

bluhm

> *You need to also rebuild vmctl to test this.*
> 
> If trying to review, I recommend looking at the header file changes as
> they better describe the change to the data types.
> 
> 
> [1]: KVM has had this file-based API design from the beginning, IIRC,
>      but KVM also creates files for each vcpu. The KVM ioctls for
>      running a vcpu or reading/writing registers are made against these
>      files.
> 
>      There's no value to go that wild with vmm, but this would
>      allow a vm process to only need a file open to the vm itself, not
>      /dev/vmm, and process exits would make the vm process "clean up"
>      the vm state. Today, vmd's "vmm" process does this cleanup via
>      VMM_IOC_TERM ioctls after the child vm processes exit.
> 
>      Another bonus would be not doing some hacky pid-based filtering in
>      vmm based on the ioctl being called since nothing currently
>      prevents a process from "guessing" another vm's identifier (or
>      accidentally using one if there's a bug in vmd).
> 
> 
> diffstat refs/heads/master refs/heads/vmd-vmctl-cleanup
>  M  usr.sbin/vmctl/vmctl.c       |  49+   64-
>  M  usr.sbin/vmd/arm64_vm.c      |   2+    2-
>  M  usr.sbin/vmd/config.c        |  14+   15-
>  M  usr.sbin/vmd/dhcp.c          |   5+    5-
>  M  usr.sbin/vmd/fw_cfg.c        |   2+    2-
>  M  usr.sbin/vmd/loadfile_elf.c  |   6+    7-
>  M  usr.sbin/vmd/parse.y         |  11+   13-
>  M  usr.sbin/vmd/priv.c          |   1+    2-
>  M  usr.sbin/vmd/sev.c           |  10+   18-
>  M  usr.sbin/vmd/vioblk.c        |   4+    5-
>  M  usr.sbin/vmd/vionet.c        |   4+    5-
>  M  usr.sbin/vmd/virtio.c        |  38+   40-
>  M  usr.sbin/vmd/virtio.h        |   2+    2-
>  M  usr.sbin/vmd/vm.c            |  70+   68-
>  M  usr.sbin/vmd/vm_agentx.c     |   9+   10-
>  M  usr.sbin/vmd/vmd.c           |  86+  104-
>  M  usr.sbin/vmd/vmd.h           |  54+   23-
>  M  usr.sbin/vmd/vmm.c           |  24+   18-
>  M  usr.sbin/vmd/x86_vm.c        |  56+   63-
> 
> 19 files changed, 447 insertions(+), 466 deletions(-)
> 
> diff refs/heads/master refs/heads/vmd-vmctl-cleanup
> commit - a39b2115abef8adc9cc601a81bdf809c4a8dc51e
> commit + f59376db8c369968041b61dfc8bd7cd9f3cc52f9
> blob - eae1a9cb191f08f6bba2cb8d6243cf70d765fcc8
> blob + f6a44b6219a58aa0aa56c1f4684777df2edf2ded
> --- usr.sbin/vmctl/vmctl.c
> +++ usr.sbin/vmctl/vmctl.c
> @@ -75,8 +75,7 @@ vm_start(uint32_t start_id, const char *name, size_t m
>      char **nics, int ndisks, char **disks, int *disktypes, char *kernel,
>      char *iso, char *instance, unsigned int bootdevice)
>  {
> -	struct vmop_create_params *vmc;
> -	struct vm_create_params *vcp;
> +	struct vmop_create_params vmc;
>  	struct stat sb;
>  	unsigned int flags = 0;
>  	int i;
> @@ -120,47 +119,43 @@ vm_start(uint32_t start_id, const char *name, size_t m
>  			warnx("starting without network interfaces");
>  	}
> 
> -	if ((vmc = calloc(1, sizeof(struct vmop_create_params))) == NULL)
> -		return (ENOMEM);
> -	vmc->vmc_kernel = -1;
> -	vmc->vmc_flags = flags;
> +	memset(&vmc, 0, sizeof(vmc));
> +	vmc.vmc_kernel = -1;
> +	vmc.vmc_flags = flags;
> 
> -	/* vcp includes configuration that is shared with the kernel */
> -	vcp = &vmc->vmc_params;
> -
>  	/*
>  	 * XXX: vmd(8) fills in the actual memory ranges. vmctl(8)
>  	 * just passes in the actual memory size here.
>  	 */
> -	vcp->vcp_nmemranges = 1;
> -	vcp->vcp_memranges[0].vmr_size = memsize;
> +	vmc.vmc_nmemranges = 1;
> +	vmc.vmc_memranges[0].vmr_size = memsize;
> 
> -	vcp->vcp_ncpus = 1;
> -	vcp->vcp_id = start_id;
> +	vmc.vmc_ncpus = 1;
> +	vmc.vmc_id = start_id;
> 
> -	vmc->vmc_ndisks = ndisks;
> -	vmc->vmc_nnics = nnics;
> +	vmc.vmc_ndisks = ndisks;
> +	vmc.vmc_nnics = nnics;
> 
>  	for (i = 0 ; i < ndisks; i++) {
> -		if (strlcpy(vmc->vmc_disks[i], disks[i],
> -		    sizeof(vmc->vmc_disks[i])) >=
> -		    sizeof(vmc->vmc_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];
> +		vmc.vmc_disktypes[i] = disktypes[i];
>  	}
>  	for (i = 0 ; i < nnics; i++) {
> -		vmc->vmc_ifflags[i] = VMIFF_UP;
> +		vmc.vmc_ifflags[i] = VMIFF_UP;
> 
>  		if (strcmp(".", nics[i]) == 0) {
>  			/* Add a "local" interface */
> -			(void)strlcpy(vmc->vmc_ifswitch[i], "",
> -			    sizeof(vmc->vmc_ifswitch[i]));
> -			vmc->vmc_ifflags[i] |= VMIFF_LOCAL;
> +			(void)strlcpy(vmc.vmc_ifswitch[i], "",
> +			    sizeof(vmc.vmc_ifswitch[i]));
> +			vmc.vmc_ifflags[i] |= VMIFF_LOCAL;
>  		} else {
>  			/* Add an interface to a switch */
> -			if (strlcpy(vmc->vmc_ifswitch[i], nics[i],
> -			    sizeof(vmc->vmc_ifswitch[i])) >=
> -			    sizeof(vmc->vmc_ifswitch[i]))
> +			if (strlcpy(vmc.vmc_ifswitch[i], nics[i],
> +			    sizeof(vmc.vmc_ifswitch[i])) >=
> +			    sizeof(vmc.vmc_ifswitch[i]))
>  				errx(1, "interface name too long");
>  		}
>  	}
> @@ -179,36 +174,35 @@ vm_start(uint32_t start_id, const char *name, size_t m
>  				errx(1, "invalid VM name");
>  		}
> 
> -		if (strlcpy(vcp->vcp_name, name,
> -		    sizeof(vcp->vcp_name)) >= sizeof(vcp->vcp_name))
> +		if (strlcpy(vmc.vmc_name, name,
> +		    sizeof(vmc.vmc_name)) >= sizeof(vmc.vmc_name))
>  			errx(1, "vm name too long");
>  	}
>  	if (kernel != NULL) {
>  		if (strnlen(kernel, PATH_MAX) == PATH_MAX)
>  			errx(1, "kernel name too long");
> -		vmc->vmc_kernel = open(kernel, O_RDONLY);
> -		if (vmc->vmc_kernel == -1)
> +		vmc.vmc_kernel = open(kernel, O_RDONLY);
> +		if (vmc.vmc_kernel == -1)
>  			err(1, "cannot open kernel '%s'", kernel);
>  		memset(&sb, 0, sizeof(sb));
> -		if (fstat(vmc->vmc_kernel, &sb) == -1)
> +		if (fstat(vmc.vmc_kernel, &sb) == -1)
>  			err(1, "fstat kernel");
>  		if (!S_ISREG(sb.st_mode))
>  			errx(1, "kernel must be a regular file");
>  	}
>  	if (iso != NULL)
> -		if (strlcpy(vmc->vmc_cdrom, iso,
> -		    sizeof(vmc->vmc_cdrom)) >= sizeof(vmc->vmc_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,
> -		    sizeof(vmc->vmc_instance)) >= sizeof(vmc->vmc_instance))
> +		if (strlcpy(vmc.vmc_instance, instance,
> +		    sizeof(vmc.vmc_instance)) >= sizeof(vmc.vmc_instance))
>  			errx(1, "instance vm name too long");
> -	vmc->vmc_bootdevice = bootdevice;
> +	vmc.vmc_bootdevice = bootdevice;
> 
> -	imsg_compose(ibuf, IMSG_VMDOP_START_VM_REQUEST, 0, 0, vmc->vmc_kernel,
> -	    vmc, sizeof(struct vmop_create_params));
> +	imsg_compose(ibuf, IMSG_VMDOP_START_VM_REQUEST, 0, 0, vmc.vmc_kernel,
> +	    &vmc, sizeof(vmc));
> 
> -	free(vmc);
>  	return (0);
>  }
> 
> @@ -495,14 +489,12 @@ terminate_vm_complete(struct imsg *imsg, int *ret, uns
>  void
>  terminate_all(struct vmop_info_result *list, size_t ct, unsigned int flags)
>  {
> -	struct vm_info_result *vir;
> -	struct vmop_info_result *vmi;
> +	struct vmop_info_result *vir;
>  	struct parse_result res;
>  	size_t i;
> 
>  	for (i = 0; i < ct; i++) {
> -		vmi = &list[i];
> -		vir = &vmi->vir_info;
> +		vir = &list[i];
> 
>  		/* The VM is already stopped */
>  		if (vir->vir_creator_pid == 0 || vir->vir_id == 0)
> @@ -705,8 +697,7 @@ vm_state(unsigned int mask)
>  int
>  print_vm_info(struct vmop_info_result *list, size_t ct)
>  {
> -	struct vm_info_result *vir;
> -	struct vmop_info_result *vmi;
> +	struct vmop_info_result *vir;
>  	size_t i;
>  	char *tty;
>  	char curmem[FMT_SCALED_STRSIZE];
> @@ -722,8 +713,7 @@ print_vm_info(struct vmop_info_result *list, size_t ct
>  	    "MAXMEM", "CURMEM", "TTY", "OWNER", "STATE", "NAME");
> 
>  	for (i = 0; i < ct; i++) {
> -		vmi = &list[i];
> -		vir = &vmi->vir_info;
> +		vir = &list[i];
>  		running = (vir->vir_creator_pid != 0 && vir->vir_id != 0);
>  		if (!running && stat_rflag)
>  			continue;
> @@ -732,18 +722,18 @@ print_vm_info(struct vmop_info_result *list, size_t ct
> 
>  		if (check_info_id(vir->vir_name, vir->vir_id)) {
>  			/* get user name */
> -			name = user_from_uid(vmi->vir_uid, 1);
> +			name = user_from_uid(vir->vir_uid, 1);
>  			if (name == NULL)
>  				(void)snprintf(user, sizeof(user),
> -				    "%d", vmi->vir_uid);
> +				    "%d", vir->vir_uid);
>  			else
>  				(void)strlcpy(user, name, sizeof(user));
>  			/* get group name */
> -			if (vmi->vir_gid != -1) {
> -				name = group_from_gid(vmi->vir_gid, 1);
> +			if (vir->vir_gid != -1) {
> +				name = group_from_gid(vir->vir_gid, 1);
>  				if (name == NULL)
>  					(void)snprintf(group, sizeof(group),
> -					    ":%lld", vmi->vir_gid);
> +					    ":%lld", vir->vir_gid);
>  				else
>  					(void)snprintf(group, sizeof(group),
>  					    ":%s", name);
> @@ -756,10 +746,10 @@ print_vm_info(struct vmop_info_result *list, size_t ct
>  			(void)fmt_scaled(vir->vir_memory_size, maxmem);
> 
>  			if (running) {
> -				if (*vmi->vir_ttyname == '\0')
> +				if (*vir->vir_ttyname == '\0')
>  					tty = "-";
>  				/* get tty - skip /dev/ path */
> -				else if ((tty = strrchr(vmi->vir_ttyname,
> +				else if ((tty = strrchr(vir->vir_ttyname,
>  				    '/')) == NULL || *++tty == '\0')
>  					tty = list[i].vir_ttyname;
> 
> @@ -769,14 +759,14 @@ print_vm_info(struct vmop_info_result *list, size_t ct
>  				printf("%5u %5u %5zd %7s %7s %7s %12s %8s %s\n",
>  				    vir->vir_id, vir->vir_creator_pid,
>  				    vir->vir_ncpus, maxmem, curmem,
> -				    tty, user, vm_state(vmi->vir_state),
> +				    tty, user, vm_state(vir->vir_state),
>  				    vir->vir_name);
>  			} else {
>  				/* disabled vm */
>  				printf("%5u %5s %5zd %7s %7s %7s %12s %8s %s\n",
>  				    vir->vir_id, "-",
>  				    vir->vir_ncpus, maxmem, curmem,
> -				    "-", user, vm_state(vmi->vir_state),
> +				    "-", user, vm_state(vir->vir_state),
>  				    vir->vir_name);
>  			}
>  		}
> @@ -805,9 +795,8 @@ vm_console(struct vmop_info_result *list, size_t ct)
> 
>  	for (i = 0; i < ct; i++) {
>  		vir = &list[i];
> -		if ((check_info_id(vir->vir_info.vir_name,
> -		    vir->vir_info.vir_id) > 0) &&
> -			(vir->vir_ttyname[0] != '\0')) {
> +		if ((check_info_id(vir->vir_name, vir->vir_id) > 0) &&
> +		    (vir->vir_ttyname[0] != '\0')) {
>  			/* does not return */
>  			ctl_openconsole(vir->vir_ttyname);
>  		}
> @@ -930,14 +919,10 @@ vmop_result_read(struct imsg *imsg, struct vmop_result
>  void
>  vmop_info_result_read(struct imsg *imsg, struct vmop_info_result *vir)
>  {
> -	struct vm_info_result *r;
> -
>  	if (imsg_get_data(imsg, vir, sizeof(*vir)))
>  		fatal("%s", __func__);
> 
> -	r = &vir->vir_info;
> -	r->vir_name[sizeof(r->vir_name) - 1] = '\0';
> -
> +	vir->vir_name[sizeof(vir->vir_name) - 1] = '\0';
>  	vir->vir_ttyname[sizeof(vir->vir_ttyname) - 1] = '\0';
>  }
> 
> blob - bb3eb114e83c6a2c1cedbd159911543b1a0cb6b2
> blob + 89b19e74b702e71e2a09265d69fc3c4f3c61c776
> --- usr.sbin/vmd/arm64_vm.c
> +++ usr.sbin/vmd/arm64_vm.c
> @@ -20,7 +20,7 @@
>  #include "vmm.h"
> 
>  void
> -create_memory_map(struct vm_create_params *vcp)
> +create_memory_map(struct vmd_vm *vm)
>  {
>  	fatalx("%s: unimplemented", __func__);
>  	/* NOTREACHED */
> @@ -35,7 +35,7 @@ load_firmware(struct vmd_vm *vm, struct vcpu_reg_state
>  }
> 
>  int
> -init_emulated_hw(struct vmop_create_params *vcp, int child_cdrom,
> +init_emulated_hw(struct vmd_vm *vm, int child_cdrom,
>      int child_disks[][VM_MAX_BASE_PER_DISK], int *child_taps)
>  {
>  	fatalx("%s: unimplemented", __func__);
> blob - 069c05608cc842bc9604504698bfb453d62ce475
> blob + 24f1c7fe8bd6edc255d5360ed6d12e56c53cf517
> --- usr.sbin/vmd/config.c
> +++ usr.sbin/vmd/config.c
> @@ -190,7 +190,6 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, ui
>  	int diskfds[VM_MAX_DISKS_PER_VM][VM_MAX_BASE_PER_DISK];
>  	struct vmd_if		*vif;
>  	struct vmop_create_params *vmc = &vm->vm_params;
> -	struct vm_create_params	*vcp = &vmc->vmc_params;
>  	unsigned int		 i, j;
>  	int			 fd = -1, cdromfd = -1, kernfd = -1;
>  	int			*tapfds = NULL;
> @@ -227,13 +226,13 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, ui
>  		}
> 
>  		log_debug("%s: vm %u restarted after %lld.%ld seconds,"
> -		    " limit %d/%d", __func__, vcp->vcp_id, since_last.tv_sec,
> +		    " limit %d/%d", __func__, vm->vm_vmid, since_last.tv_sec,
>  		    since_last.tv_usec, vm->vm_start_limit,
>  		    VM_START_RATE_LIMIT);
> 
>  		if (vm->vm_start_limit >= VM_START_RATE_LIMIT) {
> -			log_warnx("%s: vm %u restarted too quickly",
> -			    __func__, vcp->vcp_id);
> +			log_warnx("%s: vm %u restarted too quickly", __func__,
> +			    vm->vm_vmid);
>  			return (EPERM);
>  		}
>  	}
> @@ -290,7 +289,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, ui
>  		    vmc->vmc_checkaccess & VMOP_CREATE_KERNEL,
>  		    uid, R_OK) == -1) {
>  			log_warnx("vm \"%s\" no read access to kernel "
> -			    "%s", vcp->vcp_name, vm->vm_kernel_path);
> +			    "%s", vmc->vmc_name, vm->vm_kernel_path);
>  			ret = EPERM;
>  			goto fail;
>  		}
> @@ -313,7 +312,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, ui
>  		    vmc->vmc_checkaccess & VMOP_CREATE_CDROM,
>  		    uid, R_OK) == -1) {
>  			log_warnx("vm \"%s\" no read access to cdrom %s",
> -			    vcp->vcp_name, vmc->vmc_cdrom);
> +			    vmc->vmc_name, vmc->vmc_cdrom);
>  			ret = EPERM;
>  			goto fail;
>  		}
> @@ -343,7 +342,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, ui
>  			    vmc->vmc_checkaccess & VMOP_CREATE_DISK,
>  			    uid, aflags) == -1) {
>  				log_warnx("vm \"%s\" unable to access "
> -				    "disk %s", vcp->vcp_name, path);
> +				    "disk %s", vmc->vmc_name, path);
>  				errno = EPERM;
>  				goto fail;
>  			}
> @@ -361,7 +360,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, ui
>  				break;
>  			if (n == -1) {
>  				log_warnx("vm \"%s\" unable to read "
> -				    "base for disk %s", vcp->vcp_name,
> +				    "base for disk %s", vmc->vmc_name,
>  				    vmc->vmc_disks[i]);
>  				goto fail;
>  			}
> @@ -488,18 +487,18 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, ui
>  	free(tapfds);
> 
>  	/* Collapse any memranges after the vm was sent to PROC_VMM */
> -	if (vcp->vcp_nmemranges > 0) {
> -		for (i = 0; i < vcp->vcp_nmemranges; i++)
> -			bytes += vcp->vcp_memranges[i].vmr_size;
> -		memset(&vcp->vcp_memranges, 0, sizeof(vcp->vcp_memranges));
> -		vcp->vcp_nmemranges = 0;
> -		vcp->vcp_memranges[0].vmr_size = bytes;
> +	if (vmc->vmc_nmemranges > 0) {
> +		for (i = 0; i < vmc->vmc_nmemranges; i++)
> +			bytes += vmc->vmc_memranges[i].vmr_size;
> +		memset(&vmc->vmc_memranges, 0, sizeof(vmc->vmc_memranges));
> +		vmc->vmc_nmemranges = 0;
> +		vmc->vmc_memranges[0].vmr_size = bytes;
>  	}
>  	vm->vm_state |= VM_STATE_RUNNING;
>  	return (0);
> 
>   fail:
> -	log_warnx("failed to start vm %s", vcp->vcp_name);
> +	log_warnx("failed to start vm %s", vmc->vmc_name);
> 
>  	if (vm->vm_kernel != -1)
>  		close(kernfd);
> blob - 256a29f51260e7af51977b4ea16676e056376943
> blob + 03cdcb269dcc3f8560c2d35299c1226da5fdea26
> --- usr.sbin/vmd/dhcp.c
> +++ usr.sbin/vmd/dhcp.c
> @@ -139,13 +139,13 @@ dhcp_request(struct virtio_dev *dev, char *buf, size_t
> 
>  	if (vionet->pxeboot) {
>  		strlcpy(resp.file, "auto_install", sizeof resp.file);
> -		vm = vm_getbyvmid(dev->vm_vmid);
> -		if (vm && res_hnok(vm->vm_params.vmc_params.vcp_name))
> -			hostname = vm->vm_params.vmc_params.vcp_name;
> +		vm = vm_getbyid(dev->vmm_id);
> +		if (vm && res_hnok(vm->vm_params.vmc_name))
> +			hostname = vm->vm_params.vmc_name;
>  	}
> 
>  	if ((client_addr.s_addr = vm_priv_addr(&vionet->local_prefix,
> -	    dev->vm_vmid, vionet->idx, 1)) == 0)
> +	    dev->vm_id, vionet->idx, 1)) == 0)
>  		return (-1);
>  	memcpy(&resp.yiaddr, &client_addr,
>  	    sizeof(client_addr));
> @@ -154,7 +154,7 @@ dhcp_request(struct virtio_dev *dev, char *buf, size_t
>  	ss2sin(&pc.pc_dst)->sin_port = htons(CLIENT_PORT);
> 
>  	if ((server_addr.s_addr = vm_priv_addr(&vionet->local_prefix,
> -	    dev->vm_vmid, vionet->idx, 0)) == 0)
> +	    dev->vm_id, vionet->idx, 0)) == 0)
>  		return (-1);
>  	memcpy(&resp.siaddr, &server_addr, sizeof(server_addr));
>  	memcpy(&ss2sin(&pc.pc_src)->sin_addr, &server_addr,
> blob - 44bc7bd58fbf956168c8adb8731def6e14a076eb
> blob + ce6b6cc2187ed3c983ed324bd1054b7cbc3b46cb
> --- usr.sbin/vmd/fw_cfg.c
> +++ usr.sbin/vmd/fw_cfg.c
> @@ -79,8 +79,8 @@ fw_cfg_init(struct vmop_create_params *vmc)
> 
>  	/* Define e820 memory ranges. */
>  	memset(&e820, 0, sizeof(e820));
> -	for (i = 0; i < vmc->vmc_params.vcp_nmemranges; i++) {
> -		struct vm_mem_range *range = &vmc->vmc_params.vcp_memranges[i];
> +	for (i = 0; i < vmc->vmc_nmemranges; i++) {
> +		struct vm_mem_range *range = &vmc->vmc_memranges[i];
>  		bios_memmap_t *entry = &e820[i];
>  		entry->addr = range->vmr_gpa;
>  		entry->size = range->vmr_size;
> blob - 875287d8c7a856d34efd730603e1d9a9c692daa4
> blob + 36a94208ee400e3831878be04feb910dec913f09
> --- usr.sbin/vmd/loadfile_elf.c
> +++ usr.sbin/vmd/loadfile_elf.c
> @@ -113,7 +113,7 @@ static void setsegment(struct mem_segment_descriptor *
>      size_t, int, int, int, int);
>  static int elf32_exec(gzFile, Elf32_Ehdr *, u_long *, int);
>  static int elf64_exec(gzFile, Elf64_Ehdr *, u_long *, int);
> -static size_t create_bios_memmap(struct vm_create_params *, bios_memmap_t *);
> +static size_t create_bios_memmap(struct vmop_create_params *, bios_memmap_t *);
>  static uint32_t push_bootargs(bios_memmap_t *, size_t, bios_bootmac_t *);
>  static size_t push_stack(uint32_t, uint32_t);
>  static void push_gdt(void);
> @@ -217,7 +217,6 @@ loadfile_elf(gzFile fp, struct vmd_vm *vm, struct vcpu
>  	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;
> @@ -251,7 +250,7 @@ loadfile_elf(gzFile fp, struct vmd_vm *vm, struct vcpu
>  		bootmac = &bm;
>  		memcpy(bootmac, vm->vm_params.vmc_macs[0], ETHER_ADDR_LEN);
>  	}
> -	n = create_bios_memmap(vcp, memmap);
> +	n = create_bios_memmap(&vm->vm_params, memmap);
>  	bootargsz = push_bootargs(memmap, n, bootmac);
>  	stacksize = push_stack(bootargsz, marks[MARK_END]);
> 
> @@ -270,20 +269,20 @@ loadfile_elf(gzFile fp, struct vmd_vm *vm, struct vcpu
>   * Construct a memory map as returned by the BIOS INT 0x15, e820 routine.
>   *
>   * Parameters:
> - *  vcp: the VM create parameters, containing the memory map passed to vmm(4)
> + *  vmc: the VM create parameters, containing the memory map passed to vmm(4)
>   *   memmap (out): the BIOS memory map
>   *
>   * Return values:
>   * Number of bios_memmap_t entries, including the terminating nul-entry.
>   */
>  static size_t
> -create_bios_memmap(struct vm_create_params *vcp, bios_memmap_t *memmap)
> +create_bios_memmap(struct vmop_create_params *vmc, bios_memmap_t *memmap)
>  {
>  	size_t i, n = 0;
>  	struct vm_mem_range *vmr;
> 
> -	for (i = 0; i < vcp->vcp_nmemranges; i++, n++) {
> -		vmr = &vcp->vcp_memranges[i];
> +	for (i = 0; i < vmc->vmc_nmemranges; i++, n++) {
> +		vmr = &vmc->vmc_memranges[i];
>  		memmap[n].addr = vmr->vmr_gpa;
>  		memmap[n].size = vmr->vmr_size;
>  		if (vmr->vmr_type == VM_MEM_RAM)
> blob - 967583ea5fa26da4f30fe4e6b6c7e9377782621a
> blob + 4a8e2d2166784330be19cbb0c9dedbffa0dd5574
> --- usr.sbin/vmd/parse.y
> +++ usr.sbin/vmd/parse.y
> @@ -92,7 +92,6 @@ int		 parse_disk(char *, int);
>  unsigned int	 parse_format(const char *);
> 
>  static struct vmop_create_params vmc;
> -static struct vm_create_params	*vcp;
>  static struct vmd_switch	*vsw;
>  static char			*kernel = NULL;
>  static char			 vsw_type[IF_NAMESIZE];
> @@ -323,7 +322,6 @@ vm		: VM string vm_instance		{
>  			memset(&vmc, 0, sizeof(vmc));
>  			vmc.vmc_kernel = -1;
> 
> -			vcp = &vmc.vmc_params;
>  			vmc_disable = 0;
>  			vmc_nnics = 0;
> 
> @@ -349,8 +347,8 @@ vm		: VM string vm_instance		{
>  				vmc.vmc_ifflags[i] |= IFF_UP;
>  			}
> 
> -			if (strlcpy(vcp->vcp_name, name,
> -			    sizeof(vcp->vcp_name)) >= sizeof(vcp->vcp_name)) {
> +			if (strlcpy(vmc.vmc_name, name,
> +			    sizeof(vmc.vmc_name)) >= sizeof(vmc.vmc_name)) {
>  				yyerror("vm name too long");
>  				free($2);
>  				free($3);
> @@ -375,12 +373,12 @@ vm		: VM string vm_instance		{
>  					log_debug("%s:%d: vm \"%s\""
>  					    " skipped (%s)",
>  					    file->name, yylval.lineno,
> -					    vcp->vcp_name,
> +					    vmc.vmc_name,
>  					    (vm->vm_state & VM_STATE_RUNNING) ?
>  					    "running" : "already exists");
>  				} else if (ret == -1) {
>  					yyerror("vm \"%s\" failed: %s",
> -					    vcp->vcp_name, strerror(errno));
> +					    vmc.vmc_name, strerror(errno));
>  					YYERROR;
>  				} else {
>  					if (vmc_disable)
> @@ -390,7 +388,7 @@ vm		: VM string vm_instance		{
>  					log_debug("%s:%d: vm \"%s\" "
>  					    "registered (%s)",
>  					    file->name, yylval.lineno,
> -					    vcp->vcp_name,
> +					    vmc.vmc_name,
>  					    vmc_disable ?
>  					    "disabled" : "enabled");
>  				}
> @@ -414,10 +412,10 @@ vm_opts		: disable			{
>  			vmc_disable = $1;
>  		}
>  		| sev				{
> -			vcp->vcp_sev = 1;
> +			vmc.vmc_sev = 1;
>  		}
>  		| seves				{
> -			vcp->vcp_sev = vcp->vcp_seves = 1;
> +			vmc.vmc_sev = vmc.vmc_seves = 1;
>  		}
>  		| DISK string image_format	{
>  			if (parse_disk($2, $3) != 0) {
> @@ -518,7 +516,7 @@ vm_opts		: disable			{
>  		}
>  		| MEMORY NUMBER			{
>  			ssize_t	 res;
> -			if (vcp->vcp_memranges[0].vmr_size != 0) {
> +			if (vmc.vmc_memranges[0].vmr_size != 0) {
>  				yyerror("memory specified more than once");
>  				YYERROR;
>  			}
> @@ -526,12 +524,12 @@ vm_opts		: disable			{
>  				yyerror("failed to parse size: %lld", $2);
>  				YYERROR;
>  			}
> -			vcp->vcp_memranges[0].vmr_size = (size_t)res;
> +			vmc.vmc_memranges[0].vmr_size = (size_t)res;
>  			vmc.vmc_flags |= VMOP_CREATE_MEMORY;
>  		}
>  		| MEMORY STRING			{
>  			ssize_t	 res;
> -			if (vcp->vcp_memranges[0].vmr_size != 0) {
> +			if (vmc.vmc_memranges[0].vmr_size != 0) {
>  				yyerror("argument specified more than once");
>  				free($2);
>  				YYERROR;
> @@ -541,7 +539,7 @@ vm_opts		: disable			{
>  				free($2);
>  				YYERROR;
>  			}
> -			vcp->vcp_memranges[0].vmr_size = (size_t)res;
> +			vmc.vmc_memranges[0].vmr_size = (size_t)res;
>  			vmc.vmc_flags |= VMOP_CREATE_MEMORY;
>  		}
>  		| OWNER owner_id		{
> blob - 196e905aa98f0a31c0108505015c4adca947a8a6
> blob + 100454da36c65a5d70e7f7421abb121038a00b38
> --- usr.sbin/vmd/priv.c
> +++ usr.sbin/vmd/priv.c
> @@ -326,7 +326,6 @@ vm_priv_ifconfig(struct privsep *ps, struct vmd_vm *vm
>  {
>  	char			 name[64];
>  	struct vmd		*env = ps->ps_env;
> -	struct vm_create_params	*vcp = &vm->vm_params.vmc_params;
>  	struct vmd_if		*vif;
>  	struct vmd_switch	*vsw;
>  	unsigned int		 i;
> @@ -347,7 +346,7 @@ vm_priv_ifconfig(struct privsep *ps, struct vmd_vm *vm
> 
>  		/* Description can be truncated */
>  		(void)snprintf(vfr.vfr_value, sizeof(vfr.vfr_value),
> -		    "vm%u-if%u-%s", vm->vm_vmid, i, vcp->vcp_name);
> +		    "vm%u-if%u-%s", vm->vm_vmid, i, vm->vm_params.vmc_name);
> 
>  		log_debug("%s: interface %s description %s", __func__,
>  		    vfr.vfr_name, vfr.vfr_value);
> blob - 77964c495de4f5042c305208a2e79aa172b95803
> blob + eef693d6e863e25f4887c33dca0a8c1fb9b85e42
> --- usr.sbin/vmd/sev.c
> +++ usr.sbin/vmd/sev.c
> @@ -41,12 +41,11 @@ int
>  sev_init(struct vmd_vm *vm)
>  {
>  	struct vmop_create_params *vmc = &vm->vm_params;
> -	struct vm_create_params	*vcp = &vmc->vmc_params;
>  	uint32_t		 handle;
>  	uint16_t		 pstate;
>  	uint8_t			 gstate;
> 
> -	if (!vcp->vcp_sev)
> +	if (!vmc->vmc_sev)
>  		return (0);
> 
>  	if (psp_get_pstate(&pstate, NULL, NULL, NULL, NULL)) {
> @@ -58,7 +57,7 @@ sev_init(struct vmd_vm *vm)
>  		return (-1);
>  	}
> 
> -	if (psp_launch_start(&handle, vcp->vcp_seves) < 0) {
> +	if (psp_launch_start(&handle, vmc->vmc_seves) < 0) {
>  		log_warnx("%s: launch failed", __func__);
>  		return (-1);
>  	}
> @@ -83,15 +82,13 @@ int
>  sev_register_encryption(vaddr_t addr, size_t size)
>  {
>  	struct vmop_create_params *vmc;
> -	struct vm_create_params *vcp;
>  	struct vm_mem_range	*vmr;
>  	size_t			 off;
>  	int			 i;
> 
>  	vmc = &current_vm->vm_params;
> -	vcp = &vmc->vmc_params;
> 
> -	if (!vcp->vcp_sev)
> +	if (!vmc->vmc_sev)
>  		return (0);
> 
>  	if (size == 0)
> @@ -103,7 +100,7 @@ sev_register_encryption(vaddr_t addr, size_t size)
>  		addr &= ~(AES_XTS_BLOCKSIZE - 1);
>  	}
> 
> -	vmr = find_gpa_range(&current_vm->vm_params.vmc_params, addr, size);
> +	vmr = find_gpa_range(&current_vm->vm_params, addr, size);
>  	if (vmr == NULL) {
>  		log_warnx("%s: failed - invalid memory range addr = 0x%lx, "
>  		    "len = 0x%zx", __func__, addr, size);
> @@ -145,11 +142,10 @@ int
>  sev_encrypt_memory(struct vmd_vm *vm)
>  {
>  	struct vmop_create_params *vmc = &vm->vm_params;
> -	struct vm_create_params *vcp = &vmc->vmc_params;
>  	struct vm_mem_range	*vmr;
>  	size_t			 i;
> 
> -	if (!vcp->vcp_sev)
> +	if (!vmc->vmc_sev)
>  		return (0);
> 
>  	for (i = 0; i < vm->vm_sev_nmemsegments; i++) {
> @@ -178,10 +174,9 @@ int
>  sev_activate(struct vmd_vm *vm, int vcpu_id)
>  {
>  	struct vmop_create_params *vmc = &vm->vm_params;
> -	struct vm_create_params *vcp = &vmc->vmc_params;
>  	uint8_t			 gstate;
> 
> -	if (!vcp->vcp_sev)
> +	if (!vmc->vmc_sev)
>  		return (0);
> 
>  	if (psp_df_flush() ||
> @@ -208,13 +203,12 @@ int
>  sev_encrypt_state(struct vmd_vm *vm, int vcpu_id)
>  {
>  	struct vmop_create_params *vmc = &vm->vm_params;
> -	struct vm_create_params *vcp = &vmc->vmc_params;
> 
> -	if (!vcp->vcp_seves)
> +	if (!vmc->vmc_seves)
>  		return (0);
> 
>  	if (psp_encrypt_state(vm->vm_sev_handle, vm->vm_sev_asid[vcpu_id],
> -	    vcp->vcp_id, vcpu_id)) {
> +	    vm->vm_vmmid, vcpu_id)) {
>  		log_warnx("%s: failed to encrypt state: 0x%x 0x%x 0x%0x 0x%0x",
>  		    __func__, vm->vm_sev_handle, vm->vm_sev_asid[vcpu_id],
>  		    vm->vm_vmid, vcpu_id);
> @@ -228,10 +222,9 @@ int
>  sev_launch_finalize(struct vmd_vm *vm)
>  {
>  	struct vmop_create_params *vmc = &vm->vm_params;
> -	struct vm_create_params *vcp = &vmc->vmc_params;
>  	uint8_t		gstate;
> 
> -	if (!vcp->vcp_sev)
> +	if (!vmc->vmc_sev)
>  		return (0);
> 
>  	if (psp_launch_measure(vm->vm_sev_handle)) {
> @@ -262,9 +255,8 @@ int
>  sev_shutdown(struct vmd_vm *vm)
>  {
>  	struct vmop_create_params *vmc = &vm->vm_params;
> -	struct vm_create_params *vcp = &vmc->vmc_params;
> 
> -	if (!vcp->vcp_sev)
> +	if (!vmc->vmc_sev)
>  		return (0);
> 
>  	if (psp_guest_shutdown(vm->vm_sev_handle)) {
> blob - dbebb76e022433696a5894ef63ad3ddd9b6f0adf
> blob + 97b69ab11c6c8dd3311610a560f2c363fec4d695
> --- usr.sbin/vmd/vioblk.c
> +++ usr.sbin/vmd/vioblk.c
> @@ -65,7 +65,6 @@ vioblk_main(int fd, int fd_vmm)
>  	struct vioblk_dev	*vioblk = NULL;
>  	struct viodev_msg 	 msg;
>  	struct vmd_vm		 vm;
> -	struct vm_create_params	*vcp;
>  	ssize_t			 sz;
>  	off_t			 szp = 0;
>  	int			 i, ret, type;
> @@ -109,11 +108,10 @@ vioblk_main(int fd, int fd_vmm)
>  		log_warnx("failed to receive vm details");
>  		goto fail;
>  	}
> -	vcp = &vm.vm_params.vmc_params;
>  	current_vm = &vm;
> 
> -	setproctitle("%s/vioblk%d", vcp->vcp_name, vioblk->idx);
> -	log_procinit("vm/%s/vioblk%d", vcp->vcp_name, vioblk->idx);
> +	setproctitle("%s/vioblk%d", vm.vm_params.vmc_name, vioblk->idx);
> +	log_procinit("vm/%s/vioblk%d", vm.vm_params.vmc_name, vioblk->idx);
> 
>  	/* Now that we have our vm information, we can remap memory. */
>  	ret = remap_guest_mem(&vm, fd_vmm);
> @@ -178,7 +176,8 @@ vioblk_main(int fd, int fd_vmm)
>  	imsg_event_add(&dev.sync_iev);
> 
>  	/* Send a ready message over the sync channel. */
> -	log_debug("%s: telling vm %s device is ready", __func__, vcp->vcp_name);
> +	log_debug("%s: telling vm %s device is ready", __func__,
> +	    vm.vm_params.vmc_name);
>  	memset(&msg, 0, sizeof(msg));
>  	msg.type = VIODEV_MSG_READY;
>  	imsg_compose_event(&dev.sync_iev, IMSG_DEVOP_MSG, 0, 0, -1, &msg,
> blob - 7435db9f8ad7d22fe61ab35f986b03e9652547d7
> blob + 8e50229938b143626337676554a63c4080648cb4
> --- usr.sbin/vmd/vionet.c
> +++ usr.sbin/vmd/vionet.c
> @@ -112,7 +112,6 @@ vionet_main(int fd, int fd_vmm)
>  	struct vionet_dev	*vionet = NULL;
>  	struct viodev_msg 	 msg;
>  	struct vmd_vm	 	 vm;
> -	struct vm_create_params	*vcp;
>  	ssize_t			 sz;
>  	int			 ret;
> 
> @@ -154,10 +153,9 @@ vionet_main(int fd, int fd_vmm)
>  		log_warnx("failed to receive vm details");
>  		goto fail;
>  	}
> -	vcp = &vm.vm_params.vmc_params;
>  	current_vm = &vm;
> -	setproctitle("%s/vionet%d", vcp->vcp_name, vionet->idx);
> -	log_procinit("vm/%s/vionet%d", vcp->vcp_name, vionet->idx);
> +	setproctitle("%s/vionet%d", vm.vm_params.vmc_name, vionet->idx);
> +	log_procinit("vm/%s/vionet%d", vm.vm_params.vmc_name, vionet->idx);
> 
>  	/* Now that we have our vm information, we can remap memory. */
>  	ret = remap_guest_mem(&vm, fd_vmm);
> @@ -238,7 +236,8 @@ vionet_main(int fd, int fd_vmm)
>  	imsg_event_add2(&dev.sync_iev, ev_base_main);
> 
>  	/* Send a ready message over the sync channel. */
> -	log_debug("%s: telling vm %s device is ready", __func__, vcp->vcp_name);
> +	log_debug("%s: telling vm %s device is ready", __func__,
> +	    vm.vm_params.vmc_name);
>  	memset(&msg, 0, sizeof(msg));
>  	msg.type = VIODEV_MSG_READY;
>  	imsg_compose_event2(&dev.sync_iev, IMSG_DEVOP_MSG, 0, 0, -1, &msg,
> blob - ecd033cc7ac0e397936b6d2b1e18dbfbed2aa15f
> blob + 9a1f0ad93de15f1048289c46a7436879e05a6096
> --- usr.sbin/vmd/virtio.c
> +++ usr.sbin/vmd/virtio.c
> @@ -73,8 +73,8 @@ SLIST_HEAD(virtio_dev_head, virtio_dev) virtio_devs;
>  #define RXQ	0
>  #define TXQ	1
> 
> -static void virtio_dev_init(struct virtio_dev *, uint8_t, uint16_t, uint16_t,
> -    uint64_t, uint32_t);
> +static void virtio_dev_init(struct vmd_vm *, struct virtio_dev *, uint8_t,
> +    uint16_t, uint16_t, uint64_t);
>  static int virtio_dev_launch(struct vmd_vm *, struct virtio_dev *);
>  static void virtio_dispatch_dev(int, short, void *);
>  static int handle_dev_msg(struct viodev_msg *, struct virtio_dev *);
> @@ -649,7 +649,7 @@ virtio_io_isr(int dir, uint16_t reg, uint32_t *data, u
>  	if (dir == VEI_DIR_IN) {
>  		*data = dev->isr;
>  		dev->isr = 0;
> -		vcpu_deassert_irq(dev->vm_id, 0, dev->irq);
> +		vcpu_deassert_irq(dev->vmm_id, 0, dev->irq);
>  	}
> 
>  	return (0);
> @@ -750,7 +750,7 @@ vmmci_ctl(struct virtio_dev *dev, unsigned int cmd)
> 
>  		/* Trigger interrupt */
>  		dev->isr = VIRTIO_CONFIG_ISR_CONFIG_CHANGE;
> -		vcpu_assert_irq(dev->vm_id, 0, dev->irq);
> +		vcpu_assert_irq(dev->vmm_id, 0, dev->irq);
> 
>  		/* Add ACK timeout */
>  		tv.tv_sec = VMMCI_TIMEOUT_SHORT;
> @@ -762,7 +762,7 @@ vmmci_ctl(struct virtio_dev *dev, unsigned int cmd)
>  			v->cmd = cmd;
> 
>  			dev->isr = VIRTIO_CONFIG_ISR_CONFIG_CHANGE;
> -			vcpu_assert_irq(dev->vm_id, 0, dev->irq);
> +			vcpu_assert_irq(dev->vmm_id, 0, dev->irq);
>  		} else {
>  			log_debug("%s: RTC sync skipped (guest does not "
>  			    "support RTC sync)\n", __func__);
> @@ -806,7 +806,7 @@ vmmci_ack(struct virtio_dev *dev, unsigned int cmd)
>  		 */
>  		if (v->cmd == 0) {
>  			log_debug("%s: vm %u requested shutdown", __func__,
> -			    dev->vm_id);
> +			    dev->vmm_id);
>  			vm_pipe_send(&v->dev_pipe, VMMCI_SET_TIMEOUT_SHORT);
>  			return;
>  		}
> @@ -821,13 +821,13 @@ vmmci_ack(struct virtio_dev *dev, unsigned int cmd)
>  		 */
>  		if (cmd == v->cmd) {
>  			log_debug("%s: vm %u acknowledged shutdown request",
> -			    __func__, dev->vm_id);
> +			    __func__, dev->vmm_id);
>  			vm_pipe_send(&v->dev_pipe, VMMCI_SET_TIMEOUT_LONG);
>  		}
>  		break;
>  	case VMMCI_SYNCRTC:
>  		log_debug("%s: vm %u acknowledged RTC sync request",
> -		    __func__, dev->vm_id);
> +		    __func__, dev->vmm_id);
>  		v->cmd = VMMCI_NONE;
>  		break;
>  	default:
> @@ -846,7 +846,7 @@ vmmci_timeout(int fd, short type, void *arg)
>  		fatalx("%s: device is not a vmmci device", __func__);
>  	v = &dev->vmmci;
> 
> -	log_debug("vm %u shutdown", dev->vm_id);
> +	log_debug("vm %u shutdown", dev->vmm_id);
>  	vm_shutdown(v->cmd == VMMCI_REBOOT ? VMMCI_REBOOT : VMMCI_SHUTDOWN);
>  }
> 
> @@ -935,7 +935,7 @@ vmmci_io(int dir, uint16_t reg, uint32_t *data, uint8_
>  		case VIRTIO_CONFIG_ISR_STATUS:
>  			*data = dev->isr;
>  			dev->isr = 0;
> -			vcpu_deassert_irq(dev->vm_id, 0, dev->irq);
> +			vcpu_deassert_irq(dev->vmm_id, 0, dev->irq);
>  			break;
>  		}
>  	}
> @@ -990,7 +990,6 @@ virtio_init(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;
>  	struct virtio_dev *dev;
>  	uint8_t id, i, j;
>  	int bar_id, ret = 0;
> @@ -1005,8 +1004,8 @@ virtio_init(struct vmd_vm *vm, int child_cdrom,
>  		log_warnx("can't add PCI virtio rng device");
>  		return (1);
>  	}
> -	virtio_dev_init(&viornd, id, VIORND_QUEUE_SIZE_DEFAULT,
> -	    VIRTIO_RND_QUEUES, VIRTIO_F_VERSION_1, vcp->vcp_id);
> +	virtio_dev_init(vm, &viornd, id, VIORND_QUEUE_SIZE_DEFAULT,
> +	    VIRTIO_RND_QUEUES, VIRTIO_F_VERSION_1);
> 
>  	bar_id = pci_add_bar(id, PCI_MAPREG_TYPE_IO, virtio_io_dispatch,
>  	    &viornd);
> @@ -1033,10 +1032,9 @@ virtio_init(struct vmd_vm *vm, int child_cdrom,
>  				log_warnx("can't add PCI virtio net device");
>  				return (1);
>  			}
> -			virtio_dev_init(dev, id, VIONET_QUEUE_SIZE_DEFAULT,
> +			virtio_dev_init(vm, dev, id, VIONET_QUEUE_SIZE_DEFAULT,
>  			    VIRTIO_NET_QUEUES,
> -			    (VIRTIO_NET_F_MAC | VIRTIO_F_VERSION_1),
> -			    vcp->vcp_id);
> +			    (VIRTIO_NET_F_MAC | VIRTIO_F_VERSION_1));
> 
>  			if (pci_add_bar(id, PCI_MAPREG_TYPE_IO, virtio_pci_io,
>  			    dev) == -1) {
> @@ -1055,7 +1053,7 @@ virtio_init(struct vmd_vm *vm, int child_cdrom,
> 
>  			/* Device specific initializiation. */
>  			dev->dev_type = VMD_DEVTYPE_NET;
> -			dev->vm_vmid = vm->vm_vmid;
> +			dev->vmm_id = vm->vm_vmmid;
>  			dev->vionet.data_fd = child_taps[i];
> 
>  			/* MAC address has been assigned by the parent */
> @@ -1070,7 +1068,7 @@ virtio_init(struct vmd_vm *vm, int child_cdrom,
>  			    &env->vmd_cfg.cfg_localprefix,
>  			    sizeof(dev->vionet.local_prefix));
>  			log_debug("%s: vm \"%s\" vio%u lladdr %s%s%s%s",
> -			    __func__, vcp->vcp_name, i,
> +			    __func__, vm->vm_params.vmc_name, i,
>  			    ether_ntoa((void *)dev->vionet.mac),
>  			    dev->vionet.lockedmac ? ", locked" : "",
>  			    dev->vionet.local ? ", local" : "",
> @@ -1100,10 +1098,9 @@ virtio_init(struct vmd_vm *vm, int child_cdrom,
>  				    "device");
>  				return (1);
>  			}
> -			virtio_dev_init(dev, id, VIOBLK_QUEUE_SIZE_DEFAULT,
> +			virtio_dev_init(vm, dev, id, VIOBLK_QUEUE_SIZE_DEFAULT,
>  			    VIRTIO_BLK_QUEUES,
> -			    (VIRTIO_F_VERSION_1 | VIRTIO_BLK_F_SEG_MAX),
> -			    vcp->vcp_id);
> +			    (VIRTIO_F_VERSION_1 | VIRTIO_BLK_F_SEG_MAX));
> 
>  			bar_id = pci_add_bar(id, PCI_MAPREG_TYPE_IO, virtio_pci_io,
>  			    dev);
> @@ -1123,7 +1120,7 @@ virtio_init(struct vmd_vm *vm, int child_cdrom,
> 
>  			/* Device specific initialization. */
>  			dev->dev_type = VMD_DEVTYPE_DISK;
> -			dev->vm_vmid = vm->vm_vmid;
> +			dev->vmm_id = vm->vm_vmmid;
>  			dev->vioblk.seg_max = VIOBLK_SEG_MAX_DEFAULT;
> 
>  			/*
> @@ -1165,8 +1162,8 @@ virtio_init(struct vmd_vm *vm, int child_cdrom,
>  			log_warnx("can't add PCI vioscsi device");
>  			return (1);
>  		}
> -		virtio_dev_init(dev, id, VIOSCSI_QUEUE_SIZE_DEFAULT,
> -		    VIRTIO_SCSI_QUEUES, VIRTIO_F_VERSION_1, vcp->vcp_id);
> +		virtio_dev_init(vm, dev, id, VIOSCSI_QUEUE_SIZE_DEFAULT,
> +		    VIRTIO_SCSI_QUEUES, VIRTIO_F_VERSION_1);
>  		if (pci_add_bar(id, PCI_MAPREG_TYPE_IO, virtio_io_dispatch, dev)
>  		    == -1) {
>  			log_warnx("can't add bar for vioscsi device");
> @@ -1199,8 +1196,8 @@ virtio_init(struct vmd_vm *vm, int child_cdrom,
>  		log_warnx("can't add PCI vmm control device");
>  		return (1);
>  	}
> -	virtio_dev_init(dev, id, 0, 0,
> -	    VMMCI_F_TIMESYNC | VMMCI_F_ACK | VMMCI_F_SYNCRTC, vcp->vcp_id);
> +	virtio_dev_init(vm, dev, id, 0, 0,
> +	    VMMCI_F_TIMESYNC | VMMCI_F_ACK | VMMCI_F_SYNCRTC);
>  	if (pci_add_bar(id, PCI_MAPREG_TYPE_IO, vmmci_io, dev) == -1) {
>  		log_warnx("can't add bar for vmm control device");
>  		return (1);
> @@ -1346,8 +1343,8 @@ virtio_start(struct vmd_vm *vm)
>   * Initialize a new virtio device structure.
>   */
>  static void
> -virtio_dev_init(struct virtio_dev *dev, uint8_t pci_id, uint16_t queue_size,
> -    uint16_t num_queues, uint64_t features, uint32_t vm_id)
> +virtio_dev_init(struct vmd_vm *vm, struct virtio_dev *dev, uint8_t pci_id,
> +    uint16_t queue_size, uint16_t num_queues, uint64_t features)
>  {
>  	size_t i;
>  	uint16_t device_id;
> @@ -1365,7 +1362,8 @@ virtio_dev_init(struct virtio_dev *dev, uint8_t pci_id
>  	dev->device_id = device_id;
>  	dev->irq = pci_get_dev_irq(pci_id);
>  	dev->isr = 0;
> -	dev->vm_id = vm_id;
> +	dev->vm_id = vm->vm_vmid;
> +	dev->vmm_id = vm->vm_vmmid;
> 
>  	dev->device_feature = features;
> 
> @@ -1478,12 +1476,12 @@ virtio_dev_launch(struct vmd_vm *vm, struct virtio_dev
> 
>  	switch (dev->dev_type) {
>  	case VMD_DEVTYPE_NET:
> -		log_debug("%s: launching vionet%d",
> -		    vm->vm_params.vmc_params.vcp_name, dev->vionet.idx);
> +		log_debug("%s: launching vionet%d", vm->vm_params.vmc_name,
> +		    dev->vionet.idx);
>  		break;
>  	case VMD_DEVTYPE_DISK:
> -		log_debug("%s: launching vioblk%d",
> -		    vm->vm_params.vmc_params.vcp_name, dev->vioblk.idx);
> +		log_debug("%s: launching vioblk%d", vm->vm_params.vmc_name,
> +		    dev->vioblk.idx);
>  		break;
>  		/* NOTREACHED */
>  	default:
> @@ -1542,7 +1540,7 @@ virtio_dev_launch(struct vmd_vm *vm, struct virtio_dev
> 
>  		/* 2. Send over details on the VM (including memory fds). */
>  		log_debug("%s: sending vm message for '%s'", __func__,
> -			vm->vm_params.vmc_params.vcp_name);
> +			vm->vm_params.vmc_name);
>  		sz = atomicio(vwrite, sync_fds[0], vm, sizeof(*vm));
>  		if (sz != sizeof(*vm)) {
>  			log_warnx("%s: failed to send vm details", __func__);
> @@ -1616,7 +1614,7 @@ virtio_dev_launch(struct vmd_vm *vm, struct virtio_dev
>  		snprintf(vmm_fd, sizeof(vmm_fd), "%d", env->vmd_fd);
>  		memset(vm_name, 0, sizeof(vm_name));
>  		snprintf(vm_name, sizeof(vm_name), "%s",
> -		    vm->vm_params.vmc_params.vcp_name);
> +		    vm->vm_params.vmc_name);
> 
>  		t[0] = dev->dev_type;
>  		t[1] = '\0';
> @@ -1745,14 +1743,14 @@ virtio_dispatch_dev(int fd, short event, void *arg)
>  static int
>  handle_dev_msg(struct viodev_msg *msg, struct virtio_dev *gdev)
>  {
> -	uint32_t vm_id = gdev->vm_id;
> +	uint32_t vmm_id = gdev->vmm_id;
> 
>  	switch (msg->type) {
>  	case VIODEV_MSG_KICK:
>  		if (msg->state == INTR_STATE_ASSERT)
> -			vcpu_assert_irq(vm_id, msg->vcpu, msg->irq);
> +			vcpu_assert_irq(vmm_id, msg->vcpu, msg->irq);
>  		else if (msg->state == INTR_STATE_DEASSERT)
> -			vcpu_deassert_irq(vm_id, msg->vcpu, msg->irq);
> +			vcpu_deassert_irq(vmm_id, msg->vcpu, msg->irq);
>  		break;
>  	case VIODEV_MSG_READY:
>  		log_debug("%s: device reports ready", __func__);
> @@ -1851,9 +1849,9 @@ virtio_pci_io(int dir, uint16_t reg, uint32_t *data, u
>  			 * device performs a register read.
>  			 */
>  			if (msg.state == INTR_STATE_ASSERT)
> -				vcpu_assert_irq(dev->vm_id, msg.vcpu, msg.irq);
> +				vcpu_assert_irq(dev->vmm_id, msg.vcpu, msg.irq);
>  			else if (msg.state == INTR_STATE_DEASSERT)
> -				vcpu_deassert_irq(dev->vm_id, msg.vcpu, msg.irq);
> +				vcpu_deassert_irq(dev->vmm_id, msg.vcpu, msg.irq);
>  		} else {
>  			log_warnx("%s: expected IO_READ, got %d", __func__,
>  			    msg.type);
> blob - b7a49b40e0b1255139a130f554d2363eb33d99d1
> blob + 1d7f1d45c684400b5c95c2b70f2cb6a474332c96
> --- usr.sbin/vmd/virtio.h
> +++ usr.sbin/vmd/virtio.h
> @@ -358,7 +358,6 @@ struct virtio_dev {
>  	uint64_t 	driver_feature;		/* driver features [rw] */
> 
>  	uint8_t		pci_id;			/* pci device id [r] */
> -	uint32_t	vm_id;			/* vmm(4) vm identifier [r] */
>  	int		irq;			/* assigned irq [r] */
> 
>  	/* Multi-process emulation fields. */
> @@ -368,7 +367,8 @@ struct virtio_dev {
>  	int sync_fd;				/* fd for synchronous channel */
>  	int async_fd;				/* fd for async channel */
> 
> -	uint32_t	vm_vmid;		/* vmd(8) vm identifier [r] */
> +	uint32_t	vm_id;			/* vmd(8) vm identifier [r] */
> +	uint32_t	vmm_id;			/* vmm(4) vm identifier [r] */
>  	pid_t		dev_pid;		/* pid of emulator process */
>  	char		dev_type;		/* device type (as char) */
>  	SLIST_ENTRY(virtio_dev) dev_next;
> blob - b971c4688b4e47fc5bfe4ad8a26b1cdf2834a8af
> blob + 58bafe332a92f318fec6e82289dd4205fb46b5bc
> --- usr.sbin/vmd/vm.c
> +++ usr.sbin/vmd/vm.c
> @@ -44,7 +44,7 @@
> 
>  #define MMIO_NOTYET 0
> 
> -static int run_vm(struct vmop_create_params *, struct vcpu_reg_state *);
> +static int run_vm(struct vmd_vm *, struct vcpu_reg_state *);
>  static void vm_dispatch_vmm(int, short, void *);
>  static void *event_thread(void *);
>  static void *vcpu_run_loop(void *);
> @@ -82,7 +82,6 @@ uint8_t vcpu_done[VMM_MAX_VCPUS_PER_VM];
>  void
>  vm_main(int fd, int fd_vmm)
>  {
> -	struct vm_create_params	*vcp = NULL;
>  	struct vmd_vm		 vm;
>  	size_t			 sz = 0;
>  	int			 ret = 0;
> @@ -118,9 +117,8 @@ vm_main(int fd, int fd_vmm)
>  	}
> 
>  	/* Update process with the vm name. */
> -	vcp = &vm.vm_params.vmc_params;
> -	setproctitle("%s", vcp->vcp_name);
> -	log_procinit("vm/%s", vcp->vcp_name);
> +	setproctitle("%s", vm.vm_params.vmc_name);
> +	log_procinit("vm/%s", vm.vm_params.vmc_name);
> 
>  	/* Receive the local prefix settings. */
>  	sz = atomicio(read, fd, &env->vmd_cfg.cfg_localprefix,
> @@ -135,11 +133,11 @@ vm_main(int fd, int fd_vmm)
>  	 * kernel or a BIOS image.
>  	 */
>  	if (vm.vm_kernel == -1) {
> -		log_warnx("%s: failed to receive boot fd", vcp->vcp_name);
> +		log_warnx("failed to receive boot fd");
>  		_exit(EINVAL);
>  	}
> 
> -	if (vcp->vcp_sev && env->vmd_psp_fd < 0) {
> +	if (vm.vm_params.vmc_sev && env->vmd_psp_fd < 0) {
>  		log_warnx("%s not available", PSP_NODE);
>  		_exit(EINVAL);
>  	}
> @@ -173,18 +171,15 @@ vm_main(int fd, int fd_vmm)
>  int
>  start_vm(struct vmd_vm *vm, int fd)
>  {
> -	struct vmop_create_params *vmc = &vm->vm_params;
> -	struct vm_create_params	*vcp = &vmc->vmc_params;
>  	struct vcpu_reg_state	 vrs;
> -	int			 nicfds[VM_MAX_NICS_PER_VM];
> -	int			 ret;
> +	int			 ret, nicfds[VM_MAX_NICS_PER_VM];
>  	size_t			 i;
> 
>  	/*
>  	 * We first try to initialize and allocate memory before bothering
>  	 * vmm(4) with a request to create a new vm.
>  	 */
> -	create_memory_map(vcp);
> +	create_memory_map(vm);
> 
>  	/* Create the vm in vmm(4). */
>  	ret = vmm_create_vm(vm);
> @@ -201,8 +196,8 @@ start_vm(struct vmd_vm *vm, int fd)
>  		}
> 
>  		/* Let the vmm process know we failed by sending a 0 vm id. */
> -		vcp->vcp_id = 0;
> -		atomicio(vwrite, fd, &vcp->vcp_id, sizeof(vcp->vcp_id));
> +		vm->vm_vmmid = 0;
> +		atomicio(vwrite, fd, &vm->vm_vmmid, sizeof(vm->vm_vmmid));
>  		return (ret);
>  	}
> 
> @@ -227,8 +222,8 @@ start_vm(struct vmd_vm *vm, int fd)
>  	 * We now let the vmm process know we were successful by sending it our
>  	 * vmm(4) assigned vm id.
>  	 */
> -	if (atomicio(vwrite, fd, &vcp->vcp_id, sizeof(vcp->vcp_id)) !=
> -	    sizeof(vcp->vcp_id)) {
> +	if (atomicio(vwrite, fd, &vm->vm_vmmid, sizeof(vm->vm_vmmid)) !=
> +	    sizeof(vm->vm_vmmid)) {
>  		log_warn("failed to send created vm id to vmm process");
>  		return (1);
>  	}
> @@ -276,7 +271,7 @@ start_vm(struct vmd_vm *vm, int fd)
>  	 */
>  	for (i = 0; i < VMM_MAX_NICS_PER_VM; i++)
>  		nicfds[i] = vm->vm_ifs[i].vif_fd;
> -	ret = init_emulated_hw(vmc, vm->vm_cdrom, vm->vm_disks, nicfds);
> +	ret = init_emulated_hw(vm, vm->vm_cdrom, vm->vm_disks, nicfds);
>  	if (ret) {
>  		virtio_shutdown(vm);
>  		return (ret);
> @@ -289,7 +284,7 @@ start_vm(struct vmd_vm *vm, int fd)
>  	/*
>  	 * Execute the vcpu run loop(s) for this VM.
>  	 */
> -	ret = run_vm(&vm->vm_params, &vrs);
> +	ret = run_vm(vm, &vrs);
> 
>  	/* Shutdown SEV. */
>  	if (sev_shutdown(vm))
> @@ -383,14 +378,14 @@ vm_dispatch_vmm(int fd, short event, void *arg)
>  		case IMSG_VMDOP_PRIV_GET_ADDR_RESPONSE:
>  			vmop_addr_result_read(&imsg, &var);
>  			log_debug("%s: received tap addr %s for nic %d",
> -			    vm->vm_params.vmc_params.vcp_name,
> +			    vm->vm_params.vmc_name,
>  			    ether_ntoa((void *)var.var_addr), var.var_nic_idx);
> 
>  			vionet_set_hostmac(vm, var.var_nic_idx, var.var_addr);
>  			break;
>  		default:
>  			fatalx("%s: got invalid imsg %d from %s", __func__,
> -			    type, vm->vm_params.vmc_params.vcp_name);
> +			    type, vm->vm_params.vmc_name);
>  		}
>  		imsg_free(&imsg);
>  	}
> @@ -440,7 +435,7 @@ pause_vm(struct vmd_vm *vm)
>  	current_vm->vm_state |= VM_STATE_PAUSED;
>  	mutex_unlock(&vm_mtx);
> 
> -	for (n = 0; n < vm->vm_params.vmc_params.vcp_ncpus; n++) {
> +	for (n = 0; n < vm->vm_params.vmc_ncpus; n++) {
>  		ret = pthread_cond_broadcast(&vcpu_run_cond[n]);
>  		if (ret) {
>  			log_warnx("%s: can't broadcast vcpu run cond (%d)",
> @@ -472,7 +467,7 @@ unpause_vm(struct vmd_vm *vm)
>  	current_vm->vm_state &= ~VM_STATE_PAUSED;
>  	mutex_unlock(&vm_mtx);
> 
> -	for (n = 0; n < vm->vm_params.vmc_params.vcp_ncpus; n++) {
> +	for (n = 0; n < vm->vm_params.vmc_ncpus; n++) {
>  		ret = pthread_cond_broadcast(&vcpu_unpause_cond[n]);
>  		if (ret) {
>  			log_warnx("%s: can't broadcast vcpu unpause cond (%d)",
> @@ -535,44 +530,54 @@ vcpu_reset(uint32_t vmid, uint32_t vcpu_id, struct vcp
>  static int
>  vmm_create_vm(struct vmd_vm *vm)
>  {
> -	struct vm_create_params *vcp = &vm->vm_params.vmc_params;
> -	size_t i;
> +	struct vm_create_params		 vcp;
> +	struct vmop_create_params	*vmc = &vm->vm_params;
> +	size_t				 i;
> 
>  	/* Sanity check arguments */
> -	if (vcp->vcp_ncpus > VMM_MAX_VCPUS_PER_VM)
> +	if (vmc->vmc_ncpus > VMM_MAX_VCPUS_PER_VM)
>  		return (EINVAL);
> 
> -	if (vcp->vcp_nmemranges == 0 ||
> -	    vcp->vcp_nmemranges > VMM_MAX_MEM_RANGES)
> +	if (vmc->vmc_nmemranges == 0 ||
> +	    vmc->vmc_nmemranges > VMM_MAX_MEM_RANGES)
>  		return (EINVAL);
> 
> -	if (vm->vm_params.vmc_ndisks > VM_MAX_DISKS_PER_VM)
> +	if (vmc->vmc_ndisks > VM_MAX_DISKS_PER_VM)
>  		return (EINVAL);
> 
> -	if (vm->vm_params.vmc_nnics > VM_MAX_NICS_PER_VM)
> +	if (vmc->vmc_nnics > VM_MAX_NICS_PER_VM)
>  		return (EINVAL);
> 
> -	if (ioctl(env->vmd_fd, VMM_IOC_CREATE, vcp) == -1)
> +	memset(&vcp, 0, sizeof(vcp));
> +	vcp.vcp_nmemranges = vmc->vmc_nmemranges;
> +	vcp.vcp_ncpus = vmc->vmc_ncpus;
> +	memcpy(vcp.vcp_memranges, vmc->vmc_memranges,
> +	    sizeof(vcp.vcp_memranges));
> +	memcpy(vcp.vcp_name, vmc->vmc_name, sizeof(vcp.vcp_name));
> +	vcp.vcp_sev = vmc->vmc_sev;
> +	vcp.vcp_seves = vmc->vmc_seves;
> +
> +	if (ioctl(env->vmd_fd, VMM_IOC_CREATE, &vcp) == -1)
>  		return (errno);
> 
> -	for (i = 0; i < vcp->vcp_ncpus; i++)
> -		vm->vm_sev_asid[i] = vcp->vcp_asid[i];
> +	vm->vm_vmmid = vcp.vcp_id;
> +	for (i = 0; i < vcp.vcp_ncpus; i++)
> +		vm->vm_sev_asid[i] = vcp.vcp_asid[i];
> +	for (i = 0; i < vmc->vmc_nmemranges; i++)
> +		vmc->vmc_memranges[i].vmr_va = vcp.vcp_memranges[i].vmr_va;
> +	vm->vm_poscbit = vcp.vcp_poscbit;
> 
>  	return (0);
>  }
> 
> 
> -	/*
> +/*
>   * run_vm
>   *
>   * Runs the VM whose creation parameters are specified in vcp
>   *
>   * Parameters:
> - *  child_cdrom: previously-opened child ISO disk file descriptor
> - *  child_disks: previously-opened child VM disk file file descriptors
> - *  child_taps: previously-opened child tap file descriptors
> - *  vmc: vmop_create_params struct containing the VM's desired creation
> - *      configuration
> + *  vm:  vm to begin emulating
>   *  vrs: VCPU register state to initialize
>   *
>   * Return values:
> @@ -580,9 +585,9 @@ vmm_create_vm(struct vmd_vm *vm)
>   *  !0 : the VM exited abnormally or failed to start
>   */
>  static int
> -run_vm(struct vmop_create_params *vmc, struct vcpu_reg_state *vrs)
> +run_vm(struct vmd_vm *vm, struct vcpu_reg_state *vrs)
>  {
> -	struct vm_create_params *vcp = &vmc->vmc_params;
> +	struct vmop_create_params *vmc;
>  	uint8_t evdone = 0;
>  	size_t i;
>  	int ret;
> @@ -591,32 +596,31 @@ run_vm(struct vmop_create_params *vmc, struct vcpu_reg
>  	struct vm_run_params **vrp;
>  	void *exit_status;
> 
> -	if (vcp == NULL)
> -		return (EINVAL);
> +	vmc = &vm->vm_params;
> 
> -	if (vcp->vcp_nmemranges == 0 ||
> -	    vcp->vcp_nmemranges > VMM_MAX_MEM_RANGES)
> +	if (vmc->vmc_nmemranges == 0 ||
> +	    vmc->vmc_nmemranges > VMM_MAX_MEM_RANGES)
>  		return (EINVAL);
> 
> -	tid = calloc(vcp->vcp_ncpus, sizeof(pthread_t));
> +	tid = calloc(vmc->vmc_ncpus, sizeof(pthread_t));
>  	if (tid == NULL) {
>  		log_warn("failed to allocate pthread structures");
>  		return (ENOMEM);
>  	}
> -	vrp = calloc(vcp->vcp_ncpus, sizeof(struct vm_run_params *));
> +	vrp = calloc(vmc->vmc_ncpus, sizeof(struct vm_run_params *));
>  	if (vrp == NULL) {
>  		log_warn("failed to allocate vm run params array");
>  		return (ENOMEM);
>  	}
> 
> -	ret = pthread_barrier_init(&vm_pause_barrier, NULL, vcp->vcp_ncpus + 1);
> +	ret = pthread_barrier_init(&vm_pause_barrier, NULL, vmc->vmc_ncpus + 1);
>  	if (ret) {
>  		log_warnx("cannot initialize pause barrier (%d)", ret);
>  		return (ret);
>  	}
> 
>  	log_debug("%s: starting %zu vcpu thread(s) for vm %s", __func__,
> -	    vcp->vcp_ncpus, vcp->vcp_name);
> +	    vmc->vmc_ncpus, vmc->vmc_name);
> 
>  	/*
>  	 * Create and launch one thread for each VCPU. These threads may
> @@ -624,7 +628,7 @@ run_vm(struct vmop_create_params *vmc, struct vcpu_reg
>  	 * in such situations is detected and performed by vmm(4) in the
>  	 * kernel.
>  	 */
> -	for (i = 0 ; i < vcp->vcp_ncpus; i++) {
> +	for (i = 0 ; i < vmc->vmc_ncpus; i++) {
>  		vrp[i] = malloc(sizeof(struct vm_run_params));
>  		if (vrp[i] == NULL) {
>  			log_warn("failed to allocate vm run parameters");
> @@ -637,30 +641,30 @@ run_vm(struct vmop_create_params *vmc, struct vcpu_reg
>  			/* caller will exit, so skip freeing */
>  			return (ENOMEM);
>  		}
> -		vrp[i]->vrp_vm_id = vcp->vcp_id;
> +		vrp[i]->vrp_vm_id = vm->vm_vmmid;
>  		vrp[i]->vrp_vcpu_id = i;
> 
> -		if (vcpu_reset(vcp->vcp_id, i, vrs)) {
> +		if (vcpu_reset(vm->vm_vmmid, i, vrs)) {
>  			log_warnx("cannot reset vcpu %zu", i);
>  			return (EIO);
>  		}
> 
> -		if (sev_activate(current_vm, i)) {
> +		if (sev_activate(vm, i)) {
>  			log_warnx("SEV activatation failed for vcpu %zu", i);
>  			return (EIO);
>  		}
> 
> -		if (sev_encrypt_memory(current_vm)) {
> +		if (sev_encrypt_memory(vm)) {
>  			log_warnx("memory encryption failed for vcpu %zu", i);
>  			return (EIO);
>  		}
> 
> -		if (sev_encrypt_state(current_vm, i)) {
> +		if (sev_encrypt_state(vm, i)) {
>  			log_warnx("state encryption failed for vcpu %zu", i);
>  			return (EIO);
>  		}
> 
> -		if (sev_launch_finalize(current_vm)) {
> +		if (sev_launch_finalize(vm)) {
>  			log_warnx("encryption failed for vcpu %zu", i);
>  			return (EIO);
>  		}
> @@ -705,7 +709,7 @@ run_vm(struct vmop_create_params *vmc, struct vcpu_reg
>  		pthread_set_name_np(tid[i], tname);
>  	}
> 
> -	log_debug("%s: waiting on events for VM %s", __func__, vcp->vcp_name);
> +	log_debug("%s: waiting on events for VM %s", __func__, vmc->vmc_name);
>  	ret = pthread_create(&evtid, NULL, event_thread, &evdone);
>  	if (ret) {
>  		errno = ret;
> @@ -726,7 +730,7 @@ run_vm(struct vmop_create_params *vmc, struct vcpu_reg
>  		 * Did a VCPU thread exit with an error? => return the first one
>  		 */
>  		mutex_lock(&vm_mtx);
> -		for (i = 0; i < vcp->vcp_ncpus; i++) {
> +		for (i = 0; i < vmc->vmc_ncpus; i++) {
>  			if (vcpu_done[i] == 0)
>  				continue;
> 
> @@ -747,19 +751,18 @@ run_vm(struct vmop_create_params *vmc, struct vcpu_reg
>  				return (EIO);
>  			}
> 
> -			log_warnx("vm %d event thread exited unexpectedly",
> -			    vcp->vcp_id);
> +			log_warnx("event thread exited unexpectedly");
>  			return (EIO);
>  		}
> 
>  		/* Did all VCPU threads exit successfully? => return */
>  		mutex_lock(&vm_mtx);
> -		for (i = 0; i < vcp->vcp_ncpus; i++) {
> +		for (i = 0; i < vmc->vmc_ncpus; i++) {
>  			if (vcpu_done[i] == 0)
>  				break;
>  		}
>  		mutex_unlock(&vm_mtx);
> -		if (i == vcp->vcp_ncpus)
> +		if (i == vmc->vmc_ncpus)
>  			break;
> 
>  		/* Some more threads to wait for, start over */
> @@ -928,13 +931,13 @@ vcpu_run_loop(void *arg)
>  }
> 
>  int
> -vcpu_intr(uint32_t vm_id, uint32_t vcpu_id, uint8_t intr)
> +vcpu_intr(uint32_t vmm_id, uint32_t vcpu_id, uint8_t intr)
>  {
>  	struct vm_intr_params vip;
> 
>  	memset(&vip, 0, sizeof(vip));
> 
> -	vip.vip_vm_id = vm_id;
> +	vip.vip_vm_id = vmm_id;
>  	vip.vip_vcpu_id = vcpu_id; /* XXX always 0? */
>  	vip.vip_intr = intr;
> 
> @@ -1096,7 +1099,6 @@ int
>  remap_guest_mem(struct vmd_vm *vm, int vmm_fd)
>  {
>  	size_t i;
> -	struct vm_create_params	*vcp = &vm->vm_params.vmc_params;
>  	struct vm_sharemem_params vsp;
> 
>  	if (vm == NULL)
> @@ -1104,9 +1106,9 @@ remap_guest_mem(struct vmd_vm *vm, int vmm_fd)
> 
>  	/* Initialize using our original creation parameters. */
>  	memset(&vsp, 0, sizeof(vsp));
> -	vsp.vsp_nmemranges = vcp->vcp_nmemranges;
> -	vsp.vsp_vm_id = vcp->vcp_id;
> -	memcpy(&vsp.vsp_memranges, &vcp->vcp_memranges,
> +	vsp.vsp_nmemranges = vm->vm_params.vmc_nmemranges;
> +	vsp.vsp_vm_id = vm->vm_vmmid;
> +	memcpy(&vsp.vsp_memranges, &vm->vm_params.vmc_memranges,
>  	    sizeof(vsp.vsp_memranges));
> 
>  	/* Ask vmm(4) to enter a shared mapping to guest memory. */
> @@ -1115,7 +1117,7 @@ remap_guest_mem(struct vmd_vm *vm, int vmm_fd)
> 
>  	/* Update with the location of the new mappings. */
>  	for (i = 0; i < vsp.vsp_nmemranges; i++)
> -		vcp->vcp_memranges[i].vmr_va = vsp.vsp_va[i];
> +		vm->vm_params.vmc_memranges[i].vmr_va = vsp.vsp_va[i];
> 
>  	return (0);
>  }
> blob - 13b7ccf9ef324f6e99f85974d6e51024b8fee28d
> blob + 9b6f58ded8cd0c8c41f993255f677cde2094e771
> --- usr.sbin/vmd/vm_agentx.c
> +++ usr.sbin/vmd/vm_agentx.c
> @@ -183,14 +183,14 @@ vm_agentx_dispatch_parent(int fd, struct privsep_proc
>  			    vmIndex);
>  			rtype = agentx_varbind_request(vminfo[i]);
>  			for (j = 0; j < nvir; j++) {
> -				if (vir[j].vir_info.vir_id < index)
> +				if (vir[j].vir_id < index)
>  					continue;
> -				if (vir[j].vir_info.vir_id == index &&
> +				if (vir[j].vir_id == index &&
>  				    (rtype == AGENTX_REQUEST_TYPE_GET ||
>  				    rtype ==
>  				    AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE))
>  					break;
> -				if (vir[j].vir_info.vir_id > index &&
> +				if (vir[j].vir_id > index &&
>  				    (rtype == AGENTX_REQUEST_TYPE_GETNEXT ||
>  				    rtype ==
>  				    AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE))
> @@ -202,10 +202,10 @@ vm_agentx_dispatch_parent(int fd, struct privsep_proc
>  			}
>  			mvir = &(vir[j]);
>  			agentx_varbind_set_index_integer(vminfo[i], vmIndex,
> -			    mvir->vir_info.vir_id);
> +			    mvir->vir_id);
>  			if (reqObject == vmName)
>  				agentx_varbind_string(vminfo[i],
> -				    mvir->vir_info.vir_name);
> +				    mvir->vir_name);
>  			else if (reqObject == vmUUID)
>  				agentx_varbind_string(vminfo[i], "");
>  			else if (reqObject == vmOSType)
> @@ -228,17 +228,17 @@ vm_agentx_dispatch_parent(int fd, struct privsep_proc
>  			    reqObject == vmMinCpuNumber ||
>  			    reqObject == vmMaxCpuNumber)
>  				agentx_varbind_integer(vminfo[i],
> -				    mvir->vir_info.vir_ncpus);
> +				    mvir->vir_ncpus);
>  			else if (reqObject == vmMemUnit)
>  				agentx_varbind_integer(vminfo[i], MEM_SCALE);
>  			else if (reqObject == vmCurMem)
>  				agentx_varbind_integer(vminfo[i],
> -				    mvir->vir_info.vir_used_size / MEM_SCALE);
> +				    mvir->vir_used_size / MEM_SCALE);
>  			else if (reqObject == vmMinMem)
>  				agentx_varbind_integer(vminfo[i], -1);
>  			else if (reqObject == vmMaxMem)
>  				agentx_varbind_integer(vminfo[i],
> -				    mvir->vir_info.vir_memory_size / MEM_SCALE);
> +				    mvir->vir_memory_size / MEM_SCALE);
>  /* We probably had a reload */
>  			else
>  				agentx_varbind_notfound(vminfo[i]);
> @@ -433,8 +433,7 @@ vm_agentx_sortvir(const void *c1, const void *c2)
>  {
>  	const struct vmop_info_result *v1 = c1, *v2 = c2;
> 
> -	return (v1->vir_info.vir_id < v2->vir_info.vir_id ? -1 :
> -	    v1->vir_info.vir_id > v2->vir_info.vir_id);
> +	return (v1->vir_id < v2->vir_id ? -1 : v1->vir_id > v2->vir_id);
>  }
> 
>  static int
> blob - f69738bbe98955b73c542519f0d822d527101a26
> blob + de3cfa7cf57999ad863e939dd93fb73138ed6a89
> --- usr.sbin/vmd/vmd.c
> +++ usr.sbin/vmd/vmd.c
> @@ -283,8 +283,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struc
>  {
>  	struct vmop_result	 vmr;
>  	struct privsep		*ps = p->p_ps;
> -	struct vmd_vm		*vm;
> -	struct vm_create_params	*vcp;
> +	struct vmd_vm		*vm = NULL;
>  	struct vmop_info_result	 vir;
>  	uint32_t		 peer_id, type;
> 
> @@ -299,7 +298,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struc
>  		proc_compose_imsg(ps, PROC_CONTROL, type, vm->vm_peerid, -1,
>  		    &vmr, sizeof(vmr));
>  		log_info("%s: paused vm %d successfully",
> -		    vm->vm_params.vmc_params.vcp_name, vm->vm_vmid);
> +		    vm->vm_params.vmc_name, vm->vm_vmid);
>  		vm->vm_state |= VM_STATE_PAUSED;
>  		break;
>  	case IMSG_VMDOP_UNPAUSE_VM_RESPONSE:
> @@ -309,7 +308,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struc
>  		proc_compose_imsg(ps, PROC_CONTROL, type, vm->vm_peerid, -1,
>  		    &vmr, sizeof(vmr));
>  		log_info("%s: unpaused vm %d successfully.",
> -		    vm->vm_params.vmc_params.vcp_name, vm->vm_vmid);
> +		    vm->vm_params.vmc_name, vm->vm_vmid);
>  		vm->vm_state &= ~VM_STATE_PAUSED;
>  		break;
>  	case IMSG_VMDOP_START_VM_RESPONSE:
> @@ -317,8 +316,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struc
>  		if ((vm = vm_getbyvmid(vmr.vmr_id)) == NULL)
>  			break;
>  		vm->vm_pid = vmr.vmr_pid;
> -		vcp = &vm->vm_params.vmc_params;
> -		vcp->vcp_id = vmr.vmr_id;
> +		vm->vm_vmmid = vmr.vmr_id;
> 
>  		/*
>  		 * If the peerid is not -1, forward the response back to the
> @@ -332,14 +330,15 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struc
>  			    vm->vm_peerid, -1, &vmr, sizeof(vmr)) == -1) {
>  				errno = vmr.vmr_result;
>  				log_warn("%s: failed to forward vm result",
> -				    vcp->vcp_name);
> +				    vm->vm_params.vmc_name);
>  				vm_terminate(vm, __func__);
>  				return (-1);
>  			}
>  		}
> 
>  		if (vmr.vmr_result) {
> -			log_warnx("%s: failed to start vm", vcp->vcp_name);
> +			log_warnx("%s: failed to start vm",
> +			    vm->vm_params.vmc_name);
>  			vm_terminate(vm, __func__);
>  			errno = vmr.vmr_result;
>  			break;
> @@ -347,13 +346,14 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struc
> 
>  		/* Now configure all the interfaces */
>  		if (vm_priv_ifconfig(ps, vm) == -1) {
> -			log_warn("%s: failed to configure vm", vcp->vcp_name);
> +			log_warn("%s: failed to configure vm",
> +			    vm->vm_params.vmc_name);
>  			vm_terminate(vm, __func__);
>  			break;
>  		}
> 
>  		log_info("started %s (vm %d) successfully, tty %s",
> -		    vcp->vcp_name, vm->vm_vmid, vm->vm_ttyname);
> +		    vm->vm_params.vmc_name, vm->vm_vmid, vm->vm_ttyname);
>  		break;
>  	case IMSG_VMDOP_TERMINATE_VM_RESPONSE:
>  		vmop_result_read(imsg, &vmr);
> @@ -397,7 +397,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struc
>  		break;
>  	case IMSG_VMDOP_GET_INFO_VM_DATA:
>  		vmop_info_result_read(imsg, &vir);
> -		if ((vm = vm_getbyvmid(vir.vir_info.vir_id)) != NULL) {
> +		if ((vm = vm_getbyvmid(vir.vir_id)) != NULL) {
>  			memset(vir.vir_ttyname, 0, sizeof(vir.vir_ttyname));
>  			if (vm->vm_ttyname[0] != '\0')
>  				strlcpy(vir.vir_ttyname, vm->vm_ttyname,
> @@ -426,15 +426,12 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struc
>  		TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) {
>  			if (!(vm->vm_state & VM_STATE_RUNNING)) {
>  				memset(&vir, 0, sizeof(vir));
> -				vir.vir_info.vir_id = vm->vm_vmid;
> -				strlcpy(vir.vir_info.vir_name,
> -				    vm->vm_params.vmc_params.vcp_name,
> -				    VMM_MAX_NAME_LEN);
> -				vir.vir_info.vir_memory_size =
> -				    vm->vm_params.vmc_params.
> -				    vcp_memranges[0].vmr_size;
> -				vir.vir_info.vir_ncpus =
> -				    vm->vm_params.vmc_params.vcp_ncpus;
> +				vir.vir_id = vm->vm_vmid;
> +				strlcpy(vir.vir_name, vm->vm_params.vmc_name,
> +				    sizeof(vir.vir_name));
> +				vir.vir_memory_size =
> +				    vm->vm_params.vmc_memranges[0].vmr_size;
> +				vir.vir_ncpus = vm->vm_params.vmc_ncpus;
>  				/* get the configured user id for this vm */
>  				vir.vir_uid = vm->vm_params.vmc_owner.uid;
>  				vir.vir_gid = vm->vm_params.vmc_owner.gid;
> @@ -748,8 +745,7 @@ start_vm_batch(int fd, short type, void *args)
>  	TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) {
>  		if (!(vm->vm_state & VM_STATE_WAITING)) {
>  			log_debug("%s: not starting vm %s (disabled)",
> -			    __func__,
> -			    vm->vm_params.vmc_params.vcp_name);
> +			    __func__, vm->vm_params.vmc_name);
>  			continue;
>  		}
>  		i++;
> @@ -944,13 +940,14 @@ vm_getbyvmid(uint32_t vmid)
>  	if (vmid == 0)
>  		return (NULL);
>  	TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) {
> -		if (vm->vm_vmid == vmid)
> +		if (vm->vm_vmid == vmid)	// XXX check this
>  			return (vm);
>  	}
> 
>  	return (NULL);
>  }
> 
> +/* Find a vm in the list by it's vmm(4) id. */
>  struct vmd_vm *
>  vm_getbyid(uint32_t id)
>  {
> @@ -959,13 +956,14 @@ vm_getbyid(uint32_t id)
>  	if (id == 0)
>  		return (NULL);
>  	TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) {
> -		if (vm->vm_params.vmc_params.vcp_id == id)
> +		if (vm->vm_vmmid == id)	// XXX check this
>  			return (vm);
>  	}
> 
>  	return (NULL);
>  }
> 
> +/* Translate a kernel/vmm(4) vm id to a vmd(8) id. */
>  uint32_t
>  vm_id2vmid(uint32_t id, struct vmd_vm *vm)
>  {
> @@ -981,9 +979,8 @@ vm_vmid2id(uint32_t vmid, struct vmd_vm *vm)
>  {
>  	if (vm == NULL && (vm = vm_getbyvmid(vmid)) == NULL)
>  		return (0);
> -	DPRINTF("%s: vmid %u is vmm id %u", __func__,
> -	    vmid, vm->vm_params.vmc_params.vcp_id);
> -	return (vm->vm_params.vmc_params.vcp_id);
> +	DPRINTF("%s: vmid %u is vmm id %u", __func__, vmid, vm->vm_vmmid);
> +	return (vm->vm_vmmid);
>  }
> 
>  struct vmd_vm *
> @@ -994,7 +991,7 @@ vm_getbyname(const char *name)
>  	if (name == NULL)
>  		return (NULL);
>  	TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) {
> -		if (strcmp(vm->vm_params.vmc_params.vcp_name, name) == 0)
> +		if (strcmp(vm->vm_params.vmc_name, name) == 0)
>  			return (vm);
>  	}
> 
> @@ -1123,7 +1120,6 @@ vm_register(struct privsep *ps, struct vmop_create_par
>      struct vmd_vm **ret_vm, uint32_t id, uid_t uid)
>  {
>  	struct vmd_vm		*vm = NULL, *vm_parent = NULL;
> -	struct vm_create_params	*vcp = &vmc->vmc_params;
>  	struct vmop_owner	*vmo = NULL;
>  	uint32_t		 nid, rng;
>  	unsigned int		 i, j;
> @@ -1140,8 +1136,8 @@ vm_register(struct privsep *ps, struct vmop_create_par
>  	errno = 0;
>  	*ret_vm = NULL;
> 
> -	if ((vm = vm_getbyname(vcp->vcp_name)) != NULL ||
> -	    (vm = vm_getbyvmid(vcp->vcp_id)) != NULL) {
> +	if ((vm = vm_getbyname(vmc->vmc_name)) != NULL ||
> +	    (vm = vm_getbyvmid(vmc->vmc_id)) != NULL) {
>  		if (vm_checkperm(vm, &vm->vm_params.vmc_owner,
>  		    uid) != 0) {
>  			errno = EPERM;
> @@ -1167,11 +1163,11 @@ vm_register(struct privsep *ps, struct vmop_create_par
>  		errno = VMD_DISK_MISSING;
>  		goto fail;
>  	}
> -	if (vcp->vcp_ncpus == 0)
> -		vcp->vcp_ncpus = 1;
> -	if (vcp->vcp_memranges[0].vmr_size == 0)
> -		vcp->vcp_memranges[0].vmr_size = VM_DEFAULT_MEMORY;
> -	if (vcp->vcp_ncpus > VMM_MAX_VCPUS_PER_VM) {
> +	if (vmc->vmc_ncpus == 0)
> +		vmc->vmc_ncpus = 1;
> +	if (vmc->vmc_memranges[0].vmr_size == 0)
> +		vmc->vmc_memranges[0].vmr_size = VM_DEFAULT_MEMORY;
> +	if (vmc->vmc_ncpus > VMM_MAX_VCPUS_PER_VM) {
>  		log_warnx("invalid number of CPUs");
>  		goto fail;
>  	} else if (vmc->vmc_ndisks > VM_MAX_DISKS_PER_VM) {
> @@ -1184,15 +1180,15 @@ vm_register(struct privsep *ps, struct vmop_create_par
>  	    && strlen(vmc->vmc_cdrom) == 0) {
>  		log_warnx("no kernel or disk/cdrom specified");
>  		goto fail;
> -	} else if (strlen(vcp->vcp_name) == 0) {
> +	} else if (strlen(vmc->vmc_name) == 0) {
>  		log_warnx("invalid VM name");
>  		goto fail;
> -	} else if (*vcp->vcp_name == '-' || *vcp->vcp_name == '.' ||
> -	    *vcp->vcp_name == '_') {
> +	} else if (*vmc->vmc_name == '-' || *vmc->vmc_name == '.' ||
> +	    *vmc->vmc_name == '_') {
>  		log_warnx("invalid VM name");
>  		goto fail;
>  	} else {
> -		for (s = vcp->vcp_name; *s != '\0'; ++s) {
> +		for (s = vmc->vmc_name; *s != '\0'; ++s) {
>  			if (!(isalnum((unsigned char)*s) || *s == '.' || \
>  			    *s == '-' || *s == '_')) {
>  				log_warnx("invalid VM name");
> @@ -1206,7 +1202,6 @@ vm_register(struct privsep *ps, struct vmop_create_par
> 
>  	memcpy(&vm->vm_params, vmc, sizeof(vm->vm_params));
>  	vmc = &vm->vm_params;
> -	vcp = &vmc->vmc_params;
>  	vm->vm_pid = -1;
>  	vm->vm_tty = -1;
>  	vm->vm_kernel = -1;
> @@ -1252,7 +1247,7 @@ vm_register(struct privsep *ps, struct vmop_create_par
>  	 */
>  	if (id != 0)
>  		vm->vm_vmid = id;
> -	else if (vm_claimid(vcp->vcp_name, uid, &nid) == -1)
> +	else if (vm_claimid(vmc->vmc_name, uid, &nid) == -1)
>  		goto fail;
>  	else
>  		vm->vm_vmid = nid;
> @@ -1272,69 +1267,63 @@ int
>  vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
>      struct vmop_create_params *vmc, uid_t uid)
>  {
> -	char			*name;
> -	struct vm_create_params	*vcp = &vmc->vmc_params;
> -	struct vmop_create_params *vmcp;
> -	struct vm_create_params	*vcpp;
> -	unsigned int		 i, j;
> +	char				*name;
> +	struct vmop_create_params	*vmc_parent;
> +	unsigned int			 i, j;
> 
>  	/* return without error if the parent is NULL (nothing to inherit) */
>  	if ((vmc->vmc_flags & VMOP_CREATE_INSTANCE) == 0 ||
>  	    vmc->vmc_instance[0] == '\0')
>  		return (0);
> 
> -	if ((*vm_parent = vm_getbyname(vmc->vmc_instance)) == NULL) {
> +	if ((*vm_parent = vm_getbyname(vmc->vmc_instance)) == NULL)
>  		return (VMD_PARENT_INVALID);
> -	}
> 
> -	vmcp = &(*vm_parent)->vm_params;
> -	vcpp = &vmcp->vmc_params;
> +	vmc_parent = &(*vm_parent)->vm_params;
> 
>  	/* Are we allowed to create an instance from this VM? */
> -	if (vm_checkperm(NULL, &vmcp->vmc_insowner, uid) != 0) {
> +	if (vm_checkperm(NULL, &vmc_parent->vmc_insowner, uid) != 0) {
>  		log_warnx("vm \"%s\" no permission to create vm instance",
> -		    vcpp->vcp_name);
> +		    vmc->vmc_name);
>  		return (ENAMETOOLONG);
>  	}
> 
> -	name = vcp->vcp_name;
> +	name = vmc->vmc_name;
> 
> -	if (vm_getbyname(vcp->vcp_name) != NULL ||
> -	    vm_getbyvmid(vcp->vcp_id) != NULL) {
> +	if (vm_getbyname(name) != NULL || vm_getbyvmid(vmc->vmc_id) != NULL)
>  		return (EPROCLIM);
> -	}
> 
>  	/* CPU */
> -	if (vcp->vcp_ncpus == 0)
> -		vcp->vcp_ncpus = vcpp->vcp_ncpus;
> -	if (vm_checkinsflag(vmcp, VMOP_CREATE_CPU, uid) != 0 &&
> -	    vcp->vcp_ncpus != vcpp->vcp_ncpus) {
> +	if (vmc->vmc_ncpus == 0)
> +		vmc->vmc_ncpus = vmc_parent->vmc_ncpus;
> +	if (vm_checkinsflag(vmc_parent, VMOP_CREATE_CPU, uid) != 0 &&
> +	    vmc->vmc_ncpus != vmc_parent->vmc_ncpus) {
>  		log_warnx("vm \"%s\" no permission to set cpus", name);
>  		return (EPERM);
>  	}
> 
>  	/* memory */
> -	if (vcp->vcp_memranges[0].vmr_size == 0)
> -		vcp->vcp_memranges[0].vmr_size =
> -		    vcpp->vcp_memranges[0].vmr_size;
> -	if (vm_checkinsflag(vmcp, VMOP_CREATE_MEMORY, uid) != 0 &&
> -	    vcp->vcp_memranges[0].vmr_size !=
> -	    vcpp->vcp_memranges[0].vmr_size) {
> +	if (vmc->vmc_memranges[0].vmr_size == 0)
> +		vmc->vmc_memranges[0].vmr_size =
> +		    vmc_parent->vmc_memranges[0].vmr_size;
> +	if (vm_checkinsflag(vmc_parent, VMOP_CREATE_MEMORY, uid) != 0 &&
> +	    vmc->vmc_memranges[0].vmr_size !=
> +	    vmc_parent->vmc_memranges[0].vmr_size) {
>  		log_warnx("vm \"%s\" no permission to set memory", name);
>  		return (EPERM);
>  	}
> 
>  	/* disks cannot be inherited */
> -	if (vm_checkinsflag(vmcp, VMOP_CREATE_DISK, uid) != 0 &&
> +	if (vm_checkinsflag(vmc_parent, VMOP_CREATE_DISK, uid) != 0 &&
>  	    vmc->vmc_ndisks) {
>  		log_warnx("vm \"%s\" no permission to set disks", name);
>  		return (EPERM);
>  	}
>  	for (i = 0; i < vmc->vmc_ndisks; i++) {
>  		/* Check if this disk is already used in the parent */
> -		for (j = 0; j < vmcp->vmc_ndisks; j++) {
> +		for (j = 0; j < vmc_parent->vmc_ndisks; j++) {
>  			if (strcmp(vmc->vmc_disks[i],
> -			    vmcp->vmc_disks[j]) == 0) {
> +			    vmc_parent->vmc_disks[j]) == 0) {
>  				log_warnx("vm \"%s\" disk %s cannot be reused",
>  				    name, vmc->vmc_disks[i]);
>  				return (EBUSY);
> @@ -1345,34 +1334,34 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_par
> 
>  	/* interfaces */
>  	if (vmc->vmc_nnics > 0 &&
> -	    vm_checkinsflag(vmcp, VMOP_CREATE_NETWORK, uid) != 0 &&
> -	    vmc->vmc_nnics != vmcp->vmc_nnics) {
> +	    vm_checkinsflag(vmc_parent, VMOP_CREATE_NETWORK, uid) != 0 &&
> +	    vmc->vmc_nnics != vmc_parent->vmc_nnics) {
>  		log_warnx("vm \"%s\" no permission to set interfaces", name);
>  		return (EPERM);
>  	}
> -	for (i = 0; i < vmcp->vmc_nnics; i++) {
> +	for (i = 0; i < vmc_parent->vmc_nnics; i++) {
>  		/* Interface got overwritten */
>  		if (i < vmc->vmc_nnics)
>  			continue;
> 
>  		/* Copy interface from parent */
> -		vmc->vmc_ifflags[i] = vmcp->vmc_ifflags[i];
> -		(void)strlcpy(vmc->vmc_ifnames[i], vmcp->vmc_ifnames[i],
> +		vmc->vmc_ifflags[i] = vmc_parent->vmc_ifflags[i];
> +		(void)strlcpy(vmc->vmc_ifnames[i], vmc_parent->vmc_ifnames[i],
>  		    sizeof(vmc->vmc_ifnames[i]));
> -		(void)strlcpy(vmc->vmc_ifswitch[i], vmcp->vmc_ifswitch[i],
> +		(void)strlcpy(vmc->vmc_ifswitch[i], vmc_parent->vmc_ifswitch[i],
>  		    sizeof(vmc->vmc_ifswitch[i]));
> -		(void)strlcpy(vmc->vmc_ifgroup[i], vmcp->vmc_ifgroup[i],
> +		(void)strlcpy(vmc->vmc_ifgroup[i], vmc_parent->vmc_ifgroup[i],
>  		    sizeof(vmc->vmc_ifgroup[i]));
> -		memcpy(vmc->vmc_macs[i], vmcp->vmc_macs[i],
> +		memcpy(vmc->vmc_macs[i], vmc_parent->vmc_macs[i],
>  		    sizeof(vmc->vmc_macs[i]));
> -		vmc->vmc_ifrdomain[i] = vmcp->vmc_ifrdomain[i];
> +		vmc->vmc_ifrdomain[i] = vmc_parent->vmc_ifrdomain[i];
>  		vmc->vmc_nnics++;
>  	}
>  	for (i = 0; i < vmc->vmc_nnics; i++) {
> -		for (j = 0; j < vmcp->vmc_nnics; j++) {
> +		for (j = 0; j < vmc_parent->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],
> +			    memcmp(vmc_parent->vmc_macs[i], vmc->vmc_macs[i],
>  			    sizeof(vmc->vmc_macs[i])) != 0) {
>  				log_warnx("vm \"%s\" lladdr cannot be reused",
>  				    name);
> @@ -1380,7 +1369,7 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_par
>  			}
>  			if (strlen(vmc->vmc_ifnames[i]) &&
>  			    strcmp(vmc->vmc_ifnames[i],
> -			    vmcp->vmc_ifnames[j]) == 0) {
> +			    vmc_parent->vmc_ifnames[j]) == 0) {
>  				log_warnx("vm \"%s\" %s cannot be reused",
>  				    vmc->vmc_ifnames[i], name);
>  				return (EBUSY);
> @@ -1391,7 +1380,7 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_par
>  	/* kernel */
>  	if (vmc->vmc_kernel > -1 || ((*vm_parent)->vm_kernel_path != NULL &&
>  		strnlen((*vm_parent)->vm_kernel_path, PATH_MAX) < PATH_MAX)) {
> -		if (vm_checkinsflag(vmcp, VMOP_CREATE_KERNEL, uid) != 0) {
> +		if (vm_checkinsflag(vmc_parent, VMOP_CREATE_KERNEL, uid) != 0) {
>  			log_warnx("vm \"%s\" no permission to set boot image",
>  			    name);
>  			return (EPERM);
> @@ -1401,12 +1390,12 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_par
> 
>  	/* cdrom */
>  	if (strlen(vmc->vmc_cdrom) > 0) {
> -		if (vm_checkinsflag(vmcp, VMOP_CREATE_CDROM, uid) != 0) {
> +		if (vm_checkinsflag(vmc_parent, 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(vmc->vmc_cdrom, vmcp->vmc_cdrom,
> +	} else if (strlcpy(vmc->vmc_cdrom, vmc_parent->vmc_cdrom,
>  	    sizeof(vmc->vmc_cdrom)) >= sizeof(vmc->vmc_cdrom)) {
>  		log_warnx("vm \"%s\" cdrom name too long", name);
>  		return (EINVAL);
> @@ -1414,17 +1403,17 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_par
> 
>  	/* user */
>  	if (vmc->vmc_owner.uid == 0)
> -		vmc->vmc_owner.uid = vmcp->vmc_owner.uid;
> +		vmc->vmc_owner.uid = vmc_parent->vmc_owner.uid;
>  	else if (vmc->vmc_owner.uid != uid &&
> -	    vmc->vmc_owner.uid != vmcp->vmc_owner.uid) {
> +	    vmc->vmc_owner.uid != vmc_parent->vmc_owner.uid) {
>  		log_warnx("vm \"%s\" user mismatch", name);
>  		return (EPERM);
>  	}
> 
>  	/* group */
>  	if (vmc->vmc_owner.gid == 0)
> -		vmc->vmc_owner.gid = vmcp->vmc_owner.gid;
> -	else if (vmc->vmc_owner.gid != vmcp->vmc_owner.gid) {
> +		vmc->vmc_owner.gid = vmc_parent->vmc_owner.gid;
> +	else if (vmc->vmc_owner.gid != vmc_parent->vmc_owner.gid) {
>  		log_warnx("vm \"%s\" group mismatch", name);
>  		return (EPERM);
>  	}
> @@ -1434,10 +1423,10 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_par
>  		log_warnx("vm \"%s\" cannot change instance permissions", name);
>  		return (EPERM);
>  	}
> -	if (vmcp->vmc_insflags & VMOP_CREATE_INSTANCE) {
> -		vmc->vmc_insowner.gid = vmcp->vmc_insowner.gid;
> -		vmc->vmc_insowner.uid = vmcp->vmc_insowner.gid;
> -		vmc->vmc_insflags = vmcp->vmc_insflags;
> +	if (vmc_parent->vmc_insflags & VMOP_CREATE_INSTANCE) {
> +		vmc->vmc_insowner.gid = vmc_parent->vmc_insowner.gid;
> +		vmc->vmc_insowner.uid = vmc_parent->vmc_insowner.gid;
> +		vmc->vmc_insflags = vmc_parent->vmc_insflags;
>  	} else {
>  		vmc->vmc_insowner.gid = 0;
>  		vmc->vmc_insowner.uid = 0;
> @@ -1647,9 +1636,8 @@ vm_opentty(struct vmd_vm *vm)
>  		gid = 0;
>  	}
> 
> -	log_debug("%s: vm %s tty %s uid %d gid %d mode %o",
> -	    __func__, vm->vm_params.vmc_params.vcp_name,
> -	    vm->vm_ttyname, uid, gid, mode);
> +	log_debug("%s: vm %s tty %s uid %d gid %d mode %o", __func__,
> +	    vm->vm_params.vmc_name, vm->vm_ttyname, uid, gid, mode);
> 
>  	/*
>  	 * Change ownership and mode of the tty as required.
> @@ -1825,14 +1813,10 @@ vmop_result_read(struct imsg *imsg, struct vmop_result
>  void
>  vmop_info_result_read(struct imsg *imsg, struct vmop_info_result *vir)
>  {
> -	struct vm_info_result *r;
> -
>  	if (imsg_get_data(imsg, vir, sizeof(*vir)))
>  		fatal("%s", __func__);
> 
> -	r = &vir->vir_info;
> -	r->vir_name[sizeof(r->vir_name) - 1] = '\0';
> -
> +	vir->vir_name[sizeof(vir->vir_name) - 1] = '\0';
>  	vir->vir_ttyname[sizeof(vir->vir_ttyname) - 1] = '\0';
>  }
> 
> @@ -1879,14 +1863,12 @@ vmop_owner_read(struct imsg *imsg, struct vmop_owner *
>  void
>  vmop_create_params_read(struct imsg *imsg, struct vmop_create_params *vmc)
>  {
> -	struct vm_create_params *vcp;
>  	size_t i, n;
> 
>  	if (imsg_get_data(imsg, vmc, sizeof(*vmc)))
>  		fatal("%s", __func__);
> 
> -	vcp = &vmc->vmc_params;
> -	vcp->vcp_name[sizeof(vcp->vcp_name) - 1] = '\0';
> +	vmc->vmc_name[sizeof(vmc->vmc_name) - 1] = '\0';
> 
>  	n = sizeof(vmc->vmc_disks) / sizeof(vmc->vmc_disks[0]);
>  	for (i = 0; i < n; i++)
> blob - f0f5a9bccf9fc12a2ebb55c4fe31efd0a00f8105
> blob + 37bdefb911c61464e11f6119ea2519ef777b1a8e
> --- usr.sbin/vmd/vmd.h
> +++ usr.sbin/vmd/vmd.h
> @@ -159,7 +159,14 @@ struct vmop_result {
>  };
> 
>  struct vmop_info_result {
> -	struct vm_info_result	 vir_info;
> +	size_t			 vir_memory_size;
> +	size_t			 vir_used_size;
> +	size_t			 vir_ncpus;
> +	uint8_t			 vir_vcpu_state[VMM_MAX_VCPUS_PER_VM];
> +	pid_t			 vir_creator_pid;
> +	uint32_t		 vir_id;
> +	char			 vir_name[VMM_MAX_NAME_LEN];
> +
>  	char			 vir_ttyname[VM_TTYNAME_MAX];
>  	uid_t			 vir_uid;
>  	int64_t			 vir_gid;
> @@ -200,7 +207,11 @@ struct vmop_owner {
>  };
> 
>  struct vmop_create_params {
> -	struct vm_create_params	 vmc_params;
> +	/* vm identifying information */
> +	uint32_t		 vmc_id;
> +	char			 vmc_name[VMM_MAX_NAME_LEN];
> +	struct vmop_owner	 vmc_owner;
> +
>  	unsigned int		 vmc_flags;
>  #define VMOP_CREATE_CPU		0x01
>  #define VMOP_CREATE_KERNEL	0x02
> @@ -209,42 +220,53 @@ struct vmop_create_params {
>  #define VMOP_CREATE_DISK	0x10
>  #define VMOP_CREATE_CDROM	0x20
>  #define VMOP_CREATE_INSTANCE	0x40
> -
> -	/* same flags; check for access to these resources */
> +	/* same flags as vmc_flags; check for access to these resources */
>  	unsigned int		 vmc_checkaccess;
> 
> -	/* userland-only part of the create params */
> +	/* vcpu count and features */
> +	size_t			 vmc_ncpus;
> +	uint32_t		 vmc_asid[VMM_MAX_VCPUS];
> +
> +	/* AMD SEV support */
> +	uint32_t		 vmc_poscbit;
> +	int			 vmc_sev;
> +	int			 vmc_seves;
> +
> +	/* guest memory */
> +	size_t			 vmc_nmemranges;
> +	struct vm_mem_range	 vmc_memranges[VMM_MAX_MEM_RANGES];
> +
> +	/* Boot device and firmware */
> +	int			 vmc_kernel;
>  	unsigned int		 vmc_bootdevice;
>  #define VMBOOTDEV_AUTO		0
>  #define VMBOOTDEV_DISK		1
>  #define VMBOOTDEV_CDROM		2
>  #define VMBOOTDEV_NET		3
> -	unsigned int		 vmc_ifflags[VM_MAX_NICS_PER_VM];
> -#define VMIFF_UP		0x01
> -#define VMIFF_LOCKED		0x02
> -#define VMIFF_LOCAL		0x04
> -#define VMIFF_RDOMAIN		0x08
> -#define VMIFF_OPTMASK		(VMIFF_LOCKED|VMIFF_LOCAL|VMIFF_RDOMAIN)
> 
> +	/* Emulated disk and cdrom drives */
>  	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];
> -	int			 vmc_kernel;
> 
> +	/* Emulated network devices */
>  	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];
> +	unsigned int		 vmc_ifflags[VM_MAX_NICS_PER_VM];
> +#define VMIFF_UP		0x01
> +#define VMIFF_LOCKED		0x02
> +#define VMIFF_LOCAL		0x04
> +#define VMIFF_RDOMAIN		0x08
> +#define VMIFF_OPTMASK		(VMIFF_LOCKED|VMIFF_LOCAL|VMIFF_RDOMAIN)
> 
> -	struct vmop_owner	 vmc_owner;
> -
>  	/* instance template params */
>  	char			 vmc_instance[VMM_MAX_NAME_LEN];
>  	struct vmop_owner	 vmc_insowner;
> @@ -275,11 +297,18 @@ TAILQ_HEAD(switchlist, vmd_switch);
> 
>  struct vmd_vm {
>  	struct vmop_create_params vm_params;
> +
> +	/* Owner and identifier information */
>  	pid_t			 vm_pid;
> -	uint32_t		 vm_vmid;
> +	uid_t			 vm_uid;
> +	uint32_t		 vm_vmid;	/* vmd(8) identifier */
> +	uint32_t		 vm_vmmid;	/* vmm(4) identifier */
> +	uint32_t		 vm_peerid;
> +
> +	/* AMD SEV features */
>  	uint32_t		 vm_sev_handle;
>  	uint32_t		 vm_sev_asid[VMM_MAX_VCPUS_PER_VM];
> -
> +	uint32_t		 vm_poscbit;
>  #define VM_SEV_NSEGMENTS	128
>  	size_t			 vm_sev_nmemsegments;
>  	struct vm_mem_range	 vm_sev_memsegments[VM_SEV_NSEGMENTS];
> @@ -287,16 +316,18 @@ struct vmd_vm {
>  	int			 vm_kernel;
>  	char			*vm_kernel_path; /* Used by vm.conf. */
> 
> +	/* Device and disk image file descriptors */
>  	int			 vm_cdrom;
>  	int			 vm_disks[VM_MAX_DISKS_PER_VM][VM_MAX_BASE_PER_DISK];
>  	struct vmd_if		 vm_ifs[VM_MAX_NICS_PER_VM];
> +
> +	/* Serial port */
>  	char			 vm_ttyname[VM_TTYNAME_MAX];
>  	int			 vm_tty;
> -	uint32_t		 vm_peerid;
> +
>  	/* When set, VM was defined in a config file */
>  	int			 vm_from_config;
>  	struct imsgev		 vm_iev;
> -	uid_t			 vm_uid;
>  	unsigned int		 vm_state;
>  /* When set, VM is running now (PROC_PARENT only) */
>  #define VM_STATE_RUNNING	0x01
> @@ -484,16 +515,16 @@ int	 fd_hasdata(int);
>  int	 vmm_pipe(struct vmd_vm *, int, void (*)(int, short, void *));
> 
>  /* {mach}_vm.c (md interface) */
> -void	 create_memory_map(struct vm_create_params *);
> +void	 create_memory_map(struct vmd_vm *);
>  int	 load_firmware(struct vmd_vm *, struct vcpu_reg_state *);
> -int	 init_emulated_hw(struct vmop_create_params *, int,
> -    int[][VM_MAX_BASE_PER_DISK], int *);
> +int	 init_emulated_hw(struct vmd_vm *, int, int[][VM_MAX_BASE_PER_DISK],
> +    int *);
>  int	 vcpu_reset(uint32_t, uint32_t, struct vcpu_reg_state *);
>  void	 pause_vm_md(struct vmd_vm *);
>  void	 unpause_vm_md(struct vmd_vm *);
>  void	*hvaddr_mem(paddr_t, size_t);
>  struct vm_mem_range *
> -	 find_gpa_range(struct vm_create_params *, paddr_t, size_t);
> +	 find_gpa_range(struct vmop_create_params *, paddr_t, size_t);
>  int	 write_mem(paddr_t, const void *, size_t);
>  int	 read_mem(paddr_t, void *, size_t);
>  int	 intr_ack(struct vmd_vm *);
> blob - 51d6e406d1d924a3750f4aa62bd12fdeba2c2e50
> blob + 5892156f831aa8d6cb03c981cb32e51cede4b6b1
> --- usr.sbin/vmd/vmm.c
> +++ usr.sbin/vmd/vmm.c
> @@ -317,7 +317,6 @@ vmm_sighdlr(int sig, short event, void *arg)
>  {
>  	struct privsep *ps = arg;
>  	int status, ret = 0;
> -	uint32_t vmid;
>  	pid_t pid;
>  	struct vmop_result vmr;
>  	struct vmd_vm *vm;
> @@ -350,18 +349,18 @@ vmm_sighdlr(int sig, short event, void *arg)
>  				    (vm->vm_state & VM_STATE_SHUTDOWN))
>  					ret = 0;
> 
> -				vmid = vm->vm_params.vmc_params.vcp_id;
> -				vtp.vtp_vm_id = vmid;
> +				/* XXX check this */
> +				vtp.vtp_vm_id = vm->vm_vmmid;
> 
>  				if (terminate_vm(&vtp) == 0)
>  					log_debug("%s: terminated vm %s"
>  					    " (id %d)", __func__,
> -					    vm->vm_params.vmc_params.vcp_name,
> +					    vm->vm_params.vmc_name,
>  					    vm->vm_vmid);
> 
>  				memset(&vmr, 0, sizeof(vmr));
>  				vmr.vmr_result = ret;
> -				vmr.vmr_id = vm_id2vmid(vmid, vm);
> +				vmr.vmr_id = vm_id2vmid(vm->vm_vmmid, vm);
>  				if (proc_compose_imsg(ps, PROC_PARENT,
>  				    IMSG_VMDOP_TERMINATE_VM_EVENT,
>  				    vm->vm_peerid, -1, &vmr, sizeof(vmr)) == -1)
> @@ -497,7 +496,7 @@ vmm_dispatch_vm(int fd, short event, void *arg)
> 
>  		default:
>  			fatalx("%s: got invalid imsg %d from %s", __func__,
> -			    type, vm->vm_params.vmc_params.vcp_name);
> +			    type, vm->vm_params.vmc_name);
>  		}
>  		imsg_free(&imsg);
>  	}
> @@ -588,7 +587,6 @@ opentap(char *ifname)
>  int
>  vmm_start_vm(struct imsg *imsg, uint32_t *id, pid_t *pid)
>  {
> -	struct vm_create_params	*vcp;
>  	struct vmd_vm		*vm;
>  	char			*nargv[10], num[32], vmm_fd[32], psp_fd[32];
>  	int			 fd, ret = EINVAL;
> @@ -602,14 +600,12 @@ vmm_start_vm(struct imsg *imsg, uint32_t *id, pid_t *p
>  		log_warnx("%s: can't find vm", __func__);
>  		return (ENOENT);
>  	}
> -	vcp = &vm->vm_params.vmc_params;
> 
>  	if ((vm->vm_tty = imsg_get_fd(imsg)) == -1) {
>  		log_warnx("%s: can't get tty", __func__);
>  		goto err;
>  	}
> 
> -
>  	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC, fds)
>  	    == -1)
>  		fatal("socketpair");
> @@ -631,7 +627,7 @@ vmm_start_vm(struct imsg *imsg, uint32_t *id, pid_t *p
>  		sz = atomicio(vwrite, fds[0], vm, sizeof(*vm));
>  		if (sz != sizeof(*vm)) {
>  			log_warnx("%s: failed to send config for vm '%s'",
> -			    __func__, vcp->vcp_name);
> +			    __func__, vm->vm_params.vmc_name);
>  			ret = EIO;
>  			/* Defer error handling until after fd closing. */
>  		}
> @@ -663,26 +659,27 @@ vmm_start_vm(struct imsg *imsg, uint32_t *id, pid_t *p
>  		    sizeof(env->vmd_cfg.cfg_localprefix));
>  		if (sz != sizeof(env->vmd_cfg.cfg_localprefix)) {
>  			log_warnx("%s: failed to send local prefix for vm '%s'",
> -			    __func__, vcp->vcp_name);
> +			    __func__, vm->vm_params.vmc_name);
>  			ret = EIO;
>  			goto err;
>  		}
> 
>  		/* Read back the kernel-generated vm id from the child */
> -		sz = atomicio(read, fds[0], &vcp->vcp_id, sizeof(vcp->vcp_id));
> -		if (sz != sizeof(vcp->vcp_id)) {
> +		sz = atomicio(read, fds[0], &vm->vm_vmmid,
> +		    sizeof(vm->vm_vmmid));
> +		if (sz != sizeof(vm->vm_vmmid)) {
>  			log_debug("%s: failed to receive vm id from vm %s",
> -			    __func__, vcp->vcp_name);
> +			    __func__, vm->vm_params.vmc_name);
>  			/* vmd could not allocate memory for the vm. */
>  			ret = ENOMEM;
>  			goto err;
>  		}
> 
>  		/* Check for an invalid id. This indicates child failure. */
> -		if (vcp->vcp_id == 0)
> +		if (vm->vm_vmmid == 0)
>  			goto err;
> 
> -		*id = vcp->vcp_id;
> +		*id = vm->vm_vmmid;
>  		*pid = vm->vm_pid;
> 
>  		/* Wire up our pipe into the event handling. */
> @@ -828,8 +825,17 @@ get_info_vm(struct privsep *ps, struct imsg *imsg, int
>  			    info[i].vir_name, info[i].vir_id);
>  			continue;
>  		}
> -		memcpy(&vir.vir_info, &info[i], sizeof(vir.vir_info));
> -		vir.vir_info.vir_id = vm_id2vmid(info[i].vir_id, NULL);
> +
> +		/* XXX */
> +		vir.vir_memory_size = info[i].vir_memory_size;
> +		vir.vir_used_size = info[i].vir_used_size;
> +		vir.vir_ncpus = info[i].vir_ncpus;
> +		memcpy(vir.vir_vcpu_state, info[i].vir_vcpu_state,
> +		    sizeof(vir.vir_vcpu_state));
> +		vir.vir_creator_pid = info[i].vir_creator_pid;
> +		vir.vir_id = vm_id2vmid(info[i].vir_id, NULL);
> +		memcpy(vir.vir_name, info[i].vir_name, sizeof(vir.vir_name));
> +
>  		peer_id = imsg_get_id(imsg);
> 
>  		if (proc_compose_imsg(ps, PROC_PARENT,
> blob - ff02fd9a3515d05cfd468280230c3731e687bbbb
> blob + 403f0b1ec4a58ffeb7b65ee32fa2cb4a5e7f6a8a
> --- usr.sbin/vmd/x86_vm.c
> +++ usr.sbin/vmd/x86_vm.c
> @@ -47,7 +47,6 @@ typedef uint8_t (*io_fn_t)(struct vm_run_params *);
> 
>  io_fn_t	ioports_map[MAX_PORTS];
> 
> -void	 create_memory_map(struct vm_create_params *);
>  int	 translate_gva(struct vm_exit*, uint64_t, uint64_t *, int);
> 
>  static int	loadfile_bios(gzFile, off_t, struct vcpu_reg_state *);
> @@ -148,30 +147,24 @@ static const struct vcpu_reg_state vcpu_init_flat16 =
>   * create_memory_map
>   *
>   * Sets up the guest physical memory ranges that the VM can access.
> - *
> - * Parameters:
> - *  vcp: VM create parameters describing the VM whose memory map
> - *       is being created
> - *
> - * Return values:
> - *  nothing
>   */
>  void
> -create_memory_map(struct vm_create_params *vcp)
> +create_memory_map(struct vmd_vm *vm)
>  {
> +	struct vmop_create_params *vmc = &vm->vm_params;
>  	size_t len, mem_bytes;
>  	size_t above_1m = 0, above_4g = 0;
> 
> -	mem_bytes = vcp->vcp_memranges[0].vmr_size;
> -	vcp->vcp_nmemranges = 0;
> +	mem_bytes = vmc->vmc_memranges[0].vmr_size;
> +	vmc->vmc_nmemranges = 0;
>  	if (mem_bytes == 0 || mem_bytes > VMM_MAX_VM_MEM_SIZE)
>  		return;
> 
>  	/* First memory region: 0 - LOWMEM_KB (DOS low mem) */
>  	len = LOWMEM_KB * 1024;
> -	vcp->vcp_memranges[0].vmr_gpa = 0x0;
> -	vcp->vcp_memranges[0].vmr_size = len;
> -	vcp->vcp_memranges[0].vmr_type = VM_MEM_RAM;
> +	vmc->vmc_memranges[0].vmr_gpa = 0x0;
> +	vmc->vmc_memranges[0].vmr_size = len;
> +	vmc->vmc_memranges[0].vmr_type = VM_MEM_RAM;
>  	mem_bytes -= len;
> 
>  	/*
> @@ -184,9 +177,9 @@ create_memory_map(struct vm_create_params *vcp)
>  	 * to it. So allocate guest memory for it.
>  	 */
>  	len = MB(1) - (LOWMEM_KB * 1024);
> -	vcp->vcp_memranges[1].vmr_gpa = LOWMEM_KB * 1024;
> -	vcp->vcp_memranges[1].vmr_size = len;
> -	vcp->vcp_memranges[1].vmr_type = VM_MEM_RESERVED;
> +	vmc->vmc_memranges[1].vmr_gpa = LOWMEM_KB * 1024;
> +	vmc->vmc_memranges[1].vmr_size = len;
> +	vmc->vmc_memranges[1].vmr_type = VM_MEM_RESERVED;
>  	mem_bytes -= len;
> 
>  	/*
> @@ -194,10 +187,10 @@ create_memory_map(struct vm_create_params *vcp)
>  	 * BIOS area.
>  	 */
>  	if (mem_bytes <= MB(4)) {
> -		vcp->vcp_memranges[2].vmr_gpa = PCI_MMIO_BAR_END;
> -		vcp->vcp_memranges[2].vmr_size = MB(4);
> -		vcp->vcp_memranges[2].vmr_type = VM_MEM_RESERVED;
> -		vcp->vcp_nmemranges = 3;
> +		vmc->vmc_memranges[2].vmr_gpa = PCI_MMIO_BAR_END;
> +		vmc->vmc_memranges[2].vmr_size = MB(4);
> +		vmc->vmc_memranges[2].vmr_type = VM_MEM_RESERVED;
> +		vmc->vmc_nmemranges = 3;
>  		return;
>  	}
> 
> @@ -215,29 +208,29 @@ create_memory_map(struct vm_create_params *vcp)
>  	}
> 
>  	/* Third memory region: area above 1MB to MMIO region */
> -	vcp->vcp_memranges[2].vmr_gpa = MB(1);
> -	vcp->vcp_memranges[2].vmr_size = above_1m;
> -	vcp->vcp_memranges[2].vmr_type = VM_MEM_RAM;
> +	vmc->vmc_memranges[2].vmr_gpa = MB(1);
> +	vmc->vmc_memranges[2].vmr_size = above_1m;
> +	vmc->vmc_memranges[2].vmr_type = VM_MEM_RAM;
> 
>  	/* Fourth region: PCI MMIO range */
> -	vcp->vcp_memranges[3].vmr_gpa = PCI_MMIO_BAR_BASE;
> -	vcp->vcp_memranges[3].vmr_size = PCI_MMIO_BAR_END -
> +	vmc->vmc_memranges[3].vmr_gpa = PCI_MMIO_BAR_BASE;
> +	vmc->vmc_memranges[3].vmr_size = PCI_MMIO_BAR_END -
>  	    PCI_MMIO_BAR_BASE + 1;
> -	vcp->vcp_memranges[3].vmr_type = VM_MEM_MMIO;
> +	vmc->vmc_memranges[3].vmr_type = VM_MEM_MMIO;
> 
>  	/* Fifth region: 2nd copy of BIOS above MMIO ending at 4GB */
> -	vcp->vcp_memranges[4].vmr_gpa = PCI_MMIO_BAR_END + 1;
> -	vcp->vcp_memranges[4].vmr_size = MB(4);
> -	vcp->vcp_memranges[4].vmr_type = VM_MEM_RESERVED;
> +	vmc->vmc_memranges[4].vmr_gpa = PCI_MMIO_BAR_END + 1;
> +	vmc->vmc_memranges[4].vmr_size = MB(4);
> +	vmc->vmc_memranges[4].vmr_type = VM_MEM_RESERVED;
> 
>  	/* Sixth region: any remainder above 4GB */
>  	if (above_4g > 0) {
> -		vcp->vcp_memranges[5].vmr_gpa = GB(4);
> -		vcp->vcp_memranges[5].vmr_size = above_4g;
> -		vcp->vcp_memranges[5].vmr_type = VM_MEM_RAM;
> -		vcp->vcp_nmemranges = 6;
> +		vmc->vmc_memranges[5].vmr_gpa = GB(4);
> +		vmc->vmc_memranges[5].vmr_size = above_4g;
> +		vmc->vmc_memranges[5].vmr_type = VM_MEM_RAM;
> +		vmc->vmc_nmemranges = 6;
>  	} else
> -		vcp->vcp_nmemranges = 5;
> +		vmc->vmc_nmemranges = 5;
>  }
> 
>  int
> @@ -353,28 +346,28 @@ loadfile_bios(gzFile fp, off_t size, struct vcpu_reg_s
>   * Returns 0 on success, 1 on failure.
>   */
>  int
> -init_emulated_hw(struct vmop_create_params *vmc, int child_cdrom,
> +init_emulated_hw(struct vmd_vm *vm, int child_cdrom,
>      int child_disks[][VM_MAX_BASE_PER_DISK], int *child_taps)
>  {
> -	struct vm_create_params *vcp = &vmc->vmc_params;
> +	struct vmop_create_params *vmc = &vm->vm_params;
>  	size_t i;
>  	uint64_t memlo, memhi;
> 
>  	/* Calculate memory size for NVRAM registers */
>  	memlo = memhi = 0;
> -	for (i = 0; i < vcp->vcp_nmemranges; i++) {
> -		if (vcp->vcp_memranges[i].vmr_gpa == MB(1) &&
> -		    vcp->vcp_memranges[i].vmr_size > (15 * MB(1)))
> -			memlo = vcp->vcp_memranges[i].vmr_size - (15 * MB(1));
> -		else if (vcp->vcp_memranges[i].vmr_gpa == GB(4))
> -			memhi = vcp->vcp_memranges[i].vmr_size;
> +	for (i = 0; i < vmc->vmc_nmemranges; i++) {
> +		if (vmc->vmc_memranges[i].vmr_gpa == MB(1) &&
> +		    vmc->vmc_memranges[i].vmr_size > (15 * MB(1)))
> +			memlo = vmc->vmc_memranges[i].vmr_size - (15 * MB(1));
> +		else if (vmc->vmc_memranges[i].vmr_gpa == GB(4))
> +			memhi = vmc->vmc_memranges[i].vmr_size;
>  	}
> 
>  	/* Reset the IO port map */
>  	memset(&ioports_map, 0, sizeof(io_fn_t) * MAX_PORTS);
> 
>  	/* Init i8253 PIT */
> -	i8253_init(vcp->vcp_id);
> +	i8253_init(vm->vm_vmmid);
>  	ioports_map[TIMER_CTRL] = vcpu_exit_i8253;
>  	ioports_map[TIMER_BASE + TIMER_CNTR0] = vcpu_exit_i8253;
>  	ioports_map[TIMER_BASE + TIMER_CNTR1] = vcpu_exit_i8253;
> @@ -382,7 +375,7 @@ init_emulated_hw(struct vmop_create_params *vmc, int c
>  	ioports_map[PCKBC_AUX] = vcpu_exit_i8253_misc;
> 
>  	/* Init mc146818 RTC */
> -	mc146818_init(vcp->vcp_id, memlo, memhi);
> +	mc146818_init(vm->vm_vmmid, memlo, memhi);
>  	ioports_map[IO_RTC] = vcpu_exit_mc146818;
>  	ioports_map[IO_RTC + 1] = vcpu_exit_mc146818;
> 
> @@ -396,7 +389,7 @@ init_emulated_hw(struct vmop_create_params *vmc, int c
>  	ioports_map[ELCR1] = vcpu_exit_elcr;
> 
>  	/* Init ns8250 UART */
> -	ns8250_init(con_fd, vcp->vcp_id);
> +	ns8250_init(con_fd, vm->vm_vmmid);
>  	for (i = COM1_DATA; i <= COM1_SCR; i++)
>  		ioports_map[i] = vcpu_exit_com;
> 
> @@ -697,20 +690,20 @@ vcpu_exit_pci(struct vm_run_params *vrp)
>   *  Pointer to vm_mem_range that contains the start of the range otherwise.
>   */
>  struct vm_mem_range *
> -find_gpa_range(struct vm_create_params *vcp, paddr_t gpa, size_t len)
> +find_gpa_range(struct vmop_create_params *vmc, paddr_t gpa, size_t len)
>  {
>  	size_t i, n;
>  	struct vm_mem_range *vmr;
> 
>  	/* Find the first vm_mem_range that contains gpa */
> -	for (i = 0; i < vcp->vcp_nmemranges; i++) {
> -		vmr = &vcp->vcp_memranges[i];
> +	for (i = 0; i < vmc->vmc_nmemranges; i++) {
> +		vmr = &vmc->vmc_memranges[i];
>  		if (gpa < vmr->vmr_gpa + vmr->vmr_size)
>  			break;
>  	}
> 
>  	/* No range found. */
> -	if (i == vcp->vcp_nmemranges)
> +	if (i == vmc->vmc_nmemranges)
>  		return (NULL);
> 
>  	/*
> @@ -724,8 +717,8 @@ find_gpa_range(struct vm_create_params *vcp, paddr_t g
>  	else
>  		len -= n;
>  	gpa = vmr->vmr_gpa + vmr->vmr_size;
> -	for (i = i + 1; len != 0 && i < vcp->vcp_nmemranges; i++) {
> -		vmr = &vcp->vcp_memranges[i];
> +	for (i = i + 1; len != 0 && i < vmc->vmc_nmemranges; i++) {
> +		vmr = &vmc->vmc_memranges[i];
>  		if (gpa != vmr->vmr_gpa)
>  			return (NULL);
>  		if (len <= vmr->vmr_size)
> @@ -764,7 +757,7 @@ write_mem(paddr_t dst, const void *buf, size_t len)
>  	size_t n, off;
>  	struct vm_mem_range *vmr;
> 
> -	vmr = find_gpa_range(&current_vm->vm_params.vmc_params, dst, len);
> +	vmr = find_gpa_range(&current_vm->vm_params, dst, len);
>  	if (vmr == NULL) {
>  		errno = EINVAL;
>  		log_warn("%s: failed - invalid memory range dst = 0x%lx, "
> @@ -815,7 +808,7 @@ read_mem(paddr_t src, void *buf, size_t len)
>  	size_t n, off;
>  	struct vm_mem_range *vmr;
> 
> -	vmr = find_gpa_range(&current_vm->vm_params.vmc_params, src, len);
> +	vmr = find_gpa_range(&current_vm->vm_params, src, len);
>  	if (vmr == NULL) {
>  		errno = EINVAL;
>  		log_warn("%s: failed - invalid memory range src = 0x%lx, "
> @@ -864,7 +857,7 @@ hvaddr_mem(paddr_t gpa, size_t len)
>  	struct vm_mem_range *vmr;
>  	size_t off;
> 
> -	vmr = find_gpa_range(&current_vm->vm_params.vmc_params, gpa, len);
> +	vmr = find_gpa_range(&current_vm->vm_params, gpa, len);
>  	if (vmr == NULL) {
>  		log_warnx("%s: failed - invalid gpa: 0x%lx\n", __func__, gpa);
>  		errno = EFAULT;
> @@ -888,17 +881,17 @@ hvaddr_mem(paddr_t gpa, size_t len)
>   * Injects the specified IRQ on the supplied vcpu/vm
>   *
>   * Parameters:
> - *  vm_id: VM ID to inject to
> + *  vm_id: VMM vm ID to inject to
>   *  vcpu_id: VCPU ID to inject to
>   *  irq: IRQ to inject
>   */
>  void
> -vcpu_assert_irq(uint32_t vm_id, uint32_t vcpu_id, int irq)
> +vcpu_assert_irq(uint32_t vmm_id, uint32_t vcpu_id, int irq)
>  {
>  	i8259_assert_irq(irq);
> 
>  	if (i8259_is_pending()) {
> -		if (vcpu_intr(vm_id, vcpu_id, 1))
> +		if (vcpu_intr(vmm_id, vcpu_id, 1))
>  			fatalx("%s: can't assert INTR", __func__);
> 
>  		vcpu_unhalt(vcpu_id);
> @@ -912,19 +905,19 @@ vcpu_assert_irq(uint32_t vm_id, uint32_t vcpu_id, int
>   * Clears the specified IRQ on the supplied vcpu/vm
>   *
>   * Parameters:
> - *  vm_id: VM ID to clear in
> + *  vm_id: VMM vm ID to clear in
>   *  vcpu_id: VCPU ID to clear in
>   *  irq: IRQ to clear
>   */
>  void
> -vcpu_deassert_irq(uint32_t vm_id, uint32_t vcpu_id, int irq)
> +vcpu_deassert_irq(uint32_t vmm_id, uint32_t vcpu_id, int irq)
>  {
>  	i8259_deassert_irq(irq);
> 
>  	if (!i8259_is_pending()) {
> -		if (vcpu_intr(vm_id, vcpu_id, 0))
> -			fatalx("%s: can't deassert INTR for vm_id %d, "
> -			    "vcpu_id %d", __func__, vm_id, vcpu_id);
> +		if (vcpu_intr(vmm_id, vcpu_id, 0))
> +			fatalx("%s: can't deassert INTR for vmm_id %d, "
> +			    "vcpu_id %d", __func__, vmm_id, vcpu_id);
>  	}
>  }