# Makefile for GeekOS kernel, userspace, and tools
# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.55 $
+# $Revision: 1.56 $
# This is free software. You are permitted to use,
# redistribute, and modify it as specified in the file "COPYING".
DEBUG_SECTIONS=
ifeq ($(DEBUG_ALL),1)
- DEBUG_SECTIONS:= $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING -DDEBUG_CTRL_REGS -DDEBUG_INTERRUPTS -DDEBUG_IO -DDEBUG_KEYBOARD -DDEBUG_PIC -DDEBUG_PIT -DDEBUG_NVRAM
+ DEBUG_SECTIONS:= $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING -DDEBUG_CTRL_REGS -DDEBUG_INTERRUPTS -DDEBUG_IO -DDEBUG_KEYBOARD -DDEBUG_PIC -DDEBUG_PIT -DDEBUG_NVRAM -DDEBUG_EMULATOR -DDEBUG_GENERIC
endif
ifeq ($(DEBUG_SHADOW_PAGING),1)
DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING
ifeq ($(DEBUG_NVRAM),1)
DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_NVRAM
endif
+ifeq ($(DEBUG_GENERIC),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_GENERIC
+endif
+ifeq ($(DEBUG_EMULATOR),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_EMULATOR
+endif
ifeq ($(DEBUG),1)
svm_halt.c svm_pause.c vmm_config.c vmm_hashtable.c \
vmm_string.c vmm_emulator.c \
$(DECODER_SRCS)
-#\
# vmx.c vmcs_gen.c vmcs.c
VMM_C_OBJS := $(VMM_C_SRCS:%.c=palacios/%.o)
};
+
+struct v3_dbg_regs {
+ v3_reg_t dr0;
+ v3_reg_t dr1;
+ v3_reg_t dr2;
+ v3_reg_t dr3;
+ v3_reg_t dr6;
+ v3_reg_t dr7;
+};
+
struct v3_segment {
ushort_t selector;
uint_t limit;
struct v3_gprs vm_regs;
struct v3_ctrl_regs ctrl_regs;
+ struct v3_dbg_regs dbg_regs;
struct v3_segments segments;
struct vm_ctrl_ops vm_ops;
#define __VMM_DEBUG_H
+#ifdef __V3VEE__
+#include <palacios/vmm.h>
+
+struct dbg_bp32 {
+ uint_t breakpoint : 32;
+};
+
+struct dbg_bp64 {
+ ullong_t breakpoint;
+};
+
+struct dr6_32 {
+ uint_t bp0 : 1;
+ uint_t bp1 : 1;
+ uint_t bp2 : 1;
+ uint_t bp3 : 1;
+ uint_t rsvd1 : 8; // read as ones
+ uint_t rsvd2 : 1; // read as zero
+ uint_t bd : 1;
+ uint_t bs : 1;
+ uint_t bt : 1;
+ uint_t rsvd3 : 16; // read as one
+};
+
+
+struct dr6_64 {
+ uint_t bp0 : 1;
+ uint_t bp1 : 1;
+ uint_t bp2 : 1;
+ uint_t bp3 : 1;
+ uint_t rsvd1 : 8; // read as ones
+ uint_t rsvd2 : 1; // read as zero
+ uint_t bd : 1;
+ uint_t bs : 1;
+ uint_t bt : 1;
+ uint_t rsvd3 : 16; // read as one
+ uint_t rsvd4 : 32; // MBZ
+};
+
+
+struct dr7_32 {
+ uint_t L0 : 1;
+ uint_t G0 : 1;
+ uint_t L1 : 1;
+ uint_t G1 : 1;
+ uint_t L2 : 1;
+ uint_t G2 : 1;
+ uint_t L3 : 1;
+ uint_t G3 : 1;
+ uint_t LE : 1;
+ uint_t GE : 1;
+ uint_t rsvd1 : 1; // Read as one
+ uint_t rsvd2 : 2; // Read as zero
+ uint_t GD : 1;
+ uint_t rsvd3 : 2; // Read as zero
+ uint_t rw0 : 1;
+ uint_t len0 : 1;
+ uint_t rw1 : 1;
+ uint_t len1 : 1;
+ uint_t rw2 : 1;
+ uint_t len2 : 1;
+ uint_t rw3 : 1;
+ uint_t len3 : 1;
+};
+
+
+struct dr7_64 {
+ uint_t L0 : 1;
+ uint_t G0 : 1;
+ uint_t L1 : 1;
+ uint_t G1 : 1;
+ uint_t L2 : 1;
+ uint_t G2 : 1;
+ uint_t L3 : 1;
+ uint_t G3 : 1;
+ uint_t LE : 1;
+ uint_t GE : 1;
+ uint_t rsvd1 : 1; // Read as one
+ uint_t rsvd2 : 2; // Read as zero
+ uint_t GD : 1;
+ uint_t rsvd3 : 2; // Read as zero
+ uint_t rw0 : 1;
+ uint_t len0 : 1;
+ uint_t rw1 : 1;
+ uint_t len1 : 1;
+ uint_t rw2 : 1;
+ uint_t len2 : 1;
+ uint_t rw3 : 1;
+ uint_t len3 : 1;
+ uint_t rsvd4 : 32; // MBZ
+};
+
+
+
+#endif // !__V3VEE__
#endif
uint_t running : 1;
uint_t instr_length;
+
+ uint_t tf_enabled : 1;
};
-
-
struct vmm_mem_hook {
// Called when data is read from a memory page
int (*read)(addr_t guest_addr, void * dst, uint_t length, void * priv_data);
info->ctrl_regs.cr2 = guest_state->cr2;
info->ctrl_regs.cr3 = guest_state->cr3;
info->ctrl_regs.cr4 = guest_state->cr4;
+ info->dbg_regs.dr6 = guest_state->dr6;
+ info->dbg_regs.dr7 = guest_state->dr7;
info->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR;
info->ctrl_regs.rflags = guest_state->rflags;
info->ctrl_regs.efer = guest_state->efer;
if (handle_svm_pause(info) == -1) {
return -1;
}
+ } else if (exit_code == VMEXIT_EXCP1) {
+#ifdef DEBUG_EMULATOR
+ PrintDebug("DEBUG EXCEPTION\n");
+#endif
+ if (info->run_state == VM_EMULATING) {
+ if (v3_emulation_exit_handler(info) == -1) {
+ return -1;
+ }
+ } else {
+ PrintError("VMMCALL with not emulator...\n");
+ return -1;
+ }
} else if (exit_code == VMEXIT_VMMCALL) {
+#ifdef DEBUG_EMULATOR
PrintDebug("VMMCALL\n");
+#endif
if (info->run_state == VM_EMULATING) {
if (v3_emulation_exit_handler(info) == -1) {
return -1;
guest_state->cr2 = info->ctrl_regs.cr2;
guest_state->cr3 = info->ctrl_regs.cr3;
guest_state->cr4 = info->ctrl_regs.cr4;
+ guest_state->dr6 = info->dbg_regs.dr6;
+ guest_state->dr7 = info->dbg_regs.dr7;
guest_ctrl->guest_ctrl.V_TPR = info->ctrl_regs.cr8 & 0xff;
guest_state->rflags = info->ctrl_regs.rflags;
guest_state->efer = info->ctrl_regs.efer;
#include <devices/generic.h>
-static int passthrough_mem_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
- // memcpy(dst, (void*)guest_addr, length);
- int foo = 20;
+
+static int mem_test_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+ int foo = 20;
memcpy(dst, &foo, length);
PrintDebug("Passthrough mem read returning: %d (length=%d)\n", foo + (guest_addr & 0xfff), length);
return length;
+ }
+
+static int passthrough_mem_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+ memcpy(dst, (void*)guest_addr, length);
+ return length;
}
static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
//
add_shadow_region_passthrough(info, 0x0, 0xa0000, (addr_t)V3_AllocPages(160));
- add_shadow_region_passthrough(info, 0xa0000, 0xc0000, 0xa0000);
- //hook_guest_mem(info, 0xa0000, 0xc0000, passthrough_mem_read, passthrough_mem_write, NULL);
+ //add_shadow_region_passthrough(info, 0xa0000, 0xc0000, 0xa0000);
+ hook_guest_mem(info, 0xa0000, 0xc0000, passthrough_mem_read, passthrough_mem_write, NULL);
// TEMP
{
/* MEMORY HOOK TEST */
add_shadow_region_passthrough(info, 0x100000, 0xa00000, (addr_t)V3_AllocPages(2304));
- hook_guest_mem(info, 0xa00000, 0xa01000, passthrough_mem_read, passthrough_mem_write, NULL);
+ hook_guest_mem(info, 0xa00000, 0xa01000, mem_test_read, passthrough_mem_write, NULL);
add_shadow_region_passthrough(info, 0xa01000, 0x1000000, (addr_t)V3_AllocPages(1791));
#include <palacios/vmm_emulator.h>
#include <palacios/vm_guest_mem.h>
#include <palacios/vmm_decoder.h>
+#include <palacios/vmm_debug.h>
+#include <palacios/vmcb.h>
+#include <palacios/vmm_ctrl_regs.h>
static const char VMMCALL[3] = {0x0f, 0x01, 0xd9};
+#ifndef DEBUG_EMULATOR
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
+
int init_emulator(struct guest_info * info) {
struct emulation_state * emulator = &(info->emulator);
emulator->running = 0;
emulator->instr_length = 0;
+ emulator->tf_enabled = 0;
+
return 0;
}
return (addr_t)page;
}
-
+/*
static int setup_code_page(struct guest_info * info, char * instr, struct basic_instr_info * instr_info ) {
addr_t code_page_offset = PT32_PAGE_OFFSET(info->rip);
addr_t code_page = get_new_page();
memcpy((void *)(code_page + code_page_offset), instr, instr_info->instr_length);
memcpy((void *)(code_page + code_page_offset + instr_info->instr_length), VMMCALL, 3);
+#ifdef DEBUG_EMULATOR
PrintDebug("New Instr Stream:\n");
PrintTraceMemDump((void *)(code_page + code_page_offset), 32);
PrintDebug("rip =%x\n", info->rip);
-
+#endif
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;
+
+}
// get the current instr
ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
}
+#ifdef DEBUG_EMULATOR
PrintDebug("Instr (15 bytes) at %x:\n", 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;
}
+ /*
if (instr_info.has_rep == 1) {
PrintError("We currently don't handle rep* instructions\n");
V3_Free(data_page);
return -1;
}
-
+ */
data_page->page_addr = get_new_page();
data_page->va = PT32_PAGE_ADDR(read_gva);
}
- setup_code_page(info, instr, &instr_info);
+ // setup_code_page(info, instr, &instr_info);
+ set_stepping(info);
info->emulator.running = 1;
info->run_state = VM_EMULATING;
return -1;
}
+ /*
if (instr_info.has_rep == 1) {
PrintError("We currently don't handle rep* instructions\n");
V3_Free(write_op);
V3_Free(data_page);
return -1;
}
-
+ */
data_page->page_addr = get_new_page();
data_page->va = PT32_PAGE_ADDR(write_gva);
if (info->emulator.running == 0) {
- setup_code_page(info, instr, &instr_info);
+ // 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;
info->emulator.running = 0;
//info->rip += info->emulator.instr_length;
+
+ PrintDebug("Returning to rip: 0x%x\n", info->rip);
+
info->emulator.instr_length = 0;
+
+
+ unset_stepping(info);
+
PrintDebug("returning from emulation\n");