Module Name:    src
Committed By:   maxv
Date:           Thu Mar 21 20:21:41 UTC 2019

Modified Files:
        src/lib/libnvmm: libnvmm.3 libnvmm.c
        src/sys/dev/nvmm: nvmm.c nvmm.h nvmm_ioctl.h
        src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c
        src/tests/lib/libnvmm: h_io_assist.c h_mem_assist.c

Log Message:
Make it possible for an emulator to set the protection of the guest pages.
For some reason I had initially concluded that it wasn't doable; verily it
is, so let's do it.

The reserved 'flags' argument of nvmm_gpa_map() becomes 'prot' and takes
mmap-like protection codes.


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/lib/libnvmm/libnvmm.3
cvs rdiff -u -r1.6 -r1.7 src/lib/libnvmm/libnvmm.c
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/nvmm/nvmm.h
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/nvmm/nvmm_ioctl.h
cvs rdiff -u -r1.34 -r1.35 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.19 -r1.20 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
cvs rdiff -u -r1.4 -r1.5 src/tests/lib/libnvmm/h_io_assist.c
cvs rdiff -u -r1.7 -r1.8 src/tests/lib/libnvmm/h_mem_assist.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.3
diff -u src/lib/libnvmm/libnvmm.3:1.11 src/lib/libnvmm/libnvmm.3:1.12
--- src/lib/libnvmm/libnvmm.3:1.11	Tue Feb  5 15:03:35 2019
+++ src/lib/libnvmm/libnvmm.3	Thu Mar 21 20:21:40 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: libnvmm.3,v 1.11 2019/02/05 15:03:35 wiz Exp $
+.\"	$NetBSD: libnvmm.3,v 1.12 2019/03/21 20:21:40 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 February 5, 2019
+.Dd March 19, 2019
 .Dt LIBNVMM 3
 .Os
 .Sh NAME
@@ -68,7 +68,7 @@
 .Fn nvmm_hva_unmap "struct nvmm_machine *mach" "uintptr_t hva" "size_t size"
 .Ft int
 .Fn nvmm_gpa_map "struct nvmm_machine *mach" "uintptr_t hva" "gpaddr_t gpa" \
-    "size_t size" "int flags"
+    "size_t size" "int prot"
 .Ft int
 .Fn nvmm_gpa_unmap "struct nvmm_machine *mach" "uintptr_t hva" "gpaddr_t gpa" \
     "size_t size"

