Source-Changes-HG archive

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

[src/trunk]: src/lib/libnvmm Implement missing (REPE) CMPS instruction suppor...



details:   https://anonhg.NetBSD.org/src/rev/850abbf92013
branches:  trunk
changeset: 941792:850abbf92013
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Fri Oct 30 21:06:13 2020 +0000

description:
Implement missing (REPE) CMPS instruction support in NVMMs x86_decode().

In apparently rare cases the (REPE) CMPS instruction can trigger an memory
assist. NVMM wouldn't recognize the instruction and thus couldn't assist and
Qemu would abort.

diffstat:

 lib/libnvmm/libnvmm_x86.c |  64 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 62 insertions(+), 2 deletions(-)

diffs (107 lines):

diff -r 4e8cce74438c -r 850abbf92013 lib/libnvmm/libnvmm_x86.c
--- a/lib/libnvmm/libnvmm_x86.c Fri Oct 30 20:36:33 2020 +0000
+++ b/lib/libnvmm/libnvmm_x86.c Fri Oct 30 21:06:13 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: libnvmm_x86.c,v 1.40 2020/09/05 07:22:25 maxv Exp $    */
+/*     $NetBSD: libnvmm_x86.c,v 1.41 2020/10/30 21:06:13 reinoud Exp $ */
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -1051,6 +1051,7 @@
        bool movs:1;
        bool stos:1;
        bool lods:1;
+       bool cmps:1;
        bool szoverride:1;
        bool group1:1;
        bool group3:1;
@@ -1463,6 +1464,26 @@
        },
 
        /*
+        * CMPS
+        */
+       [0xA6] = {
+               /* Yb, Xb */
+               .valid = true,
+               .cmps = true,
+               .szoverride = false,
+               .defsize = OPSIZE_BYTE,
+               .emul = &x86_emul_cmp
+       },
+       [0xA7] = {
+               /* Yv, Xv */
+               .valid = true,
+               .cmps = true,
+               .szoverride = true,
+               .defsize = -1,
+               .emul = &x86_emul_cmp
+       },
+
+       /*
         * STOS
         */
        [0xAA] = {
@@ -1871,6 +1892,35 @@
 }
 
 /*
+ * Special node, for CMPS. Fake two displacements of zero on the source and
+ * destination registers.
+ * XXX coded as clone of movs as its similar in register usage
+ * XXX might be merged with node_movs()
+ */
+static int
+node_cmps(struct x86_decode_fsm *fsm, struct x86_instr *instr)
+{
+       size_t adrsize;
+
+       adrsize = instr->address_size;
+
+       /* DS:RSI */
+       instr->src.type = STORE_REG;
+       instr->src.u.reg = &gpr_map__special[1][2][adrsize-1];
+       instr->src.disp.type = DISP_0;
+
+       /* ES:RDI, force ES */
+       instr->dst.type = STORE_REG;
+       instr->dst.u.reg = &gpr_map__special[1][3][adrsize-1];
+       instr->dst.disp.type = DISP_0;
+       instr->dst.hardseg = NVMM_X64_SEG_ES;
+
+       fsm_advance(fsm, 0, NULL);
+
+       return 0;
+}
+
+/*
  * Special node, for STOS and LODS. Fake a displacement of zero on the
  * destination register.
  */
@@ -2470,6 +2520,8 @@
                fsm_advance(fsm, 1, node_stlo);
        } else if (opcode->movs) {
                fsm_advance(fsm, 1, node_movs);
+       } else if (opcode->cmps) {
+               fsm_advance(fsm, 1, node_cmps);
        } else {
                return -1;
        }
@@ -2646,8 +2698,16 @@
 
        while (fsm.fn != NULL) {
                ret = (*fsm.fn)(&fsm, instr);
-               if (ret == -1)
+               if (ret == -1) {
+                       printf("\nNVMM: %s missing support for instruction " \
+                              "with max length %ld : [ ", __func__,
+                              inst_len);
+                       for (uint i = 0; i < inst_len; i++)
+                               printf("%02x ", inst_bytes[i]);
+                       printf("], please report to NetBSD!\n\n");
+                       fflush(stdout);
                        return -1;
+               }
        }
 
        instr->len = fsm.buf - inst_bytes;



Home | Main Index | Thread Index | Old Index