From: Jack Lange Date: Thu, 10 Mar 2011 18:37:32 +0000 (-0600) Subject: added initial 64 bit decoding support X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=a71f35bcb2dc587326be18345adb1ad1d81b9435;p=palacios.git added initial 64 bit decoding support --- diff --git a/palacios/include/palacios/vmm_decoder.h b/palacios/include/palacios/vmm_decoder.h index 7f05064..c03de83 100644 --- a/palacios/include/palacios/vmm_decoder.h +++ b/palacios/include/palacios/vmm_decoder.h @@ -62,6 +62,13 @@ struct x86_prefixes { uint_t br_taken : 1; // 0x3E uint_t op_size : 1; // 0x66 uint_t addr_size : 1; // 0x67 + struct { + uint_t rm : 1; // REX.B + uint_t sib_idx : 1; // REX.X + uint_t reg : 1; // REX.R + uint_t op_size : 1; // REX.W + uint8_t rsvd : 4; + } __attribute__((packed)) rex; } __attribute__((packed)); @@ -119,7 +126,6 @@ void v3_strip_rep_prefix(uint8_t * instr, int length); uint8_t v3_get_prefixes(uint8_t * instr, struct x86_prefixes * prefixes); - void v3_print_instr(struct x86_instr * instr); diff --git a/palacios/include/palacios/vmm_instr_decoder.h b/palacios/include/palacios/vmm_instr_decoder.h index 1c292a3..aa106b6 100644 --- a/palacios/include/palacios/vmm_instr_decoder.h +++ b/palacios/include/palacios/vmm_instr_decoder.h @@ -140,11 +140,16 @@ static int get_addr_width(struct guest_info * info, struct x86_instr * instr) { switch (v3_get_vm_cpu_mode(info)) { case REAL: return (instr->prefixes.addr_size) ? 4 : 2; + case LONG: + return 8; case PROTECTED: case PROTECTED_PAE: - return (instr->prefixes.addr_size) ? 2 : 4; case LONG_32_COMPAT: - case LONG: + if (info->segments.cs.db) { + return (instr->prefixes.addr_size) ? 2 : 4; + } else { + return (instr->prefixes.addr_size) ? 4 : 2; + } default: PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); return -1; @@ -251,14 +256,22 @@ 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: - switch (v3_get_vm_cpu_mode(info)) { + switch (v3_get_vm_cpu_mode(info)) { case REAL: return (instr->prefixes.op_size) ? 4 : 2; + case LONG: + if (instr->prefixes.rex.op_size) { + return 8; + } case PROTECTED: case PROTECTED_PAE: - return (instr->prefixes.op_size) ? 2 : 4; case LONG_32_COMPAT: - case LONG: + if (info->segments.cs.db) { + // default is 32 + return (instr->prefixes.op_size) ? 2 : 4; + } else { + return (instr->prefixes.op_size) ? 4 : 2; + } default: PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); return -1; @@ -271,9 +284,11 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, return 0; case PROTECTED: case PROTECTED_PAE: - return 4; case LONG_32_COMPAT: + + return 4; case LONG: + return 8; default: PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); return -1; @@ -286,9 +301,10 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, return 2; case PROTECTED: case PROTECTED_PAE: - return 4; case LONG_32_COMPAT: + return 4; case LONG: + return 8; default: PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); return -1; @@ -302,9 +318,11 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, case REAL: case PROTECTED: case PROTECTED_PAE: - return 4; case LONG_32_COMPAT: + + return 4; case LONG: + return 8; default: PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); return -1; @@ -746,7 +764,13 @@ static int decode_rm_operand32(struct guest_info * core, } - +int decode_rm_operand64(struct guest_info * core, uint8_t * instr_ptr, + struct x86_instr * instr, struct x86_operand * operand, + uint8_t * reg_code) { + + + return 0; +} static int decode_rm_operand(struct guest_info * core, @@ -759,8 +783,10 @@ static int decode_rm_operand(struct guest_info * core, if (mode == REAL) { return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code); - } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE)) { + } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE) || (mode == LONG_32_COMPAT)) { return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code); + } else if (mode == LONG) { + return decode_rm_operand64(core, instr_ptr, instr, operand, reg_code); } else { PrintError("Invalid CPU_MODE (%d)\n", mode); return -1; diff --git a/palacios/src/palacios/vmm_v3dec.c b/palacios/src/palacios/vmm_v3dec.c index 7dd716e..0b0d7a4 100644 --- a/palacios/src/palacios/vmm_v3dec.c +++ b/palacios/src/palacios/vmm_v3dec.c @@ -78,7 +78,13 @@ int v3_decode(struct guest_info * core, addr_t instr_ptr, struct x86_instr * ins length = v3_get_prefixes((uint8_t *)instr_ptr, &(instr->prefixes)); - // check for REX prefix + // REX prefix + if (v3_get_vm_cpu_mode(core) == LONG) { + if ((*(uint8_t *)(instr_ptr + length) & 0xf0) == 0x40) { + *(uint8_t *)&(instr->prefixes.rex) = *(uint8_t *)(instr_ptr + length); + length += 1; + } + } form = op_code_to_form((uint8_t *)(instr_ptr + length), &length);