summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2022-01-14 17:53:13 +0000
committerPatrick Mooney <pmooney@oxide.computer>2022-01-25 22:22:35 +0000
commit70ae9a334a768113a660b21305bf7d2cff941499 (patch)
treeebf6e4096c5b3f6be0cc00058be738ed5c30e607 /usr
parent25cdfc4f8d373444e56178d1053ca53f1c3ea928 (diff)
downloadillumos-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.p5m4
-rw-r--r--usr/src/test/bhyve-tests/runfiles/default.run4
-rw-r--r--usr/src/test/bhyve-tests/tests/Makefile38
-rw-r--r--usr/src/test/bhyve-tests/tests/vmm/Makefile59
-rw-r--r--usr/src/test/bhyve-tests/tests/vmm/common.c53
-rw-r--r--usr/src/test/bhyve-tests/tests/vmm/common.h24
-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.c138
-rw-r--r--usr/src/uts/i86pc/io/vmm/intel/vmx.c27
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)