CVS commit: src/lib/libnvmm

2021-04-06 Thread Reinoud Zandijk
Module Name:src
Committed By:   reinoud
Date:   Tue Apr  6 08:40:17 UTC 2021

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

Log Message:
Implement nvmm_vcpu::stop, a race-free exit from nvmm_vcpu_run() without
signals. This introduces a new kernel and userland NVMM version indicating
this support.

Patch by Kamil Rytarowski  and committed on his request.

This is the missing libnvmm part I forgot to include in the origional commit.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/lib/libnvmm/libnvmm.c
cvs rdiff -u -r1.18 -r1.19 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.c
diff -u src/lib/libnvmm/libnvmm.c:1.19 src/lib/libnvmm/libnvmm.c:1.20
--- src/lib/libnvmm/libnvmm.c:1.19	Sat Sep  5 07:22:25 2020
+++ src/lib/libnvmm/libnvmm.c	Tue Apr  6 08:40:17 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm.c,v 1.19 2020/09/05 07:22:25 maxv Exp $	*/
+/*	$NetBSD: libnvmm.c,v 1.20 2021/04/06 08:40:17 reinoud Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -310,6 +310,7 @@ nvmm_vcpu_create(struct nvmm_machine *ma
 	vcpu->cpuid = cpuid;
 	vcpu->state = >state;
 	vcpu->event = >event;
+	vcpu->stop = >stop;
 	vcpu->exit = malloc(sizeof(*vcpu->exit));
 
 	return 0;
@@ -561,3 +562,12 @@ nvmm_ctl(int op, void *data, size_t size
 
 	return 0;
 }
+
+int
+nvmm_vcpu_stop(struct nvmm_vcpu *vcpu)
+{
+
+	*vcpu->stop = 1;
+
+	return 0;
+}

Index: src/lib/libnvmm/nvmm.h
diff -u src/lib/libnvmm/nvmm.h:1.18 src/lib/libnvmm/nvmm.h:1.19
--- src/lib/libnvmm/nvmm.h:1.18	Sat Sep  5 07:22:25 2020
+++ src/lib/libnvmm/nvmm.h	Tue Apr  6 08:40:17 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.h,v 1.18 2020/09/05 07:22:25 maxv Exp $	*/
+/*	$NetBSD: nvmm.h,v 1.19 2021/04/06 08:40:17 reinoud Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -37,7 +37,12 @@
 #include 
 #include 
 
-#define NVMM_USER_VERSION	1
+#define NVMM_USER_VERSION	2
+
+/*
+ * Version 1 - Initial release in NetBSD 9.0.
+ * Version 2 - Added nvmm_vcpu::stop.
+ */
 
 struct nvmm_io;
 struct nvmm_mem;
