From: Jack Lange Date: Tue, 24 Feb 2009 22:13:20 +0000 (-0600) Subject: fixed emulation bugs X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=90c92392972d3ad76753f21a31a8e7db796073cc;p=palacios.releases.git fixed emulation bugs --- diff --git a/palacios/include/palacios/vmm_instr_emulator.h b/palacios/include/palacios/vmm_instr_emulator.h index f8738f4..89753d9 100644 --- a/palacios/include/palacios/vmm_instr_emulator.h +++ b/palacios/include/palacios/vmm_instr_emulator.h @@ -22,12 +22,10 @@ #define MAKE_1OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * flags) { \ - uchar_t tmp_dst = *dst; \ - \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ - asm volatile ( \ + asm volatile ( \ "pushf; " \ "push %2; " \ "popf; " \ @@ -35,21 +33,18 @@ "pushf; " \ "pop %1; " \ "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(*flags), "0"(tmp_dst) \ + : "=q"(*(uint8_t *)dst),"=q"(*flags) \ + : "q"(*flags), "0"(*(uint8_t *)dst) \ ); \ - *dst = tmp_dst; \ *flags |= flags_rsvd; \ \ } #define MAKE_1OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * flags) { \ - ushort_t tmp_dst = *dst; \ - \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ - asm volatile ( \ + asm volatile ( \ "pushf; " \ "push %2; " \ "popf; " \ @@ -57,21 +52,18 @@ "pushf; " \ "pop %1; " \ "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(*flags), "0"(tmp_dst) \ + : "=q"(*(uint16_t *)dst),"=q"(*flags) \ + : "q"(*flags), "0"(*(uint16_t *)dst) \ ); \ - *dst = tmp_dst; \ *flags |= flags_rsvd; \ \ } #define MAKE_1OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * flags) { \ - uint_t tmp_dst = *dst; \ - \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ - asm volatile ( \ + asm volatile ( \ "pushf; " \ "push %2; " \ "popf; " \ @@ -79,21 +71,18 @@ "pushf; " \ "pop %1; " \ "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(*flags), "0"(tmp_dst) \ + : "=q"(*(uint32_t *)dst),"=q"(*flags) \ + : "q"(*flags), "0"(*(uint32_t *)dst) \ ); \ - *dst = tmp_dst; \ *flags |= flags_rsvd; \ \ } #define MAKE_1OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * flags) { \ - ullong_t tmp_dst = *dst; \ - \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ - asm volatile ( \ + asm volatile ( \ "pushfq; " \ "push %2; " \ "popfq; " \ @@ -101,10 +90,9 @@ "pushfq; " \ "pop %1; " \ "popfq; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(*flags), "0"(tmp_dst) \ + : "=q"(*(uint64_t *)dst),"=q"(*flags) \ + : "q"(*flags), "0"(*(uint64_t *)dst) \ ); \ - *dst = tmp_dst; \ *flags |= flags_rsvd; \ \ } @@ -112,71 +100,53 @@ #define MAKE_1OP_8_INST(iname) static inline void iname##8(addr_t * dst) { \ - uchar_t tmp_dst = *dst; \ - \ asm volatile ( \ #iname"b %0; " \ - : "=q"(tmp_dst) \ - : "0"(tmp_dst) \ + : "=q"(*(uint8_t *)dst) \ + : "0"(*(uint8_t *)dst) \ ); \ - *dst = tmp_dst; \ } #define MAKE_1OP_16_INST(iname) static inline void iname##16(addr_t * dst) { \ - ushort_t tmp_dst = *dst; \ - \ asm volatile ( \ - #iname"w %0; " \ - : "=q"(tmp_dst) \ - : "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ + #iname"w %0; " \ + : "=q"(*(uint16_t *)dst) \ + : "0"(*(uint16_t *)dst) \ + ); \ } #define MAKE_1OP_32_INST(iname) static inline void iname##32(addr_t * dst) { \ - uint_t tmp_dst = *dst; \ - \ asm volatile ( \ - #iname"l %0; " \ - : "=q"(tmp_dst) \ - : "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ + #iname"l %0; " \ + : "=q"(*(uint32_t *)dst) \ + : "0"(*(uint32_t *)dst) \ + ); \ } #define MAKE_1OP_64_INST(iname) static inline void iname##64(addr_t * dst) { \ - ullong_t tmp_dst = *dst; \ - \ asm volatile ( \ #iname"q %0; " \ - : "=q"(tmp_dst) \ - : "0"(tmp_dst) \ + : "=q"(*(uint64_t *)dst) \ + : "0"(*(uint64_t *)dst) \ ); \ - *dst = tmp_dst; \ } #define MAKE_2OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src, addr_t * flags) { \ - uint64_t tmp_dst = *dst, tmp_src = *src; \ - addr_t tmp_flags = *flags; \ - \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ - asm volatile ( \ - "pushfq\r\n" \ - "push %3\r\n" \ - "popfq\r\n" \ - #iname"q %2, %0\r\n" \ - "pushfq\r\n" \ - "pop %1\r\n" \ - "popfq\r\n" \ - : "=q"(tmp_dst),"=q"(tmp_flags) \ - : "q"(tmp_src),"q"(tmp_flags), "0"(tmp_dst) \ - ); \ - \ - *dst = tmp_dst; \ - *flags = tmp_flags; \ + asm volatile ( \ + "pushfq\r\n" \ + "push %3\r\n" \ + "popfq\r\n" \ + #iname"q %2, %0\r\n" \ + "pushfq\r\n" \ + "pop %1\r\n" \ + "popfq\r\n" \ + : "=q"(*(uint64_t *)dst),"=q"(*flags) \ + : "q"(*(uint64_t *)src),"q"(*flags), "0"(*(uint64_t *)dst) \ + ); \ *flags |= flags_rsvd; \ \ } @@ -185,8 +155,6 @@ #define MAKE_2OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src, addr_t * flags) { \ - uint32_t tmp_dst = *dst, tmp_src = *src; \ - \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ @@ -198,18 +166,14 @@ "pushf; " \ "pop %1; " \ "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(tmp_src),"q"(*flags), "0"(tmp_dst) \ + : "=q"(*(uint32_t *)dst),"=q"(*flags) \ + : "q"(*(uint32_t *)src),"q"(*flags), "0"(*(uint32_t *)dst) \ ); \ - *dst = tmp_dst; \ *flags |= flags_rsvd; \ - \ } #define MAKE_2OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, addr_t * flags) { \ - ushort_t tmp_dst = *dst, tmp_src = *src; \ - \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ @@ -221,17 +185,13 @@ "pushf; " \ "pop %1; " \ "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(tmp_src),"q"(*flags), "0"(tmp_dst) \ + : "=q"(*(uint16_t *)dst),"=q"(*flags) \ + : "q"(*(uint16_t *)src),"q"(*flags), "0"(*(uint16_t *)dst) \ ); \ - *dst = tmp_dst; \ *flags |= flags_rsvd; \ - \ } #define MAKE_2OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, addr_t * flags) { \ - uchar_t tmp_dst = *dst, tmp_src = *src; \ - \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ @@ -243,12 +203,10 @@ "pushf; " \ "pop %1; " \ "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(tmp_src),"q"(*flags), "0"(tmp_dst) \ + : "=q"(*(uint8_t *)dst),"=q"(*flags) \ + : "q"(*(uint8_t *)src),"q"(*flags), "0"(*(uint8_t *)dst) \ ); \ - *dst = tmp_dst; \ *flags |= flags_rsvd; \ - \ } @@ -256,8 +214,8 @@ #define MAKE_2OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \ - addr_t * src, \ - addr_t * ecx, addr_t * flags) { \ + addr_t * src, \ + addr_t * ecx, addr_t * flags) { \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ @@ -271,10 +229,8 @@ "popq %0; " \ "popfq; " \ : "=q"(*flags) \ - : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ + : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ ); \ - \ - /* : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/ \ *flags |= flags_rsvd; \ } @@ -297,8 +253,6 @@ : "=q"(*flags) \ : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ ); \ - \ - /* : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/ \ *flags |= flags_rsvd; \ } @@ -390,7 +344,6 @@ : "=q"(*flags) \ : "D"(*(uint32_t *)dst),"a"(*(uint32_t *)src),"c"(*(uint32_t *)ecx),"q"(*flags) \ ); \ - \ *flags |= flags_rsvd; \ } @@ -442,47 +395,35 @@ #define MAKE_2OP_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \ - uint64_t tmp_dst = *dst, tmp_src = *src; \ - \ asm volatile ( \ #iname"q %1, %0; " \ - : "=q"(tmp_dst) \ - : "q"(tmp_src), "0"(tmp_dst) \ + : "=q"(*(uint64_t *)dst) \ + : "q"(*(uint64_t *)src), "0"(*(uint64_t *)dst) \ ); \ - *dst = tmp_dst; \ } #define MAKE_2OP_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \ - uint32_t tmp_dst = *dst, tmp_src = *src; \ - \ asm volatile ( \ #iname"l %1, %0; " \ - : "=q"(tmp_dst) \ - : "q"(tmp_src), "0"(tmp_dst) \ + : "=q"(*(uint32_t *)dst) \ + : "q"(*(uint32_t *)src), "0"(*(uint32_t *)dst) \ ); \ - *dst = tmp_dst; \ } #define MAKE_2OP_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \ - ushort_t tmp_dst = *dst, tmp_src = *src; \ - \ asm volatile ( \ #iname"w %1, %0; " \ - : "=q"(tmp_dst) \ - : "q"(tmp_src), "0"(tmp_dst) \ + : "=q"(*(uint16_t *)dst) \ + : "q"(*(uint16_t *)src), "0"(*(uint16_t *)dst) \ ); \ - *dst = tmp_dst; \ } #define MAKE_2OP_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \ - uchar_t tmp_dst = *dst, tmp_src = *src; \ - \ asm volatile ( \ #iname"b %1, %0; " \ - : "=q"(tmp_dst) \ - : "q"(tmp_src), "0"(tmp_dst) \ + : "=q"(*(uint8_t *)dst) \ + : "q"(*(uint8_t *)src), "0"(*(uint8_t *)dst) \ ); \ - *dst = tmp_dst; \ } diff --git a/palacios/src/palacios/vmm_direct_paging_32.h b/palacios/src/palacios/vmm_direct_paging_32.h index a3a3e4a..abe55fe 100644 --- a/palacios/src/palacios/vmm_direct_paging_32.h +++ b/palacios/src/palacios/vmm_direct_paging_32.h @@ -30,8 +30,8 @@ static inline int handle_passthrough_pagefault_32(struct guest_info * info, - addr_t fault_addr, - pf_error_t error_code) { + addr_t fault_addr, + pf_error_t error_code) { // Check to see if pde and pte exist (create them if not) pde32_t * pde = CR3_TO_PDE32_VA(info->ctrl_regs.cr3); pte32_t * pte = NULL; @@ -44,7 +44,7 @@ static inline int handle_passthrough_pagefault_32(struct guest_info * info, if ((region == NULL) || (region->host_type == SHDW_REGION_INVALID)) { - PrintError("Invalid region in passthrough page fault 32PAE, addr=%p\n", + PrintError("Invalid region in passthrough page fault 32, addr=%p\n", (void *)fault_addr); return -1; } diff --git a/palacios/src/palacios/vmm_emulator.c b/palacios/src/palacios/vmm_emulator.c index 735b997..9e75887 100644 --- a/palacios/src/palacios/vmm_emulator.c +++ b/palacios/src/palacios/vmm_emulator.c @@ -320,6 +320,7 @@ int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gp static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int src_op_size, int dst_op_size) { if (src_op_size == 1) { + PrintDebug("Executing 8 bit instruction\n"); switch (op_type) { case V3_OP_ADC: @@ -424,6 +425,7 @@ static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_add } } else if (src_op_size == 2) { + PrintDebug("Executing 16 bit instruction\n"); switch (op_type) { case V3_OP_ADC: @@ -478,6 +480,7 @@ static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_add } } else if (src_op_size == 4) { + PrintDebug("Executing 32 bit instruction\n"); switch (op_type) { case V3_OP_ADC: @@ -527,7 +530,7 @@ static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_add #ifdef __V3_64BIT__ } else if (src_op_size == 8) { - + PrintDebug("Executing 64 bit instruction\n"); switch (op_type) { case V3_OP_ADC: diff --git a/palacios/src/palacios/vmm_mem.c b/palacios/src/palacios/vmm_mem.c index cc79b44..3a3acbf 100644 --- a/palacios/src/palacios/vmm_mem.c +++ b/palacios/src/palacios/vmm_mem.c @@ -204,9 +204,8 @@ int handle_special_page_fault(struct guest_info * info, int v3_handle_mem_wr_hook(struct guest_info * info, addr_t guest_va, addr_t guest_pa, struct v3_shadow_region * reg, pf_error_t access_info) { - addr_t dst_addr = 0; - - dst_addr = v3_get_shadow_addr(reg, guest_pa); + + addr_t dst_addr = (addr_t)V3_VAddr((void *)v3_get_shadow_addr(reg, guest_pa)); if (v3_emulate_write_op(info, guest_va, guest_pa, dst_addr, reg->write_hook, reg->priv_data) == -1) { PrintError("Write hook emulation failed\n"); @@ -260,9 +259,9 @@ struct v3_shadow_region * v3_get_shadow_region(struct guest_info * info, addr_t addr_t v3_get_shadow_addr(struct v3_shadow_region * reg, addr_t guest_addr) { - if ((reg) && - (reg->host_type != SHDW_REGION_FULL_HOOK) && - (reg->host_type != SHDW_REGION_INVALID)) { + if ( (reg) && + (reg->host_type != SHDW_REGION_FULL_HOOK) && + (reg->host_type != SHDW_REGION_INVALID) ) { return (guest_addr - reg->guest_start) + reg->host_addr; } else { PrintError("MEM Region Invalid\n"); diff --git a/palacios/src/palacios/vmm_xed.c b/palacios/src/palacios/vmm_xed.c index 25103cc..fedca72 100644 --- a/palacios/src/palacios/vmm_xed.c +++ b/palacios/src/palacios/vmm_xed.c @@ -643,8 +643,14 @@ static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xe base = MASK(mem_op.base, mem_op.base_size); index = MASK(mem_op.index, mem_op.index_size); scale = mem_op.scale; - // displacement = MASK(mem_op.displacement, mem_op.displacement_size); - displacement = mem_op.displacement; + + // This is a horrendous hack... + // XED really screwed the pooch in calculating the displacement + if (v3_get_cpu_mode(info) == LONG) { + displacement = mem_op.displacement; + } else { + displacement = MASK(mem_op.displacement, mem_op.displacement_size); + } PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n", (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);