Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add initial tests for libnvmm's Mem Assist, with 8 test cases.



details:   https://anonhg.NetBSD.org/src/rev/2f44af2ff262
branches:  trunk
changeset: 446865:2f44af2ff262
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sun Dec 23 13:35:02 2018 +0000

description:
Add initial tests for libnvmm's Mem Assist, with 8 test cases.

diffstat:

 distrib/sets/lists/tests/md.amd64    |    6 +-
 tests/lib/Makefile                   |    4 +-
 tests/lib/libnvmm/Makefile           |   19 ++
 tests/lib/libnvmm/h_mem_assist.c     |  328 +++++++++++++++++++++++++++++++++++
 tests/lib/libnvmm/h_mem_assist_asm.S |  159 ++++++++++++++++
 tests/lib/libnvmm/t_mem_assist.sh    |   50 +++++
 6 files changed, 563 insertions(+), 3 deletions(-)

diffs (truncated from 604 to 300 lines):

diff -r a09532d457f1 -r 2f44af2ff262 distrib/sets/lists/tests/md.amd64
--- a/distrib/sets/lists/tests/md.amd64 Sun Dec 23 12:32:33 2018 +0000
+++ b/distrib/sets/lists/tests/md.amd64 Sun Dec 23 13:35:02 2018 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: md.amd64,v 1.3 2017/04/02 01:49:52 kamil Exp $
+# $NetBSD: md.amd64,v 1.4 2018/12/23 13:35:02 maxv Exp $
 ./usr/tests/kernel/arch/x86/Atffile            tests-obsolete  obsolete
 ./usr/tests/kernel/arch/x86/Kyuafile           tests-obsolete  obsolete
 ./usr/tests/kernel/arch/x86/t_ptrace_wait      tests-obsolete  obsolete
@@ -7,3 +7,7 @@
 ./usr/tests/kernel/arch/x86/t_ptrace_wait6     tests-obsolete  obsolete
 ./usr/tests/kernel/arch/x86/t_ptrace_waitid    tests-obsolete  obsolete
 ./usr/tests/kernel/arch/x86/t_ptrace_waitpid   tests-obsolete  obsolete
+./usr/tests/lib/libnvmm/Atffile                        tests-lib-tests compattestfile,atf
+./usr/tests/lib/libnvmm/Kyuafile               tests-lib-tests compattestfile,atf,kyua
+./usr/tests/lib/libnvmm/h_mem_assist           tests-lib-tests compattestfile,atf
+./usr/tests/lib/libnvmm/t_mem_assist           tests-lib-tests compattestfile,atf
diff -r a09532d457f1 -r 2f44af2ff262 tests/lib/Makefile
--- a/tests/lib/Makefile        Sun Dec 23 12:32:33 2018 +0000
+++ b/tests/lib/Makefile        Sun Dec 23 13:35:02 2018 +0000
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.30 2017/11/23 02:40:01 kre Exp $
+# $NetBSD: Makefile,v 1.31 2018/12/23 13:35:02 maxv Exp $
 
 .include <bsd.own.mk>
 
 TESTS_SUBDIRS= csu libbluetooth libc libcrypt libcurses libexecinfo \
-               libm libobjc libposix libppath libprop libpthread \
+               libm libnvmm libobjc libposix libppath libprop libpthread \
                librefuse librt libtre libusbhid libutil \
                semaphore
 