@@ -59,6 +64,7 @@ struct nvmm_vcpu {
 	struct nvmm_vcpu_state *state;
 	struct nvmm_vcpu_event *event;
 	struct nvmm_vcpu_exit *exit;
+	volatile int *stop;
 };
 
 struct nvmm_io {
@@ -123,4 +129,6 @@ int nvmm_ctl(int, void *, size_t);
 
 int nvmm_vcpu_dump(struct nvmm_machine *, struct nvmm_vcpu *);
 
+int nvmm_vcpu_stop(struct nvmm_vcpu *);
+
 #endif /* _LIBNVMM_H_ */



CVS commit: src/lib/libnvmm

2020-10-31 Thread Reinoud Zandijk
Module Name:src
Committed By:   reinoud
Date:   Sat Oct 31 15:44:01 UTC 2020

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Revert (REPE) CMPS support per request of Maxime, it is incorrect.


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.41 src/lib/libnvmm/libnvmm_x86.c:1.42
--- src/lib/libnvmm/libnvmm_x86.c:1.41	Fri Oct 30 21:06:13 2020
+++ src/lib/libnvmm/libnvmm_x86.c	Sat Oct 31 15:44:01 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.41 2020/10/30 21:06:13 reinoud Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.42 2020/10/31 15:44:01 reinoud Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -1051,7 +1051,6 @@ struct x86_opcode {
 	bool movs:1;
 	bool stos:1;
 	bool lods:1;
-	bool cmps:1;
 	bool szoverride:1;
 	bool group1:1;
 	bool group3:1;
@@ -1464,26 +1463,6 @@ static const struct x86_opcode primary_o
 	},
 
 	/*
-	 * CMPS
-	 */
-	[0xA6] = {
-		/* Yb, Xb */
-		.valid = true,
-		.cmps = true,
-		.szoverride = false,
-		.defsize = OPSIZE_BYTE,
-		.emul = _emul_cmp
-	},
-	[0xA7] = {
-		/* Yv, Xv */
-		.valid = true,
-		.cmps = true,
-		.szoverride = true,
-		.defsize = -1,
-		.emul = _emul_cmp
-	},
-
-	/*
 	 * STOS
 	 */
 	[0xAA] = {
@@ -1892,35 +1871,6 @@ node_movs(struct x86_decode_fsm *fsm, st
 }
 
 /*
- * Special node, for CMPS. Fake two displacements of zero on the source and
- * destination registers.
- * XXX coded as clone of movs as its similar in register usage
- * XXX might be merged with node_movs()
- */
-static int
-node_cmps(struct x86_decode_fsm *fsm, struct x86_instr *instr)
-{
-	size_t adrsize;
-
-	adrsize = instr->address_size;
-
-	/* DS:RSI */
-	instr->src.type = STORE_REG;
-	instr->src.u.reg = _map__special[1][2][adrsize-1];
-	instr->src.disp.type = DISP_0;
-
-	/* ES:RDI, force ES */
-	instr->dst.type = STORE_REG;
-	instr->dst.u.reg = _map__special[1][3][adrsize-1];
-	instr->dst.disp.type = DISP_0;
-	instr->dst.hardseg = NVMM_X64_SEG_ES;
-
-	fsm_advance(fsm, 0, NULL);
-
-	return 0;
-}
-
-/*
  * Special node, for STOS and LODS. Fake a displacement of zero on the
  * destination register.
  */
@@ -2520,8 +2470,6 @@ node_primary_opcode(struct x86_decode_fs
 		fsm_advance(fsm, 1, node_stlo);
 	} else if (opcode->movs) {
 		fsm_advance(fsm, 1, node_movs);
-	} else if (opcode->cmps) {
-		fsm_advance(fsm, 1, node_cmps);
 	} else {
 		return -1;
 	}
@@ -2698,16 +2646,8 @@ x86_decode(uint8_t *inst_bytes, size_t i
 
 	while (fsm.fn != NULL) {
 		ret = (*fsm.fn)(, instr);
-		if (ret == -1) {
-			printf("\nNVMM: %s missing support for instruction " \
-			   "with max length %ld : [ ", __func__,
-			   inst_len);
-			for (uint i = 0; i < inst_len; i++)
-printf("%02x ", inst_bytes[i]);
-			printf("], please report to NetBSD!\n\n");
-			fflush(stdout);
+		if (ret == -1)
 			return -1;
-		}
 	}
 
 	instr->len = fsm.buf - inst_bytes;



CVS commit: src/lib/libnvmm

2020-10-30 Thread Reinoud Zandijk
Module Name:src
Committed By:   reinoud
Date:   Fri Oct 30 21:06:13 UTC 2020

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Implement missing (REPE) CMPS instruction support in NVMMs x86_decode().

In apparently rare cases the (REPE) CMPS instruction can trigger an memory
assist. NVMM wouldn't recognize the instruction and thus couldn't assist and
Qemu would abort.


To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.41 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.40 src/lib/libnvmm/libnvmm_x86.c:1.41
--- src/lib/libnvmm/libnvmm_x86.c:1.40	Sat Sep  5 07:22:25 2020
+++ src/lib/libnvmm/libnvmm_x86.c	Fri Oct 30 21:06:13 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.40 2020/09/05 07:22:25 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.41 2020/10/30 21:06:13 reinoud Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -1051,6 +1051,7 @@ struct x86_opcode {
 	bool movs:1;
 	bool stos:1;
 	bool lods:1;
+	bool cmps:1;
 	bool szoverride:1;
 	bool group1:1;
 	bool group3:1;
@@ -1463,6 +1464,26 @@ static const struct x86_opcode primary_o
 	},
 
 	/*
+	 * CMPS
+	 */
+	[0xA6] = {
+		/* Yb, Xb */
+		.valid = true,
+		.cmps = true,
+		.szoverride = false,
+		.defsize = OPSIZE_BYTE,
+		.emul = _emul_cmp
+	},
+	[0xA7] = {
+		/* Yv, Xv */
+		.valid = true,
+		.cmps = true,
+		.szoverride = true,
+		.defsize = -1,
+		.emul = _emul_cmp
+	},
+
+	/*
 	 * STOS
 	 */
 	[0xAA] = {
@@ -1871,6 +1892,35 @@ node_movs(struct x86_decode_fsm *fsm, st
 }
 
 /*
+ * Special node, for CMPS. Fake two displacements of zero on the source and
+ * destination registers.
+ * XXX coded as clone of movs as its similar in register usage
+ * XXX might be merged with node_movs()
+ */
+static int
+node_cmps(struct x86_decode_fsm *fsm, struct x86_instr *instr)
+{
+	size_t adrsize;
+
+	adrsize = instr->address_size;
+
+	/* DS:RSI */
+	instr->src.type = STORE_REG;
+	instr->src.u.reg = _map__special[1][2][adrsize-1];
+	instr->src.disp.type = DISP_0;
+
+	/* ES:RDI, force ES */
+	instr->dst.type = STORE_REG;
+	instr->dst.u.reg = _map__special[1][3][adrsize-1];
+	instr->dst.disp.type = DISP_0;
+	instr->dst.hardseg = NVMM_X64_SEG_ES;
+
+	fsm_advance(fsm, 0, NULL);
+
+	return 0;
+}
+
+/*
  * Special node, for STOS and LODS. Fake a displacement of zero on the
  * destination register.
  */
@@ -2470,6 +2520,8 @@ node_primary_opcode(struct x86_decode_fs
 		fsm_advance(fsm, 1, node_stlo);
 	} else if (opcode->movs) {
 		fsm_advance(fsm, 1, node_movs);
+	} else if (opcode->cmps) {
+		fsm_advance(fsm, 1, node_cmps);
 	} else {
 		return -1;
 	}
@@ -2646,8 +2698,16 @@ x86_decode(uint8_t *inst_bytes, size_t i
 
 	while (fsm.fn != NULL) {
 		ret = (*fsm.fn)(, instr);
-		if (ret == -1)
+		if (ret == -1) {
+			printf("\nNVMM: %s missing support for instruction " \
+			   "with max length %ld : [ ", __func__,
+			   inst_len);
+			for (uint i = 0; i < inst_len; i++)
+printf("%02x ", inst_bytes[i]);
+			printf("], please report to NetBSD!\n\n");
+			fflush(stdout);
 			return -1;
+		}
 	}
 
 	instr->len = fsm.buf - inst_bytes;



CVS commit: src/lib/libnvmm

2019-04-29 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Apr 29 19:03:17 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm.3

Log Message:
sync with reality


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/lib/libnvmm/libnvmm.3

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.15 src/lib/libnvmm/libnvmm.3:1.16
--- src/lib/libnvmm/libnvmm.3:1.15	Mon Apr 29 18:54:25 2019
+++ src/lib/libnvmm/libnvmm.3	Mon Apr 29 19:03:17 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: libnvmm.3,v 1.15 2019/04/29 18:54:25 maxv Exp $
+.\"	$NetBSD: libnvmm.3,v 1.16 2019/04/29 19:03:17 maxv Exp $
 .\"
 .\" Copyright (c) 2018, 2019 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 April 7, 2019
+.Dd April 29, 2019
 .Dt LIBNVMM 3
 .Os
 .Sh NAME
@@ -284,12 +284,9 @@ struct nvmm_capability {
 	uint64_t max_machines;
 	uint64_t max_vcpus;
 	uint64_t max_ram;
-	union {
-		struct {
-			...
-		} x86;
-		uint64_t rsvd[8];
-	} u;
+	struct {
+		...
+	} arch;
 };
 .Ed
 .Pp
@@ -384,26 +381,20 @@ The
 .Cd nvmm_exit
 structure is used to handle VM exits:
 .Bd -literal
-enum nvmm_exit_reason {
-	NVMM_EXIT_NONE		= 0x,
-
-	/* General. */
-	NVMM_EXIT_MEMORY	= 0x0001,
-	NVMM_EXIT_IO		= 0x0002,
-	NVMM_EXIT_MSR		= 0x0003,
-	NVMM_EXIT_INT_READY	= 0x0004,
-	NVMM_EXIT_NMI_READY	= 0x0005,
-	NVMM_EXIT_HALTED	= 0x0006,
-	NVMM_EXIT_SHUTDOWN	= 0x0007,
-
-	/* Instructions (x86). */
+/* Exit Reasons */
+#define NVMM_EXIT_NONE		0xULL
+#define NVMM_EXIT_MEMORY	0x0001ULL
+#define NVMM_EXIT_IO		0x0002ULL
+#define NVMM_EXIT_MSR		0x0003ULL
+#define NVMM_EXIT_INT_READY	0x0004ULL
+#define NVMM_EXIT_NMI_READY	0x0005ULL
+#define NVMM_EXIT_HALTED	0x0006ULL
+#define NVMM_EXIT_SHUTDOWN	0x0007ULL
 	...
-
-	NVMM_EXIT_INVALID	= 0x
-};
+#define NVMM_EXIT_INVALID	0xULL
 
 struct nvmm_exit {
-	enum nvmm_exit_reason reason;
+	uint64_t reason;
 	union {
 		...
 	} u;



CVS commit: src/lib/libnvmm

2019-04-29 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Apr 29 17:27:57 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm.c

Log Message:
Remove useless calls to nvmm_init().


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/lib/libnvmm/libnvmm.c

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.c
diff -u src/lib/libnvmm/libnvmm.c:1.10 src/lib/libnvmm/libnvmm.c:1.11
--- src/lib/libnvmm/libnvmm.c:1.10	Sun Apr 28 14:22:13 2019
+++ src/lib/libnvmm/libnvmm.c	Mon Apr 29 17:27:57 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm.c,v 1.10 2019/04/28 14:22:13 maxv Exp $	*/
+/*	$NetBSD: libnvmm.c,v 1.11 2019/04/29 17:27:57 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -237,10 +237,6 @@ nvmm_machine_destroy(struct nvmm_machine
 	struct nvmm_ioc_machine_destroy args;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	args.machid = mach->machid;
 
 	ret = ioctl(nvmm_fd, NVMM_IOC_MACHINE_DESTROY, );
@@ -259,10 +255,6 @@ nvmm_machine_configure(struct nvmm_machi
 	struct nvmm_ioc_machine_configure args;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	args.machid = mach->machid;
 	args.op = op;
 	args.conf = conf;
@@ -281,10 +273,6 @@ nvmm_vcpu_create(struct nvmm_machine *ma
 	struct nvmm_comm_page *comm;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	args.machid = mach->machid;
 	args.cpuid = cpuid;
 
@@ -309,10 +297,6 @@ nvmm_vcpu_destroy(struct nvmm_machine *m
 	struct nvmm_comm_page *comm;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	args.machid = mach->machid;
 	args.cpuid = cpuid;
 
@@ -332,10 +316,6 @@ nvmm_vcpu_setstate(struct nvmm_machine *
 {
 	struct nvmm_comm_page *comm;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	if (__predict_false(cpuid >= mach->npages)) {
 		return -1;
 	}
@@ -356,10 +336,6 @@ nvmm_vcpu_getstate(struct nvmm_machine *
 	struct nvmm_comm_page *comm;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	if (__predict_false(cpuid >= mach->npages)) {
 		return -1;
 	}
@@ -389,10 +365,6 @@ nvmm_vcpu_inject(struct nvmm_machine *ma
 	struct nvmm_ioc_vcpu_inject args;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	args.machid = mach->machid;
 	args.cpuid = cpuid;
 	memcpy(, event, sizeof(args.event));
@@ -411,10 +383,6 @@ nvmm_vcpu_run(struct nvmm_machine *mach,
 	struct nvmm_ioc_vcpu_run args;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	args.machid = mach->machid;
 	args.cpuid = cpuid;
 	memset(, 0, sizeof(args.exit));
@@ -435,10 +403,6 @@ nvmm_gpa_map(struct nvmm_machine *mach, 
 	struct nvmm_ioc_gpa_map args;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	ret = __area_add(mach, hva, gpa, size, prot);
 	if (ret == -1)
 		return -1;
@@ -465,10 +429,6 @@ nvmm_gpa_unmap(struct nvmm_machine *mach
 	struct nvmm_ioc_gpa_unmap args;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	ret = __area_delete(mach, hva, gpa, size);
 	if (ret == -1)
 		return -1;
@@ -492,10 +452,6 @@ nvmm_hva_map(struct nvmm_machine *mach, 
 	struct nvmm_ioc_hva_map args;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	args.machid = mach->machid;
 	args.hva = hva;
 	args.size = size;
@@ -513,10 +469,6 @@ nvmm_hva_unmap(struct nvmm_machine *mach
 	struct nvmm_ioc_hva_unmap args;
 	int ret;
 
-	if (nvmm_init() == -1) {
-		return -1;
-	}
-
 	args.machid = mach->machid;
 	args.hva = hva;
 	args.size = size;



CVS commit: src/lib/libnvmm

2019-04-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Apr  7 14:13:03 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm.3

Log Message:
Sync, and fix grammar.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/lib/libnvmm/libnvmm.3

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.13 src/lib/libnvmm/libnvmm.3:1.14
--- src/lib/libnvmm/libnvmm.3:1.13	Thu Apr  4 17:33:47 2019
+++ src/lib/libnvmm/libnvmm.3	Sun Apr  7 14:13:03 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: libnvmm.3,v 1.13 2019/04/04 17:33:47 maxv Exp $
+.\"	$NetBSD: libnvmm.3,v 1.14 2019/04/07 14:13:03 maxv Exp $
 .\"
 .\" Copyright (c) 2018, 2019 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 April 4, 2019
+.Dd April 7, 2019
 .Dt LIBNVMM 3
 .Os
 .Sh NAME
@@ -361,7 +361,7 @@ struct nvmm_x64_state {
 	uint64_t crs[NVMM_X64_NCR];
 	uint64_t drs[NVMM_X64_NDR];
 	uint64_t msrs[NVMM_X64_NMSR];
-	uint64_t misc[NVMM_X64_NMISC];
+	struct nvmm_x64_state_intr intr;
 	struct fxsave fpu;
 };
 .Ed
@@ -466,7 +466,7 @@ event, if:
 the event is a hardware interrupt, and the VCPU runs with interrupts disabled,
 or
 .It
-the event is a non-maskable interrupt (NMI), and the VCPU is already in a
+the event is a non-maskable interrupt (NMI), and the VCPU is already in an
 in-NMI context.
 .El
 .Pp



CVS commit: src/lib/libnvmm

2019-04-04 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Apr  4 17:33:47 UTC 2019

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

Log Message:
Check the GPA permissions too in the Assists, because it is possible that
the guest traps on a page the virtualizer marked as read-only (even if it
appears as read-write in the HVA).


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/lib/libnvmm/libnvmm.3
cvs rdiff -u -r1.7 -r1.8 src/lib/libnvmm/libnvmm.c
cvs rdiff -u -r1.27 -r1.28 src/lib/libnvmm/libnvmm_x86.c
cvs rdiff -u -r1.6 -r1.7 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.12 src/lib/libnvmm/libnvmm.3:1.13
--- src/lib/libnvmm/libnvmm.3:1.12	Thu Mar 21 20:21:40 2019
+++ src/lib/libnvmm/libnvmm.3	Thu Apr  4 17:33:47 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: libnvmm.3,v 1.12 2019/03/21 20:21:40 maxv Exp $
+.\"	$NetBSD: libnvmm.3,v 1.13 2019/04/04 17:33:47 maxv Exp $
 .\"
 .\" Copyright (c) 2018, 2019 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 March 19, 2019
+.Dd April 4, 2019
 .Dt LIBNVMM 3
 .Os
 .Sh NAME
@@ -77,7 +77,7 @@
 "gvaddr_t gva" "gpaddr_t *gpa" "nvmm_prot_t *prot"
 .Ft int
 .Fn nvmm_gpa_to_hva "struct nvmm_machine *mach" "gpaddr_t gpa" \
-"uintptr_t *hva"
+"uintptr_t *hva" "nvmm_prot_t *prot"
 .Ft void
 .Fn nvmm_callbacks_register "const struct nvmm_callbacks *cbs"
 .Ft int
@@ -241,6 +241,8 @@ the guest physical address indicated in
 .Fa gpa
 into a host virtual address returned in
 .Fa hva .
+The associated page premissions are returned in
+.Fa prot .
 .Fa gpa
 must be page-aligned.
 .Pp

Index: src/lib/libnvmm/libnvmm.c
diff -u src/lib/libnvmm/libnvmm.c:1.7 src/lib/libnvmm/libnvmm.c:1.8
--- src/lib/libnvmm/libnvmm.c:1.7	Thu Mar 21 20:21:40 2019
+++ src/lib/libnvmm/libnvmm.c	Thu Apr  4 17:33:47 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm.c,v 1.7 2019/03/21 20:21:40 maxv Exp $	*/
+/*	$NetBSD: libnvmm.c,v 1.8 2019/04/04 17:33:47 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -50,6 +50,7 @@ typedef struct __area {
 	gpaddr_t gpa;
 	uintptr_t hva;
 	size_t size;
+	nvmm_prot_t prot;
 } area_t;
 
 typedef LIST_HEAD(, __area) area_list_t;
@@ -83,11 +84,21 @@ __area_isvalid(struct nvmm_machine *mach
 }
 
 static int
-__area_add(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa, size_t size)
+__area_add(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa, size_t size,
+int prot)
 {
 	area_list_t *areas = mach->areas;
+	nvmm_prot_t nprot;
 	area_t *area;
 
+	nprot = 0;
+	if (prot & PROT_READ)
+		nprot |= NVMM_PROT_READ;
+	if (prot & PROT_WRITE)
+		nprot |= NVMM_PROT_WRITE;
+	if (prot & PROT_EXEC)
+		nprot |= NVMM_PROT_EXEC;
+
 	if (!__area_isvalid(mach, hva, gpa, size)) {
 		errno = EINVAL;
 		return -1;
@@ -99,6 +110,7 @@ __area_add(struct nvmm_machine *mach, ui
 	area->gpa = gpa;
 	area->hva = hva;
 	area->size = size;
+	area->prot = nprot;
 
 	LIST_INSERT_HEAD(areas, area, list);
 
@@ -383,7 +395,7 @@ nvmm_gpa_map(struct nvmm_machine *mach, 
 		return -1;
 	}
 
-	ret = __area_add(mach, hva, gpa, size);
+	ret = __area_add(mach, hva, gpa, size, prot);
 	if (ret == -1)
 		return -1;
 
@@ -477,7 +489,8 @@ nvmm_hva_unmap(struct nvmm_machine *mach
  */
 
 int
-nvmm_gpa_to_hva(struct nvmm_machine *mach, gpaddr_t gpa, uintptr_t *hva)
+nvmm_gpa_to_hva(struct nvmm_machine *mach, gpaddr_t gpa, uintptr_t *hva,
+nvmm_prot_t *prot)
 {
 	area_list_t *areas = mach->areas;
 	area_t *ent;
@@ -485,6 +498,7 @@ nvmm_gpa_to_hva(struct nvmm_machine *mac
 	LIST_FOREACH(ent, areas, list) {
 		if (gpa >= ent->gpa && gpa < ent->gpa + ent->size) {
 			*hva = ent->hva + (gpa - ent->gpa);
+			*prot = ent->prot;
 			return 0;
 		}
 	}

Index: src/lib/libnvmm/libnvmm_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.27 src/lib/libnvmm/libnvmm_x86.c:1.28
--- src/lib/libnvmm/libnvmm_x86.c:1.27	Thu Mar  7 15:47:34 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Thu Apr  4 17:33:47 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.27 2019/03/07 15:47:34 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.28 2019/04/04 17:33:47 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -123,13 +123,14 @@ x86_gva_to_gpa_32bit(struct nvmm_machine
 	gpaddr_t L2gpa, L1gpa;
 	uintptr_t L2hva, L1hva;
 	pte_32bit_t *pdir, pte;
+	nvmm_prot_t pageprot;
 
 	/* We begin with an RWXU access. */
 	*prot = NVMM_PROT_ALL;
 
 	/* Parse L2. */
 	L2gpa = (cr3 & CR3_FRAME_32BIT);
-	if (nvmm_gpa_to_hva(mach, L2gpa, ) == -1)
+	if (nvmm_gpa_to_hva(mach, L2gpa, , ) == -1)
 		return -1;
 	pdir = (pte_32bit_t *)L2hva;
 	pte = pdir[pte32_l2idx(gva)];
@@ -149,7 +150,7 @@ x86_gva_to_gpa_32bit(struct nvmm_machine
 
 	/* Parse L1. */
 	L1gpa = (pte & 

CVS commit: src/lib/libnvmm

2019-03-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Mar  7 15:47:34 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Micro optimizations:

 - Compress x86_rexpref, x86_regmodrm, x86_opcode and x86_instr.
 - Cache-align the register, opcode and group tables.
 - Modify the opcode tables to have 256 entries, and avoid a lookup.


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.26 src/lib/libnvmm/libnvmm_x86.c:1.27
--- src/lib/libnvmm/libnvmm_x86.c:1.26	Tue Feb 26 12:23:12 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Thu Mar  7 15:47:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.26 2019/02/26 12:23:12 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.27 2019/03/07 15:47:34 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -46,6 +46,7 @@
 #include "nvmm.h"
 
 #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define __cacheline_aligned __attribute__((__aligned__(64)))
 
 #include 
 
@@ -904,15 +905,15 @@ struct x86_legpref {
 	bool adr_ovr:1;
 	bool rep:1;
 	bool repn:1;
-	int seg;
+	int8_t seg;
 };
 
 struct x86_rexpref {
-	bool present;
-	bool w;
-	bool r;
-	bool x;
-	bool b;
+	bool b:1;
+	bool x:1;
+	bool r:1;
+	bool w:1;
+	bool present:1;
 };
 
 struct x86_reg {
@@ -962,10 +963,9 @@ enum REGMODRM__Rm {
 };
 
 struct x86_regmodrm {
-	bool present;
-	enum REGMODRM__Mod mod;
-	enum REGMODRM__Reg reg;
-	enum REGMODRM__Rm rm;
+	uint8_t mod:2;
+	uint8_t reg:3;
+	uint8_t rm:3;
 };
 
 struct x86_immediate {
@@ -999,22 +999,20 @@ struct x86_store {
 };
 
 struct x86_instr {
-	size_t len;
+	uint8_t len;
 	struct x86_legpref legpref;
 	struct x86_rexpref rexpref;
-	size_t operand_size;
-	size_t address_size;
-	uint64_t zeroextend_mask;
-
 	struct x86_regmodrm regmodrm;
+	uint8_t operand_size;
+	uint8_t address_size;
+	uint64_t zeroextend_mask;
 
 	const struct x86_opcode *opcode;
+	const struct x86_emul *emul;
 
 	struct x86_store src;
 	struct x86_store dst;
 	struct x86_store *strm;
-
-	const struct x86_emul *emul;
 };
 
 struct x86_decode_fsm {
@@ -1030,22 +1028,21 @@ struct x86_decode_fsm {
 };
 
 struct x86_opcode {
-	uint8_t byte;
-	bool regmodrm;
-	bool regtorm;
-	bool dmo;
-	bool todmo;
-	bool movs;
-	bool stos;
-	bool lods;
-	bool szoverride;
-	int defsize;
-	int allsize;
-	bool group1;
-	bool group3;
-	bool group11;
-	bool immediate;
-	int flags;
+	bool valid:1;
+	bool regmodrm:1;
+	bool regtorm:1;
+	bool dmo:1;
+	bool todmo:1;
+	bool movs:1;
+	bool stos:1;
+	bool lods:1;
+	bool szoverride:1;
+	bool group1:1;
+	bool group3:1;
+	bool group11:1;
+	bool immediate:1;
+	uint8_t defsize;
+	uint8_t flags;
 	const struct x86_emul *emul;
 };
 
@@ -1062,59 +1059,56 @@ struct x86_group_entry {
 #define FLAG_immz	0x02
 #define FLAG_ze		0x04
 
-static const struct x86_group_entry group1[8] = {
+static const struct x86_group_entry group1[8] __cacheline_aligned = {
 	[1] = { .emul = _emul_or },
 	[4] = { .emul = _emul_and },
 	[6] = { .emul = _emul_xor },
 	[7] = { .emul = _emul_cmp }
 };
 
-static const struct x86_group_entry group3[8] = {
+static const struct x86_group_entry group3[8] __cacheline_aligned = {
 	[0] = { .emul = _emul_test },
 	[1] = { .emul = _emul_test }
 };
 
-static const struct x86_group_entry group11[8] = {
+static const struct x86_group_entry group11[8] __cacheline_aligned = {
 	[0] = { .emul = _emul_mov }
 };
 
-static const struct x86_opcode primary_opcode_table[] = {
+static const struct x86_opcode primary_opcode_table[256] __cacheline_aligned = {
 	/*
 	 * Group1
 	 */
-	{
+	[0x80] = {
 		/* Eb, Ib */
-		.byte = 0x80,
+		.valid = true,
 		.regmodrm = true,
 		.regtorm = true,
 		.szoverride = false,
 		.defsize = OPSIZE_BYTE,
-		.allsize = -1,
 		.group1 = true,
 		.immediate = true,
 		.emul = NULL /* group1 */
 	},
-	{
+	[0x81] = {
 		/* Ev, Iz */
-		.byte = 0x81,
+		.valid = true,
 		.regmodrm = true,
 		.regtorm = true,
 		.szoverride = true,
 		.defsize = -1,
-		.allsize = OPSIZE_WORD|OPSIZE_DOUB|OPSIZE_QUAD,
 		.group1 = true,
 		.immediate = true,
 		.flags = FLAG_immz,
 		.emul = NULL /* group1 */
 	},
-	{
+	[0x83] = {
 		/* Ev, Ib */
-		.byte = 0x83,
+		.valid = true,
 		.regmodrm = true,
 		.regtorm = true,
 		.szoverride = true,
 		.defsize = -1,
-		.allsize = OPSIZE_WORD|OPSIZE_DOUB|OPSIZE_QUAD,
 		.group1 = true,
 		.immediate = true,
 		.flags = FLAG_imm8,
@@ -1124,26 +1118,24 @@ static const struct x86_opcode primary_o
 	/*
 	 * Group3
 	 */
-	{
+	[0xF6] = {
 		/* Eb, Ib */
-		.byte = 0xF6,
+		.valid = true,
 		.regmodrm = true,
 		.regtorm = true,
 		.szoverride = false,
 		.defsize = OPSIZE_BYTE,
-		.allsize = -1,
 		.group3 = true,
 		.immediate = true,
 		.emul = NULL /* group3 */
 	},
-	{
+	[0xF7] = {
 		/* Ev, Iz */
-		.byte = 0xF7,
+		.valid = true,
 		.regmodrm = true,
 		

CVS commit: src/lib/libnvmm

2019-02-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Feb 26 10:18:39 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Set hardseg to -1 rather than 0, because 0 can be a valid segment.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.24 src/lib/libnvmm/libnvmm_x86.c:1.25
--- src/lib/libnvmm/libnvmm_x86.c:1.24	Sun Feb 17 20:25:46 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Tue Feb 26 10:18:39 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.24 2019/02/17 20:25:46 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.25 2019/02/26 10:18:39 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -2556,6 +2556,8 @@ x86_decode(uint8_t *inst_bytes, size_t i
 
 	memset(instr, 0, sizeof(*instr));
 	instr->legpref.seg = -1;
+	instr->src.hardseg = -1;
+	instr->dst.hardseg = -1;
 
 	fsm.is64bit = is_64bit(state);
 	fsm.is32bit = is_32bit(state);
@@ -2926,7 +2928,7 @@ store_to_gva(struct nvmm_x64_state *stat
 		gva += store->disp.data;
 	}
 
-	if (store->hardseg != 0) {
+	if (store->hardseg != -1) {
 		seg = store->hardseg;
 	} else {
 		if (__predict_false(instr->legpref.seg != -1)) {



CVS commit: src/lib/libnvmm

2019-02-17 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Feb 17 20:25:46 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Fix handling of SIB instructions. We were jumping to the SIB node _before_
fetching the displacement, so the node would always think there was no
displacement.

This didn't alter the final GPA we would be touching - because it is
fetched from the kernel directly and not from the computation -, but it
altered the instruction length, and on some guests (like Fedora 64bit),
the VCPU would resume execution at the wrong RIP and crash.

Now these guests work.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.23 src/lib/libnvmm/libnvmm_x86.c:1.24
--- src/lib/libnvmm/libnvmm_x86.c:1.23	Fri Feb 15 16:42:27 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Sun Feb 17 20:25:46 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.23 2019/02/15 16:42:27 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.24 2019/02/17 20:25:46 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -2233,15 +2233,15 @@ node_regmodrm(struct x86_decode_fsm *fsm
 		strg->u.reg = reg;
 	}
 
+	/* The displacement applies to RM. */
+	strm->disp.type = get_disp_type(instr);
+
 	if (has_sib(instr)) {
 		/* Overwrites RM */
 		fsm_advance(fsm, 1, node_sib);
 		return 0;
 	}
 
-	/* The displacement applies to RM. */
-	strm->disp.type = get_disp_type(instr);
-
 	if (is_rip_relative(fsm, instr)) {
 		/* Overwrites RM */
 		strm->type = STORE_REG;



CVS commit: src/lib/libnvmm

2019-02-15 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Fri Feb 15 16:42:27 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Remove the PSE check in the 32bit-PAE MMU. Setting CR4.PAE automatically
enables PSE regardless of whether CR4.PSE is set or not, so we should just
ignore it.

With this in place I can boot Windows 8.1 on NVMM.


To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.22 src/lib/libnvmm/libnvmm_x86.c:1.23
--- src/lib/libnvmm/libnvmm_x86.c:1.22	Thu Feb 14 14:30:20 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Fri Feb 15 16:42:27 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.22 2019/02/14 14:30:20 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.23 2019/02/15 16:42:27 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -188,7 +188,7 @@ typedef uint64_t pte_32bit_pae_t;
 
 static int
 x86_gva_to_gpa_32bit_pae(struct nvmm_machine *mach, uint64_t cr3,
-gvaddr_t gva, gpaddr_t *gpa, bool has_pse, nvmm_prot_t *prot)
+gvaddr_t gva, gpaddr_t *gpa, nvmm_prot_t *prot)
 {
 	gpaddr_t L3gpa, L2gpa, L1gpa;
 	uintptr_t L3hva, L2hva, L1hva;
@@ -224,8 +224,6 @@ x86_gva_to_gpa_32bit_pae(struct nvmm_mac
 		*prot &= ~NVMM_PROT_WRITE;
 	if (pte & PG_NX)
 		*prot &= ~NVMM_PROT_EXEC;
-	if ((pte & PG_PS) && !has_pse)
-		return -1;
 	if (pte & PG_PS) {
 		*gpa = (pte & PTE32_PAE_L2_FRAME);
 		*gpa = *gpa + (gva & PTE32_PAE_L1_MASK);
@@ -408,8 +406,7 @@ x86_gva_to_gpa(struct nvmm_machine *mach
 		ret = x86_gva_to_gpa_64bit(mach, cr3, gva, gpa, prot);
 	} else if (is_pae && !is_lng) {
 		/* 32bit PAE */
-		ret = x86_gva_to_gpa_32bit_pae(mach, cr3, gva, gpa, has_pse,
-		prot);
+		ret = x86_gva_to_gpa_32bit_pae(mach, cr3, gva, gpa, prot);
 	} else if (!is_pae && !is_lng) {
 		/* 32bit */
 		ret = x86_gva_to_gpa_32bit(mach, cr3, gva, gpa, has_pse, prot);



CVS commit: src/lib/libnvmm

2019-02-12 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Feb 12 14:50:21 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Optimize: fetch only 5 bytes instead of 15, the instruction can have only
up to five prefixes.


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.20 src/lib/libnvmm/libnvmm_x86.c:1.21
--- src/lib/libnvmm/libnvmm_x86.c:1.20	Sun Feb 10 19:30:28 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Tue Feb 12 14:50:21 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.20 2019/02/10 19:30:28 christos Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.21 2019/02/12 14:50:21 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -2958,7 +2958,7 @@ store_to_gva(struct nvmm_x64_state *stat
 static int
 fetch_segment(struct nvmm_machine *mach, struct nvmm_x64_state *state)
 {
-	uint8_t inst_bytes[15], byte;
+	uint8_t inst_bytes[5], byte;
 	size_t i, fetchsize;
 	gvaddr_t gva;
 	int ret, seg;



CVS commit: src/lib/libnvmm

2019-02-10 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Sun Feb 10 19:30:28 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
 is not legal.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.19 src/lib/libnvmm/libnvmm_x86.c:1.20
--- src/lib/libnvmm/libnvmm_x86.c:1.19	Thu Feb  7 05:58:45 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Sun Feb 10 14:30:28 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.19 2019/02/07 10:58:45 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.20 2019/02/10 19:30:28 christos Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -2584,7 +2584,7 @@ x86_decode(uint8_t *inst_bytes, size_t i
 
 #define EXEC_INSTR(sz, instr)		\
 static uint##sz##_t			\
-exec_##instrsz(uint##sz##_t op1, uint##sz##_t op2, uint64_t *rflags)\
+exec_##instr##sz(uint##sz##_t op1, uint##sz##_t op2, uint64_t *rflags)	\
 {	\
 	uint##sz##_t res;		\
 	__asm __volatile (		\



CVS commit: src/lib/libnvmm

2019-02-05 Thread Thomas Klausner
Module Name:src
Committed By:   wiz
Date:   Tue Feb  5 15:03:35 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm.3

Log Message:
Mark up NULL with Dv. Remove empty line.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/lib/libnvmm/libnvmm.3

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.10 src/lib/libnvmm/libnvmm.3:1.11
--- src/lib/libnvmm/libnvmm.3:1.10	Tue Feb  5 13:56:32 2019
+++ src/lib/libnvmm/libnvmm.3	Tue Feb  5 15:03:35 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: libnvmm.3,v 1.10 2019/02/05 13:56:32 maxv Exp $
+.\"	$NetBSD: libnvmm.3,v 1.11 2019/02/05 15:03:35 wiz Exp $
 .\"
 .\" Copyright (c) 2018, 2019 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -377,7 +377,6 @@ During VM exits, a partial VCPU state ar
 see
 .Sx Exit Reasons
 below for details.
-
 .Ss Exit Reasons
 The
 .Cd nvmm_exit
@@ -499,7 +498,8 @@ or
 .Fn nvmm_assist_mem
 are invoked.
 VMM software that does not intend to use either of these assists can put
-NULL in the callbacks.
+.Dv NULL
+in the callbacks.
 .Ss I/O Assist
 When a VM exit occurs with reason
 .Cd NVMM_EXIT_IO ,



CVS commit: src/lib/libnvmm

2019-02-05 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Feb  5 13:56:32 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm.3

Log Message:
Sync with reality, and improve.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/lib/libnvmm/libnvmm.3

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.9 src/lib/libnvmm/libnvmm.3:1.10
--- src/lib/libnvmm/libnvmm.3:1.9	Mon Jan  7 22:17:02 2019
+++ src/lib/libnvmm/libnvmm.3	Tue Feb  5 13:56:32 2019
@@ -1,6 +1,6 @@
-.\"	$NetBSD: libnvmm.3,v 1.9 2019/01/07 22:17:02 wiz Exp $
+.\"	$NetBSD: libnvmm.3,v 1.10 2019/02/05 13:56:32 maxv Exp $
 .\"
-.\" Copyright (c) 2018 The NetBSD Foundation, Inc.
+.\" Copyright (c) 2018, 2019 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This code is derived from software contributed to The NetBSD Foundation
@@ -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 7, 2019
+.Dd February 5, 2019
 .Dt LIBNVMM 3
 .Os
 .Sh NAME
@@ -96,10 +96,13 @@ A virtual machine is described by an opa
 VMM software should not attempt to modify this structure directly, and should
 use the API provided by
 .Nm
-to handle virtual machines.
+to manage virtual machines.
 .Pp
 .Fn nvmm_capability
 gets the capabilities of NVMM.
+See
+.Sx NVMM Capability
+below for details.
 .Pp
 .Fn nvmm_machine_create
 creates a virtual machine in the kernel.
@@ -159,6 +162,17 @@ See
 .Sx VCPU State Area
 below for details.
 .Pp
+.Fn nvmm_vcpu_inject
+injects into the CPU identified by
+.Fa cpuid
+of the machine
+.Fa mach
+an event described by
+.Fa event .
+See
+.Sx Event Injection
+below for details.
+.Pp
 .Fn nvmm_vcpu_run
 runs the CPU identified by
 .Fa cpuid
@@ -282,17 +296,88 @@ For example, the
 field indicates the maximum number of virtual machines supported, while
 .Cd max_vcpus
 indicates the maximum number of VCPUs supported per virtual machine.
+.Ss Guest-Host Mappings
+Each virtual machine has an associated guest physical memory.
+VMM software is allowed to modify this guest physical memory by mapping
+it into some parts of its virtual address space.
+.Pp
+VMM software should follow the following steps to achieve that:
+.Pp
+.Bl -bullet -offset indent -compact
+.It
+Call
+.Fn nvmm_hva_map
+to create in the host's virtual address space an area of memory that can
+be shared with a guest.
+Typically, the
+.Fa hva
+parameter will be a pointer to an area that was previously mapped via
+.Fn mmap .
+.Fn nvmm_hva_map
+will replace the content of the area, and will make it read-write (but not
+executable).
+.It
+Make available in the guest an area of guest physical memory, by calling
+.Fn nvmm_gpa_map
+and passing in the
+.Fa hva
+parameter the value that was previously given to
+.Fn nvmm_hva_map .
+.Fn nvmm_gpa_map
+does not replace the content of any memory, it only creates a direct link
+from
+.Fa gpa
+into
+.Fa hva .
+.Fn nvmm_gpa_unmap
+removes this link without modifying
+.Fa hva .
+.El
+.Pp
+The guest will then be able to use the guest physical address passed in the
+.Fa gpa
+parameter of
+.Fn nvmm_gpa_map .
+Each change the guest makes in
+.Fa gpa
+will be reflected in the host's
+.Fa hva ,
+and vice versa.
+.Pp
+It is illegal for VMM software to use
+.Fn munmap
+on an area that was mapped via
+.Fn nvmm_hva_map .
 .Ss VCPU State Area
 A VCPU state area is a structure that entirely defines the content of the
 registers of a VCPU.
 Only one such structure exists, for x86:
 .Bd -literal
 struct nvmm_x64_state {
-	...
+	struct nvmm_x64_state_seg segs[NVMM_X64_NSEG];
+	uint64_t gprs[NVMM_X64_NGPR];
+	uint64_t crs[NVMM_X64_NCR];
+	uint64_t drs[NVMM_X64_NDR];
+	uint64_t msrs[NVMM_X64_NMSR];
+	uint64_t misc[NVMM_X64_NMISC];
+	struct fxsave fpu;
 };
 .Ed
 .Pp
 Refer to functional examples to see precisely how to use this structure.
+.Pp
+A VCPU state area is divided in sub-states.
+A
+.Fa flags
+parameter is used to set and get the VCPU state; it acts as a bitmap which
+indicates which sub-states to set or get.
+.Pp
+During VM exits, a partial VCPU state area is provided in
+.Va exitstate ,
+see
+.Sx Exit Reasons
+below for details.
+
 .Ss Exit Reasons
 The
 .Cd nvmm_exit
@@ -307,7 +392,8 @@ enum nvmm_exit_reason {
 	NVMM_EXIT_MSR		= 0x0003,
 	NVMM_EXIT_INT_READY	= 0x0004,
 	NVMM_EXIT_NMI_READY	= 0x0005,
-	NVMM_EXIT_SHUTDOWN	= 0x0006,
+	NVMM_EXIT_HALTED	= 0x0006,
+	NVMM_EXIT_SHUTDOWN	= 0x0007,
 
 	/* Instructions (x86). */
 	...
@@ -392,6 +478,28 @@ and NVMM will cause a VM exit with reaso
 or
 .Cd NVMM_EXIT_NMI_READY
 to indicate that VMM software can now reinject the desired event.
+.Ss Assist Callbacks
+In order to assist emulation of certain operations,
+.Nm
+requires VMM software to register, via
+.Fn 

CVS commit: src/lib/libnvmm

2019-01-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Jan 26 14:44:54 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Ah, fix bug: when the opcode has an immediate, we fill the src with a
register storage, but then we overwrite it without zeroing out the highest
bits of the resulting immediate (which may contain garbage from the union).


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.15 src/lib/libnvmm/libnvmm_x86.c:1.16
--- src/lib/libnvmm/libnvmm_x86.c:1.15	Sun Jan 13 10:43:22 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Sat Jan 26 14:44:54 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.15 2019/01/13 10:43:22 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.16 2019/01/26 14:44:54 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -2071,12 +2071,14 @@ node_regmodrm(struct x86_decode_fsm *fsm
 		instr->emul = group11[instr->regmodrm.reg].emul;
 	}
 
-	reg = get_register_reg(instr, opcode);
-	if (reg == NULL) {
-		return -1;
+	if (!opcode->immediate) {
+		reg = get_register_reg(instr, opcode);
+		if (reg == NULL) {
+			return -1;
+		}
+		strg->type = STORE_REG;
+		strg->u.reg = reg;
 	}
-	strg->type = STORE_REG;
-	strg->u.reg = reg;
 
 	if (has_sib(instr)) {
 		/* Overwrites RM */



CVS commit: src/lib/libnvmm

2019-01-13 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Jan 13 10:43:23 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Handle more corner cases, clean up a little, and add a set of instructions
in Group1.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.14 src/lib/libnvmm/libnvmm_x86.c:1.15
--- src/lib/libnvmm/libnvmm_x86.c:1.14	Tue Jan  8 07:34:22 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Sun Jan 13 10:43:22 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.14 2019/01/08 07:34:22 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.15 2019/01/13 10:43:22 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -77,13 +77,15 @@ nvmm_vcpu_dump(struct nvmm_machine *mach
 	printf("| -> RAX=%p\n", (void *)state.gprs[NVMM_X64_GPR_RAX]);
 	printf("| -> RBX=%p\n", (void *)state.gprs[NVMM_X64_GPR_RBX]);
 	printf("| -> RCX=%p\n", (void *)state.gprs[NVMM_X64_GPR_RCX]);
+	printf("| -> RFLAGS=%p\n", (void *)state.gprs[NVMM_X64_GPR_RFLAGS]);
 	for (i = 0; i < NVMM_X64_NSEG; i++) {
-		printf("| -> %s: sel=0x%lx base=%p, limit=%p, P=%d, D=%d\n",
+		printf("| -> %s: sel=0x%lx base=%p, limit=%p, P=%d, D=%d L=%d\n",
 		segnames[i],
 		state.segs[i].selector,
 		(void *)state.segs[i].base,
 		(void *)state.segs[i].limit,
-		state.segs[i].attrib.p, state.segs[i].attrib.def32);
+		state.segs[i].attrib.p, state.segs[i].attrib.def32,
+		state.segs[i].attrib.lng);
 	}
 	printf("| -> MSR_EFER=%p\n", (void *)state.msrs[NVMM_X64_MSR_EFER]);
 	printf("| -> CR0=%p\n", (void *)state.crs[NVMM_X64_CR_CR0]);
@@ -392,7 +394,7 @@ x86_gva_to_gpa(struct nvmm_machine *mach
 	gva &= ~PAGE_MASK;
 
 	is_pae = (state->crs[NVMM_X64_CR_CR4] & CR4_PAE) != 0;
-	is_lng = (state->msrs[NVMM_X64_MSR_EFER] & EFER_LME) != 0;
+	is_lng = (state->msrs[NVMM_X64_MSR_EFER] & EFER_LMA) != 0;
 	has_pse = (state->crs[NVMM_X64_CR_CR4] & CR4_PSE) != 0;
 	cr3 = state->crs[NVMM_X64_CR_CR3];
 
@@ -437,6 +439,12 @@ nvmm_gva_to_gpa(struct nvmm_machine *mac
 /* -- */
 
 static inline bool
+is_long_mode(struct nvmm_x64_state *state)
+{
+	return (state->msrs[NVMM_X64_MSR_EFER] & EFER_LMA) != 0;
+}
+
+static inline bool
 is_64bit(struct nvmm_x64_state *state)
 {
 	return (state->segs[NVMM_X64_SEG_CS].attrib.lng != 0);
@@ -456,14 +464,8 @@ is_16bit(struct nvmm_x64_state *state)
 	(state->segs[NVMM_X64_SEG_CS].attrib.def32 == 0);
 }
 
-static inline bool
-is_long_mode(struct nvmm_x64_state *state)
-{
-	return (state->msrs[NVMM_X64_MSR_EFER] & EFER_LME) != 0;
-}
-
 static int
-segment_apply(struct nvmm_x64_state_seg *seg, gvaddr_t *gva, size_t size)
+segment_check(struct nvmm_x64_state_seg *seg, gvaddr_t gva, size_t size)
 {
 	uint64_t limit;
 
@@ -480,11 +482,10 @@ segment_apply(struct nvmm_x64_state_seg 
 		limit *= PAGE_SIZE;
 	}
 
-	if (__predict_false(*gva + size > limit)) {
+	if (__predict_false(gva + size > limit)) {
 		goto error;
 	}
 
-	*gva += seg->base;
 	return 0;
 
 error:
@@ -492,17 +493,25 @@ error:
 	return -1;
 }
 
-static uint64_t
-mask_from_adsize(size_t adsize)
+static inline void
+segment_apply(struct nvmm_x64_state_seg *seg, gvaddr_t *gva)
 {
-	switch (adsize) {
-	case 8:
-		return 0x;
-	case 4:
-		return 0x;
+	*gva += seg->base;
+}
+
+static inline uint64_t
+size_to_mask(size_t size)
+{
+	switch (size) {
+	case 1:
+		return 0x00FF;
 	case 2:
-	default: /* impossible */
 		return 0x;
+	case 4:
+		return 0x;
+	case 8:
+	default:
+		return 0x;
 	}
 }
 
@@ -511,7 +520,7 @@ rep_get_cnt(struct nvmm_x64_state *state
 {
 	uint64_t mask, cnt;
 
-	mask = mask_from_adsize(adsize);
+	mask = size_to_mask(adsize);
 	cnt = state->gprs[NVMM_X64_GPR_RCX] & mask;
 
 	return cnt;
@@ -522,28 +531,12 @@ rep_set_cnt(struct nvmm_x64_state *state
 {
 	uint64_t mask;
 
-	mask = mask_from_adsize(adsize);
+	/* XXX: should we zero-extend? */
+	mask = size_to_mask(adsize);
 	state->gprs[NVMM_X64_GPR_RCX] &= ~mask;
 	state->gprs[NVMM_X64_GPR_RCX] |= cnt;
 }
 
-static uint64_t
-rep_dec_apply(struct nvmm_x64_state *state, size_t adsize)
-{
-	uint64_t mask, cnt;
-
-	mask = mask_from_adsize(adsize);
-
-	cnt = state->gprs[NVMM_X64_GPR_RCX] & mask;
-	cnt -= 1;
-	cnt &= mask;
-
-	state->gprs[NVMM_X64_GPR_RCX] &= ~mask;
-	state->gprs[NVMM_X64_GPR_RCX] |= cnt;
-
-	return cnt;
-}
-
 static int
 read_guest_memory(struct nvmm_machine *mach, struct nvmm_x64_state *state,
 gvaddr_t gva, uint8_t *data, size_t size)
@@ -693,7 +686,7 @@ nvmm_assist_io(struct nvmm_machine *mach
 	uint64_t cnt = 0; /* GCC */
 	uint8_t iobuf[8];
 	int iocnt = 1;
-	gvaddr_t gva;
+	gvaddr_t gva = 0; /* GCC */
 	int reg = 0; /* GCC */
 	

CVS commit: src/lib/libnvmm

2019-01-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Jan  8 07:34:22 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Handle REPN. FreeBSD has a "repn movs", which is a bit unusual, but doesn't
seem illegal as far as I can tell from the AMD SDM.

With that, I can boot FreeBSD on Qemu+NVMM.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.13 src/lib/libnvmm/libnvmm_x86.c:1.14
--- src/lib/libnvmm/libnvmm_x86.c:1.13	Mon Jan  7 18:13:34 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Tue Jan  8 07:34:22 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.13 2019/01/07 18:13:34 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.14 2019/01/08 07:34:22 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -2902,11 +2902,6 @@ nvmm_assist_mem(struct nvmm_machine *mac
 		return -1;
 	}
 
-	if (__predict_false(instr.legpref.repn)) {
-		errno = ENODEV;
-		return -1;
-	}
-
 	if (instr.opcode->movs) {
 		ret = assist_mem_double(mach, , );
 	} else {
@@ -2917,10 +2912,14 @@ nvmm_assist_mem(struct nvmm_machine *mac
 		return -1;
 	}
 
-	if (instr.legpref.rep) {
+	if (instr.legpref.rep || instr.legpref.repn) {
 		cnt = rep_dec_apply(, instr.address_size);
 		if (cnt == 0) {
 			state.gprs[NVMM_X64_GPR_RIP] += instr.len;
+		} else if (__predict_false(instr.legpref.repn)) {
+			if (state.gprs[NVMM_X64_GPR_RFLAGS] & PSL_Z) {
+state.gprs[NVMM_X64_GPR_RIP] += instr.len;
+			}
 		}
 	} else {
 		state.gprs[NVMM_X64_GPR_RIP] += instr.len;



CVS commit: src/lib/libnvmm

2019-01-07 Thread Thomas Klausner
Module Name:src
Committed By:   wiz
Date:   Mon Jan  7 22:17:02 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm.3

Log Message:
Remove leading zero from date.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/lib/libnvmm/libnvmm.3

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.8 src/lib/libnvmm/libnvmm.3:1.9
--- src/lib/libnvmm/libnvmm.3:1.8	Mon Jan  7 16:30:25 2019
+++ src/lib/libnvmm/libnvmm.3	Mon Jan  7 22:17:02 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: libnvmm.3,v 1.8 2019/01/07 16:30:25 maxv Exp $
+.\"	$NetBSD: libnvmm.3,v 1.9 2019/01/07 22:17:02 wiz 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 07, 2019
+.Dd January 7, 2019
 .Dt LIBNVMM 3
 .Os
 .Sh NAME



CVS commit: src/lib/libnvmm

2019-01-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Jan  7 18:13:34 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Optimize the legpref node: omit BRN (we don't care and it's the same as
OVR_CS), inline the loops, sort the checks from most to least likely
prefix, and use a compact structure.


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.12 src/lib/libnvmm/libnvmm_x86.c:1.13
--- src/lib/libnvmm/libnvmm_x86.c:1.12	Mon Jan  7 16:30:25 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Mon Jan  7 18:13:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.12 2019/01/07 16:30:25 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.13 2019/01/07 18:13:34 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -824,26 +824,25 @@ static void x86_emul_stos(struct nvmm_me
 static void x86_emul_lods(struct nvmm_mem *, void (*)(struct nvmm_mem *), uint64_t *);
 static void x86_emul_movs(struct nvmm_mem *, void (*)(struct nvmm_mem *), uint64_t *);
 
-enum x86_legpref {
-	/* Group 1 */
-	LEG_LOCK = 0,
-	LEG_REPN,	/* REPNE/REPNZ */
-	LEG_REP,	/* REP/REPE/REPZ */
-	/* Group 2 */
-	LEG_OVR_CS,
-	LEG_OVR_SS,
-	LEG_OVR_DS,
-	LEG_OVR_ES,
-	LEG_OVR_FS,
-	LEG_OVR_GS,
-	LEG_BRN_TAKEN,
-	LEG_BRN_NTAKEN,
-	/* Group 3 */
-	LEG_OPR_OVR,
-	/* Group 4 */
-	LEG_ADR_OVR,
-
-	NLEG
+/* Legacy prefixes. */
+#define LEG_LOCK	0xF0
+#define LEG_REPN	0xF2
+#define LEG_REP		0xF3
+#define LEG_OVR_CS	0x2E
+#define LEG_OVR_SS	0x36
+#define LEG_OVR_DS	0x3E
+#define LEG_OVR_ES	0x26
+#define LEG_OVR_FS	0x64
+#define LEG_OVR_GS	0x65
+#define LEG_OPR_OVR	0x66
+#define LEG_ADR_OVR	0x67
+
+struct x86_legpref {
+	bool opr_ovr:1;
+	bool adr_ovr:1;
+	bool rep:1;
+	bool repn:1;
+	int seg;
 };
 
 struct x86_rexpref {
@@ -940,7 +939,7 @@ struct x86_store {
 
 struct x86_instr {
 	size_t len;
-	bool legpref[NLEG];
+	struct x86_legpref legpref;
 	struct x86_rexpref rexpref;
 	size_t operand_size;
 	size_t address_size;
@@ -2133,13 +2132,13 @@ get_operand_size(struct x86_decode_fsm *
 		opsize = 8;
 	} else {
 		if (!fsm->is16bit) {
-			if (instr->legpref[LEG_OPR_OVR]) {
+			if (instr->legpref.opr_ovr) {
 opsize = 2;
 			} else {
 opsize = 4;
 			}
 		} else { /* 16bit */
-			if (instr->legpref[LEG_OPR_OVR]) {
+			if (instr->legpref.opr_ovr) {
 opsize = 4;
 			} else {
 opsize = 2;
@@ -2159,21 +2158,21 @@ static size_t
 get_address_size(struct x86_decode_fsm *fsm, struct x86_instr *instr)
 {
 	if (fsm->is64bit) {
-		if (__predict_false(instr->legpref[LEG_ADR_OVR])) {
+		if (__predict_false(instr->legpref.adr_ovr)) {
 			return 4;
 		}
 		return 8;
 	}
 
 	if (fsm->is32bit) {
-		if (__predict_false(instr->legpref[LEG_ADR_OVR])) {
+		if (__predict_false(instr->legpref.adr_ovr)) {
 			return 2;
 		}
 		return 4;
 	}
 
 	/* 16bit. */
-	if (__predict_false(instr->legpref[LEG_ADR_OVR])) {
+	if (__predict_false(instr->legpref.adr_ovr)) {
 		return 4;
 	}
 	return 2;
@@ -2344,51 +2343,44 @@ node_rex_prefix(struct x86_decode_fsm *f
 	return 0;
 }
 
-static const struct {
-	uint8_t byte;
-	int seg;
-} legpref_table[NLEG] = {
-	/* Group 1 */
-	[LEG_LOCK] = { 0xF0, -1 },
-	[LEG_REPN] = { 0xF2, -1 },
-	[LEG_REP]  = { 0xF3, -1 },
-	/* Group 2 */
-	[LEG_OVR_CS] = { 0x2E, NVMM_X64_SEG_CS },
-	[LEG_OVR_SS] = { 0x36, NVMM_X64_SEG_SS },
-	[LEG_OVR_DS] = { 0x3E, NVMM_X64_SEG_DS },
-	[LEG_OVR_ES] = { 0x26, NVMM_X64_SEG_ES },
-	[LEG_OVR_FS] = { 0x64, NVMM_X64_SEG_FS },
-	[LEG_OVR_GS] = { 0x65, NVMM_X64_SEG_GS },
-	[LEG_BRN_TAKEN]  = { 0x2E, -1 },
-	[LEG_BRN_NTAKEN] = { 0x3E, -1 },
-	/* Group 3 */
-	[LEG_OPR_OVR] = { 0x66, -1 },
-	/* Group 4 */
-	[LEG_ADR_OVR] = { 0x67, -1 },
-};
-
 static int
 node_legacy_prefix(struct x86_decode_fsm *fsm, struct x86_instr *instr)
 {
 	uint8_t byte;
-	size_t i;
 
 	if (fsm_read(fsm, , sizeof(byte)) == -1) {
 		return -1;
 	}
 
-	for (i = 0; i < NLEG; i++) {
-		if (byte == legpref_table[i].byte)
-			break;
-	}
-
-	if (i == NLEG) {
-		fsm->fn = node_rex_prefix;
+	if (byte == LEG_OPR_OVR) {
+		instr->legpref.opr_ovr = 1;
+	} else if (byte == LEG_OVR_DS) {
+		instr->legpref.seg = NVMM_X64_SEG_DS;
+	} else if (byte == LEG_OVR_ES) {
+		instr->legpref.seg = NVMM_X64_SEG_ES;
+	} else if (byte == LEG_REP) {
+		instr->legpref.rep = 1;
+	} else if (byte == LEG_OVR_GS) {
+		instr->legpref.seg = NVMM_X64_SEG_GS;
+	} else if (byte == LEG_OVR_FS) {
+		instr->legpref.seg = NVMM_X64_SEG_FS;
+	} else if (byte == LEG_ADR_OVR) {
+		instr->legpref.adr_ovr = 1;
+	} else if (byte == LEG_OVR_CS) {
+		instr->legpref.seg = NVMM_X64_SEG_CS;
+	} else if (byte == LEG_OVR_SS) {
+		instr->legpref.seg = NVMM_X64_SEG_SS;
+	} else if (byte == LEG_REPN) {
+		instr->legpref.repn = 1;
+	} else if (byte == LEG_LOCK) {
+		/* ignore */
 	} else {
-		instr->legpref[i] = true;
-		

CVS commit: src/lib/libnvmm

2019-01-07 Thread Maxime Villard
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, >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, >gpa, );
-	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, >src,
-			);
-			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, , mem.size);
 		}
 		break;
-
 	case STORE_IMM:
 		mem.write = true;
-		mem.size = instr->src.u.imm.size;
-		memcpy(mem.data, >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, >src, );
-		if (ret == -1)
-			return -1;
 		break;
-
 	case STORE_DMO:
 		mem.write = false;
-		mem.size = instr->operand_size;
-		ret = store_to_mem(mach, state, instr, >src, );
-		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) {
+		

CVS commit: src/lib/libnvmm

2019-01-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Jan  7 13:47:33 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Improvements and fixes:

 * Decode AND/OR/XOR from Group1.

 * Sign-extend the immediates and displacements in 64bit mode.

 * Fix the storage of {read,write}_guest_memory, now that we batch certain
   IO operations we can copy more than 8 bytes, and shit hits the fan.

 * Remove the CR4_PSE check in the 64bit MMU. This bit is actually ignored
   in long mode, and some systems (like FreeBSD) don't set it.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.10 src/lib/libnvmm/libnvmm_x86.c:1.11
--- src/lib/libnvmm/libnvmm_x86.c:1.10	Sun Jan  6 16:10:51 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Mon Jan  7 13:47:33 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.10 2019/01/06 16:10:51 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.11 2019/01/07 13:47:33 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -282,7 +282,7 @@ x86_gva_64bit_canonical(gvaddr_t gva)
 
 static int
 x86_gva_to_gpa_64bit(struct nvmm_machine *mach, uint64_t cr3,
-gvaddr_t gva, gpaddr_t *gpa, bool has_pse, nvmm_prot_t *prot)
+gvaddr_t gva, gpaddr_t *gpa, nvmm_prot_t *prot)
 {
 	gpaddr_t L4gpa, L3gpa, L2gpa, L1gpa;
 	uintptr_t L4hva, L3hva, L2hva, L1hva;
@@ -325,8 +325,6 @@ x86_gva_to_gpa_64bit(struct nvmm_machine
 		*prot &= ~NVMM_PROT_WRITE;
 	if (pte & PG_NX)
 		*prot &= ~NVMM_PROT_EXEC;
-	if ((pte & PG_PS) && !has_pse)
-		return -1;
 	if (pte & PG_PS) {
 		*gpa = (pte & PTE64_L3_FRAME);
 		*gpa = *gpa + (gva & (PTE64_L2_MASK|PTE64_L1_MASK));
@@ -347,8 +345,6 @@ x86_gva_to_gpa_64bit(struct nvmm_machine
 		*prot &= ~NVMM_PROT_WRITE;
 	if (pte & PG_NX)
 		*prot &= ~NVMM_PROT_EXEC;
-	if ((pte & PG_PS) && !has_pse)
-		return -1;
 	if (pte & PG_PS) {
 		*gpa = (pte & PTE64_L2_FRAME);
 		*gpa = *gpa + (gva & PTE64_L1_MASK);
@@ -402,7 +398,7 @@ x86_gva_to_gpa(struct nvmm_machine *mach
 
 	if (is_pae && is_lng) {
 		/* 64bit */
-		ret = x86_gva_to_gpa_64bit(mach, cr3, gva, gpa, has_pse, prot);
+		ret = x86_gva_to_gpa_64bit(mach, cr3, gva, gpa, prot);
 	} else if (is_pae && !is_lng) {
 		/* 32bit PAE */
 		ret = x86_gva_to_gpa_32bit_pae(mach, cr3, gva, gpa, has_pse,
@@ -553,7 +549,6 @@ read_guest_memory(struct nvmm_machine *m
 gvaddr_t gva, uint8_t *data, size_t size)
 {
 	struct nvmm_mem mem;
-	uint8_t membuf[8];
 	nvmm_prot_t prot;
 	gpaddr_t gpa;
 	uintptr_t hva;
@@ -580,13 +575,12 @@ read_guest_memory(struct nvmm_machine *m
 	is_mmio = (ret == -1);
 
 	if (is_mmio) {
-		mem.data = membuf;
+		mem.data = data;
 		mem.gva = gva;
 		mem.gpa = gpa;
 		mem.write = false;
 		mem.size = size;
 		(*__callbacks.mem)();
-		memcpy(data, mem.data, size);
 	} else {
 		memcpy(data, (uint8_t *)hva, size);
 	}
@@ -606,7 +600,6 @@ write_guest_memory(struct nvmm_machine *
 gvaddr_t gva, uint8_t *data, size_t size)
 {
 	struct nvmm_mem mem;
-	uint8_t membuf[8];
 	nvmm_prot_t prot;
 	gpaddr_t gpa;
 	uintptr_t hva;
@@ -633,11 +626,10 @@ write_guest_memory(struct nvmm_machine *
 	is_mmio = (ret == -1);
 
 	if (is_mmio) {
-		mem.data = membuf;
+		mem.data = data;
 		mem.gva = gva;
 		mem.gpa = gpa;
 		mem.write = true;
-		memcpy(mem.data, data, size);
 		mem.size = size;
 		(*__callbacks.mem)();
 	} else {
@@ -878,7 +870,7 @@ enum x86_disp_type {
 
 struct x86_disp {
 	enum x86_disp_type type;
-	uint8_t data[4];
+	uint64_t data; /* 4 bytes, but can be sign-extended */
 };
 
 enum REGMODRM__Mod {
@@ -919,7 +911,7 @@ struct x86_regmodrm {
 
 struct x86_immediate {
 	size_t size;	/* 1/2/4/8 */
-	uint8_t data[8];
+	uint64_t data;
 };
 
 struct x86_sib {
@@ -992,9 +984,9 @@ struct x86_opcode {
 	bool szoverride;
 	int defsize;
 	int allsize;
+	bool group1;
 	bool group11;
 	bool immediate;
-	int immsize;
 	int flags;
 	void (*emul)(struct nvmm_mem *, void (*)(struct nvmm_mem *), uint64_t *);
 };
@@ -1008,8 +1000,15 @@ struct x86_group_entry {
 #define OPSIZE_DOUB 0x04 /* 4 bytes */
 #define OPSIZE_QUAD 0x08 /* 8 bytes */
 
-#define FLAG_z	0x02
-#define FLAG_e	0x10
+#define FLAG_imm8	0x01
+#define FLAG_immz	0x02
+#define FLAG_ze		0x04
+
+static const struct x86_group_entry group1[8] = {
+	[1] = { .emul = x86_emul_or },
+	[4] = { .emul = x86_emul_and },
+	[6] = { .emul = x86_emul_xor }
+};
 
 static const struct x86_group_entry group11[8] = {
 	[0] = { .emul = x86_emul_mov }
@@ -1017,9 +1016,27 @@ static const struct x86_group_entry grou
 
 static const struct x86_opcode primary_opcode_table[] = {
 	/*
+	 * Group1
+	 */
+	{
+		/* Ev, Ib */
+		.byte = 0x83,
+		.regmodrm = true,
+		.regtorm = true,
+		.szoverride = true,
+		.defsize = -1,
+		.allsize = OPSIZE_WORD|OPSIZE_DOUB|OPSIZE_QUAD,
+		.group1 = true,
+		.immediate = true,
+		.flags 

CVS commit: src/lib/libnvmm

2019-01-04 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Fri Jan  4 10:25:40 UTC 2019

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
In !64bit mode RIP-relative is null+disp32, handle that correctly.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.8 src/lib/libnvmm/libnvmm_x86.c:1.9
--- src/lib/libnvmm/libnvmm_x86.c:1.8	Wed Jan  2 12:18:08 2019
+++ src/lib/libnvmm/libnvmm_x86.c	Fri Jan  4 10:25:39 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.8 2019/01/02 12:18:08 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.9 2019/01/04 10:25:39 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -1826,9 +1826,16 @@ has_sib(struct x86_instr *instr)
 }
 
 static inline bool
-is_rip_relative(struct x86_instr *instr)
+is_rip_relative(struct x86_decode_fsm *fsm, struct x86_instr *instr)
 {
-	return (instr->strm->disp.type == DISP_0 &&
+	return (fsm->is64bit && instr->strm->disp.type == DISP_0 &&
+	instr->regmodrm.rm == RM_RBP_DISP32);
+}
+
+static inline bool
+is_disp32_only(struct x86_decode_fsm *fsm, struct x86_instr *instr)
+{
+	return (!fsm->is64bit && instr->strm->disp.type == DISP_0 &&
 	instr->regmodrm.rm == RM_RBP_DISP32);
 }
 
@@ -1905,7 +1912,7 @@ node_regmodrm(struct x86_decode_fsm *fsm
 	/* The displacement applies to RM. */
 	strm->disp.type = get_disp_type(instr);
 
-	if (is_rip_relative(instr)) {
+	if (is_rip_relative(fsm, instr)) {
 		/* Overwrites RM */
 		strm->type = STORE_REG;
 		strm->u.reg = _map__rip;
@@ -1914,6 +1921,15 @@ node_regmodrm(struct x86_decode_fsm *fsm
 		return 0;
 	}
 
+	if (is_disp32_only(fsm, instr)) {
+		/* Overwrites RM */
+		strm->type = STORE_REG;
+		strm->u.reg = NULL;
+		strm->disp.type = DISP_4;
+		fsm_advance(fsm, 1, node_disp);
+		return 0;
+	}
+
 	reg = get_register_rm(instr, opcode);
 	if (reg == NULL) {
 		return -1;
@@ -2405,7 +2421,11 @@ store_to_gva(struct nvmm_x64_state *stat
 			gva += sib->scale * reg;
 		}
 	} else if (store->type == STORE_REG) {
-		gva = gpr_read_address(instr, state, store->u.reg->num);
+		if (store->u.reg == NULL) {
+			/* The base is null. Happens with disp32-only. */
+		} else {
+			gva = gpr_read_address(instr, state, store->u.reg->num);
+		}
 	} else {
 		gva = store->u.dmo;
 	}



CVS commit: src/lib/libnvmm

2018-12-29 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Dec 29 17:54:54 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Fix the segmentation check, the limit is relative, not absolute.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.6 src/lib/libnvmm/libnvmm_x86.c:1.7
--- src/lib/libnvmm/libnvmm_x86.c:1.6	Thu Dec 27 07:22:31 2018
+++ src/lib/libnvmm/libnvmm_x86.c	Sat Dec 29 17:54:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.6 2018/12/27 07:22:31 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.7 2018/12/29 17:54:54 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -472,7 +472,7 @@ segment_apply(struct nvmm_x64_state_seg 
 		limit *= PAGE_SIZE;
 	}
 
-	if (__predict_false(*gva + seg->base + size > limit)) {
+	if (__predict_false(*gva + size > limit)) {
 		goto error;
 	}
 



CVS commit: src/lib/libnvmm

2018-12-15 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Dec 15 13:09:02 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Two changes:

 - Fix the I/O Assist, for INS* it is RDI and not RSI, and the register
   gets updated regardless of the REP prefix.

 - Fill in the Mem Assist. We decode and emulate certain instructions,
   and pass a mem descriptor to the callback to handle the transaction.
   The disassembler could use some polishing, and there are still a
   few instructions missing; but basically it works.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.4 src/lib/libnvmm/libnvmm_x86.c:1.5
--- src/lib/libnvmm/libnvmm_x86.c:1.4	Sat Nov 17 16:11:33 2018
+++ src/lib/libnvmm/libnvmm_x86.c	Sat Dec 15 13:09:02 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.4 2018/11/17 16:11:33 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.5 2018/12/15 13:09:02 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -388,6 +388,26 @@ nvmm_gva_to_gpa(struct nvmm_machine *mac
 /* -- */
 
 static inline bool
+is_64bit(struct nvmm_x64_state *state)
+{
+	return (state->segs[NVMM_X64_SEG_CS].attrib.lng != 0);
+}
+
+static inline bool
+is_32bit(struct nvmm_x64_state *state)
+{
+	return (state->segs[NVMM_X64_SEG_CS].attrib.lng == 0) &&
+	(state->segs[NVMM_X64_SEG_CS].attrib.def32 == 1);
+}
+
+static inline bool
+is_16bit(struct nvmm_x64_state *state)
+{
+	return (state->segs[NVMM_X64_SEG_CS].attrib.lng == 0) &&
+	(state->segs[NVMM_X64_SEG_CS].attrib.def32 == 0);
+}
+
+static inline bool
 is_long_mode(struct nvmm_x64_state *state)
 {
 	return (state->msrs[NVMM_X64_MSR_EFER] & EFER_LME) != 0;
@@ -440,9 +460,9 @@ nvmm_assist_io(struct nvmm_machine *mach
 	uintptr_t hva;
 	gvaddr_t gva, off;
 	gpaddr_t gpa;
-	uint64_t rsi;
 	uint8_t tmp[8];
 	uint8_t *ptr, *ptr2;
+	int reg = 0; /* GCC */
 	bool cross;
 	int ret;
 
@@ -466,18 +486,22 @@ nvmm_assist_io(struct nvmm_machine *mach
 	if (!exit->u.io.str) {
 		ptr = (uint8_t *)[NVMM_X64_GPR_RAX];
 	} else {
-		rsi = state.gprs[NVMM_X64_GPR_RSI];
+		if (io.in) {
+			reg = NVMM_X64_GPR_RDI;
+		} else {
+			reg = NVMM_X64_GPR_RSI;
+		}
 
 		switch (exit->u.io.address_size) {
 		case 8:
-			gva = rsi;
+			gva = state.gprs[reg];
 			break;
 		case 4:
-			gva = (rsi & 0x);
+			gva = (state.gprs[reg] & 0x);
 			break;
 		case 2:
 		default: /* impossible */
-			gva = (rsi & 0x);
+			gva = (state.gprs[reg] & 0x);
 			break;
 		}
 
@@ -553,18 +577,19 @@ nvmm_assist_io(struct nvmm_machine *mach
 		/* nothing to do */
 	}
 
+	if (exit->u.io.str) {
+		if (state.gprs[NVMM_X64_GPR_RFLAGS] & PSL_D) {
+			state.gprs[reg] -= io.size;
+		} else {
+			state.gprs[reg] += io.size;
+		}
+	}
+
 	if (exit->u.io.rep) {
 		state.gprs[NVMM_X64_GPR_RCX] -= 1;
 		if (state.gprs[NVMM_X64_GPR_RCX] == 0) {
 			state.gprs[NVMM_X64_GPR_RIP] = exit->u.io.npc;
 		}
-		if (exit->u.io.str) {
-			if (state.gprs[NVMM_X64_GPR_RFLAGS] & PSL_D) {
-state.gprs[NVMM_X64_GPR_RSI] -= io.size;
-			} else {
-state.gprs[NVMM_X64_GPR_RSI] += io.size;
-			}
-		}
 	} else {
 		state.gprs[NVMM_X64_GPR_RIP] = exit->u.io.npc;
 	}
@@ -578,16 +603,1897 @@ nvmm_assist_io(struct nvmm_machine *mach
 
 /* -- */
 
-int
-nvmm_assist_mem(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
-struct nvmm_exit *exit, void (*cb)(struct nvmm_mem *))
+static void x86_emul_or(struct nvmm_mem *, void (*)(struct nvmm_mem *), uint64_t *);
+static void x86_emul_and(struct nvmm_mem *, void (*)(struct nvmm_mem *), uint64_t *);
+static void x86_emul_xor(struct nvmm_mem *, void (*)(struct nvmm_mem *), uint64_t *);
+static void x86_emul_mov(struct nvmm_mem *, void (*)(struct nvmm_mem *), uint64_t *);
+static void x86_emul_stos(struct nvmm_mem *, void (*)(struct nvmm_mem *), uint64_t *);
+static void x86_emul_lods(struct nvmm_mem *, void (*)(struct nvmm_mem *), uint64_t *);
+
+enum x86_legpref {
+	/* Group 1 */
+	LEG_LOCK = 0,
+	LEG_REPN,	/* REPNE/REPNZ */
+	LEG_REP,	/* REP/REPE/REPZ */
+	/* Group 2 */
+	LEG_OVR_CS,
+	LEG_OVR_SS,
+	LEG_OVR_DS,
+	LEG_OVR_ES,
+	LEG_OVR_FS,
+	LEG_OVR_GS,
+	LEG_BRN_TAKEN,
+	LEG_BRN_NTAKEN,
+	/* Group 3 */
+	LEG_OPR_OVR,
+	/* Group 4 */
+	LEG_ADR_OVR,
+
+	NLEG
+};
+
+struct x86_rexpref {
+	bool present;
+	bool w;
+	bool r;
+	bool x;
+	bool b;
+};
+
+struct x86_reg {
+	int num;	/* NVMM GPR state index */
+	uint64_t mask;
+};
+
+enum x86_disp_type {
+	DISP_NONE,
+	DISP_0,
+	DISP_1,
+	DISP_4
+};
+
+struct x86_disp {
+	enum x86_disp_type type;
+	uint8_t data[4];
+};
+
+enum REGMODRM__Mod {
+	MOD_DIS0, /* also, register indirect 

CVS commit: src/lib/libnvmm

2018-12-12 Thread Thomas Klausner
Module Name:src
Committed By:   wiz
Date:   Wed Dec 12 11:40:08 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm.3

Log Message:
Remove superfluous dot.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/lib/libnvmm/libnvmm.3

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.3 src/lib/libnvmm/libnvmm.3:1.4
--- src/lib/libnvmm/libnvmm.3:1.3	Wed Dec 12 09:09:08 2018
+++ src/lib/libnvmm/libnvmm.3	Wed Dec 12 11:40:08 2018
@@ -1,4 +1,4 @@
-.\"	$NetBSD: libnvmm.3,v 1.3 2018/12/12 09:09:08 maxv Exp $
+.\"	$NetBSD: libnvmm.3,v 1.4 2018/12/12 11:40:08 wiz Exp $
 .\"
 .\" Copyright (c) 2018 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -513,7 +513,7 @@ uses the following error codes:
 The VCPU cannot receive the event immediately.
 .El
 .Sh SEE ALSO
-.Xr nvmm 4 .
+.Xr nvmm 4
 .Sh AUTHORS
 NVMM was designed and implemented by
 .An Maxime Villard .



CVS commit: src/lib/libnvmm

2018-12-12 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Dec 12 10:42:34 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm.c

Log Message:
Change the map/unmap functions, again.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/lib/libnvmm/libnvmm.c

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.c
diff -u src/lib/libnvmm/libnvmm.c:1.3 src/lib/libnvmm/libnvmm.c:1.4
--- src/lib/libnvmm/libnvmm.c:1.3	Thu Nov 29 19:55:20 2018
+++ src/lib/libnvmm/libnvmm.c	Wed Dec 12 10:42:34 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm.c,v 1.3 2018/11/29 19:55:20 maxv Exp $	*/
+/*	$NetBSD: libnvmm.c,v 1.4 2018/12/12 10:42:34 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -57,89 +57,40 @@ static size_t nvmm_page_size = 0;
 
 /* -- */
 
-static int
-__area_unmap(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
- size_t size)
-{
-	struct nvmm_ioc_gpa_unmap args;
-	int ret;
-
-	args.machid = mach->machid;
-	args.gpa = gpa;
-	args.size = size;
-
-	ret = ioctl(nvmm_fd, NVMM_IOC_GPA_UNMAP, );
-	if (ret == -1)
-		return -1;
-
-	ret = munmap((void *)hva, size);
-
-	return ret;
-}
-
-static int
-__area_dig_hole(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
+static bool
+__area_isvalid(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
 size_t size)
 {
 	area_list_t *areas = mach->areas;
-	area_t *ent, *tmp, *nxt;
-	size_t diff;
+	area_t *ent;
 
-	LIST_FOREACH_SAFE(ent, areas, list, nxt) {
-		/* Case 1. */
-		if ((gpa < ent->gpa) && (gpa + size > ent->gpa)) {
-			diff = (gpa + size) - ent->gpa;
-			if (__area_unmap(mach, ent->hva, ent->gpa, diff) == -1) {
-return -1;
-			}
-			ent->gpa  += diff;
-			ent->hva  += diff;
-			ent->size -= diff;
+	LIST_FOREACH(ent, areas, list) {
+		/* Collision on HVA */
+		if (hva >= ent->hva && hva < ent->hva + ent->size) {
+			return false;
 		}
-
-		/* Case 2. */
-		if ((gpa >= ent->gpa) && (gpa + size <= ent->gpa + ent->size)) {
-			/* First half. */
-			tmp = malloc(sizeof(*tmp));
-			tmp->gpa = ent->gpa;
-			tmp->hva = ent->hva;
-			tmp->size = (gpa - ent->gpa);
-			LIST_INSERT_BEFORE(ent, tmp, list);
-			/* Second half. */
-			ent->gpa  += tmp->size;
-			ent->hva  += tmp->size;
-			ent->size -= tmp->size;
-			diff = size;
-			if (__area_unmap(mach, ent->hva, ent->gpa, diff) == -1) {
-return -1;
-			}
-			ent->gpa  += diff;
-			ent->hva  += diff;
-			ent->size -= diff;
+		if (hva + size >= ent->hva &&
+		hva + size < ent->hva + ent->size) {
+			return false;
 		}
-
-		/* Case 3. */
-		if ((gpa < ent->gpa + ent->size) &&
-		(gpa + size > ent->gpa + ent->size)) {
-			diff = (ent->gpa + ent->size) - gpa;
-			if (__area_unmap(mach, hva, gpa, diff) == -1) {
-return -1;
-			}
-			ent->size -= diff;
+		if (hva <= ent->hva && hva + size >= ent->hva + ent->size) {
+			return false;
 		}
 
-		/* Case 4. */
-		if ((gpa < ent->gpa + ent->size) &&
-		(gpa + size > ent->gpa + ent->size)) {
-			if (__area_unmap(mach, ent->hva, ent->gpa, ent->size) == -1) {
-return -1;
-			}
-			LIST_REMOVE(ent, list);
-			free(ent);
+		/* Collision on GPA */
+		if (gpa >= ent->gpa && gpa < ent->gpa + ent->size) {
+			return false;
+		}
+		if (gpa + size >= ent->gpa &&
+		gpa + size < ent->gpa + ent->size) {
+			return false;
+		}
+		if (gpa <= ent->gpa && gpa + size >= ent->gpa + ent->size) {
+			return false;
 		}
 	}
 
-	return 0;
+	return true;
 }
 
 static int
@@ -147,7 +98,11 @@ __area_add(struct nvmm_machine *mach, ui
 {
 	area_list_t *areas = mach->areas;
 	area_t *area;
-	int ret;
+
+	if (!__area_isvalid(mach, hva, gpa, size)) {
+		errno = EINVAL;
+		return -1;
+	}
 
 	area = malloc(sizeof(*area));
 	if (area == NULL)
@@ -156,16 +111,29 @@ __area_add(struct nvmm_machine *mach, ui
 	area->hva = hva;
 	area->size = size;
 
-	ret = __area_dig_hole(mach, hva, gpa, size);
-	if (ret == -1) {
-		free(area);
-		return -1;
-	}
-
 	LIST_INSERT_HEAD(areas, area, list);
+
 	return 0;
 }
 
+static int
+__area_delete(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
+size_t size)
+{
+	area_list_t *areas = mach->areas;
+	area_t *ent, *nxt;
+
+	LIST_FOREACH_SAFE(ent, areas, list, nxt) {
+		if (hva == ent->hva && gpa == ent->gpa && size == ent->size) {
+			LIST_REMOVE(ent, list);
+			free(ent);
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
 static void
 __area_remove_all(struct nvmm_machine *mach)
 {
@@ -450,11 +418,28 @@ int
 nvmm_gpa_unmap(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
 size_t size)
 {
+	struct nvmm_ioc_gpa_unmap args;
+	int ret;
+
 	if (nvmm_init() == -1) {
 		return -1;
 	}
 
-	return __area_dig_hole(mach, hva, gpa, size);
+	ret = __area_delete(mach, hva, gpa, size);
+	if (ret == -1)
+		return -1;
+
+	args.machid = mach->machid;
+	args.gpa = gpa;
+	args.size = size;
+
+	ret = ioctl(nvmm_fd, 

CVS commit: src/lib/libnvmm

2018-12-12 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Dec 12 09:09:08 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm.3

Log Message:
Change the "FILES" section, in the end I don't want to commit toyvirt
and smallkern, there is little interest installing them by default,
rather they can be downloaded from www. It's better this way.

While here add NVMM(4) in "SEE ALSO".


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/lib/libnvmm/libnvmm.3

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.2 src/lib/libnvmm/libnvmm.3:1.3
--- src/lib/libnvmm/libnvmm.3:1.2	Sat Nov 10 10:57:06 2018
+++ src/lib/libnvmm/libnvmm.3	Wed Dec 12 09:09:08 2018
@@ -1,4 +1,4 @@
-.\"	$NetBSD: libnvmm.3,v 1.2 2018/11/10 10:57:06 maxv Exp $
+.\"	$NetBSD: libnvmm.3,v 1.3 2018/12/12 09:09:08 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 November 10, 2018
+.Dd December 12, 2018
 .Dt LIBNVMM 3
 .Os
 .Sh NAME
@@ -473,14 +473,18 @@ variable
 .Va errno
 is set to indicate the error.
 .Sh FILES
-Functional examples:
-.Pp
 .Bl -tag -width  -compact
-.It Pa src/share/examples/nvmm/toyvirt/
-Example of virtualizer.
-Launches the binary given as argument in a virtual machine.
-.It Pa src/share/examples/nvmm/smallkern/
-Example of a kernel that can be executed by toyvirt.
+.It Lk https://www.netbsd.org/~maxv/nvmm/nvmm-demo.zip
+Functional example (demonstrator).
+Contains a virtualizer that uses the
+.Nm
+API, and a small kernel that exercises this virtualizer.
+.It Pa src/sys/dev/nvmm/
+Source code of the kernel NVMM driver.
+.It Pa src/lib/libnvmm/
+Source code of the
+.Nm
+library.
 .El
 .Sh ERRORS
 These functions will fail if:
@@ -508,6 +512,8 @@ uses the following error codes:
 .It Bq Er EAGAIN
 The VCPU cannot receive the event immediately.
 .El
+.Sh SEE ALSO
+.Xr nvmm 4 .
 .Sh AUTHORS
 NVMM was designed and implemented by
 .An Maxime Villard .



CVS commit: src/lib/libnvmm

2018-11-29 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Nov 29 19:55:21 UTC 2018

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

Log Message:
Rewrite the gpa map/unmap functions. Dig holes in the mapped areas when
there is an overlap. Close to what Qemu expects.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/lib/libnvmm/libnvmm.c
cvs rdiff -u -r1.1 -r1.2 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.c
diff -u src/lib/libnvmm/libnvmm.c:1.2 src/lib/libnvmm/libnvmm.c:1.3
--- src/lib/libnvmm/libnvmm.c:1.2	Mon Nov 19 21:45:37 2018
+++ src/lib/libnvmm/libnvmm.c	Thu Nov 29 19:55:20 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm.c,v 1.2 2018/11/19 21:45:37 maxv Exp $	*/
+/*	$NetBSD: libnvmm.c,v 1.3 2018/11/29 19:55:20 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -39,78 +39,145 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "nvmm.h"
 
+typedef struct __area {
+	LIST_ENTRY(__area) list;
+	gpaddr_t gpa;
+	uintptr_t hva;
+	size_t size;
+} area_t;
+
+typedef LIST_HEAD(, __area) area_list_t;
+
 static int nvmm_fd = -1;
 static size_t nvmm_page_size = 0;
 
 /* -- */
 
 static int
-_nvmm_area_add(struct nvmm_machine *mach, gpaddr_t gpa, uintptr_t hva,
+__area_unmap(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
+ size_t size)
+{
+	struct nvmm_ioc_gpa_unmap args;
+	int ret;
+
+	args.machid = mach->machid;
+	args.gpa = gpa;
+	args.size = size;
+
+	ret = ioctl(nvmm_fd, NVMM_IOC_GPA_UNMAP, );
+	if (ret == -1)
+		return -1;
+
+	ret = munmap((void *)hva, size);
+
+	return ret;
+}
+
+static int
+__area_dig_hole(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
 size_t size)
 {
-	struct nvmm_area *area;
-	void *ptr;
-	size_t i;
-
-	for (i = 0; i < mach->nareas; i++) {
-		if (gpa >= mach->areas[i].gpa &&
-		gpa < mach->areas[i].gpa + mach->areas[i].size) {
-			goto error;
+	area_list_t *areas = mach->areas;
+	area_t *ent, *tmp, *nxt;
+	size_t diff;
+
+	LIST_FOREACH_SAFE(ent, areas, list, nxt) {
+		/* Case 1. */
+		if ((gpa < ent->gpa) && (gpa + size > ent->gpa)) {
+			diff = (gpa + size) - ent->gpa;
+			if (__area_unmap(mach, ent->hva, ent->gpa, diff) == -1) {
+return -1;
+			}
+			ent->gpa  += diff;
+			ent->hva  += diff;
+			ent->size -= diff;
 		}
-		if (gpa + size > mach->areas[i].gpa &&
-		gpa + size <= mach->areas[i].gpa + mach->areas[i].size) {
-			goto error;
+
+		/* Case 2. */
+		if ((gpa >= ent->gpa) && (gpa + size <= ent->gpa + ent->size)) {
+			/* First half. */
+			tmp = malloc(sizeof(*tmp));
+			tmp->gpa = ent->gpa;
+			tmp->hva = ent->hva;
+			tmp->size = (gpa - ent->gpa);
+			LIST_INSERT_BEFORE(ent, tmp, list);
+			/* Second half. */
+			ent->gpa  += tmp->size;
+			ent->hva  += tmp->size;
+			ent->size -= tmp->size;
+			diff = size;
+			if (__area_unmap(mach, ent->hva, ent->gpa, diff) == -1) {
+return -1;
+			}
+			ent->gpa  += diff;
+			ent->hva  += diff;
+			ent->size -= diff;
 		}
-		if (gpa < mach->areas[i].gpa &&
-		gpa + size >= mach->areas[i].gpa + mach->areas[i].size) {
-			goto error;
+
+		/* Case 3. */
+		if ((gpa < ent->gpa + ent->size) &&
+		(gpa + size > ent->gpa + ent->size)) {
+			diff = (ent->gpa + ent->size) - gpa;
+			if (__area_unmap(mach, hva, gpa, diff) == -1) {
+return -1;
+			}
+			ent->size -= diff;
+		}
+
+		/* Case 4. */
+		if ((gpa < ent->gpa + ent->size) &&
+		(gpa + size > ent->gpa + ent->size)) {
+			if (__area_unmap(mach, ent->hva, ent->gpa, ent->size) == -1) {
+return -1;
+			}
+			LIST_REMOVE(ent, list);
+			free(ent);
 		}
 	}
 
-	ptr = realloc(mach->areas, (mach->nareas + 1) *
-	sizeof(struct nvmm_area));
-	if (ptr == NULL)
-		return -1;
-	mach->areas = ptr;
+	return 0;
+}
+
+static int
+__area_add(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa, size_t size)
+{
+	area_list_t *areas = mach->areas;
+	area_t *area;
+	int ret;
 
-	area = >areas[mach->nareas++];
+	area = malloc(sizeof(*area));
+	if (area == NULL)
+		return -1;
 	area->gpa = gpa;
 	area->hva = hva;
 	area->size = size;
 
-	return 0;
+	ret = __area_dig_hole(mach, hva, gpa, size);
+	if (ret == -1) {
+		free(area);
+		return -1;
+	}
 
-error:
-	errno = EEXIST;
-	return -1;
+	LIST_INSERT_HEAD(areas, area, list);
+	return 0;
 }
 
-static int
-_nvmm_area_delete(struct nvmm_machine *mach, gpaddr_t gpa, uintptr_t hva,
-size_t size)
+static void
+__area_remove_all(struct nvmm_machine *mach)
 {
-	size_t i;
+	area_list_t *areas = mach->areas;
+	area_t *ent;
 
-	for (i = 0; i < mach->nareas; i++) {
-		if (gpa == mach->areas[i].gpa &&
-		hva == mach->areas[i].hva &&
-		size == mach->areas[i].size) {
-			break;
-		}
-	}
-	if (i == mach->nareas) {
-		errno = ENOENT;
-		return -1;
+	while ((ent = LIST_FIRST(areas)) != NULL) {
+		LIST_REMOVE(ent, list);
+		free(ent);
 	}
 
-	

CVS commit: src/lib/libnvmm

2018-11-19 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Nov 19 21:45:37 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm.c

Log Message:
Fix error handling of realloc, and use memmove because the areas overlap;
noted by agc@. These _nvmm_area_add/delete functions don't make a lot of
sense right now and will likely be rewritten to match the behavior
expected by Qemu; but still fix for the time being.

Also fix a collision check while here.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/lib/libnvmm/libnvmm.c

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.c
diff -u src/lib/libnvmm/libnvmm.c:1.1 src/lib/libnvmm/libnvmm.c:1.2
--- src/lib/libnvmm/libnvmm.c:1.1	Sat Nov 10 09:28:56 2018
+++ src/lib/libnvmm/libnvmm.c	Mon Nov 19 21:45:37 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm.c,v 1.1 2018/11/10 09:28:56 maxv Exp $	*/
+/*	$NetBSD: libnvmm.c,v 1.2 2018/11/19 21:45:37 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -60,8 +60,8 @@ _nvmm_area_add(struct nvmm_machine *mach
 		gpa < mach->areas[i].gpa + mach->areas[i].size) {
 			goto error;
 		}
-		if (gpa + size >= mach->areas[i].gpa &&
-		gpa + size < mach->areas[i].gpa + mach->areas[i].size) {
+		if (gpa + size > mach->areas[i].gpa &&
+		gpa + size <= mach->areas[i].gpa + mach->areas[i].size) {
 			goto error;
 		}
 		if (gpa < mach->areas[i].gpa &&
@@ -70,13 +70,13 @@ _nvmm_area_add(struct nvmm_machine *mach
 		}
 	}
 
-	mach->nareas++;
-	ptr = realloc(mach->areas, mach->nareas * sizeof(struct nvmm_area));
+	ptr = realloc(mach->areas, (mach->nareas + 1) *
+	sizeof(struct nvmm_area));
 	if (ptr == NULL)
 		return -1;
 	mach->areas = ptr;
 
-	area = >areas[mach->nareas-1];
+	area = >areas[mach->nareas++];
 	area->gpa = gpa;
 	area->hva = hva;
 	area->size = size;
@@ -106,7 +106,7 @@ _nvmm_area_delete(struct nvmm_machine *m
 		return -1;
 	}
 
-	memcpy(>areas[i], >areas[i+1],
+	memmove(>areas[i], >areas[i+1],
 	(mach->nareas - i - 1) * sizeof(struct nvmm_area));
 	mach->nareas--;
 



CVS commit: src/lib/libnvmm

2018-11-17 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Nov 17 16:11:33 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Don't forget to set 'prot' when the guest has paging disabled.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.3 src/lib/libnvmm/libnvmm_x86.c:1.4
--- src/lib/libnvmm/libnvmm_x86.c:1.3	Tue Nov 13 06:57:14 2018
+++ src/lib/libnvmm/libnvmm_x86.c	Sat Nov 17 16:11:33 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.3 2018/11/13 06:57:14 maya Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.4 2018/11/17 16:11:33 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -334,6 +334,7 @@ x86_gva_to_gpa(struct nvmm_machine *mach
 
 	if ((state->crs[NVMM_X64_CR_CR0] & CR0_PG) == 0) {
 		/* No paging. */
+		*prot = NVMM_PROT_ALL;
 		*gpa = gva;
 		return 0;
 	}



CVS commit: src/lib/libnvmm

2018-11-13 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Tue Nov 13 09:14:14 UTC 2018

Modified Files:
src/lib/libnvmm: Makefile

Log Message:
Need some minimalistic support for additional things that ../Makefile
requires, even if we do nothing here


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/lib/libnvmm/Makefile

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/Makefile
diff -u src/lib/libnvmm/Makefile:1.3 src/lib/libnvmm/Makefile:1.4
--- src/lib/libnvmm/Makefile:1.3	Tue Nov 13 09:00:09 2018
+++ src/lib/libnvmm/Makefile	Tue Nov 13 09:14:14 2018
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.3 2018/11/13 09:00:09 martin Exp $
-
-.if ${MACHINE_ARCH} == "x86_64" && ${MLIBDIR:Unone} != "i386"
+# $NetBSD: Makefile,v 1.4 2018/11/13 09:14:14 martin Exp $
 
 .include 
 
+.if ${MACHINE_ARCH} == "x86_64" && ${MLIBDIR:Unone} != "i386"
+
 LIB=		nvmm
 MAN=		libnvmm.3
 
@@ -14,6 +14,10 @@ INCSDIR=	/usr/include
 
 WARNS=		5
 
+.else
+LIB=
+LIBDPLIBS=
+.endif
+
 .include 
 
-.endif



CVS commit: src/lib/libnvmm

2018-11-12 Thread Maya Rashish
Module Name:src
Committed By:   maya
Date:   Tue Nov 13 06:57:14 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Revert my own rev 1.2, the missing include was only when building the 32-bit
compat library, we no longer do this.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.2 src/lib/libnvmm/libnvmm_x86.c:1.3
--- src/lib/libnvmm/libnvmm_x86.c:1.2	Sun Nov 11 00:06:48 2018
+++ src/lib/libnvmm/libnvmm_x86.c	Tue Nov 13 06:57:14 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.2 2018/11/11 00:06:48 maya Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.3 2018/11/13 06:57:14 maya Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -42,7 +42,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "nvmm.h"
 



CVS commit: src/lib/libnvmm

2018-11-12 Thread Takeshi Nakayama
Module Name:src
Committed By:   nakayama
Date:   Mon Nov 12 17:46:53 UTC 2018

Modified Files:
src/lib/libnvmm: Makefile

Log Message:
No need to install shared libraries to /lib.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/lib/libnvmm/Makefile

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/Makefile
diff -u src/lib/libnvmm/Makefile:1.1 src/lib/libnvmm/Makefile:1.2
--- src/lib/libnvmm/Makefile:1.1	Sat Nov 10 09:28:56 2018
+++ src/lib/libnvmm/Makefile	Mon Nov 12 17:46:53 2018
@@ -1,6 +1,4 @@
-# $NetBSD: Makefile,v 1.1 2018/11/10 09:28:56 maxv Exp $
-
-USE_SHLIBDIR=   yes
+# $NetBSD: Makefile,v 1.2 2018/11/12 17:46:53 nakayama Exp $
 
 .include 
 



CVS commit: src/lib/libnvmm

2018-11-10 Thread Maya Rashish
Module Name:src
Committed By:   maya
Date:   Sun Nov 11 00:06:48 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm_x86.c

Log Message:
Add missing include for struct nvmm_x64_state
(Pointed out by the clang build)


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/lib/libnvmm/libnvmm_x86.c

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_x86.c
diff -u src/lib/libnvmm/libnvmm_x86.c:1.1 src/lib/libnvmm/libnvmm_x86.c:1.2
--- src/lib/libnvmm/libnvmm_x86.c:1.1	Sat Nov 10 09:28:56 2018
+++ src/lib/libnvmm/libnvmm_x86.c	Sun Nov 11 00:06:48 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm_x86.c,v 1.1 2018/11/10 09:28:56 maxv Exp $	*/
+/*	$NetBSD: libnvmm_x86.c,v 1.2 2018/11/11 00:06:48 maya Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "nvmm.h"
 



CVS commit: src/lib/libnvmm

2018-11-10 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Nov 10 10:57:06 UTC 2018

Modified Files:
src/lib/libnvmm: libnvmm.3

Log Message:
Add copyright and RCSID, from wiz@.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/lib/libnvmm/libnvmm.3

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.1 src/lib/libnvmm/libnvmm.3:1.2
--- src/lib/libnvmm/libnvmm.3:1.1	Sat Nov 10 09:28:56 2018
+++ src/lib/libnvmm/libnvmm.3	Sat Nov 10 10:57:06 2018
@@ -1,4 +1,33 @@
-.Dd September 12, 2018
+.\"	$NetBSD: libnvmm.3,v 1.2 2018/11/10 10:57:06 maxv Exp $
+.\"
+.\" 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.
+.\"
+.Dd November 10, 2018
 .Dt LIBNVMM 3
 .Os
 .Sh NAME