diff options
author | Patrick Mooney <pmooney@pfmooney.com> | 2022-01-14 17:53:13 +0000 |
---|---|---|
committer | Patrick Mooney <pmooney@oxide.computer> | 2022-01-25 22:22:35 +0000 |
commit | 70ae9a334a768113a660b21305bf7d2cff941499 (patch) | |
tree | ebf6e4096c5b3f6be0cc00058be738ed5c30e607 /usr | |
parent | 25cdfc4f8d373444e56178d1053ca53f1c3ea928 (diff) | |
download | illumos-gate-70ae9a334a768113a660b21305bf7d2cff941499.tar.gz |
14425 want probes for invvpid and invept
14426 expand seg_vmm tests
Reviewed by: Andy Fiddaman <andy@omnios.org>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Robert Mustacchi <rm@fingolfin.org>
Diffstat (limited to 'usr')
-rw-r--r-- | usr/src/pkg/manifests/system-bhyve-tests.p5m | 4 | ||||
-rw-r--r-- | usr/src/test/bhyve-tests/runfiles/default.run | 4 | ||||
-rw-r--r-- | usr/src/test/bhyve-tests/tests/Makefile | 38 | ||||
-rw-r--r-- | usr/src/test/bhyve-tests/tests/vmm/Makefile | 59 | ||||
-rw-r--r-- | usr/src/test/bhyve-tests/tests/vmm/common.c | 53 | ||||
-rw-r--r-- | usr/src/test/bhyve-tests/tests/vmm/common.h | 24 | ||||
-rw-r--r-- | usr/src/test/bhyve-tests/tests/vmm/mem_partial.c (renamed from usr/src/test/bhyve-tests/tests/memmap.c) | 40 | ||||
-rw-r--r-- | usr/src/test/bhyve-tests/tests/vmm/mem_seg_map.c | 138 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/vmm/intel/vmx.c | 27 |
9 files changed, 310 insertions, 77 deletions
diff --git a/usr/src/pkg/manifests/system-bhyve-tests.p5m b/usr/src/pkg/manifests/system-bhyve-tests.p5m index 070f9790c9..74881cf19c 100644 --- a/usr/src/pkg/manifests/system-bhyve-tests.p5m +++ b/usr/src/pkg/manifests/system-bhyve-tests.p5m @@ -30,12 +30,14 @@ file path=opt/bhyve-tests/bin/bhyvetest mode=0555 dir path=opt/bhyve-tests/runfiles file path=opt/bhyve-tests/runfiles/default.run mode=0444 dir path=opt/bhyve-tests/tests -file path=opt/bhyve-tests/tests/memmap mode=0555 dir path=opt/bhyve-tests/tests/mevent file path=opt/bhyve-tests/tests/mevent/lists_delete mode=0555 file path=opt/bhyve-tests/tests/mevent/read_disable mode=0555 file path=opt/bhyve-tests/tests/mevent/read_pause mode=0555 file path=opt/bhyve-tests/tests/mevent/read_requeue mode=0555 +dir path=opt/bhyve-tests/tests/vmm +file path=opt/bhyve-tests/tests/vmm/mem_partial mode=0555 +file path=opt/bhyve-tests/tests/vmm/mem_seg_map mode=0555 license lic_CDDL license=lic_CDDL depend type=require fmri=system/bhyve depend type=require fmri=system/test/testrunner diff --git a/usr/src/test/bhyve-tests/runfiles/default.run b/usr/src/test/bhyve-tests/runfiles/default.run index 0e92d9359e..51afd4581a 100644 --- a/usr/src/test/bhyve-tests/runfiles/default.run +++ b/usr/src/test/bhyve-tests/runfiles/default.run @@ -19,8 +19,8 @@ timeout = 60 post = outputdir = /var/tmp/test_results -[/opt/bhyve-tests/tests] -tests = ['memmap'] +[/opt/bhyve-tests/tests/vmm] +tests = ['mem_partial', 'mem_seg_map'] # Tests of userspace mevent system, built from cmd/bhyve [/opt/bhyve-tests/tests/mevent] diff --git a/usr/src/test/bhyve-tests/tests/Makefile b/usr/src/test/bhyve-tests/tests/Makefile index 5edb6d2be4..bf18b300ca 100644 --- a/usr/src/test/bhyve-tests/tests/Makefile +++ b/usr/src/test/bhyve-tests/tests/Makefile @@ -9,40 +9,12 @@ # http://www.illumos.org/license/CDDL. # +# # Copyright 2022 Oxide Computer Company +# -include $(SRC)/cmd/Makefile.cmd -include $(SRC)/cmd/Makefile.cmd.64 -include $(SRC)/test/Makefile.com - -PROG = memmap - -ROOTOPTPKG = $(ROOT)/opt/bhyve-tests -TESTDIR = $(ROOTOPTPKG)/tests - -CMDS = $(PROG:%=$(TESTDIR)/%) -$(CMDS) := FILEMODE = 0555 - -CSTD= $(CSTD_GNU99) -CPPFLAGS = -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \ - -I$(COMPAT)/bhyve/amd64 -I$(CONTRIB)/bhyve/amd64 \ - $(CPPFLAGS.master) \ - -I$(SRC)/uts/i86pc/io/vmm \ - -I$(SRC)/uts/i86pc -$(PROG) := LDLIBS += \ - -lvmmapi - -all: $(PROG) - -install: all $(CMDS) - -clobber: clean - -$(RM) $(PROG) - -$(CMDS): $(TESTDIR) $(PROG) +.PARALLEL: $(SUBDIRS) -$(TESTDIR): - $(INS.dir) +SUBDIRS = vmm -$(TESTDIR)/%: % - $(INS.file) +include $(SRC)/test/Makefile.com diff --git a/usr/src/test/bhyve-tests/tests/vmm/Makefile b/usr/src/test/bhyve-tests/tests/vmm/Makefile new file mode 100644 index 0000000000..c91ed9a7e4 --- /dev/null +++ b/usr/src/test/bhyve-tests/tests/vmm/Makefile @@ -0,0 +1,59 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# Copyright 2022 Oxide Computer Company + +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/cmd/Makefile.cmd.64 +include $(SRC)/test/Makefile.com + +PROG = mem_partial \ + mem_seg_map + +COMMON_OBJS = common.o +CLEAN_OBJS = $(PROG:%=%.o) + +ROOTOPTPKG = $(ROOT)/opt/bhyve-tests +TESTDIR = $(ROOTOPTPKG)/tests/vmm + +CMDS = $(PROG:%=$(TESTDIR)/%) +$(CMDS) := FILEMODE = 0555 + +CSTD= $(CSTD_GNU99) +CPPFLAGS = -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \ + -I$(COMPAT)/bhyve/amd64 -I$(CONTRIB)/bhyve/amd64 \ + $(CPPFLAGS.master) \ + -I$(SRC)/uts/i86pc/io/vmm \ + -I$(SRC)/uts/i86pc +$(PROG) := LDLIBS += -lvmmapi + +all: $(PROG) + +install: all $(CMDS) + +clean: + -$(RM) $(CLEAN_OBJS) $(COMMON_OBJS) +clobber: clean + -$(RM) $(PROG) + +$(PROG): $(COMMON_OBJS) + +$(CMDS): $(TESTDIR) $(PROG) + +$(TESTDIR): + $(INS.dir) + +$(TESTDIR)/%: % + $(INS.file) + +%: %.o + $(LINK.c) -o $@ $< $(COMMON_OBJS) $(LDLIBS) + $(POST_PROCESS) diff --git a/usr/src/test/bhyve-tests/tests/vmm/common.c b/usr/src/test/bhyve-tests/tests/vmm/common.c new file mode 100644 index 0000000000..b7f0a30ed0 --- /dev/null +++ b/usr/src/test/bhyve-tests/tests/vmm/common.c @@ -0,0 +1,53 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2022 Oxide Computer Company + */ + +#include <stdio.h> +#include <unistd.h> +#include <strings.h> + +#include <sys/types.h> +#include <sys/vmm.h> +#include <sys/vmm_dev.h> +#include <vmmapi.h> + +struct vmctx * +create_test_vm(void) +{ + char name[VM_MAX_NAMELEN]; + int res; + + (void) snprintf(name, sizeof (name), "bhyve-test-memmap-%d", getpid()); + + res = vm_create(name, 0); + if (res != 0) { + return (NULL); + } + + return (vm_open(name)); +} + +int +alloc_memseg(struct vmctx *ctx, int segid, size_t len, const char *name) +{ + struct vm_memseg memseg = { + .segid = segid, + .len = len, + }; + (void) strlcpy(memseg.name, name, sizeof (memseg.name)); + + int fd = vm_get_device_fd(ctx); + + return (ioctl(fd, VM_ALLOC_MEMSEG, &memseg)); +} diff --git a/usr/src/test/bhyve-tests/tests/vmm/common.h b/usr/src/test/bhyve-tests/tests/vmm/common.h new file mode 100644 index 0000000000..7b64574cf2 --- /dev/null +++ b/usr/src/test/bhyve-tests/tests/vmm/common.h @@ -0,0 +1,24 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2022 Oxide Computer Company + */ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +struct vmctx *create_test_vm(void); +int alloc_memseg(struct vmctx *, int, size_t, const char *); + +#define PROT_ALL (PROT_READ | PROT_WRITE | PROT_EXEC) + +#endif /* _COMMON_H_ */ diff --git a/usr/src/test/bhyve-tests/tests/memmap.c b/usr/src/test/bhyve-tests/tests/vmm/mem_partial.c index c5c2f179da..b410c673ab 100644 --- a/usr/src/test/bhyve-tests/tests/memmap.c +++ b/usr/src/test/bhyve-tests/tests/vmm/mem_partial.c @@ -20,12 +20,15 @@ #include <strings.h> #include <signal.h> #include <setjmp.h> +#include <libgen.h> #include <sys/vmm.h> #include <sys/vmm_dev.h> #include <sys/mman.h> #include <vmmapi.h> +#include "common.h" + /* Half of a leaf page table is 256 pages */ #define LOWER_SZ (256 * 4096) #define UPPER_SZ LOWER_SZ @@ -34,43 +37,11 @@ #define LOWER_OFF 0 #define UPPER_OFF LOWER_SZ -#define PROT_ALL (PROT_READ | PROT_WRITE | PROT_EXEC) - enum test_memsegs { MSEG_LOW = 0, MSEG_HIGH = 1, }; -struct vmctx * -create_test_vm() -{ - char name[VM_MAX_NAMELEN]; - int res; - - (void) snprintf(name, sizeof (name), "bhyve-test-memmap-%d", getpid()); - - res = vm_create(name, 0); - if (res != 0) { - return (NULL); - } - - return (vm_open(name)); -} - -int -alloc_memseg(struct vmctx *ctx, int segid, size_t len, const char *name) -{ - struct vm_memseg memseg = { - .segid = segid, - .len = len, - }; - (void) strlcpy(memseg.name, name, sizeof (memseg.name)); - - int fd = vm_get_device_fd(ctx); - - return (ioctl(fd, VM_ALLOC_MEMSEG, &memseg)); -} - static sigjmp_buf segv_env; void @@ -88,6 +59,10 @@ main(int argc, char *argv[]) void *guest_mem; ctx = create_test_vm(); + if (ctx == NULL) { + perror("could open test VM"); + return (1); + } fd = vm_get_device_fd(ctx); res = alloc_memseg(ctx, MSEG_LOW, LOWER_SZ, "mseg_low"); @@ -217,6 +192,7 @@ main(int argc, char *argv[]) } /* mission accomplished */ + (void) printf("%s\tPASS\n", basename(argv[0])); vm_destroy(ctx); return (0); diff --git a/usr/src/test/bhyve-tests/tests/vmm/mem_seg_map.c b/usr/src/test/bhyve-tests/tests/vmm/mem_seg_map.c new file mode 100644 index 0000000000..e80f18547e --- /dev/null +++ b/usr/src/test/bhyve-tests/tests/vmm/mem_seg_map.c @@ -0,0 +1,138 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2022 Oxide Computer Company + */ + + +#include <stdio.h> +#include <unistd.h> +#include <stropts.h> +#include <strings.h> +#include <signal.h> +#include <setjmp.h> +#include <libgen.h> + +#include <sys/vmm.h> +#include <sys/vmm_dev.h> +#include <sys/mman.h> +#include <vmmapi.h> + +#include "common.h" + +#define TEST_SEGID 0 +#define PAGE_CNT 1024 +#define PAGE_SZ 4096 +#define SEG_SZ (PAGE_CNT * PAGE_SZ) + +int +main(int argc, char *argv[]) +{ + struct vmctx *ctx; + int res, fd; + void *seg_obj, *guest_mem; + + ctx = create_test_vm(); + if (ctx == NULL) { + perror("could open test VM"); + return (1); + } + fd = vm_get_device_fd(ctx); + + res = alloc_memseg(ctx, TEST_SEGID, SEG_SZ, "test_seg"); + if (res != 0) { + perror("could not alloc memseg"); + goto bail; + } + off_t seg_obj_off; + res = vm_get_devmem_offset(ctx, TEST_SEGID, &seg_obj_off); + if (res != 0) { + perror("could not find mapping offset for seg object"); + goto bail; + } + + seg_obj = mmap(NULL, SEG_SZ, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, seg_obj_off); + if (seg_obj == MAP_FAILED) { + perror("could not mmap seg object"); + goto bail; + } + + /* populate with initial data */ + for (uint_t i = 0; i < PAGE_CNT; i++) { + uint64_t *p = (uint64_t *)((uintptr_t)seg_obj + i * PAGE_SZ); + + *p = i; + } + + res = vm_mmap_memseg(ctx, 0, TEST_SEGID, 0, SEG_SZ, PROT_ALL); + if (res != 0) { + perror("could not map memseg into vmspace"); + goto bail; + } + guest_mem = mmap(NULL, SEG_SZ, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0); + if (seg_obj == MAP_FAILED) { + perror("could not mmap vmspace"); + goto bail; + } + + /* check data and access though vmspace */ + for (uint_t i = 0; i < PAGE_CNT; i++) { + const uint64_t off = i * PAGE_SZ; + uint64_t *p = (uint64_t *)((uintptr_t)guest_mem + off); + + const uint64_t val = *p; + if (val != i) { + (void) printf("%lu != %u at gpa:%lx\n", val, i, off); + goto bail; + } + + /* leave a change behind */ + *p = val * 2; + } + + /* check changes made through vmspace */ + for (uint_t i = 0; i < PAGE_CNT; i++) { + const uint64_t off = i * PAGE_SZ; + uint64_t *p = (uint64_t *)((uintptr_t)seg_obj + off); + + const uint_t expected = i * 2; + const uint64_t val = *p; + if (val != expected) { + (void) printf("%lu != %u at gpa:%lx\n", val, expected, + off); + goto bail; + } + } + + /* unmap access mappings */ + res = munmap(guest_mem, SEG_SZ); + if (res != 0) { + perror("could not munmap vmspace"); + goto bail; + } + res = munmap(seg_obj, SEG_SZ); + if (res != 0) { + perror("could not munmap seg object"); + goto bail; + } + + /* mission accomplished */ + vm_destroy(ctx); + (void) printf("%s\tPASS\n", basename(argv[0])); + return (0); + +bail: + vm_destroy(ctx); + return (1); +} diff --git a/usr/src/uts/i86pc/io/vmm/intel/vmx.c b/usr/src/uts/i86pc/io/vmm/intel/vmx.c index 88bc56acfa..d07a8142e3 100644 --- a/usr/src/uts/i86pc/io/vmm/intel/vmx.c +++ b/usr/src/uts/i86pc/io/vmm/intel/vmx.c @@ -931,14 +931,18 @@ invvpid(uint64_t type, struct invvpid_desc desc) { int error; + DTRACE_PROBE3(vmx__invvpid, uint64_t, type, uint16_t, desc.vpid, + uint64_t, desc.linear_addr); + __asm __volatile("invvpid %[desc], %[type];" VMX_SET_ERROR_CODE_ASM : [error] "=r" (error) : [desc] "m" (desc), [type] "r" (type) : "memory"); - if (error) + if (error) { panic("invvpid error %d", error); + } } /* @@ -948,17 +952,16 @@ invvpid(uint64_t type, struct invvpid_desc desc) * mappings" (to use the VMX parlance). Actions which modify the EPT structures * for the instance (such as unmapping GPAs) would require an 'invept' flush. */ -static __inline void +static void vmx_invvpid(struct vmx *vmx, int vcpu, int running) { struct vmxstate *vmxstate; - struct invvpid_desc invvpid_desc; struct vmspace *vms; vmxstate = &vmx->state[vcpu]; - if (vmxstate->vpid == 0) + if (vmxstate->vpid == 0) { return; - vms = vm_get_vmspace(vmx->vm); + } if (!running) { /* @@ -978,11 +981,15 @@ vmx_invvpid(struct vmx *vmx, int vcpu, int running) * stale TLB entries for this VPID on the target, or if emulated actions * in the guest CPU have incurred an explicit TLB flush. */ + vms = vm_get_vmspace(vmx->vm); if (vmspace_table_gen(vms) == vmx->eptgen[curcpu]) { - invvpid_desc._res1 = 0; - invvpid_desc._res2 = 0; - invvpid_desc.vpid = vmxstate->vpid; - invvpid_desc.linear_addr = 0; + struct invvpid_desc invvpid_desc = { + .vpid = vmxstate->vpid, + .linear_addr = 0, + ._res1 = 0, + ._res2 = 0, + }; + invvpid(INVVPID_TYPE_SINGLE_CONTEXT, invvpid_desc); vmm_stat_incr(vmx->vm, vcpu, VCPU_INVVPID_DONE, 1); } else { @@ -1005,6 +1012,8 @@ invept(uint64_t type, uint64_t eptp) uint64_t _resv; } desc = { eptp, 0 }; + DTRACE_PROBE2(vmx__invept, uint64_t, type, uint64_t, eptp); + __asm __volatile("invept %[desc], %[type];" VMX_SET_ERROR_CODE_ASM : [error] "=r" (error) |