X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Finclude%2Fpalacios%2Fvmm_instr_decoder.h;h=a7c63fb20591c55ca92859a2033d3003dfde80a5;hb=659151a0b655c619f3acbb98a45e9eeb8002a4b3;hp=d690af9ccbaa0ce59e8cfa853f7bb7cdebb3c8fd;hpb=3db6f4c76bd6412d0154b7693c1516d792486b13;p=palacios.git diff --git a/palacios/include/palacios/vmm_instr_decoder.h b/palacios/include/palacios/vmm_instr_decoder.h index d690af9..a7c63fb 100644 --- a/palacios/include/palacios/vmm_instr_decoder.h +++ b/palacios/include/palacios/vmm_instr_decoder.h @@ -28,7 +28,7 @@ typedef enum { SMSW, CLTS, INVLPG, - INT, // KCH: adding software interrupts + INT, MOV_CR2, MOV_2CR, @@ -151,7 +151,7 @@ static int get_addr_width(struct guest_info * info, struct x86_instr * instr) { return (instr->prefixes.addr_size) ? 4 : 2; } default: - PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); + PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode); return -1; } } @@ -191,6 +191,7 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, case XOR_MEM2_8: case XOR_IMM2_8: case INC_8: + case INT: case DEC_8: case NEG_8: case NOT_8: @@ -221,8 +222,7 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, case MOV_MEM2: case MOV_2MEM: case MOV_MEM2AX: - case MOV_AX2MEM: - case MOV_IMM2: + case MOV_AX2MEM: case MOVS: case MOVSX: case MOVZX: @@ -256,6 +256,7 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, case OR_IMM2SX_8: case SUB_IMM2SX_8: case XOR_IMM2SX_8: + case MOV_IMM2: switch (v3_get_vm_cpu_mode(info)) { case REAL: return (instr->prefixes.op_size) ? 4 : 2; @@ -263,7 +264,7 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, if (instr->prefixes.rex_op_size) { return 8; } else { - return 4; + return (instr->prefixes.op_size) ? 2 : 4; } case PROTECTED: case PROTECTED_PAE: @@ -275,14 +276,13 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, return (instr->prefixes.op_size) ? 4 : 2; } default: - PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); + PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode); return -1; } - case INVLPG: switch (v3_get_vm_cpu_mode(info)) { case REAL: - PrintError("Invalid instruction given operating mode (%d)\n", form); + PrintError(info->vm_info, info, "Invalid instruction given operating mode (%d)\n", form); return 0; case PROTECTED: case PROTECTED_PAE: @@ -291,7 +291,7 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, case LONG: return 8; default: - PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); + PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode); return -1; } @@ -307,11 +307,11 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, case LONG: return 8; default: - PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); + PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode); return -1; } - case INT: // KCH + //case INT: case MOV_DR2: case MOV_2DR: case MOV_CR2: @@ -326,14 +326,14 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, case LONG: return 8; default: - PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); + PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode); return -1; } case MOV_SR2: case MOV_2SR: default: - PrintError("Unsupported instruction form %d\n", form); + PrintError(info->vm_info, info, "Unsupported instruction form %d\n", form); return -1; } @@ -437,7 +437,7 @@ static inline int decode_gpr(struct guest_info * core, reg->operand = (addr_t)&(gprs->r15); break; default: - PrintError("Invalid Reg Code (%d)\n", reg_code); + PrintError(core->vm_info, core, "Invalid Reg Code (%d)\n", reg_code); reg->operand = 0; return -1; } @@ -454,7 +454,7 @@ static inline int decode_cr(struct guest_info * core, struct v3_ctrl_regs * crs = &(core->ctrl_regs); -// PrintDebug("\t Ctrl regs %d\n", reg_code); +// PrintDebug(core->vm_info, core, "\t Ctrl regs %d\n", reg_code); switch (reg_code) { case 0: @@ -471,13 +471,31 @@ static inline int decode_cr(struct guest_info * core, break; default: reg->operand = 0; - PrintError("Invalid Reg Code (%d)\n", reg_code); + PrintError(core->vm_info, core, "Invalid Reg Code (%d)\n", reg_code); return -1; } return 0; } +static struct v3_segment * get_instr_segment(struct guest_info * core, struct x86_instr * instr) { + struct v3_segment * seg = &(core->segments.ds); + + if (instr->prefixes.cs_override) { + seg = &(core->segments.cs); + } else if (instr->prefixes.es_override) { + seg = &(core->segments.es); + } else if (instr->prefixes.ss_override) { + seg = &(core->segments.ss); + } else if (instr->prefixes.fs_override) { + seg = &(core->segments.fs); + } else if (instr->prefixes.gs_override) { + seg = &(core->segments.gs); + } + + return seg; +} + #define ADDR_MASK(val, length) ({ \ @@ -510,14 +528,14 @@ static int decode_rm_operand16(struct guest_info * core, modrm_mode_t mod_mode = 0; uint8_t * instr_cursor = modrm_instr; - // PrintDebug("ModRM mod=%d\n", modrm->mod); + // PrintDebug(core->vm_info, core, "ModRM mod=%d\n", modrm->mod); *reg_code = modrm->reg; instr_cursor += 1; if (modrm->mod == 3) { - //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm); + //PrintDebug(core->vm_info, core, "first operand = Register (RM=%d)\n",modrm->rm); operand->type = REG_OPERAND; decode_gpr(core, modrm->rm, operand); @@ -534,7 +552,7 @@ static int decode_rm_operand16(struct guest_info * core, } else if (modrm->mod == 2) { mod_mode = DISP16; } else { - PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod); + PrintError(core->vm_info, core, "Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod); v3_print_instr(instr); return -1; } @@ -627,7 +645,7 @@ static int decode_rm_operand32(struct guest_info * core, if (modrm->mod == 3) { operand->type = REG_OPERAND; - // PrintDebug("first operand = Register (RM=%d)\n",modrm->rm); + // PrintDebug(core->vm_info, core, "first operand = Register (RM=%d)\n",modrm->rm); decode_gpr(core, modrm->rm, operand); @@ -643,7 +661,7 @@ static int decode_rm_operand32(struct guest_info * core, } else if (modrm->mod == 2) { mod_mode = DISP32; } else { - PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod); + PrintError(core->vm_info, core, "Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod); v3_print_instr(instr); return -1; } @@ -681,7 +699,6 @@ static int decode_rm_operand32(struct guest_info * core, } if (has_sib_byte) { - instr_cursor += 1; struct sib_byte * sib = (struct sib_byte *)(instr_cursor); int scale = 0x1 << sib->scale; @@ -736,6 +753,9 @@ static int decode_rm_operand32(struct guest_info * core, case 5: if (modrm->mod != 0) { base_addr += ADDR_MASK(gprs->rbp, 4); + } else { + mod_mode = DISP32; + base_addr = 0; } break; case 6: @@ -804,7 +824,7 @@ int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, rm_val |= (instr->prefixes.rex_rm << 3); operand->type = REG_OPERAND; - // PrintDebug("first operand = Register (RM=%d)\n",modrm->rm); + // PrintDebug(core->vm_info, core, "first operand = Register (RM=%d)\n",modrm->rm); decode_gpr(core, rm_val, operand); } else { @@ -821,7 +841,7 @@ int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, } else if (modrm->mod == 2) { mod_mode = DISP32; } else { - PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod); + PrintError(core->vm_info, core, "Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod); v3_print_instr(instr); return -1; } @@ -888,7 +908,6 @@ int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, } if (has_sib_byte) { - instr_cursor += 1; struct sib_byte * sib = (struct sib_byte *)(instr_cursor); int scale = 0x1 << sib->scale; uint8_t index_val = sib->index; @@ -972,6 +991,9 @@ int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, case 5: if (modrm->mod != 0) { base_addr += gprs->rbp; + } else { + mod_mode = DISP32; + base_addr = 0; } break; case 6: @@ -1018,23 +1040,24 @@ int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, } - /* - Segments should be ignored - // get appropriate segment - if (instr->prefixes.cs_override) { - seg = &(core->segments.cs); - } else if (instr->prefixes.es_override) { - seg = &(core->segments.es); - } else if (instr->prefixes.ss_override) { - seg = &(core->segments.ss); - } else if (instr->prefixes.fs_override) { - seg = &(core->segments.fs); - } else if (instr->prefixes.gs_override) { - seg = &(core->segments.gs); - } else { - seg = &(core->segments.ds); - } - */ + + //Segments should be ignored + // get appropriate segment + + if (instr->prefixes.cs_override) { + seg = &(core->segments.cs); + } else if (instr->prefixes.es_override) { + seg = &(core->segments.es); + } else if (instr->prefixes.ss_override) { + seg = &(core->segments.ss); + } else if (instr->prefixes.fs_override) { + seg = &(core->segments.fs); + } else if (instr->prefixes.gs_override) { + seg = &(core->segments.gs); + } else { + seg = &(core->segments.ds); + } + operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), get_addr_width(core, instr)); @@ -1062,7 +1085,7 @@ static int decode_rm_operand(struct guest_info * core, case REAL: return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code); case LONG: - if (instr->prefixes.rex_op_size) { + if (instr->prefixes.rex) { return decode_rm_operand64(core, instr_ptr, instr, operand, reg_code); } case PROTECTED: @@ -1070,7 +1093,7 @@ static int decode_rm_operand(struct guest_info * core, case LONG_32_COMPAT: return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code); default: - PrintError("Invalid CPU_MODE (%d)\n", mode); + PrintError(core->vm_info, core, "Invalid CPU_MODE (%d)\n", mode); return -1; } } @@ -1332,10 +1355,9 @@ static op_form_t op_code_to_form(uint8_t * instr, int * length) { case 0xf4: return HLT; - - // KCH - case 0xcd: - return INT; + + case 0xcd: + return INT; case 0xf6: { struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]); @@ -1498,7 +1520,7 @@ static char * op_form_to_str(op_form_t form) { case SETO: return "SETO"; case STOS_8: return "STOS_8"; case STOS: return "STOS"; - case INT: return "INT"; // KCH + case INT: return "INT"; case INVALID_INSTR: default: