Module Name: src Committed By: maxv Date: Mon Jan 7 16:30:26 UTC 2019
Modified Files: src/lib/libnvmm: libnvmm.3 libnvmm_x86.c nvmm.h Log Message: Optimize: on single memory operand instructions, take the GPA directly from the exit structure provided by the kernel. This saves an MMU translation, and sometimes complex address computation (eg SIB). Drop the GVA field, it is not useful to virtualizers. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/lib/libnvmm/libnvmm.3 cvs rdiff -u -r1.11 -r1.12 src/lib/libnvmm/libnvmm_x86.c cvs rdiff -u -r1.5 -r1.6 src/lib/libnvmm/nvmm.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libnvmm/libnvmm.3 diff -u src/lib/libnvmm/libnvmm.3:1.7 src/lib/libnvmm/libnvmm.3:1.8 --- src/lib/libnvmm/libnvmm.3:1.7 Sun Jan 6 16:10:51 2019 +++ src/lib/libnvmm/libnvmm.3 Mon Jan 7 16:30:25 2019 @@ -1,4 +1,4 @@ -.\" $NetBSD: libnvmm.3,v 1.7 2019/01/06 16:10:51 maxv Exp $ +.\" $NetBSD: libnvmm.3,v 1.8 2019/01/07 16:30:25 maxv Exp $ .\" .\" Copyright (c) 2018 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 06, 2019 +.Dd January 07, 2019 .Dt LIBNVMM 3 .Os .Sh NAME @@ -455,7 +455,6 @@ structure as argument. This structure describes a Mem transaction: .Bd -literal struct nvmm_mem { - gvaddr_t gva; gpaddr_t gpa; bool write; size_t size; @@ -480,8 +479,6 @@ to retrieve the desired value. .El .Pp In either case, -.Va gva -will indicate the guest virtual address, .Va gpa will indicate the guest physical address, .Va write Index: src/lib/libnvmm/libnvmm_x86.c diff -u src/lib/libnvmm/libnvmm_x86.c:1.11 src/lib/libnvmm/libnvmm_x86.c:1.12 --- src/lib/libnvmm/libnvmm_x86.c:1.11 Mon Jan 7 13:47:33 2019 +++ src/lib/libnvmm/libnvmm_x86.c Mon Jan 7 16:30:25 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: libnvmm_x86.c,v 1.11 2019/01/07 13:47:33 maxv Exp $ */ +/* $NetBSD: libnvmm_x86.c,v 1.12 2019/01/07 16:30:25 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -576,7 +576,6 @@ read_guest_memory(struct nvmm_machine *m if (is_mmio) { mem.data = data; - mem.gva = gva; mem.gpa = gpa; mem.write = false; mem.size = size; @@ -627,7 +626,6 @@ write_guest_memory(struct nvmm_machine * if (is_mmio) { mem.data = data; - mem.gva = gva; mem.gpa = gpa; mem.write = true; mem.size = size; @@ -2687,30 +2685,6 @@ store_to_gva(struct nvmm_x64_state *stat } static int -store_to_mem(struct nvmm_machine *mach, struct nvmm_x64_state *state, - struct x86_instr *instr, struct x86_store *store, struct nvmm_mem *mem) -{ - nvmm_prot_t prot; - int ret; - - ret = store_to_gva(state, instr, store, &mem->gva, mem->size); - if (ret == -1) - return -1; - - if ((mem->gva & PAGE_MASK) + mem->size > PAGE_SIZE) { - /* Don't allow a cross-page MMIO. */ - errno = EINVAL; - return -1; - } - - ret = x86_gva_to_gpa(mach, state, mem->gva, &mem->gpa, &prot); - if (ret == -1) - return -1; - - return 0; -} - -static int fetch_segment(struct nvmm_machine *mach, struct nvmm_x64_state *state) { uint8_t inst_bytes[15], byte; @@ -2820,110 +2794,66 @@ assist_mem_double(struct nvmm_machine *m static int assist_mem_single(struct nvmm_machine *mach, struct nvmm_x64_state *state, - struct x86_instr *instr) + struct x86_instr *instr, struct nvmm_exit *exit) { struct nvmm_mem mem; uint8_t membuf[8]; uint64_t val; - int ret; memset(membuf, 0, sizeof(membuf)); + + mem.gpa = exit->u.mem.gpa; + mem.size = instr->operand_size; mem.data = membuf; + /* Determine the direction. */ switch (instr->src.type) { case STORE_REG: if (instr->src.disp.type != DISP_NONE) { /* Indirect access. */ mem.write = false; - mem.size = instr->operand_size; - ret = store_to_mem(mach, state, instr, &instr->src, - &mem); - if (ret == -1) - return -1; } else { /* Direct access. */ mem.write = true; - mem.size = instr->operand_size; - val = state->gprs[instr->src.u.reg->num]; - val = __SHIFTOUT(val, instr->src.u.reg->mask); - memcpy(mem.data, &val, mem.size); } break; - case STORE_IMM: mem.write = true; - mem.size = instr->src.u.imm.size; - memcpy(mem.data, &instr->src.u.imm.data, mem.size); break; - case STORE_SIB: mem.write = false; - mem.size = instr->operand_size; - ret = store_to_mem(mach, state, instr, &instr->src, &mem); - if (ret == -1) - return -1; break; - case STORE_DMO: mem.write = false; - mem.size = instr->operand_size; - ret = store_to_mem(mach, state, instr, &instr->src, &mem); - if (ret == -1) - return -1; break; - default: - return -1; + DISASSEMBLER_BUG(); } - switch (instr->dst.type) { - case STORE_REG: - if (instr->dst.disp.type != DISP_NONE) { - if (__predict_false(!mem.write)) { + if (mem.write) { + switch (instr->src.type) { + case STORE_REG: + if (instr->src.disp.type != DISP_NONE) { DISASSEMBLER_BUG(); } - mem.size = instr->operand_size; - ret = store_to_mem(mach, state, instr, &instr->dst, - &mem); - if (ret == -1) - return -1; - } else { - /* nothing */ - } - break; - - case STORE_IMM: - /* The dst can't be an immediate. */ - DISASSEMBLER_BUG(); - - case STORE_SIB: - if (__predict_false(!mem.write)) { - DISASSEMBLER_BUG(); - } - mem.size = instr->operand_size; - ret = store_to_mem(mach, state, instr, &instr->dst, &mem); - if (ret == -1) - return -1; - break; - - case STORE_DMO: - if (__predict_false(!mem.write)) { + val = state->gprs[instr->src.u.reg->num]; + val = __SHIFTOUT(val, instr->src.u.reg->mask); + memcpy(mem.data, &val, mem.size); + break; + case STORE_IMM: + memcpy(mem.data, &instr->src.u.imm.data, mem.size); + break; + default: DISASSEMBLER_BUG(); } - mem.size = instr->operand_size; - ret = store_to_mem(mach, state, instr, &instr->dst, &mem); - if (ret == -1) - return -1; - break; - - default: - return -1; } (*instr->emul)(&mem, __callbacks.mem, state->gprs); if (!mem.write) { - /* instr->dst.type == STORE_REG */ + if (instr->dst.type != STORE_REG) { + DISASSEMBLER_BUG(); + } memcpy(&val, mem.data, sizeof(uint64_t)); val = __SHIFTIN(val, instr->dst.u.reg->mask); state->gprs[instr->dst.u.reg->num] &= ~instr->dst.u.reg->mask; @@ -2979,7 +2909,7 @@ nvmm_assist_mem(struct nvmm_machine *mac if (instr.opcode->movs) { ret = assist_mem_double(mach, &state, &instr); } else { - ret = assist_mem_single(mach, &state, &instr); + ret = assist_mem_single(mach, &state, &instr, exit); } if (ret == -1) { errno = ENODEV; Index: src/lib/libnvmm/nvmm.h diff -u src/lib/libnvmm/nvmm.h:1.5 src/lib/libnvmm/nvmm.h:1.6 --- src/lib/libnvmm/nvmm.h:1.5 Sun Jan 6 16:10:51 2019 +++ src/lib/libnvmm/nvmm.h Mon Jan 7 16:30:25 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm.h,v 1.5 2019/01/06 16:10:51 maxv Exp $ */ +/* $NetBSD: nvmm.h,v 1.6 2019/01/07 16:30:25 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -54,7 +54,6 @@ struct nvmm_io { }; struct nvmm_mem { - gvaddr_t gva; gpaddr_t gpa; bool write; size_t size;