Module Name:    src
Committed By:   maxv
Date:           Mon Jan  7 16:30:26 UTC 2019

Modified Files:
        src/lib/libnvmm: libnvmm.3 libnvmm_x86.c nvmm.h

Log Message:
Optimize: on single memory operand instructions, take the GPA directly from
the exit structure provided by the kernel. This saves an MMU translation,
and sometimes complex address computation (eg SIB).

Drop the GVA field, it is not useful to virtualizers.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/lib/libnvmm/libnvmm.3
cvs rdiff -u -r1.11 -r1.12 src/lib/libnvmm/libnvmm_x86.c
cvs rdiff -u -r1.5 -r1.6 src/lib/libnvmm/nvmm.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libnvmm/libnvmm.3
diff -u src/lib/libnvmm/libnvmm.3:1.7 src/lib/libnvmm/libnvmm.3:1.8
--- src/lib/libnvmm/libnvmm.3:1.7	Sun Jan  6 16:10:51 2019
+++ src/lib/libnvmm/libnvmm.3	Mon Jan  7 16:30:25 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: libnvmm.3,v 1.7 2019/01/06 16:10:51 maxv Exp $
+.\"	$NetBSD: libnvmm.3,v 1.8 2019/01/07 16:30:25 maxv Exp $
 .\"
 .\" Copyright (c) 2018 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd January 06, 2019
+.Dd January 07, 2019
 .Dt LIBNVMM 3
 .Os
 .Sh NAME
