From: Peter Dinda Date: Fri, 9 Sep 2011 22:10:16 +0000 (-0500) Subject: Merge branch 'devel' of newskysaw.cs.northwestern.edu:/home/palacios/palacios into... X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=a6c0311d9dcfe9b14042a23f94fee580308177cd;hp=b04d9381c4dd473df048685d5feae5e82d322cac;p=palacios.git Merge branch 'devel' of newskysaw.cs.northwestern.edu:/home/palacios/palacios into devel --- diff --git a/palacios/include/palacios/vmm_decoder.h b/palacios/include/palacios/vmm_decoder.h index 767fe25..03c5edb 100644 --- a/palacios/include/palacios/vmm_decoder.h +++ b/palacios/include/palacios/vmm_decoder.h @@ -216,11 +216,18 @@ static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, stru return addr + seg->base; break; - case LONG: + case LONG: { + uint64_t seg_base = 0; + // In long mode the segment bases are disregarded (forced to 0), unless using // FS or GS, then the base addresses are added - return addr + seg->base; + if (seg) { + seg_base = seg->base; + } + + return addr + seg_base; + } case LONG_16_COMPAT: default: PrintError("Unsupported CPU Mode: %d\n", info->cpu_mode); diff --git a/palacios/include/palacios/vmm_instr_decoder.h b/palacios/include/palacios/vmm_instr_decoder.h index 6ed6ba0..6e33c46 100644 --- a/palacios/include/palacios/vmm_instr_decoder.h +++ b/palacios/include/palacios/vmm_instr_decoder.h @@ -221,8 +221,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 +255,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 +263,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: @@ -278,7 +278,6 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr, PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); return -1; } - case INVLPG: switch (v3_get_vm_cpu_mode(info)) { case REAL: @@ -1018,23 +1017,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 +1062,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: diff --git a/palacios/src/palacios/vmm_v3dec.c b/palacios/src/palacios/vmm_v3dec.c index b862f96..5980dcb 100644 --- a/palacios/src/palacios/vmm_v3dec.c +++ b/palacios/src/palacios/vmm_v3dec.c @@ -122,7 +122,9 @@ int v3_decode(struct guest_info * core, addr_t instr_ptr, struct x86_instr * ins instr->instr_length += length; #ifdef V3_CONFIG_DEBUG_DECODER + V3_Print("Decoding Instr at %p\n", (void *)core->rip); v3_print_instr(instr); + V3_Print("CS DB FLag=%x\n", core->segments.cs.db); #endif return 0; @@ -153,8 +155,8 @@ static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, case AND_IMM2: case OR_IMM2: case SUB_IMM2: - case XOR_IMM2: - case MOV_IMM2:{ + case XOR_IMM2: + case MOV_IMM2: { uint8_t reg_code = 0; ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), ®_code); @@ -176,6 +178,8 @@ static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, instr->src_operand.operand = *(uint16_t *)instr_ptr; } else if (operand_width == 4) { instr->src_operand.operand = *(uint32_t *)instr_ptr; + } else if (operand_width == 8) { + instr->src_operand.operand = *(sint32_t *)instr_ptr; // This is a special case for sign extended 64bit ops } else { PrintError("Illegal operand width (%d)\n", operand_width); return -1; @@ -348,7 +352,7 @@ static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, instr->is_str_op = 1; if (instr->prefixes.rep == 1) { - instr->str_op_length = MASK(core->vm_regs.rcx, operand_width); + instr->str_op_length = MASK(core->vm_regs.rcx, addr_width); } else { instr->str_op_length = 1; } @@ -424,7 +428,7 @@ static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, instr->is_str_op = 1; if (instr->prefixes.rep == 1) { - instr->str_op_length = MASK(core->vm_regs.rcx, operand_width); + instr->str_op_length = MASK(core->vm_regs.rcx, addr_width); } else { instr->str_op_length = 1; }