diff options
author | neel <neel@FreeBSD.org> | 2012-08-04 23:51:21 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2012-08-04 23:51:21 +0000 |
commit | 9f954dc59906b0a4f03d285e1c4b6a0fc4e36c40 (patch) | |
tree | b166c9bf4338504c67c78c61b975b1a8480fdfc4 /usr.sbin | |
parent | 72240bed65f0a58f17a96e6a3931f12e92eb37f1 (diff) | |
download | FreeBSD-src-9f954dc59906b0a4f03d285e1c4b6a0fc4e36c40.zip FreeBSD-src-9f954dc59906b0a4f03d285e1c4b6a0fc4e36c40.tar.gz |
The displacement field in the decoded instruction should be treated as a 8-bit
or 32-bit signed integer.
Simplify the handling of indirect addressing with displacement by
unconditionally adding the 'instruction->disp' to the target address.
This is alright since 'instruction->disp' is non-zero only for the
addressing modes that specify a displacement.
Obtained from: NetApp
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bhyve/instruction_emul.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/usr.sbin/bhyve/instruction_emul.c b/usr.sbin/bhyve/instruction_emul.c index 8c99194..790c5ff 100644 --- a/usr.sbin/bhyve/instruction_emul.c +++ b/usr.sbin/bhyve/instruction_emul.c @@ -135,7 +135,7 @@ struct decoded_instruction uint8_t *opcode; uint8_t *modrm; uint8_t *sib; - uint8_t *displacement; + uint8_t *displacement; uint8_t *immediate; uint8_t opcode_flags; @@ -337,9 +337,9 @@ decode_extension_operands(struct decoded_instruction *decoded) if (decoded->displacement) { if (decoded->addressing_mode == MOD_INDIRECT_DISP8) { - decoded->disp = (int32_t)*decoded->displacement; + decoded->disp = *((int8_t *)decoded->displacement); } else if (decoded->addressing_mode == MOD_INDIRECT_DISP32) { - decoded->disp = *((int32_t*)decoded->displacement); + decoded->disp = *((int32_t *)decoded->displacement); } } @@ -432,14 +432,6 @@ get_operand(struct vmctx *vm, int vcpu, uint64_t guest_cr3, *operand = reg; return (0); case MOD_INDIRECT: - target = gla2gpa(reg, guest_cr3); - emulated_memory = find_region(target); - if (emulated_memory) { - return emulated_memory->memread(vm, vcpu, target, - 4, operand, - emulated_memory->arg); - } - return (-1); case MOD_INDIRECT_DISP8: case MOD_INDIRECT_DISP32: target = gla2gpa(reg, guest_cr3); @@ -450,7 +442,7 @@ get_operand(struct vmctx *vm, int vcpu, uint64_t guest_cr3, 4, operand, emulated_memory->arg); } - return (-1); + return (-1); default: return (-1); } @@ -473,19 +465,22 @@ perform_write(struct vmctx *vm, int vcpu, uint64_t guest_cr3, } else if (instruction->opcode_flags & TO_REG) { reg = instruction->reg; addressing_mode = MOD_DIRECT; - } else + } else return (-1); regname = get_vm_reg_name(reg); error = vm_get_register(vm, vcpu, regname, ®); - if (error) + if (error) return (error); switch(addressing_mode) { case MOD_DIRECT: return vm_set_register(vm, vcpu, regname, operand); case MOD_INDIRECT: + case MOD_INDIRECT_DISP8: + case MOD_INDIRECT_DISP32: target = gla2gpa(reg, guest_cr3); + target += instruction->disp; emulated_memory = find_region(target); if (emulated_memory) { return emulated_memory->memwrite(vm, vcpu, target, @@ -506,7 +501,7 @@ emulate_decoded_instruction(struct vmctx *vm, int vcpu, uint64_t cr3, int error; error = get_operand(vm, vcpu, cr3, instruction, &operand); - if (error) + if (error) return (error); return perform_write(vm, vcpu, cr3, instruction, operand); @@ -519,17 +514,17 @@ emulate_instruction(struct vmctx *vm, int vcpu, uint64_t rip, uint64_t cr3) int error; void *instruction = gla2hla(rip, cr3); - if ((error = decode_instruction(instruction, &instr)) != 0) + if ((error = decode_instruction(instruction, &instr)) != 0) return (error); - + return emulate_decoded_instruction(vm, vcpu, cr3, &instr); } struct memory_region * -register_emulated_memory(uintptr_t start, size_t len, emulated_read_func_t memread, +register_emulated_memory(uintptr_t start, size_t len, emulated_read_func_t memread, emulated_write_func_t memwrite, void *arg) { - if (registered_regions > MAX_EMULATED_REGIONS) + if (registered_regions >= MAX_EMULATED_REGIONS) return (NULL); struct memory_region *region = &emulated_regions[registered_regions]; @@ -552,4 +547,3 @@ move_memory_region(struct memory_region *region, uintptr_t start) region->start = start; region->end = start + len; } - |