diff -r a09532d457f1 -r 2f44af2ff262 tests/lib/libnvmm/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/libnvmm/Makefile        Sun Dec 23 13:35:02 2018 +0000
@@ -0,0 +1,19 @@
+# $NetBSD: Makefile,v 1.1 2018/12/23 13:35:02 maxv Exp $
+
+NOMAN= # defined
+
+.include <bsd.own.mk>
+
+TESTSDIR=      ${TESTSBASE}/lib/libnvmm
+
+COPTS+=        -Wall
+LDADD+=        -lnvmm
+
+.if ${MACHINE} == "amd64"
+# Mem Assist
+TESTS_SH=              t_mem_assist
+PROGS=                 h_mem_assist
+SRCS.h_mem_assist=     h_mem_assist.c h_mem_assist_asm.S
+.endif
+
+.include <bsd.test.mk>
diff -r a09532d457f1 -r 2f44af2ff262 tests/lib/libnvmm/h_mem_assist.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/libnvmm/h_mem_assist.c  Sun Dec 23 13:35:02 2018 +0000
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Maxime Villard.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <err.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <machine/segments.h>
+#include <machine/psl.h>
+#include <machine/pte.h>
+#include <x86/specialreg.h>
+
+#include <nvmm.h>
+
+#define PAGE_SIZE 4096
+
+static uint8_t mmiobuf[PAGE_SIZE];
+static uint8_t *instbuf;
+
+static void
+init_seg(struct nvmm_x64_state_seg *seg, int type, int sel)
+{
+       seg->selector = sel;
+       seg->attrib.type = type;
+       seg->attrib.dpl = 0;
+       seg->attrib.p = 1;
+       seg->attrib.avl = 1;
+       seg->attrib.lng = 1;
+       seg->attrib.def32 = 0;
+       seg->attrib.gran = 1;
+       seg->limit = 0xFFFFFFFF;
+       seg->base = 0x00000000;
+}
+
+static void
+reset_machine(struct nvmm_machine *mach)
+{
+       struct nvmm_x64_state state;
+
+       memset(&state, 0, sizeof(state));
+
+       /* Default. */
+       state.gprs[NVMM_X64_GPR_RFLAGS] = PSL_MBO;
+       init_seg(&state.segs[NVMM_X64_SEG_CS], SDT_MEMERA, GSEL(GCODE_SEL, SEL_KPL));
+       init_seg(&state.segs[NVMM_X64_SEG_SS], SDT_MEMRWA, GSEL(GDATA_SEL, SEL_KPL));
+       init_seg(&state.segs[NVMM_X64_SEG_DS], SDT_MEMRWA, GSEL(GDATA_SEL, SEL_KPL));
+       init_seg(&state.segs[NVMM_X64_SEG_ES], SDT_MEMRWA, GSEL(GDATA_SEL, SEL_KPL));
+       init_seg(&state.segs[NVMM_X64_SEG_FS], SDT_MEMRWA, GSEL(GDATA_SEL, SEL_KPL));
+       init_seg(&state.segs[NVMM_X64_SEG_GS], SDT_MEMRWA, GSEL(GDATA_SEL, SEL_KPL));
+
+       /* Blank. */
+       init_seg(&state.segs[NVMM_X64_SEG_GDT], 0, 0x0000);
+       init_seg(&state.segs[NVMM_X64_SEG_IDT], 0, 0x0000);
+       init_seg(&state.segs[NVMM_X64_SEG_LDT], 0, 0x0000);
+       init_seg(&state.segs[NVMM_X64_SEG_TR], 0, 0x0000);
+
+       /* Protected mode enabled. */
+       state.crs[NVMM_X64_CR_CR0] = CR0_PG|CR0_PE|CR0_NE|CR0_TS|CR0_MP|CR0_WP|CR0_AM;
+
+       /* 64bit mode enabled. */
+       state.crs[NVMM_X64_CR_CR4] = CR4_PAE;
+       state.msrs[NVMM_X64_MSR_EFER] = EFER_LME | EFER_SCE | EFER_LMA;
+
+       /* Stolen from x86/pmap.c */
+#define        PATENTRY(n, type)       (type << ((n) * 8))
+#define        PAT_UC          0x0ULL
+#define        PAT_WC          0x1ULL
+#define        PAT_WT          0x4ULL
+#define        PAT_WP          0x5ULL
+#define        PAT_WB          0x6ULL
+#define        PAT_UCMINUS     0x7ULL
+       state.msrs[NVMM_X64_MSR_PAT] =
+           PATENTRY(0, PAT_WB) | PATENTRY(1, PAT_WT) |
+           PATENTRY(2, PAT_UCMINUS) | PATENTRY(3, PAT_UC) |
+           PATENTRY(4, PAT_WB) | PATENTRY(5, PAT_WT) |
+           PATENTRY(6, PAT_UCMINUS) | PATENTRY(7, PAT_UC);
+
+       /* Page tables. */
+       state.crs[NVMM_X64_CR_CR3] = 0x3000;
+
+       state.gprs[NVMM_X64_GPR_RIP] = 0x2000;
+
+       if (nvmm_vcpu_setstate(mach, 0, &state, NVMM_X64_STATE_ALL) == -1)
+               err(errno, "nvmm_vcpu_setstate");
+}
+
+static void
+map_pages(struct nvmm_machine *mach)
+{
+       pt_entry_t *L4, *L3, *L2, *L1;
+
+       instbuf = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
+           -1, 0);
+       if (instbuf == MAP_FAILED)
+               err(errno, "mmap");
+
+       if (nvmm_hva_map(mach, (uintptr_t)instbuf, PAGE_SIZE) == -1)
+               err(errno, "nvmm_hva_map");
+       if (nvmm_gpa_map(mach, (uintptr_t)instbuf, 0x2000, PAGE_SIZE, 0) == -1)
+               err(errno, "nvmm_gpa_map");
+
+       L4 = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
+           -1, 0);
+       if (L4 == MAP_FAILED)
+               err(errno, "mmap");
+       L3 = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
+           -1, 0);
+       if (L3 == MAP_FAILED)
+               err(errno, "mmap");
+       L2 = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
+           -1, 0);
+       if (L2 == MAP_FAILED)
+               err(errno, "mmap");
+       L1 = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
+           -1, 0);
+       if (L1 == MAP_FAILED)
+               err(errno, "mmap");
+
+       if (nvmm_hva_map(mach, (uintptr_t)L4, PAGE_SIZE) == -1)
+               err(errno, "nvmm_hva_map");
+       if (nvmm_hva_map(mach, (uintptr_t)L3, PAGE_SIZE) == -1)
+               err(errno, "nvmm_hva_map");
+       if (nvmm_hva_map(mach, (uintptr_t)L2, PAGE_SIZE) == -1)
+               err(errno, "nvmm_hva_map");
+       if (nvmm_hva_map(mach, (uintptr_t)L1, PAGE_SIZE) == -1)
+               err(errno, "nvmm_hva_map");
+
+       if (nvmm_gpa_map(mach, (uintptr_t)L4, 0x3000, PAGE_SIZE, 0) == -1)
+               err(errno, "nvmm_gpa_map");
+       if (nvmm_gpa_map(mach, (uintptr_t)L3, 0x4000, PAGE_SIZE, 0) == -1)
+               err(errno, "nvmm_gpa_map");
+       if (nvmm_gpa_map(mach, (uintptr_t)L2, 0x5000, PAGE_SIZE, 0) == -1)
+               err(errno, "nvmm_gpa_map");
+       if (nvmm_gpa_map(mach, (uintptr_t)L1, 0x6000, PAGE_SIZE, 0) == -1)
+               err(errno, "nvmm_gpa_map");
+
+       memset(L4, 0, PAGE_SIZE);
+       memset(L3, 0, PAGE_SIZE);
+       memset(L2, 0, PAGE_SIZE);
+       memset(L1, 0, PAGE_SIZE);
+
+       L4[0] = PG_V | PG_RW | 0x4000;
+       L3[0] = PG_V | PG_RW | 0x5000;
+       L2[0] = PG_V | PG_RW | 0x6000;
+       L1[0x2000 / PAGE_SIZE] = PG_V | PG_RW | 0x2000;
+       L1[0x1000 / PAGE_SIZE] = PG_V | PG_RW | 0x1000;
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void
+mem_callback(struct nvmm_mem *mem)
+{
+       size_t off;
+
+       if (mem->gpa < 0x1000 || mem->gpa + mem->size > 0x1000 + PAGE_SIZE) {
+               printf("Out of page\n");
+               exit(-1);
+       }
+
+       off = mem->gpa - 0x1000;
+
+       printf("-> gpa = %p\n", (void *)mem->gpa);
+
+       if (mem->write) {
+               memcpy(mmiobuf + off, mem->data, mem->size);
+       } else {
+               memcpy(mem->data, mmiobuf + off, mem->size);
+       }
+}
+static int
+handle_memory(struct nvmm_machine *mach, struct nvmm_exit *exit)
+{
+       int ret;
+
+       ret = nvmm_assist_mem(mach, 0, exit, mem_callback);
+       if (ret == -1) {
+               err(errno, "nvmm_assist_mem");
+       }
+
+       return 0;
+}
+
+static void
+run_machine(struct nvmm_machine *mach)
+{
+       struct nvmm_exit exit;
+
+       while (1) {
+               if (nvmm_vcpu_run(mach, 0, &exit) == -1)
+                       err(errno, "nvmm_vcpu_run");
+
+               switch (exit.reason) {
+               case NVMM_EXIT_NONE:
+                       break;
+
+               case NVMM_EXIT_MSR:
+                       /* Stop here. */
+                       return;
+
+               case NVMM_EXIT_MEMORY:
+                       handle_memory(mach, &exit);
+                       break;
+
+               case NVMM_EXIT_SHUTDOWN:
+                       printf("Shutting down!\n");
+                       return;
+
+               default:



Home | Main Index | Thread Index | Old Index