diff options
| author | maxv <maxv@NetBSD.org> | 2019-01-07 16:30:25 +0000 |
|---|---|---|
| committer | maxv <maxv@NetBSD.org> | 2019-01-07 16:30:25 +0000 |
| commit | e92e367e3e87a0e2446c709c07b2dae1ab4349bc (patch) | |
| tree | bef50214a83fcf24c558a3ff67d1dc281108fef0 /lib/libnvmm | |
| parent | e116ff21f91c84c9fbb77423b5a5af87f761698d (diff) | |
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.
Diffstat (limited to 'lib/libnvmm')
| -rw-r--r-- | lib/libnvmm/libnvmm.3 | 7 | ||||
| -rw-r--r-- | lib/libnvmm/libnvmm_x86.c | 116 | ||||
| -rw-r--r-- | lib/libnvmm/nvmm.h | 3 |
3 files changed, 26 insertions, 100 deletions
diff --git a/lib/libnvmm/libnvmm.3 b/lib/libnvmm/libnvmm.3 index cf86d294369..e94618ae33a 100644 --- a/lib/libnvmm/libnvmm.3 +++ b/lib/libnvmm/libnvmm.3 @@ -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 diff --git a/lib/libnvmm/libnvmm_x86.c b/lib/libnvmm/libnvmm_x86.c index dc8338034d1..a79f7a1d4f9 100644 --- a/lib/libnvmm/libnvmm_x86.c +++ b/lib/libnvmm/libnvmm_x86.c @@ -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 *mach, struct nvmm_x64_state *state, 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 *mach, struct nvmm_x64_state *state, 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 *state, struct x86_instr *instr, } 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 *mach, struct nvmm_x64_state *state, 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 *mach, nvmm_cpuid_t cpuid, 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; diff --git a/lib/libnvmm/nvmm.h b/lib/libnvmm/nvmm.h index b924f235c80..6893b23639a 100644 --- a/lib/libnvmm/nvmm.h +++ b/lib/libnvmm/nvmm.h @@ -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; |
