Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


quix86 instruction patches
Maciek Swiech [Fri, 7 Jun 2013 20:46:02 +0000 (15:46 -0500)]
palacios/include/palacios/vmm_decoder.h
palacios/src/palacios/vmm_quix86.c

index c2686d9..80f8f12 100644 (file)
 typedef enum { V3_INVALID_OP,
               V3_OP_MOVCR2, V3_OP_MOV2CR, V3_OP_SMSW, V3_OP_LMSW, V3_OP_CLTS,
               V3_OP_INVLPG,
+           /* 441-tm: adding CMP, POP, JLE, CALL, TEST*/
+           V3_OP_CMP, V3_OP_POP, V3_OP_JLE, V3_OP_CALL, V3_OP_TEST, V3_OP_PUSH,
+           V3_OP_JAE, V3_OP_JMP, V3_OP_JNZ, V3_OP_JZ, V3_OP_LEA, V3_OP_IMUL,
+           V3_OP_RET, V3_OP_JL, V3_OP_CMOVZ, V3_OP_MOVSXD, V3_OP_JNS,
+           V3_OP_CMOVS, V3_OP_SHL,
+
               V3_OP_ADC, V3_OP_ADD, V3_OP_AND, V3_OP_OR, V3_OP_XOR, V3_OP_SUB,
               V3_OP_INC, V3_OP_DEC, V3_OP_NEG, V3_OP_MOV, V3_OP_NOT, V3_OP_XCHG, 
               V3_OP_SETB, V3_OP_SETBE, V3_OP_SETL, V3_OP_SETLE, V3_OP_SETNB, 
index ac4ce9c..acd9a64 100644 (file)
 
 #include <quix86/quix86.h>
 
+#ifdef V3_CONFIG_TM_FUNC
+#include <extensions/trans_mem.h>
+#endif
+
 #ifndef V3_CONFIG_DEBUG_DECODER
 #undef PrintDebug
 #define PrintDebug(fmt, args...)
@@ -148,6 +152,33 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
     qx86_insn qx86_inst;
     uint8_t inst_buf[QX86_INSN_SIZE_MAX];
 
+    /* 441-tm: add 'escape' trap for Haswell instructions, dont want to stumble
+     * on them!
+     */
+#ifdef V3_CONFIG_TM_FUNC
+    {
+        struct v3_trans_mem * tm = (struct v3_trans_mem *)v3_get_ext_core_state(info, "trans_mem");
+        if (tm->TM_MODE == TM_ON) {
+          int byte1 = *(uint8_t *)(instr_ptr);
+          int byte2 = *(uint8_t *)(instr_ptr + 1);
+          int byte3 = *(uint8_t *)(instr_ptr + 2);
+          if (byte1 == 0xc7 && byte2 == 0xf8) {  /* third byte is an immediate */
+            //V3_Print("Decoding  %x %x %d\n", byte1, byte2, byte3);
+            instr->instr_length = 6;
+            return 0;
+          } else if (byte1 == 0xc6 && byte2 == 0xf8) { /* third byte is an immediate */
+            //V3_Print("Decoding XABORT %x %x %d\n", byte1, byte2, byte3);
+            instr->instr_length = 3;
+            return 0;
+          } else if (byte1 == 0x0f && byte2 == 0x01 && byte3 == 0xd5) {
+            //V3_Print("Decoding XEND %x %x %x\n", byte1, byte2, byte3);
+            instr->instr_length = 3;
+            return 0;
+          }
+        }
+    }
+#endif
+
     memset(instr, 0, sizeof(struct x86_instr));
     memset(&qx86_inst, 0, sizeof(qx86_inst));
 
@@ -204,6 +235,14 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
 
     instr->instr_length = qx86_inst.rawSize;
 
+    // 441 - dump memory for quix86 debugging
+    if ((instr->op_type = get_opcode(&qx86_inst,info)) == V3_INVALID_OP) {
+        PrintError(info->vm_info, info, "++==++ QX86 DECODE ++==++\n");
+        v3_dump_mem((void *)instr_ptr, 15);
+        PrintError(info->vm_info, info, "Could not get opcode. (mnemonic=%s)\n",
+                qx86_minfo(qx86_inst.mnemonic)->name);
+        return -1;
+    }
     if ((instr->op_type = get_opcode(&qx86_inst, info)) == V3_INVALID_OP) {
         PrintError(info->vm_info, info, "Could not get opcode. (mnemonic=%s)\n",
                 qx86_minfo(qx86_inst.mnemonic)->name);
@@ -274,6 +313,10 @@ static int get_opcode(qx86_insn *inst, struct guest_info *core) {
             return V3_OP_MOV2CR;
         if(IS_CR(1))
             return V3_OP_MOVCR2;
+        // 441 - mov reg reg is also ok
+        if(inst->operands[0].ot == QX86_OPERAND_TYPE_REGISTER
+                || inst->operands[1].ot == QX86_OPERAND_TYPE_REGISTER)
+            return V3_OP_MOV;
 
         PrintError(core->vm_info, core, "Bad operand types for MOV: %d %d\n", inst->operands[0].ot,
                 inst->operands[1].ot);
@@ -395,6 +438,66 @@ static int get_opcode(qx86_insn *inst, struct guest_info *core) {
     case QX86_MNEMONIC_STOSQ:
         return V3_OP_STOS;
 
+    /* 441-tm: add in CMP, POP, JLE, CALL cases */
+    case QX86_MNEMONIC_CMP:
+        return V3_OP_CMP;
+
+    case QX86_MNEMONIC_POP:
+        return V3_OP_POP;
+
+    case QX86_MNEMONIC_JLE:
+        return V3_OP_JLE;
+
+    case QX86_MNEMONIC_CALL:
+        return V3_OP_CALL;
+
+    case QX86_MNEMONIC_TEST:
+        return V3_OP_TEST;
+
+    case QX86_MNEMONIC_PUSH:
+        return V3_OP_PUSH;
+
+    case QX86_MNEMONIC_JAE:
+        return V3_OP_JAE;
+
+    case QX86_MNEMONIC_JMP:
+        return V3_OP_JMP;
+
+    case QX86_MNEMONIC_JNZ:
+        return V3_OP_JNZ;
+
+    case QX86_MNEMONIC_JZ:
+        return V3_OP_JZ;
+
+    case QX86_MNEMONIC_RET:
+        return V3_OP_RET;
+
+    case QX86_MNEMONIC_IMUL:
+        return V3_OP_IMUL;
+
+    case QX86_MNEMONIC_LEA:
+        return V3_OP_LEA;
+
+    case QX86_MNEMONIC_JL:
+        return V3_OP_JL;
+
+    case QX86_MNEMONIC_CMOVZ:
+        return V3_OP_CMOVZ;
+
+    case QX86_MNEMONIC_MOVSXD:
+        return V3_OP_MOVSXD;
+
+    case QX86_MNEMONIC_JNS:
+        return V3_OP_JNS;
+
+    case QX86_MNEMONIC_CMOVS:
+        return V3_OP_CMOVS;
+
+    case QX86_MNEMONIC_SHL:
+        return V3_OP_SHL;
+
+    case QX86_MNEMONIC_INT:
+        return V3_OP_INT;
 
     default:
         return V3_INVALID_OP;