@@ -455,7 +455,6 @@ structure as argument.
 This structure describes a Mem transaction:
 .Bd -literal
 struct nvmm_mem {
-	gvaddr_t gva;
 	gpaddr_t gpa;
 	bool write;
 	size_t size;
@@ -480,8 +479,6 @@ to retrieve the desired value.
 .El
 .Pp
 In either case,
-.Va gva
-will indicate the guest virtual address,
 .Va gpa
 will indicate the guest physical address,
 .Va write

Index: src/lib/libnvmm/libnvmm_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.11 src/lib/libnvmm/libnvmm_x86.c:1.12
--- src/lib/libnvmm/libnvmm_x86.c:1.11	Mon Jan  7 13:47:33 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Mon Jan  7 16:30:25 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.11 2019/01/07 13:47:33 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.12 2019/01/07 16:30:25 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -576,7 +576,6 @@ read_guest_memory(struct nvmm_machine *m
 
 	if (is_mmio) {
 		mem.data = data;
-		mem.gva = gva;
 		mem.gpa = gpa;
 		mem.write = false;
 		mem.size = size;
@@ -627,7 +626,6 @@ write_guest_memory(struct nvmm_machine *
 
 	if (is_mmio) {
 		mem.data = data;
-		mem.gva = gva;
 		mem.gpa = gpa;
 		mem.write = true;
 		mem.size = size;
@@ -2687,30 +2685,6 @@ store_to_gva(struct nvmm_x64_state *stat
 }
 
 static int
-store_to_mem(struct nvmm_machine *mach, struct nvmm_x64_state *state,
-    struct x86_instr *instr, struct x86_store *store, struct nvmm_mem *mem)
-{
-	nvmm_prot_t prot;
-	int ret;
-
-	ret = store_to_gva(state, instr, store, &mem->gva, mem->size);
-	if (ret == -1)
-		return -1;
-
-	if ((mem->gva & PAGE_MASK) + mem->size > PAGE_SIZE) {
-		/* Don't allow a cross-page MMIO. */
-		errno = EINVAL;
-		return -1;
-	}
-
-	ret = x86_gva_to_gpa(mach, state, mem->gva, &mem->gpa, &prot);
-	if (ret == -1)
-		return -1;
-
-	return 0;
-}
-
-static int
 fetch_segment(struct nvmm_machine *mach, struct nvmm_x64_state *state)
 {
 	uint8_t inst_bytes[15], byte;
@@ -2820,110 +2794,66 @@ assist_mem_double(struct nvmm_machine *m
 
 static int
 assist_mem_single(struct nvmm_machine *mach, struct nvmm_x64_state *state,
-    struct x86_instr *instr)
+    struct x86_instr *instr, struct nvmm_exit *exit)
 {
 	struct nvmm_mem mem;
 	uint8_t membuf[8];
 	uint64_t val;
-	int ret;
 
 	memset(membuf, 0, sizeof(membuf));
+
+	mem.gpa = exit->u.mem.gpa;
+	mem.size = instr->operand_size;
 	mem.data = membuf;
 
+	/* Determine the direction. */
 	switch (instr->src.type) {
 	case STORE_REG:
 		if (instr->src.disp.type != DISP_NONE) {
 			/* Indirect access. */
 			mem.write = false;
-			mem.size = instr->operand_size;
-			ret = store_to_mem(mach, state, instr, &instr->src,
-			    &mem);
-			if (ret == -1)
-				return -1;
 		} else {
 			/* Direct access. */
 			mem.write = true;
-			mem.size = instr->operand_size;
-			val = state->gprs[instr->src.u.reg->num];
-			val = __SHIFTOUT(val, instr->src.u.reg->mask);
-			memcpy(mem.data, &val, mem.size);
 		}
 		break;
-
 	case STORE_IMM:
 		mem.write = true;
-		mem.size = instr->src.u.imm.size;
-		memcpy(mem.data, &instr->src.u.imm.data, mem.size);
 		break;
-
 	case STORE_SIB:
 		mem.write = false;
-		mem.size = instr->operand_size;
-		ret = store_to_mem(mach, state, instr, &instr->src, &mem);
-		if (ret == -1)
-			return -1;
 		break;
-
 	case STORE_DMO:
 		mem.write = false;
-		mem.size = instr->operand_size;
-		ret = store_to_mem(mach, state, instr, &instr->src, &mem);
-		if (ret == -1)
-			return -1;
 		break;
-
 	default:
-		return -1;
+		DISASSEMBLER_BUG();
 	}
 
-	switch (instr->dst.type) {
-	case STORE_REG:
-		if (instr->dst.disp.type != DISP_NONE) {
-			if (__predict_false(!mem.write)) {
+	if (mem.write) {
+		switch (instr->src.type) {
+		case STORE_REG:
+			if (instr->src.disp.type != DISP_NONE) {
 				DISASSEMBLER_BUG();
 			}
-			mem.size = instr->operand_size;
-			ret = store_to_mem(mach, state, instr, &instr->dst,
-			    &mem);
-			if (ret == -1)
-				return -1;
-		} else {
-			/* nothing */
-		}
-		break;
-
-	case STORE_IMM:
-		/* The dst can't be an immediate. */
-		DISASSEMBLER_BUG();
-
-	case STORE_SIB:
-		if (__predict_false(!mem.write)) {
-			DISASSEMBLER_BUG();
-		}
-		mem.size = instr->operand_size;
-		ret = store_to_mem(mach, state, instr, &instr->dst, &mem);
-		if (ret == -1)
-			return -1;
-		break;
-
-	case STORE_DMO:
-		if (__predict_false(!mem.write)) {
+			val = state->gprs[instr->src.u.reg->num];
+			val = __SHIFTOUT(val, instr->src.u.reg->mask);
+			memcpy(mem.data, &val, mem.size);
+			break;
+		case STORE_IMM:
+			memcpy(mem.data, &instr->src.u.imm.data, mem.size);
+			break;
+		default:
 			DISASSEMBLER_BUG();
 		}
-		mem.size = instr->operand_size;
-		ret = store_to_mem(mach, state, instr, &instr->dst, &mem);
-		if (ret == -1)
-			return -1;
-		break;
-
-	default:
-		return -1;
 	}
 
 	(*instr->emul)(&mem, __callbacks.mem, state->gprs);
 
 	if (!mem.write) {
-		/* instr->dst.type == STORE_REG */
+		if (instr->dst.type != STORE_REG) {
+			DISASSEMBLER_BUG();
+		}
 		memcpy(&val, mem.data, sizeof(uint64_t));
 		val = __SHIFTIN(val, instr->dst.u.reg->mask);
 		state->gprs[instr->dst.u.reg->num] &= ~instr->dst.u.reg->mask;
@@ -2979,7 +2909,7 @@ nvmm_assist_mem(struct nvmm_machine *mac
 	if (instr.opcode->movs) {
 		ret = assist_mem_double(mach, &state, &instr);
 	} else {
-		ret = assist_mem_single(mach, &state, &instr);
+		ret = assist_mem_single(mach, &state, &instr, exit);
 	}
 	if (ret == -1) {
 		errno = ENODEV;

Index: src/lib/libnvmm/nvmm.h
diff -u src/lib/libnvmm/nvmm.h:1.5 src/lib/libnvmm/nvmm.h:1.6
--- src/lib/libnvmm/nvmm.h:1.5	Sun Jan  6 16:10:51 2019
+++ src/lib/libnvmm/nvmm.h	Mon Jan  7 16:30:25 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.h,v 1.5 2019/01/06 16:10:51 maxv Exp $	*/
+/*	$NetBSD: nvmm.h,v 1.6 2019/01/07 16:30:25 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -54,7 +54,6 @@ struct nvmm_io {
 };
 
 struct nvmm_mem {
-	gvaddr_t gva;
 	gpaddr_t gpa;
 	bool write;
 	size_t size;

Reply via email to