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);