#include <palacios/vmm_paging.h>
#include <palacios/vmm_instr_emulator.h>
-#ifndef DEBUG_EMULATOR
+#ifndef CONFIG_DEBUG_EMULATOR
#undef PrintDebug
#define PrintDebug(fmt, args...)
#endif
int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
void * priv_data) {
uint_t emulation_length = 0;
+ uint_t emulation_iter_cnt = 0;
addr_t tmp_rcx = 0;
addr_t src_addr = 0;
return -1;
}
- emulation_length = ( (dec_instr->str_op_length < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
+ /*emulation_length = ( (dec_instr->str_op_length < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
dec_instr->str_op_length :
+ (0x1000 - PAGE_OFFSET_4KB(write_gva)));*/
+ emulation_length = ( (dec_instr->str_op_length * (dec_instr->dst_operand.size) < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
+ dec_instr->str_op_length * dec_instr->dst_operand.size :
(0x1000 - PAGE_OFFSET_4KB(write_gva)));
/* ** Fix emulation length so that it doesn't overrun over the src page either ** */
- tmp_rcx = emulation_length;
+ emulation_iter_cnt = emulation_length / dec_instr->dst_operand.size;
+ tmp_rcx = emulation_iter_cnt;
-
-
-
if (dec_instr->op_type == V3_OP_MOVS) {
// figure out addresses here....
// RCX is only modified if the rep prefix is present
if (dec_instr->prefixes.rep == 1) {
- info->vm_regs.rcx -= emulation_length;
+ info->vm_regs.rcx -= emulation_iter_cnt;
}
} else if (dec_instr->op_type == V3_OP_STOS) {
// RCX is only modified if the rep prefix is present
if (dec_instr->prefixes.rep == 1) {
- info->vm_regs.rcx -= emulation_length;
+ info->vm_regs.rcx -= emulation_iter_cnt;
}
} else {
int dst_op_len = 0;
PrintDebug("Emulating Write for instruction at %p\n", (void *)(addr_t)(info->rip));
- PrintDebug("GVA=%p\n", (void *)write_gva);
+ PrintDebug("GVA=%p Dst_Addr=%p\n", (void *)write_gva, (void *)dst_addr);
if (info->mem_mode == PHYSICAL_MEM) {
ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
} else {
ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
}
-
+
if (ret == -1) {
+ PrintError("Could not read instruction for Emulated Read at %p\n", (void *)(addr_t)(info->rip));
return -1;
}
+
if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
PrintError("Decoding Error\n");
// Kick off single step emulator
if (info->shdw_pg_mode == SHADOW_PAGING) {
if ((dec_instr.src_operand.type != MEM_OPERAND) ||
(dec_instr.src_operand.operand != read_gva)) {
- PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
- (void *)dec_instr.src_operand.operand, (void *)read_gva);
+ PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p operand_type=%d\n",
+ (void *)dec_instr.src_operand.operand, (void *)read_gva, dec_instr.src_operand.type);
return -1;
}
} else {