Index: src/lib/libnvmm/libnvmm.c
diff -u src/lib/libnvmm/libnvmm.c:1.6 src/lib/libnvmm/libnvmm.c:1.7
--- src/lib/libnvmm/libnvmm.c:1.6	Thu Dec 27 07:22:31 2018
+++ src/lib/libnvmm/libnvmm.c	Thu Mar 21 20:21:40 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: libnvmm.c,v 1.6 2018/12/27 07:22:31 maxv Exp $	*/
+/*	$NetBSD: libnvmm.c,v 1.7 2019/03/21 20:21:40 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -374,7 +374,7 @@ nvmm_vcpu_run(struct nvmm_machine *mach,
 
 int
 nvmm_gpa_map(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
-    size_t size, int flags)
+    size_t size, int prot)
 {
 	struct nvmm_ioc_gpa_map args;
 	int ret;
@@ -391,7 +391,7 @@ nvmm_gpa_map(struct nvmm_machine *mach, 
 	args.hva = hva;
 	args.gpa = gpa;
 	args.size = size;
-	args.flags = flags;
+	args.prot = prot;
 
 	ret = ioctl(nvmm_fd, NVMM_IOC_GPA_MAP, &args);
 	if (ret == -1) {

Index: src/sys/dev/nvmm/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.10 src/sys/dev/nvmm/nvmm.c:1.11
--- src/sys/dev/nvmm/nvmm.c:1.10	Thu Mar 14 19:10:27 2019
+++ src/sys/dev/nvmm/nvmm.c	Thu Mar 21 20:21:40 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.10 2019/03/14 19:10:27 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.11 2019/03/21 20:21:40 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.10 2019/03/14 19:10:27 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.11 2019/03/21 20:21:40 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.1
 #include <sys/kmem.h>
 #include <sys/module.h>
 #include <sys/proc.h>
+#include <sys/mman.h>
 
 #include <uvm/uvm.h>
 #include <uvm/uvm_page.h>
@@ -493,7 +494,7 @@ nvmm_do_vcpu_run(struct nvmm_machine *ma
 		if (exit->u.mem.gpa >= mach->gpa_end) {
 			break;
 		}
-		if (uvm_fault(&vm->vm_map, exit->u.mem.gpa, VM_PROT_ALL)) {
+		if (uvm_fault(&vm->vm_map, exit->u.mem.gpa, exit->u.mem.prot)) {
 			break;
 		}
 	}
@@ -706,6 +707,11 @@ nvmm_gpa_map(struct nvmm_ioc_gpa_map *ar
 	if (error)
 		return error;
 
+	if ((args->prot & ~(PROT_READ|PROT_WRITE|PROT_EXEC)) != 0) {
+		error = EINVAL;
+		goto out;
+	}
+
 	if ((args->gpa % PAGE_SIZE) != 0 || (args->size % PAGE_SIZE) != 0 ||
 	    (args->hva % PAGE_SIZE) != 0) {
 		error = EINVAL;
@@ -740,7 +746,7 @@ nvmm_gpa_map(struct nvmm_ioc_gpa_map *ar
 
 	/* Map the uobj into the machine address space, as pageable. */
 	error = uvm_map(&mach->vm->vm_map, &gpa, args->size, uobj, off, 0,
-	    UVM_MAPFLAG(UVM_PROT_RWX, UVM_PROT_RWX, UVM_INH_NONE,
+	    UVM_MAPFLAG(args->prot, UVM_PROT_RWX, UVM_INH_NONE,
 	    UVM_ADV_RANDOM, UVM_FLAG_FIXED|UVM_FLAG_UNMAP));
 	if (error) {
 		uao_detach(uobj);

Index: src/sys/dev/nvmm/nvmm.h
diff -u src/sys/dev/nvmm/nvmm.h:1.4 src/sys/dev/nvmm/nvmm.h:1.5
--- src/sys/dev/nvmm/nvmm.h:1.4	Sat Jan 26 15:12:20 2019
+++ src/sys/dev/nvmm/nvmm.h	Thu Mar 21 20:21:40 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.h,v 1.4 2019/01/26 15:12:20 maxv Exp $	*/
+/*	$NetBSD: nvmm.h,v 1.5 2019/03/21 20:21:40 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -64,14 +64,8 @@ enum nvmm_exit_reason {
 	NVMM_EXIT_INVALID	= 0xFFFFFFFFFFFFFFFF
 };
 
-enum nvmm_exit_memory_perm {
-	NVMM_EXIT_MEMORY_READ,
-	NVMM_EXIT_MEMORY_WRITE,
-	NVMM_EXIT_MEMORY_EXEC
-};
-
 struct nvmm_exit_memory {
-	enum nvmm_exit_memory_perm perm;
+	int prot;
 	gpaddr_t gpa;
 	uint8_t inst_len;
 	uint8_t inst_bytes[15];

Index: src/sys/dev/nvmm/nvmm_ioctl.h
diff -u src/sys/dev/nvmm/nvmm_ioctl.h:1.3 src/sys/dev/nvmm/nvmm_ioctl.h:1.4
--- src/sys/dev/nvmm/nvmm_ioctl.h:1.3	Tue Jan  8 07:29:46 2019
+++ src/sys/dev/nvmm/nvmm_ioctl.h	Thu Mar 21 20:21:40 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_ioctl.h,v 1.3 2019/01/08 07:29:46 maxv Exp $	*/
+/*	$NetBSD: nvmm_ioctl.h,v 1.4 2019/03/21 20:21:40 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -109,7 +109,7 @@ struct nvmm_ioc_gpa_map {
 	uintptr_t hva;
 	gpaddr_t gpa;
 	size_t size;
-	int flags;
+	int prot;
 };
 
 struct nvmm_ioc_gpa_unmap {

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.34 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.35
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.34	Thu Mar 14 19:15:26 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Thu Mar 21 20:21:41 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.34 2019/03/14 19:15:26 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.35 2019/03/21 20:21:41 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.34 2019/03/14 19:15:26 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.35 2019/03/21 20:21:41 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm
 #include <sys/kmem.h>
 #include <sys/cpu.h>
 #include <sys/xcall.h>
+#include <sys/mman.h>
 
 #include <uvm/uvm.h>
 #include <uvm/uvm_page.h>
@@ -1066,11 +1067,11 @@ svm_exit_npf(struct nvmm_machine *mach, 
 
 	exit->reason = NVMM_EXIT_MEMORY;
 	if (cpudata->vmcb->ctrl.exitinfo1 & PGEX_W)
-		exit->u.mem.perm = NVMM_EXIT_MEMORY_WRITE;
+		exit->u.mem.prot = PROT_WRITE;
 	else if (cpudata->vmcb->ctrl.exitinfo1 & PGEX_X)
-		exit->u.mem.perm = NVMM_EXIT_MEMORY_EXEC;
+		exit->u.mem.prot = PROT_EXEC;
 	else
-		exit->u.mem.perm = NVMM_EXIT_MEMORY_READ;
+		exit->u.mem.prot = PROT_READ;
 	exit->u.mem.gpa = gpa;
 	exit->u.mem.inst_len = cpudata->vmcb->ctrl.inst_len;
 	memcpy(exit->u.mem.inst_bytes, cpudata->vmcb->ctrl.inst_bytes,

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.19 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.20
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.19	Thu Mar 14 20:29:53 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Mar 21 20:21:41 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.19 2019/03/14 20:29:53 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.20 2019/03/21 20:21:41 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.19 2019/03/14 20:29:53 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.20 2019/03/21 20:21:41 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx
 #include <sys/kmem.h>
 #include <sys/cpu.h>
 #include <sys/xcall.h>
+#include <sys/mman.h>
 
 #include <uvm/uvm.h>
 #include <uvm/uvm_page.h>
@@ -1600,11 +1601,11 @@ vmx_exit_epf(struct nvmm_machine *mach, 
 	exit->reason = NVMM_EXIT_MEMORY;
 	vmx_vmread(VMCS_EXIT_QUALIFICATION, &perm);
 	if (perm & VMX_EPT_VIOLATION_WRITE)
-		exit->u.mem.perm = NVMM_EXIT_MEMORY_WRITE;
+		exit->u.mem.prot = PROT_WRITE;
 	else if (perm & VMX_EPT_VIOLATION_EXECUTE)
-		exit->u.mem.perm = NVMM_EXIT_MEMORY_EXEC;
+		exit->u.mem.prot = PROT_EXEC;
 	else
-		exit->u.mem.perm = NVMM_EXIT_MEMORY_READ;
+		exit->u.mem.prot = PROT_READ;
 	exit->u.mem.gpa = gpa;
 	exit->u.mem.inst_len = 0;
 }

Index: src/tests/lib/libnvmm/h_io_assist.c
diff -u src/tests/lib/libnvmm/h_io_assist.c:1.4 src/tests/lib/libnvmm/h_io_assist.c:1.5
--- src/tests/lib/libnvmm/h_io_assist.c:1.4	Tue Mar 19 19:23:39 2019
+++ src/tests/lib/libnvmm/h_io_assist.c	Thu Mar 21 20:21:41 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: h_io_assist.c,v 1.4 2019/03/19 19:23:39 maxv Exp $	*/
+/*	$NetBSD: h_io_assist.c,v 1.5 2019/03/21 20:21:41 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -126,6 +126,7 @@ static void
 map_pages(struct nvmm_machine *mach)
 {
 	pt_entry_t *L4, *L3, *L2, *L1;
+	int ret;
 
 	instbuf = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
 	    -1, 0);
@@ -140,9 +141,13 @@ map_pages(struct nvmm_machine *mach)
 		err(errno, "nvmm_hva_map");
 	if (nvmm_hva_map(mach, (uintptr_t)databuf, PAGE_SIZE) == -1)
 		err(errno, "nvmm_hva_map");
-	if (nvmm_gpa_map(mach, (uintptr_t)instbuf, 0x2000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)instbuf, 0x2000, PAGE_SIZE,
+	    PROT_READ|PROT_EXEC);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
-	if (nvmm_gpa_map(mach, (uintptr_t)databuf, 0x1000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)databuf, 0x1000, PAGE_SIZE,
+	    PROT_READ|PROT_WRITE);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
 
 	L4 = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
@@ -171,13 +176,21 @@ map_pages(struct nvmm_machine *mach)
 	if (nvmm_hva_map(mach, (uintptr_t)L1, PAGE_SIZE) == -1)
 		err(errno, "nvmm_hva_map");
 
-	if (nvmm_gpa_map(mach, (uintptr_t)L4, 0x3000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)L4, 0x3000, PAGE_SIZE,
+	    PROT_READ|PROT_WRITE);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
-	if (nvmm_gpa_map(mach, (uintptr_t)L3, 0x4000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)L3, 0x4000, PAGE_SIZE,
+	    PROT_READ|PROT_WRITE);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
-	if (nvmm_gpa_map(mach, (uintptr_t)L2, 0x5000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)L2, 0x5000, PAGE_SIZE,
+	    PROT_READ|PROT_WRITE);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
-	if (nvmm_gpa_map(mach, (uintptr_t)L1, 0x6000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)L1, 0x6000, PAGE_SIZE,
+	if (ret == -1)
+	    PROT_READ|PROT_WRITE);
 		err(errno, "nvmm_gpa_map");
 
 	memset(L4, 0, PAGE_SIZE);

Index: src/tests/lib/libnvmm/h_mem_assist.c
diff -u src/tests/lib/libnvmm/h_mem_assist.c:1.7 src/tests/lib/libnvmm/h_mem_assist.c:1.8
--- src/tests/lib/libnvmm/h_mem_assist.c:1.7	Tue Mar 19 19:23:39 2019
+++ src/tests/lib/libnvmm/h_mem_assist.c	Thu Mar 21 20:21:41 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: h_mem_assist.c,v 1.7 2019/03/19 19:23:39 maxv Exp $	*/
+/*	$NetBSD: h_mem_assist.c,v 1.8 2019/03/21 20:21:41 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -131,7 +131,9 @@ map_pages(struct nvmm_machine *mach)
 
 	if (nvmm_hva_map(mach, (uintptr_t)instbuf, PAGE_SIZE) == -1)
 		err(errno, "nvmm_hva_map");
-	if (nvmm_gpa_map(mach, (uintptr_t)instbuf, 0x2000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)instbuf, 0x2000, PAGE_SIZE,
+	    PROT_READ|PROT_EXEC);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
 
 	L4 = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
@@ -160,13 +162,21 @@ map_pages(struct nvmm_machine *mach)
 	if (nvmm_hva_map(mach, (uintptr_t)L1, PAGE_SIZE) == -1)
 		err(errno, "nvmm_hva_map");
 
-	if (nvmm_gpa_map(mach, (uintptr_t)L4, 0x3000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)L4, 0x3000, PAGE_SIZE,
+	    PROT_READ|PROT_WRITE);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
-	if (nvmm_gpa_map(mach, (uintptr_t)L3, 0x4000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)L3, 0x4000, PAGE_SIZE,
+	    PROT_READ|PROT_WRITE);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
-	if (nvmm_gpa_map(mach, (uintptr_t)L2, 0x5000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)L2, 0x5000, PAGE_SIZE,
+	    PROT_READ|PROT_WRITE);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
-	if (nvmm_gpa_map(mach, (uintptr_t)L1, 0x6000, PAGE_SIZE, 0) == -1)
+	ret = nvmm_gpa_map(mach, (uintptr_t)L1, 0x6000, PAGE_SIZE,
+	    PROT_READ|PROT_WRITE);
+	if (ret == -1)
 		err(errno, "nvmm_gpa_map");
 
 	memset(L4, 0, PAGE_SIZE);

Reply via email to