Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libnvmm Optimize: on single memory operand instructions, ...



details:   https://anonhg.NetBSD.org/src/rev/9fccbe326785
branches:  trunk
changeset: 447324:9fccbe326785
user:      maxv <maxv%NetBSD.org@localhost>
date:      Mon Jan 07 16:30:25 2019 +0000

description:
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:

 lib/libnvmm/libnvmm.3     |    7 +-
 lib/libnvmm/libnvmm_x86.c |  142 +++++++++++----------------------------------
 lib/libnvmm/nvmm.h        |    3 +-
 3 files changed, 39 insertions(+), 113 deletions(-)

diffs (262 lines):

diff -r 72eef1778a6d -r 9fccbe326785 lib/libnvmm/libnvmm.3
--- a/lib/libnvmm/libnvmm.3     Mon Jan 07 15:44:47 2019 +0000
+++ b/lib/libnvmm/libnvmm.3     Mon Jan 07 16:30:25 2019 +0000
@@ -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 @@
 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 @@
 .El
 .Pp
 In either case,
-.Va gva
-will indicate the guest virtual address,
 .Va gpa
 will indicate the guest physical address,
 .Va write
diff -r 72eef1778a6d -r 9fccbe326785 lib/libnvmm/libnvmm_x86.c
--- a/lib/libnvmm/libnvmm_x86.c Mon Jan 07 15:44:47 2019 +0000
+++ b/lib/libnvmm/libnvmm_x86.c Mon Jan 07 16:30:25 2019 +0000
@@ -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 @@
 
        if (is_mmio) {
                mem.data = data;
-               mem.gva = gva;
                mem.gpa = gpa;
                mem.write = false;
                mem.size = size;
@@ -627,7 +626,6 @@
 
        if (is_mmio) {
                mem.data = data;
-               mem.gva = gva;
                mem.gpa = gpa;
                mem.write = true;
                mem.size = size;
@@ -2687,30 +2685,6 @@
 }
 
 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 @@
 
 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;
+               }
+               break;
+       case STORE_IMM:
+               mem.write = true;
+               break;
+       case STORE_SIB:
+               mem.write = false;
+               break;
+       case STORE_DMO:
+               mem.write = false;
+               break;
+       default:
+               DISASSEMBLER_BUG();
+       }
+
+       if (mem.write) {
+               switch (instr->src.type) {
+               case STORE_REG:
+                       if (instr->src.disp.type != DISP_NONE) {
+                               DISASSEMBLER_BUG();
+                       }
                        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;
-       }
-
-       switch (instr->dst.type) {
-       case STORE_REG:
-               if (instr->dst.disp.type != DISP_NONE) {
-                       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;
-               } else {
-                       /* nothing */
-               }
-               break;
-
-       case STORE_IMM:
-               /* The dst can't be an immediate. */
-               DISASSEMBLER_BUG();
-
-       case STORE_SIB:
-               if (__predict_false(!mem.write)) {
+                       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;
-
-       case STORE_DMO:
-               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;
-
-       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 @@
        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 -r 72eef1778a6d -r 9fccbe326785 lib/libnvmm/nvmm.h
--- a/lib/libnvmm/nvmm.h        Mon Jan 07 15:44:47 2019 +0000
+++ b/lib/libnvmm/nvmm.h        Mon Jan 07 16:30:25 2019 +0000
@@ -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_mem {
-       gvaddr_t gva;
        gpaddr_t gpa;
        bool write;
        size_t size;



Home | Main Index | Thread Index | Old Index