X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Finclude%2Fpalacios%2Fvmm_instr_decoder.h;h=6ed6ba0232a7d6b70b9820534f84a94351dfea83;hb=dd90b1f8b73b9697894d10daa5eba902c22ccd94;hp=623ca4d38ba5845884365284a1d1e5dd834a6a82;hpb=5614cff13837121053e831419f569b4e6e32bcd9;p=palacios.releases.git diff --git a/palacios/include/palacios/vmm_instr_decoder.h b/palacios/include/palacios/vmm_instr_decoder.h index 623ca4d..6ed6ba0 100644 --- a/palacios/include/palacios/vmm_instr_decoder.h +++ b/palacios/include/palacios/vmm_instr_decoder.h @@ -28,6 +28,7 @@ typedef enum { SMSW, CLTS, INVLPG, + INT, MOV_CR2, MOV_2CR, @@ -310,6 +311,7 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, return -1; } + case INT: case MOV_DR2: case MOV_2DR: case MOV_CR2: @@ -476,24 +478,6 @@ static inline int decode_cr(struct guest_info * core, return 0; } -// This converts the displacement into the appropriate masked value -/* - QUESTION: Are the register Values signed ????? - */ -#define MASK_DISPLACEMENT(reg, mode) ({ \ - sint64_t val = 0; \ - if (mode == DISP8) { \ - val = (sint8_t)(reg & 0xff); \ - } else if (mode == DISP16) { \ - val = (sint16_t)(reg & 0xffff); \ - } else if (mode == DISP32) { \ - val = (sint32_t)(reg & 0xffffffff); \ - } else { \ - PrintError("Error invalid displacement size (%d)\n", mode); \ - /*V3_ASSERT(0);*/ \ - } \ - val; \ - }) #define ADDR_MASK(val, length) ({ \ @@ -549,37 +533,41 @@ static int decode_rm_operand16(struct guest_info * core, mod_mode = DISP8; } else if (modrm->mod == 2) { mod_mode = DISP16; + } else { + PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod); + v3_print_instr(instr); + return -1; } switch (modrm->rm) { case 0: - base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rsi, mod_mode); + base_addr = gprs->rbx + ADDR_MASK(gprs->rsi, 2); break; case 1: - base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rdi, mod_mode); + base_addr = gprs->rbx + ADDR_MASK(gprs->rdi, 2); break; case 2: - base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rsi, mod_mode); + base_addr = gprs->rbp + ADDR_MASK(gprs->rsi, 2); break; case 3: - base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rdi, mod_mode); + base_addr = gprs->rbp + ADDR_MASK(gprs->rdi, 2); break; case 4: - base_addr = gprs->rsi; + base_addr = ADDR_MASK(gprs->rsi, 2); break; case 5: - base_addr = gprs->rdi; + base_addr = ADDR_MASK(gprs->rdi, 2); break; case 6: if (modrm->mod == 0) { base_addr = 0; mod_mode = DISP16; } else { - base_addr = gprs->rbp; + base_addr = ADDR_MASK(gprs->rbp, 2); } break; case 7: - base_addr = gprs->rbx; + base_addr = ADDR_MASK(gprs->rbx, 2); break; } @@ -654,6 +642,10 @@ static int decode_rm_operand32(struct guest_info * core, mod_mode = DISP8; } else if (modrm->mod == 2) { mod_mode = DISP32; + } else { + PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod); + v3_print_instr(instr); + return -1; } switch (modrm->rm) { @@ -727,30 +719,30 @@ static int decode_rm_operand32(struct guest_info * core, switch (sib->base) { case 0: - base_addr += MASK_DISPLACEMENT(gprs->rax, mod_mode); + base_addr += ADDR_MASK(gprs->rax, 4); break; case 1: - base_addr += MASK_DISPLACEMENT(gprs->rcx, mod_mode); + base_addr += ADDR_MASK(gprs->rcx, 4); break; case 2: - base_addr += MASK_DISPLACEMENT(gprs->rdx, mod_mode); + base_addr += ADDR_MASK(gprs->rdx, 4); break; case 3: - base_addr += MASK_DISPLACEMENT(gprs->rbx, mod_mode); + base_addr += ADDR_MASK(gprs->rbx, 4); break; case 4: - base_addr += MASK_DISPLACEMENT(gprs->rsp, mod_mode); + base_addr += ADDR_MASK(gprs->rsp, 4); break; case 5: if (modrm->mod != 0) { - base_addr += MASK_DISPLACEMENT(gprs->rbp, mod_mode); + base_addr += ADDR_MASK(gprs->rbp, 4); } break; case 6: - base_addr += MASK_DISPLACEMENT(gprs->rsi, mod_mode); + base_addr += ADDR_MASK(gprs->rsi, 4); break; case 7: - base_addr += MASK_DISPLACEMENT(gprs->rdi, mod_mode); + base_addr += ADDR_MASK(gprs->rdi, 4); break; } @@ -828,6 +820,10 @@ int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, mod_mode = DISP8; } else if (modrm->mod == 2) { mod_mode = DISP32; + } else { + PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod); + v3_print_instr(instr); + return -1; } if (rm_val == 4) { @@ -959,54 +955,54 @@ int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, switch (base_val) { case 0: - base_addr += MASK_DISPLACEMENT(gprs->rax, mod_mode); + base_addr += gprs->rax; break; case 1: - base_addr += MASK_DISPLACEMENT(gprs->rcx, mod_mode); + base_addr += gprs->rcx; break; case 2: - base_addr += MASK_DISPLACEMENT(gprs->rdx, mod_mode); + base_addr += gprs->rdx; break; case 3: - base_addr += MASK_DISPLACEMENT(gprs->rbx, mod_mode); + base_addr += gprs->rbx; break; case 4: - base_addr += MASK_DISPLACEMENT(gprs->rsp, mod_mode); + base_addr += gprs->rsp; break; case 5: if (modrm->mod != 0) { - base_addr += MASK_DISPLACEMENT(gprs->rbp, mod_mode); + base_addr += gprs->rbp; } break; case 6: - base_addr += MASK_DISPLACEMENT(gprs->rsi, mod_mode); + base_addr += gprs->rsi; break; case 7: - base_addr += MASK_DISPLACEMENT(gprs->rdi, mod_mode); + base_addr += gprs->rdi; break; case 8: - base_addr += MASK_DISPLACEMENT(gprs->r8, mod_mode); + base_addr += gprs->r8; break; case 9: - base_addr += MASK_DISPLACEMENT(gprs->r9, mod_mode); + base_addr += gprs->r9; break; case 10: - base_addr += MASK_DISPLACEMENT(gprs->r10, mod_mode); + base_addr += gprs->r10; break; case 11: - base_addr += MASK_DISPLACEMENT(gprs->r11, mod_mode); + base_addr += gprs->r11; break; case 12: - base_addr += MASK_DISPLACEMENT(gprs->r12, mod_mode); + base_addr += gprs->r12; break; case 13: - base_addr += MASK_DISPLACEMENT(gprs->r13, mod_mode); + base_addr += gprs->r13; break; case 14: - base_addr += MASK_DISPLACEMENT(gprs->r14, mod_mode); + base_addr += gprs->r14; break; case 15: - base_addr += MASK_DISPLACEMENT(gprs->r15, mod_mode); + base_addr += gprs->r15; break; } @@ -1337,6 +1333,8 @@ static op_form_t op_code_to_form(uint8_t * instr, int * length) { case 0xf4: return HLT; + case 0xcd: + return INT; case 0xf6: { struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]); @@ -1499,6 +1497,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"; case INVALID_INSTR: default: