From: Jack Lange Date: Fri, 26 Jun 2009 22:02:01 +0000 (-0500) Subject: added single step emulator files X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=c8eeaab8082f8c0b00a1889089a706ec6b1af88e added single step emulator files --- diff --git a/palacios/include/palacios/vmm_ss_emulator.h b/palacios/include/palacios/vmm_ss_emulator.h new file mode 100644 index 0000000..173cddd --- /dev/null +++ b/palacios/include/palacios/vmm_ss_emulator.h @@ -0,0 +1,60 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#ifndef __VMM_EMULATOR_H__ +#define __VMM_EMULATOR_H__ + +#ifdef __V3VEE__ + +#include +#include +#include + + + + + + + + +struct emulation_state { + + uint_t running : 1; + uint_t instr_length; + + uint_t tf_enabled : 1; +}; + + +int v3_init_emulator(struct guest_info * info); + + +int v3_emulation_exit_handler(struct guest_info * info); + +int v3_emulate_memory_write(struct guest_info * info, addr_t fault_gva, + int (*write)(addr_t write_addr, void * src, uint_t length, void * priv_data), + addr_t write_addr, void * private_data); +int v3_emulate_memory_read(struct guest_info * info, addr_t fault_gva, + int (*read)(addr_t read_addr, void * dst, uint_t length, void * priv_data), + addr_t read_addr, void * private_data); + + +#endif // !__V3VEE__ + +#endif diff --git a/palacios/src/palacios/vmm_ss_emulator.c b/palacios/src/palacios/vmm_ss_emulator.c new file mode 100644 index 0000000..329ee0f --- /dev/null +++ b/palacios/src/palacios/vmm_ss_emulator.c @@ -0,0 +1,186 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include +#include +#include +#include +#include +#include + + +#ifndef DEBUG_EMULATOR +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + + +int v3_init_emulator(struct guest_info * info) { + + + emulator->tf_enabled = 0; + + return 0; +} + + + + + + + + + + +static int set_stepping(struct guest_info * info) { + vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data)); + ctrl_area->exceptions.db = 1; + + info->emulator.tf_enabled = ((struct rflags *)&(info->ctrl_regs.rflags))->tf; + + ((struct rflags *)&(info->ctrl_regs.rflags))->tf = 1; + + return 0; +} + + +static int unset_stepping(struct guest_info * info) { + vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data)); + ctrl_area->exceptions.db = 0; + + ((struct rflags *)&(info->ctrl_regs.rflags))->tf = info->emulator.tf_enabled; + + if (info->emulator.tf_enabled) { + // Inject breakpoint exception into guest + } + + return 0; + +} + + +int v3_emulate_memory_read(struct guest_info * info, addr_t read_gva, + int (*read)(addr_t read_addr, void * dst, uint_t length, void * priv_data), + addr_t read_gpa, void * private_data) { + struct basic_instr_info instr_info; + uchar_t instr[15]; + int ret; + addr_t data_addr_offset = PAGE_OFFSET(read_gva); + + PrintDebug("Emulating Read\n"); + + 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 guest memory\n"); + return -1; + } + +#ifdef DEBUG_EMULATOR + PrintDebug("Instr (15 bytes) at %p:\n", (void *)(addr_t)instr); + PrintTraceMemDump(instr, 15); +#endif + + + if (v3_basic_mem_decode(info, (addr_t)instr, &instr_info) == -1) { + PrintError("Could not do a basic memory instruction decode\n"); + V3_Free(data_page); + return -1; + } + + // Read the data directly onto the emulated page + ret = read(read_gpa, (void *)(data_page->page_addr + data_addr_offset), instr_info.op_size, private_data); + if ((ret == -1) || ((uint_t)ret != instr_info.op_size)) { + PrintError("Read error in emulator\n"); + return -1; + } + + + + // setup_code_page(info, instr, &instr_info); + set_stepping(info); + + info->emulator.running = 1; + info->run_state = VM_EMULATING; + info->emulator.instr_length = instr_info.instr_length; + + return 0; +} + + + +int v3_emulate_memory_write(struct guest_info * info, addr_t write_gva, + int (*write)(addr_t write_addr, void * src, uint_t length, void * priv_data), + addr_t write_gpa, void * private_data) { + + struct basic_instr_info instr_info; + uchar_t instr[15]; + int ret; + addr_t data_addr_offset = PAGE_OFFSET(write_gva); + int i; + + PrintDebug("Emulating Write for instruction at 0x%p\n", (void *)(addr_t)(info->rip)); + + 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 (v3_basic_mem_decode(info, (addr_t)instr, &instr_info) == -1) { + PrintError("Could not do a basic memory instruction decode\n"); + V3_Free(write_op); + V3_Free(data_page); + return -1; + } + + if (instr_info.has_rep==1) { + PrintDebug("Emulated instruction has rep\n"); + } + + + if (info->emulator.running == 0) { + // setup_code_page(info, instr, &instr_info); + set_stepping(info); + info->emulator.running = 1; + info->run_state = VM_EMULATING; + info->emulator.instr_length = instr_info.instr_length; + } + + return 0; +} + + +// end emulation +int v3_emulation_exit_handler(struct guest_info * info) { + + unset_stepping(info); + + + PrintDebug("returning from emulation\n"); + + return 0; +}