*/
-
-
-
#include <palacios/svm.h>
#include <palacios/vmm.h>
static vmcb_t * Allocate_VMCB() {
- vmcb_t * vmcb_page = (vmcb_t *)V3_VAddr(V3_AllocPages(1));
+ vmcb_t * vmcb_page = (vmcb_t *)V3_VAddr(V3_AllocPages(1));
- memset(vmcb_page, 0, 4096);
+ memset(vmcb_page, 0, 4096);
- return vmcb_page;
+ return vmcb_page;
}
#include <palacios/vmm_ctrl_regs.h>
static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
- vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
- vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(vmcb);
- uint_t i;
-
-
- guest_state->rsp = vm_info->vm_regs.rsp;
- // guest_state->rip = vm_info->rip;
- guest_state->rip = 0xfff0;
-
- guest_state->cpl = 0;
-
- //ctrl_area->instrs.instrs.CR0 = 1;
- ctrl_area->cr_reads.cr0 = 1;
- ctrl_area->cr_writes.cr0 = 1;
- //ctrl_area->cr_reads.cr4 = 1;
- ctrl_area->cr_writes.cr4 = 1;
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(vmcb);
+ uint_t i;
- /* Set up the efer to enable 64 bit page tables */
- /*
- {
- struct efer_64 * efer = (struct efer_64 *)&(guest_state->efer);
- struct cr4_32 * cr4 = (struct cr4_32 *)&(guest_state->cr4);
- efer->lma = 1;
- efer->lme = 1;
+ guest_state->rsp = vm_info->vm_regs.rsp;
+ // guest_state->rip = vm_info->rip;
+ guest_state->rip = 0xfff0;
- cr4->pae = 1;
- }
- */
-
- guest_state->efer |= EFER_MSR_svm_enable;
- vm_info->guest_efer.value = 0x0LL;
+ guest_state->cpl = 0;
- v3_hook_msr(vm_info, EFER_MSR,
- &v3_handle_efer_read,
- &v3_handle_efer_write,
- vm_info);
+ //ctrl_area->instrs.instrs.CR0 = 1;
+ ctrl_area->cr_reads.cr0 = 1;
+ ctrl_area->cr_writes.cr0 = 1;
+ //ctrl_area->cr_reads.cr4 = 1;
+ ctrl_area->cr_writes.cr4 = 1;
+ /* Set up the efer to enable 64 bit page tables */
+ /*
+ {
+ struct efer_64 * efer = (struct efer_64 *)&(guest_state->efer);
+ struct cr4_32 * cr4 = (struct cr4_32 *)&(guest_state->cr4);
+ efer->lma = 1;
+ efer->lme = 1;
+
+ cr4->pae = 1;
+ }
+ */
- guest_state->rflags = 0x00000002; // The reserved bit is always 1
- ctrl_area->svm_instrs.VMRUN = 1;
- ctrl_area->svm_instrs.VMMCALL = 1;
- ctrl_area->svm_instrs.VMLOAD = 1;
- ctrl_area->svm_instrs.VMSAVE = 1;
- ctrl_area->svm_instrs.STGI = 1;
- ctrl_area->svm_instrs.CLGI = 1;
- ctrl_area->svm_instrs.SKINIT = 1;
- ctrl_area->svm_instrs.RDTSCP = 1;
- ctrl_area->svm_instrs.ICEBP = 1;
- ctrl_area->svm_instrs.WBINVD = 1;
- ctrl_area->svm_instrs.MONITOR = 1;
- ctrl_area->svm_instrs.MWAIT_always = 1;
- ctrl_area->svm_instrs.MWAIT_if_armed = 1;
-
-
- ctrl_area->instrs.HLT = 1;
- // guest_state->cr0 = 0x00000001; // PE
- ctrl_area->guest_ASID = 1;
-
-
- /*
- ctrl_area->exceptions.de = 1;
- ctrl_area->exceptions.df = 1;
+ guest_state->efer |= EFER_MSR_svm_enable;
+ vm_info->guest_efer.value = 0x0LL;
- ctrl_area->exceptions.ts = 1;
- ctrl_area->exceptions.ss = 1;
- ctrl_area->exceptions.ac = 1;
- ctrl_area->exceptions.mc = 1;
- ctrl_area->exceptions.gp = 1;
- ctrl_area->exceptions.ud = 1;
- ctrl_area->exceptions.np = 1;
- ctrl_area->exceptions.of = 1;
-
- ctrl_area->exceptions.nmi = 1;
- */
+ v3_hook_msr(vm_info, EFER_MSR,
+ &v3_handle_efer_read,
+ &v3_handle_efer_write,
+ vm_info);
- // Debug of boot on physical machines - 7/14/08
- ctrl_area->instrs.NMI=1;
- ctrl_area->instrs.SMI=1;
- ctrl_area->instrs.INIT=1;
- ctrl_area->instrs.PAUSE=1;
- ctrl_area->instrs.shutdown_evts=1;
- vm_info->vm_regs.rdx = 0x00000f00;
+ guest_state->rflags = 0x00000002; // The reserved bit is always 1
+ ctrl_area->svm_instrs.VMRUN = 1;
+ ctrl_area->svm_instrs.VMMCALL = 1;
+ ctrl_area->svm_instrs.VMLOAD = 1;
+ ctrl_area->svm_instrs.VMSAVE = 1;
+ ctrl_area->svm_instrs.STGI = 1;
+ ctrl_area->svm_instrs.CLGI = 1;
+ ctrl_area->svm_instrs.SKINIT = 1;
+ ctrl_area->svm_instrs.RDTSCP = 1;
+ ctrl_area->svm_instrs.ICEBP = 1;
+ ctrl_area->svm_instrs.WBINVD = 1;
+ ctrl_area->svm_instrs.MONITOR = 1;
+ ctrl_area->svm_instrs.MWAIT_always = 1;
+ ctrl_area->svm_instrs.MWAIT_if_armed = 1;
- guest_state->cr0 = 0x60000010;
-
- guest_state->cs.selector = 0xf000;
- guest_state->cs.limit=0xffff;
- guest_state->cs.base = 0x0000000f0000LL;
- guest_state->cs.attrib.raw = 0xf3;
+ ctrl_area->instrs.HLT = 1;
+ // guest_state->cr0 = 0x00000001; // PE
+ ctrl_area->guest_ASID = 1;
- /* DEBUG FOR RETURN CODE */
- ctrl_area->exit_code = 1;
-
-
- struct vmcb_selector *segregs [] = {&(guest_state->ss), &(guest_state->ds), &(guest_state->es), &(guest_state->fs), &(guest_state->gs), NULL};
- for ( i = 0; segregs[i] != NULL; i++) {
- struct vmcb_selector * seg = segregs[i];
+ /*
+ ctrl_area->exceptions.de = 1;
+ ctrl_area->exceptions.df = 1;
+
+ ctrl_area->exceptions.ts = 1;
+ ctrl_area->exceptions.ss = 1;
+ ctrl_area->exceptions.ac = 1;
+ ctrl_area->exceptions.mc = 1;
+ ctrl_area->exceptions.gp = 1;
+ ctrl_area->exceptions.ud = 1;
+ ctrl_area->exceptions.np = 1;
+ ctrl_area->exceptions.of = 1;
+
+ ctrl_area->exceptions.nmi = 1;
+ */
- seg->selector = 0x0000;
- // seg->base = seg->selector << 4;
- seg->base = 0x00000000;
- seg->attrib.raw = 0xf3;
- seg->limit = ~0u;
- }
-
- guest_state->gdtr.limit = 0x0000ffff;
- guest_state->gdtr.base = 0x0000000000000000LL;
- guest_state->idtr.limit = 0x0000ffff;
- guest_state->idtr.base = 0x0000000000000000LL;
-
- guest_state->ldtr.selector = 0x0000;
- guest_state->ldtr.limit = 0x0000ffff;
- guest_state->ldtr.base = 0x0000000000000000LL;
- guest_state->tr.selector = 0x0000;
- guest_state->tr.limit = 0x0000ffff;
- guest_state->tr.base = 0x0000000000000000LL;
-
- guest_state->dr6 = 0x00000000ffff0ff0LL;
- guest_state->dr7 = 0x0000000000000400LL;
+ // Debug of boot on physical machines - 7/14/08
+ ctrl_area->instrs.NMI=1;
+ ctrl_area->instrs.SMI=1;
+ ctrl_area->instrs.INIT=1;
+ ctrl_area->instrs.PAUSE=1;
+ ctrl_area->instrs.shutdown_evts=1;
+
+ vm_info->vm_regs.rdx = 0x00000f00;
+
+ guest_state->cr0 = 0x60000010;
+
+
+ guest_state->cs.selector = 0xf000;
+ guest_state->cs.limit=0xffff;
+ guest_state->cs.base = 0x0000000f0000LL;
+ guest_state->cs.attrib.raw = 0xf3;
+ /* DEBUG FOR RETURN CODE */
+ ctrl_area->exit_code = 1;
+
+
+ struct vmcb_selector *segregs [] = {&(guest_state->ss), &(guest_state->ds), &(guest_state->es), &(guest_state->fs), &(guest_state->gs), NULL};
+ for ( i = 0; segregs[i] != NULL; i++) {
+ struct vmcb_selector * seg = segregs[i];
+
+ seg->selector = 0x0000;
+ // seg->base = seg->selector << 4;
+ seg->base = 0x00000000;
+ seg->attrib.raw = 0xf3;
+ seg->limit = ~0u;
+ }
-
-
-
- if ( !RB_EMPTY_ROOT(&(vm_info->io_map)) ) {
- struct v3_io_hook * iter;
- struct rb_node * io_node = v3_rb_first(&(vm_info->io_map));
- addr_t io_port_bitmap;
- int i = 0;
-
- io_port_bitmap = (addr_t)V3_VAddr(V3_AllocPages(3));
- memset((uchar_t*)io_port_bitmap, 0, PAGE_SIZE * 3);
+ guest_state->gdtr.limit = 0x0000ffff;
+ guest_state->gdtr.base = 0x0000000000000000LL;
+ guest_state->idtr.limit = 0x0000ffff;
+ guest_state->idtr.base = 0x0000000000000000LL;
- ctrl_area->IOPM_BASE_PA = (addr_t)V3_PAddr((void *)io_port_bitmap);
+ guest_state->ldtr.selector = 0x0000;
+ guest_state->ldtr.limit = 0x0000ffff;
+ guest_state->ldtr.base = 0x0000000000000000LL;
+ guest_state->tr.selector = 0x0000;
+ guest_state->tr.limit = 0x0000ffff;
+ guest_state->tr.base = 0x0000000000000000LL;
- //PrintDebug("Setting up IO Map at 0x%x\n", io_port_bitmap);
- do {
- iter = rb_entry(io_node, struct v3_io_hook, tree_node);
+ guest_state->dr6 = 0x00000000ffff0ff0LL;
+ guest_state->dr7 = 0x0000000000000400LL;
- ushort_t port = iter->port;
- uchar_t * bitmap = (uchar_t *)io_port_bitmap;
- //PrintDebug("%d: Hooking Port %d\n", i, port);
-
- bitmap += (port / 8);
- // PrintDebug("Setting Bit for port 0x%x\n", port);
- *bitmap |= 1 << (port % 8);
-
- i++;
- } while ((io_node = v3_rb_next(io_node)));
-
-
- //PrintDebugMemDump((uchar_t*)io_port_bitmap, PAGE_SIZE *2);
-
- ctrl_area->instrs.IOIO_PROT = 1;
- }
+
- PrintDebug("Exiting on interrupts\n");
- ctrl_area->guest_ctrl.V_INTR_MASKING = 1;
- ctrl_area->instrs.INTR = 1;
-
-
- if (vm_info->shdw_pg_mode == SHADOW_PAGING) {
- PrintDebug("Creating initial shadow page table\n");
-
-
-
- /* Testing 64 bit page tables for long paged real mode guests */
- // vm_info->direct_map_pt = (addr_t)V3_PAddr(create_passthrough_pts_64(vm_info));
- vm_info->direct_map_pt = (addr_t)V3_PAddr((void *)v3_create_direct_passthrough_pts(vm_info));
- /* End Test */
-
- vm_info->shdw_pg_state.guest_cr0 = 0x0000000000000010LL;
- PrintDebug("Created\n");
-
-
- guest_state->cr3 = vm_info->direct_map_pt;
-
-
- //PrintDebugPageTables((pde32_t*)(vm_info->shdw_pg_state.shadow_cr3.e_reg.low));
-
- ctrl_area->cr_reads.cr3 = 1;
- ctrl_area->cr_writes.cr3 = 1;
-
-
- ctrl_area->instrs.INVLPG = 1;
- ctrl_area->instrs.INVLPGA = 1;
- ctrl_area->exceptions.pf = 1;
- /* JRL: This is a performance killer, and a simplistic solution */
- /* We need to fix this */
- ctrl_area->TLB_CONTROL = 1;
+ if ( !RB_EMPTY_ROOT(&(vm_info->io_map)) ) {
+ struct v3_io_hook * iter;
+ struct rb_node * io_node = v3_rb_first(&(vm_info->io_map));
+ addr_t io_port_bitmap;
+ int i = 0;
+
+ io_port_bitmap = (addr_t)V3_VAddr(V3_AllocPages(3));
+ memset((uchar_t*)io_port_bitmap, 0, PAGE_SIZE * 3);
+
+ ctrl_area->IOPM_BASE_PA = (addr_t)V3_PAddr((void *)io_port_bitmap);
+
+ //PrintDebug("Setting up IO Map at 0x%x\n", io_port_bitmap);
+
+ do {
+ iter = rb_entry(io_node, struct v3_io_hook, tree_node);
+
+ ushort_t port = iter->port;
+ uchar_t * bitmap = (uchar_t *)io_port_bitmap;
+ //PrintDebug("%d: Hooking Port %d\n", i, port);
+
+ bitmap += (port / 8);
+ // PrintDebug("Setting Bit for port 0x%x\n", port);
+ *bitmap |= 1 << (port % 8);
+
+ i++;
+ } while ((io_node = v3_rb_next(io_node)));
+
+
+ //PrintDebugMemDump((uchar_t*)io_port_bitmap, PAGE_SIZE *2);
+
+ ctrl_area->instrs.IOIO_PROT = 1;
+ }
+
+
+ PrintDebug("Exiting on interrupts\n");
+ ctrl_area->guest_ctrl.V_INTR_MASKING = 1;
+ ctrl_area->instrs.INTR = 1;
+
+
+ if (vm_info->shdw_pg_mode == SHADOW_PAGING) {
+ PrintDebug("Creating initial shadow page table\n");
+
+
+
+ /* Testing 64 bit page tables for long paged real mode guests */
+ // vm_info->direct_map_pt = (addr_t)V3_PAddr(create_passthrough_pts_64(vm_info));
+ vm_info->direct_map_pt = (addr_t)V3_PAddr((void *)v3_create_direct_passthrough_pts(vm_info));
+ /* End Test */
+
+ vm_info->shdw_pg_state.guest_cr0 = 0x0000000000000010LL;
+ PrintDebug("Created\n");
+
+
+ guest_state->cr3 = vm_info->direct_map_pt;
+
+
+ //PrintDebugPageTables((pde32_t*)(vm_info->shdw_pg_state.shadow_cr3.e_reg.low));
+
+ ctrl_area->cr_reads.cr3 = 1;
+ ctrl_area->cr_writes.cr3 = 1;
+
+
+ ctrl_area->instrs.INVLPG = 1;
+ ctrl_area->instrs.INVLPGA = 1;
+
+ ctrl_area->exceptions.pf = 1;
+
+ /* JRL: This is a performance killer, and a simplistic solution */
+ /* We need to fix this */
+ ctrl_area->TLB_CONTROL = 1;
+
+
+ guest_state->g_pat = 0x7040600070406ULL;
+
+ guest_state->cr0 |= 0x80000000;
+
+ } else if (vm_info->shdw_pg_mode == NESTED_PAGING) {
+ // Flush the TLB on entries/exits
+ ctrl_area->TLB_CONTROL = 1;
+
+ // Enable Nested Paging
+ ctrl_area->NP_ENABLE = 1;
+
+ PrintDebug("NP_Enable at 0x%p\n", (void *)&(ctrl_area->NP_ENABLE));
+
+ // Set the Nested Page Table pointer
+ vm_info->direct_map_pt = ((addr_t)create_passthrough_pts_32(vm_info) & ~0xfff);
+ ctrl_area->N_CR3 = vm_info->direct_map_pt;
+
+ // ctrl_area->N_CR3 = Get_CR3();
+ // guest_state->cr3 |= (Get_CR3() & 0xfffff000);
+
+ guest_state->g_pat = 0x7040600070406ULL;
+ }
- guest_state->g_pat = 0x7040600070406ULL;
-
- guest_state->cr0 |= 0x80000000;
-
- } else if (vm_info->shdw_pg_mode == NESTED_PAGING) {
- // Flush the TLB on entries/exits
- ctrl_area->TLB_CONTROL = 1;
-
- // Enable Nested Paging
- ctrl_area->NP_ENABLE = 1;
-
- PrintDebug("NP_Enable at 0x%p\n", (void *)&(ctrl_area->NP_ENABLE));
-
- // Set the Nested Page Table pointer
- vm_info->direct_map_pt = ((addr_t)create_passthrough_pts_32(vm_info) & ~0xfff);
- ctrl_area->N_CR3 = vm_info->direct_map_pt;
-
- // ctrl_area->N_CR3 = Get_CR3();
- // guest_state->cr3 |= (Get_CR3() & 0xfffff000);
-
- guest_state->g_pat = 0x7040600070406ULL;
- }
-
-
- if (vm_info->msr_map.num_hooks > 0) {
- PrintDebug("Hooking %d msrs\n", vm_info->msr_map.num_hooks);
- ctrl_area->MSRPM_BASE_PA = v3_init_svm_msr_map(vm_info);
- ctrl_area->instrs.MSR_PROT = 1;
-
- }
-
-
- /* Safety locations for fs/gs */
- vm_info->fs = 0;
- vm_info->gs = 0;
-
-
+ if (vm_info->msr_map.num_hooks > 0) {
+ PrintDebug("Hooking %d msrs\n", vm_info->msr_map.num_hooks);
+ ctrl_area->MSRPM_BASE_PA = v3_init_svm_msr_map(vm_info);
+ ctrl_area->instrs.MSR_PROT = 1;
+
+ }
+
+ /* Safety locations for fs/gs */
+ vm_info->fs = 0;
+ vm_info->gs = 0;
}
static int init_svm_guest(struct guest_info *info) {
-
- PrintDebug("Allocating VMCB\n");
- info->vmm_data = (void*)Allocate_VMCB();
+ PrintDebug("Allocating VMCB\n");
+ info->vmm_data = (void*)Allocate_VMCB();
- //PrintDebug("Generating Guest nested page tables\n");
- // info->page_tables = NULL;
- //info->page_tables = generate_guest_page_tables_64(&(info->mem_layout), &(info->mem_list));
- //info->page_tables = generate_guest_page_tables(&(info->mem_layout), &(info->mem_list));
- // PrintDebugPageTables(info->page_tables);
+ //PrintDebug("Generating Guest nested page tables\n");
+ // info->page_tables = NULL;
+ //info->page_tables = generate_guest_page_tables_64(&(info->mem_layout), &(info->mem_list));
+ //info->page_tables = generate_guest_page_tables(&(info->mem_layout), &(info->mem_list));
+ // PrintDebugPageTables(info->page_tables);
- PrintDebug("Initializing VMCB (addr=%p)\n", (void *)info->vmm_data);
- Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info);
+ PrintDebug("Initializing VMCB (addr=%p)\n", (void *)info->vmm_data);
+ Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info);
- info->run_state = VM_STOPPED;
-
- // info->rip = 0;
+ info->run_state = VM_STOPPED;
- info->vm_regs.rdi = 0;
- info->vm_regs.rsi = 0;
- info->vm_regs.rbp = 0;
- info->vm_regs.rsp = 0;
- info->vm_regs.rbx = 0;
- info->vm_regs.rdx = 0;
- info->vm_regs.rcx = 0;
- info->vm_regs.rax = 0;
-
- return 0;
+ // info->rip = 0;
+
+ info->vm_regs.rdi = 0;
+ info->vm_regs.rsi = 0;
+ info->vm_regs.rbp = 0;
+ info->vm_regs.rsp = 0;
+ info->vm_regs.rbx = 0;
+ info->vm_regs.rdx = 0;
+ info->vm_regs.rcx = 0;
+ info->vm_regs.rax = 0;
+
+ return 0;
}
// can we start a kernel thread here...
static int start_svm_guest(struct guest_info *info) {
- vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
- // vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
- uint_t num_exits = 0;
-
-
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ // vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
+ uint_t num_exits = 0;
- PrintDebug("Launching SVM VM (vmcb=%p)\n", (void *)info->vmm_data);
- //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
- info->run_state = VM_RUNNING;
-
- while (1) {
- ullong_t tmp_tsc;
+ PrintDebug("Launching SVM VM (vmcb=%p)\n", (void *)info->vmm_data);
+ //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
+
+ info->run_state = VM_RUNNING;
+
+ while (1) {
+ ullong_t tmp_tsc;
+
#define MSR_STAR 0xc0000081
#define MSR_KERNGS_BASE 0xc0000102
- struct v3_msr host_cstar;
- struct v3_msr host_star;
- struct v3_msr host_lstar;
- struct v3_msr host_syscall_mask;
- struct v3_msr host_gs_base;
- struct v3_msr host_kerngs_base;
+ struct v3_msr host_cstar;
+ struct v3_msr host_star;
+ struct v3_msr host_lstar;
+ struct v3_msr host_syscall_mask;
+ struct v3_msr host_gs_base;
+ struct v3_msr host_kerngs_base;
- v3_enable_ints();
- v3_clgi();
+ v3_enable_ints();
+ v3_clgi();
- /*
- PrintDebug("SVM Entry to CS=%p rip=%p...\n",
- (void *)(addr_t)info->segments.cs.base,
- (void *)(addr_t)info->rip);
- */
-
-
- v3_get_msr(MSR_STAR, &(host_star.hi), &(host_star.lo));
- v3_get_msr(MSR_LSTAR, &(host_lstar.hi), &(host_lstar.lo));
- v3_get_msr(MSR_CSTAR, &(host_cstar.hi), &(host_cstar.lo));
- v3_get_msr(MSR_SF_MASK, &(host_syscall_mask.hi), &(host_syscall_mask.lo));
- v3_get_msr(MSR_GS_BASE, &(host_gs_base.hi), &(host_gs_base.lo));
- v3_get_msr(MSR_KERNGS_BASE, &(host_kerngs_base.hi), &(host_kerngs_base.lo));
-
-
- rdtscll(info->time_state.cached_host_tsc);
- // guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
+ /*
+ PrintDebug("SVM Entry to CS=%p rip=%p...\n",
+ (void *)(addr_t)info->segments.cs.base,
+ (void *)(addr_t)info->rip);
+ */
- //v3_svm_launch((vmcb_t*)V3_PAddr(info->vmm_data), &(info->vm_regs), &(info->fs), &(info->gs));
- v3_svm_launch((vmcb_t*)V3_PAddr(info->vmm_data), &(info->vm_regs));
- rdtscll(tmp_tsc);
+ v3_get_msr(MSR_STAR, &(host_star.hi), &(host_star.lo));
+ v3_get_msr(MSR_LSTAR, &(host_lstar.hi), &(host_lstar.lo));
+ v3_get_msr(MSR_CSTAR, &(host_cstar.hi), &(host_cstar.lo));
+ v3_get_msr(MSR_SF_MASK, &(host_syscall_mask.hi), &(host_syscall_mask.lo));
+ v3_get_msr(MSR_GS_BASE, &(host_gs_base.hi), &(host_gs_base.lo));
+ v3_get_msr(MSR_KERNGS_BASE, &(host_kerngs_base.hi), &(host_kerngs_base.lo));
- v3_set_msr(MSR_STAR, host_star.hi, host_star.lo);
- v3_set_msr(MSR_LSTAR, host_lstar.hi, host_lstar.lo);
- v3_set_msr(MSR_CSTAR, host_cstar.hi, host_cstar.lo);
- v3_set_msr(MSR_SF_MASK, host_syscall_mask.hi, host_syscall_mask.lo);
- v3_set_msr(MSR_GS_BASE, host_gs_base.hi, host_gs_base.lo);
- v3_set_msr(MSR_KERNGS_BASE, host_kerngs_base.hi, host_kerngs_base.lo);
- //PrintDebug("SVM Returned\n");
+ rdtscll(info->time_state.cached_host_tsc);
+ // guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
+
+ //v3_svm_launch((vmcb_t*)V3_PAddr(info->vmm_data), &(info->vm_regs), &(info->fs), &(info->gs));
+ v3_svm_launch((vmcb_t*)V3_PAddr(info->vmm_data), &(info->vm_regs));
+
+ rdtscll(tmp_tsc);
+
+ v3_set_msr(MSR_STAR, host_star.hi, host_star.lo);
+ v3_set_msr(MSR_LSTAR, host_lstar.hi, host_lstar.lo);
+ v3_set_msr(MSR_CSTAR, host_cstar.hi, host_cstar.lo);
+ v3_set_msr(MSR_SF_MASK, host_syscall_mask.hi, host_syscall_mask.lo);
+ v3_set_msr(MSR_GS_BASE, host_gs_base.hi, host_gs_base.lo);
+ v3_set_msr(MSR_KERNGS_BASE, host_kerngs_base.hi, host_kerngs_base.lo);
+
+ //PrintDebug("SVM Returned\n");
- v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc);
- num_exits++;
+ v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc);
+ num_exits++;
- //PrintDebug("Turning on global interrupts\n");
- v3_stgi();
+ //PrintDebug("Turning on global interrupts\n");
+ v3_stgi();
+
+
+ if ((num_exits % 5000) == 0) {
+ PrintDebug("SVM Exit number %d\n", num_exits);
-
- if ((num_exits % 5000) == 0) {
- PrintDebug("SVM Exit number %d\n", num_exits);
- if (info->enable_profiler)
- v3_print_profile(info);
- }
+ if (info->enable_profiler) {
+ v3_print_profile(info);
+ }
+ }
- if (v3_handle_svm_exit(info) != 0) {
- vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
- addr_t host_addr;
- addr_t linear_addr = 0;
-
- info->run_state = VM_ERROR;
-
- PrintDebug("SVM ERROR!!\n");
+ if (v3_handle_svm_exit(info) != 0) {
+ vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
+ addr_t host_addr;
+ addr_t linear_addr = 0;
+
+ info->run_state = VM_ERROR;
+
+ PrintDebug("SVM ERROR!!\n");
- PrintDebug("RIP: %p\n", (void *)(addr_t)(guest_state->rip));
+ PrintDebug("RIP: %p\n", (void *)(addr_t)(guest_state->rip));
- linear_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
+ linear_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
- PrintDebug("RIP Linear: %p\n", (void *)linear_addr);
- v3_print_segments(info);
- v3_print_ctrl_regs(info);
- if (info->shdw_pg_mode == SHADOW_PAGING) {
- PrintDebug("Shadow Paging Guest Registers:\n");
- PrintDebug("\tGuest CR0=%p\n", (void *)(addr_t)(info->shdw_pg_state.guest_cr0));
- PrintDebug("\tGuest CR3=%p\n", (void *)(addr_t)(info->shdw_pg_state.guest_cr3));
- // efer
- // CR4
- }
- v3_print_GPRs(info);
+ PrintDebug("RIP Linear: %p\n", (void *)linear_addr);
+ v3_print_segments(info);
+ v3_print_ctrl_regs(info);
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
+ PrintDebug("Shadow Paging Guest Registers:\n");
+ PrintDebug("\tGuest CR0=%p\n", (void *)(addr_t)(info->shdw_pg_state.guest_cr0));
+ PrintDebug("\tGuest CR3=%p\n", (void *)(addr_t)(info->shdw_pg_state.guest_cr3));
+ // efer
+ // CR4
+ }
+ v3_print_GPRs(info);
- PrintDebug("SVM Exit Code: %p\n", (void *)(addr_t)guest_ctrl->exit_code);
+ PrintDebug("SVM Exit Code: %p\n", (void *)(addr_t)guest_ctrl->exit_code);
- PrintDebug("exit_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
- PrintDebug("exit_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
+ PrintDebug("exit_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
+ PrintDebug("exit_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
- PrintDebug("exit_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
- PrintDebug("exit_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
+ PrintDebug("exit_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
+ PrintDebug("exit_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
- if (info->mem_mode == PHYSICAL_MEM) {
- guest_pa_to_host_va(info, linear_addr, &host_addr);
- } else if (info->mem_mode == VIRTUAL_MEM) {
- guest_va_to_host_va(info, linear_addr, &host_addr);
- }
+ if (info->mem_mode == PHYSICAL_MEM) {
+ guest_pa_to_host_va(info, linear_addr, &host_addr);
+ } else if (info->mem_mode == VIRTUAL_MEM) {
+ guest_va_to_host_va(info, linear_addr, &host_addr);
+ }
- PrintDebug("Host Address of rip = 0x%p\n", (void *)host_addr);
+ PrintDebug("Host Address of rip = 0x%p\n", (void *)host_addr);
- PrintDebug("Instr (15 bytes) at %p:\n", (void *)host_addr);
- PrintTraceMemDump((uchar_t *)host_addr, 15);
+ PrintDebug("Instr (15 bytes) at %p:\n", (void *)host_addr);
+ PrintTraceMemDump((uchar_t *)host_addr, 15);
- break;
+ break;
+ }
}
-
- }
- return 0;
+ return 0;
}
/* Checks machine SVM capability */
/* Implemented from: AMD Arch Manual 3, sect 15.4 */
int v3_is_svm_capable() {
+ // Dinda
+ uint_t vm_cr_low = 0, vm_cr_high = 0;
+ addr_t eax = 0, ebx = 0, ecx = 0, edx = 0;
-#if 1
- // Dinda
- uint_t vm_cr_low = 0, vm_cr_high = 0;
- addr_t eax = 0, ebx = 0, ecx = 0, edx = 0;
-
- v3_cpuid(CPUID_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
+ v3_cpuid(CPUID_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
- PrintDebug("CPUID_FEATURE_IDS_ecx=%p\n", (void *)ecx);
+ PrintDebug("CPUID_FEATURE_IDS_ecx=%p\n", (void *)ecx);
- if ((ecx & CPUID_FEATURE_IDS_ecx_svm_avail) == 0) {
- PrintDebug("SVM Not Available\n");
- return 0;
- } else {
- v3_get_msr(SVM_VM_CR_MSR, &vm_cr_high, &vm_cr_low);
-
- PrintDebug("SVM_VM_CR_MSR = 0x%x 0x%x\n", vm_cr_high, vm_cr_low);
-
- if ((vm_cr_low & SVM_VM_CR_MSR_svmdis) == 1) {
- PrintDebug("SVM is available but is disabled.\n");
-
- v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
-
- PrintDebug("CPUID_FEATURE_IDS_edx=%p\n", (void *)edx);
-
- if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_svml) == 0) {
- PrintDebug("SVM BIOS Disabled, not unlockable\n");
- } else {
- PrintDebug("SVM is locked with a key\n");
- }
+ if ((ecx & CPUID_FEATURE_IDS_ecx_svm_avail) == 0) {
+ PrintDebug("SVM Not Available\n");
return 0;
-
- } else {
- PrintDebug("SVM is available and enabled.\n");
-
- v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
- PrintDebug("CPUID_FEATURE_IDS_eax=%p\n", (void *)eax);
- PrintDebug("CPUID_FEATURE_IDS_ebx=%p\n", (void *)ebx);
- PrintDebug("CPUID_FEATURE_IDS_ecx=%p\n", (void *)ecx);
- PrintDebug("CPUID_FEATURE_IDS_edx=%p\n", (void *)edx);
-
-
- if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 0) {
- PrintDebug("SVM Nested Paging not supported\n");
- } else {
- PrintDebug("SVM Nested Paging supported\n");
- }
-
- return 1;
-
+ } else {
+ v3_get_msr(SVM_VM_CR_MSR, &vm_cr_high, &vm_cr_low);
+
+ PrintDebug("SVM_VM_CR_MSR = 0x%x 0x%x\n", vm_cr_high, vm_cr_low);
+
+ if ((vm_cr_low & SVM_VM_CR_MSR_svmdis) == 1) {
+ PrintDebug("SVM is available but is disabled.\n");
+
+ v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
+
+ PrintDebug("CPUID_FEATURE_IDS_edx=%p\n", (void *)edx);
+
+ if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_svml) == 0) {
+ PrintDebug("SVM BIOS Disabled, not unlockable\n");
+ } else {
+ PrintDebug("SVM is locked with a key\n");
+ }
+ return 0;
+
+ } else {
+ PrintDebug("SVM is available and enabled.\n");
+
+ v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
+ PrintDebug("CPUID_FEATURE_IDS_eax=%p\n", (void *)eax);
+ PrintDebug("CPUID_FEATURE_IDS_ebx=%p\n", (void *)ebx);
+ PrintDebug("CPUID_FEATURE_IDS_ecx=%p\n", (void *)ecx);
+ PrintDebug("CPUID_FEATURE_IDS_edx=%p\n", (void *)edx);
+
+
+ if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 0) {
+ PrintDebug("SVM Nested Paging not supported\n");
+ } else {
+ PrintDebug("SVM Nested Paging supported\n");
+ }
+
+ return 1;
+ }
}
- }
-
-#else
- uint_t eax = 0, ebx = 0, ecx = 0, edx = 0;
- addr_t vm_cr_low = 0, vm_cr_high = 0;
-
- v3_cpuid(CPUID_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
-
- if ((ecx & CPUID_FEATURE_IDS_ecx_svm_avail) == 0) {
- PrintDebug("SVM Not Available\n");
- return 0;
- }
-
- v3_get_msr(SVM_VM_CR_MSR, &vm_cr_high, &vm_cr_low);
-
- PrintDebug("SVM_VM_CR_MSR = 0x%x 0x%x\n", vm_cr_high, vm_cr_low);
-
-
- // this part is clearly wrong, since the np bit is in
- // edx, not ecx
- if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 1) {
- PrintDebug("Nested Paging not supported\n");
- } else {
- PrintDebug("Nested Paging supported\n");
- }
-
- if ((vm_cr_low & SVM_VM_CR_MSR_svmdis) == 0) {
- PrintDebug("SVM is disabled.\n");
- return 1;
- }
-
- v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
-
- if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_svml) == 0) {
- PrintDebug("SVM BIOS Disabled, not unlockable\n");
- } else {
- PrintDebug("SVM is locked with a key\n");
- }
-
- return 0;
-
-#endif
-
}
static int has_svm_nested_paging() {
- addr_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+ addr_t eax = 0, ebx = 0, ecx = 0, edx = 0;
- v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
+ v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
- //PrintDebug("CPUID_FEATURE_IDS_edx=0x%x\n", edx);
+ //PrintDebug("CPUID_FEATURE_IDS_edx=0x%x\n", edx);
- if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 0) {
- PrintDebug("SVM Nested Paging not supported\n");
- return 0;
- } else {
- PrintDebug("SVM Nested Paging supported\n");
- return 1;
- }
-
+ if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 0) {
+ PrintDebug("SVM Nested Paging not supported\n");
+ return 0;
+ } else {
+ PrintDebug("SVM Nested Paging supported\n");
+ return 1;
+ }
}
void v3_init_SVM(struct v3_ctrl_ops * vmm_ops) {
- reg_ex_t msr;
- void * host_state;
+ reg_ex_t msr;
+ void * host_state;
+ // Enable SVM on the CPU
+ v3_get_msr(EFER_MSR, &(msr.e_reg.high), &(msr.e_reg.low));
+ msr.e_reg.low |= EFER_MSR_svm_enable;
+ v3_set_msr(EFER_MSR, 0, msr.e_reg.low);
- // Enable SVM on the CPU
- v3_get_msr(EFER_MSR, &(msr.e_reg.high), &(msr.e_reg.low));
- msr.e_reg.low |= EFER_MSR_svm_enable;
- v3_set_msr(EFER_MSR, 0, msr.e_reg.low);
-
- PrintDebug("SVM Enabled\n");
+ PrintDebug("SVM Enabled\n");
- // Setup the host state save area
- host_state = V3_AllocPages(4);
-
+ // Setup the host state save area
+ host_state = V3_AllocPages(4);
+
- /* 64-BIT-ISSUE */
- // msr.e_reg.high = 0;
- //msr.e_reg.low = (uint_t)host_state;
- msr.r_reg = (addr_t)host_state;
+ /* 64-BIT-ISSUE */
+ // msr.e_reg.high = 0;
+ //msr.e_reg.low = (uint_t)host_state;
+ msr.r_reg = (addr_t)host_state;
- PrintDebug("Host State being saved at %p\n", (void *)(addr_t)host_state);
- v3_set_msr(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low);
+ PrintDebug("Host State being saved at %p\n", (void *)(addr_t)host_state);
+ v3_set_msr(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low);
- // Setup the SVM specific vmm operations
- vmm_ops->init_guest = &init_svm_guest;
- vmm_ops->start_guest = &start_svm_guest;
- vmm_ops->has_nested_paging = &has_svm_nested_paging;
+ // Setup the SVM specific vmm operations
+ vmm_ops->init_guest = &init_svm_guest;
+ vmm_ops->start_guest = &start_svm_guest;
+ vmm_ops->has_nested_paging = &has_svm_nested_paging;
- return;
+ return;
}
int v3_handle_svm_halt(struct guest_info * info)
{
- if (info->cpl!=0) {
- v3_raise_exception(info, GPF_EXCEPTION);
- } else {
+ if (info->cpl!=0) {
+ v3_raise_exception(info, GPF_EXCEPTION);
+ } else {
- // What we should do is starting waiting on an OS event that will
- // result in an injection of an interrupt.
+ // What we should do is starting waiting on an OS event that will
+ // result in an injection of an interrupt.
+
+ // What we will hackishly do instead is resume on any event
+ // Plus is this totally GeekOS specific
+
+ ullong_t yield_start = 0;
+ ullong_t yield_stop = 0;
+ uint32_t gap = 0;
+
+ PrintDebug("GeekOS Yield\n");
+
+ rdtscll(yield_start);
+ V3_Yield();
+ rdtscll(yield_stop);
- // What we will hackishly do instead is resume on any event
- // Plus is this totally GeekOS specific
- ullong_t yield_start = 0;
- ullong_t yield_stop = 0;
- uint32_t gap = 0;
-
- PrintDebug("GeekOS Yield\n");
-
- rdtscll(yield_start);
- V3_Yield();
- rdtscll(yield_stop);
-
-
- //v3_update_time(info, yield_stop - yield_start);
- gap = yield_stop - yield_start;
- v3_raise_irq(info, 0);
-
- PrintDebug("GeekOS Yield Done (%d cycles)\n", gap);
-
- info->rip+=1;
- }
-
- return 0;
-
+ //v3_update_time(info, yield_stop - yield_start);
+ gap = yield_stop - yield_start;
+ v3_raise_irq(info, 0);
+
+ PrintDebug("GeekOS Yield Done (%d cycles)\n", gap);
+
+ info->rip+=1;
+ }
+ return 0;
}
int v3_handle_svm_exit(struct guest_info * info) {
- vmcb_ctrl_t * guest_ctrl = 0;
- vmcb_saved_state_t * guest_state = 0;
- ulong_t exit_code = 0;
-
- guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
- guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ vmcb_ctrl_t * guest_ctrl = 0;
+ vmcb_saved_state_t * guest_state = 0;
+ ulong_t exit_code = 0;
+
+ guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
+ guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
- // Update the high level state
- info->rip = guest_state->rip;
- info->vm_regs.rsp = guest_state->rsp;
- info->vm_regs.rax = guest_state->rax;
+ // Update the high level state
+ info->rip = guest_state->rip;
+ info->vm_regs.rsp = guest_state->rsp;
+ info->vm_regs.rax = guest_state->rax;
- info->cpl = guest_state->cpl;
+ info->cpl = guest_state->cpl;
- info->ctrl_regs.cr0 = guest_state->cr0;
- 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;
-
- get_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
- info->cpu_mode = v3_get_cpu_mode(info);
- info->mem_mode = v3_get_mem_mode(info);
+ info->ctrl_regs.cr0 = guest_state->cr0;
+ 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;
+
+ get_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
+ info->cpu_mode = v3_get_cpu_mode(info);
+ info->mem_mode = v3_get_mem_mode(info);
- exit_code = guest_ctrl->exit_code;
+ exit_code = guest_ctrl->exit_code;
- // Disable printing io exits due to bochs debug messages
- //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
-
-
- // PrintDebug("SVM Returned: Exit Code: 0x%x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc);
-
- if ((0) && (exit_code <= VMEXIT_EXCP14)) {
- uchar_t instr[32];
- int ret;
- // Dump out the instr stream
-
- //PrintDebug("RIP: %x\n", guest_state->rip);
- PrintDebug("\n\n\nRIP Linear: %p\n", (void *)get_addr_linear(info, info->rip, &(info->segments.cs)));
-
- v3_print_GPRs(info);
- v3_print_ctrl_regs(info);
-
-
- // OK, now we will read the instruction
- // The only difference between PROTECTED and PROTECTED_PG is whether we read
- // from guest_pa or guest_va
- if (info->mem_mode == PHYSICAL_MEM) {
- // The real rip address is actually a combination of the rip + CS base
- ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
- } else {
- ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
- }
+ // Disable printing io exits due to bochs debug messages
+ //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
+
+ // PrintDebug("SVM Returned: Exit Code: 0x%x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc);
+
+ if ((0) && (exit_code <= VMEXIT_EXCP14)) {
+ uchar_t instr[32];
+ int ret;
+ // Dump out the instr stream
+ //PrintDebug("RIP: %x\n", guest_state->rip);
+ PrintDebug("\n\n\nRIP Linear: %p\n", (void *)get_addr_linear(info, info->rip, &(info->segments.cs)));
+
+ v3_print_GPRs(info);
+ v3_print_ctrl_regs(info);
+
+
+ // OK, now we will read the instruction
+ // The only difference between PROTECTED and PROTECTED_PG is whether we read
+ // from guest_pa or guest_va
+ if (info->mem_mode == PHYSICAL_MEM) {
+ // The real rip address is actually a combination of the rip + CS base
+ ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
+ } else {
+ ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
+ }
+
- if (ret != 32) {
- // I think we should inject a GPF into the guest
- PrintDebug("Could not read instruction (ret=%d)\n", ret);
- } else {
- PrintDebug("Instr Stream:\n");
- PrintTraceMemDump(instr, 32);
+ if (ret != 32) {
+ // I think we should inject a GPF into the guest
+ PrintDebug("Could not read instruction (ret=%d)\n", ret);
+ } else {
+ PrintDebug("Instr Stream:\n");
+ PrintTraceMemDump(instr, 32);
+ }
}
- }
-
-
-
- if (info->enable_profiler) {
- rdtscll(info->profiler.start_time);
- }
-
- //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code);
- switch (exit_code) {
- case VMEXIT_IOIO:
- {
- struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
-
- if (io_info->type == 0) {
- if (io_info->str) {
- if (v3_handle_svm_io_outs(info) == -1 ) {
- return -1;
- }
- } else {
- if (v3_handle_svm_io_out(info) == -1) {
- return -1;
- }
- }
- } else {
- if (io_info->str) {
- if (v3_handle_svm_io_ins(info) == -1) {
- return -1;
- }
- } else {
- if (v3_handle_svm_io_in(info) == -1) {
- return -1;
- }
- }
- }
- break;
+ if (info->enable_profiler) {
+ rdtscll(info->profiler.start_time);
}
- case VMEXIT_MSR:
- {
- if (guest_ctrl->exit_info1 == 0) {
- if (v3_handle_msr_read(info) == -1) {
- return -1;
- }
- } else if (guest_ctrl->exit_info1 == 1) {
- if (v3_handle_msr_write(info) == -1) {
- return -1;
+
+ //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code);
+
+ switch (exit_code) {
+ case VMEXIT_IOIO: {
+ struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
+
+ if (io_info->type == 0) {
+ if (io_info->str) {
+
+ if (v3_handle_svm_io_outs(info) == -1 ) {
+ return -1;
+ }
+ } else {
+ if (v3_handle_svm_io_out(info) == -1) {
+ return -1;
+ }
+ }
+
+ } else {
+
+ if (io_info->str) {
+ if (v3_handle_svm_io_ins(info) == -1) {
+ return -1;
+ }
+ } else {
+ if (v3_handle_svm_io_in(info) == -1) {
+ return -1;
+ }
+ }
+
+ }
+ break;
}
- } else {
- PrintError("Invalid MSR Operation\n");
- return -1;
- }
-
- break;
- }
- case VMEXIT_CR0_WRITE:
- {
+ case VMEXIT_MSR:
+ if (guest_ctrl->exit_info1 == 0) {
+ if (v3_handle_msr_read(info) == -1) {
+ return -1;
+ }
+ } else if (guest_ctrl->exit_info1 == 1) {
+ if (v3_handle_msr_write(info) == -1) {
+ return -1;
+ }
+ } else {
+ PrintError("Invalid MSR Operation\n");
+ return -1;
+ }
+
+ break;
+ case VMEXIT_CR0_WRITE:
#ifdef DEBUG_CTRL_REGS
- PrintDebug("CR0 Write\n");
+ PrintDebug("CR0 Write\n");
#endif
- if (v3_handle_cr0_write(info) == -1) {
- return -1;
- }
- break;
- }
- case VMEXIT_CR0_READ:
- {
+ if (v3_handle_cr0_write(info) == -1) {
+ return -1;
+ }
+ break;
+ case VMEXIT_CR0_READ:
#ifdef DEBUG_CTRL_REGS
- PrintDebug("CR0 Read\n");
+ PrintDebug("CR0 Read\n");
#endif
- if (v3_handle_cr0_read(info) == -1) {
- return -1;
- }
- break;
- }
- case VMEXIT_CR3_WRITE:
- {
+ if (v3_handle_cr0_read(info) == -1) {
+ return -1;
+ }
+ break;
+ case VMEXIT_CR3_WRITE:
#ifdef DEBUG_CTRL_REGS
- PrintDebug("CR3 Write\n");
+ PrintDebug("CR3 Write\n");
#endif
- if (v3_handle_cr3_write(info) == -1) {
- return -1;
- }
- break;
- }
- case VMEXIT_CR3_READ:
- {
+ if (v3_handle_cr3_write(info) == -1) {
+ return -1;
+ }
+ break;
+ case VMEXIT_CR3_READ:
#ifdef DEBUG_CTRL_REGS
- PrintDebug("CR3 Read\n");
+ PrintDebug("CR3 Read\n");
#endif
- if (v3_handle_cr3_read(info) == -1) {
- return -1;
- }
- break;
- }
- case VMEXIT_CR4_WRITE:
- {
+ if (v3_handle_cr3_read(info) == -1) {
+ return -1;
+ }
+ break;
+ case VMEXIT_CR4_WRITE:
#ifdef DEBUG_CTRL_REGS
- PrintDebug("CR4 Write\n");
+ PrintDebug("CR4 Write\n");
#endif
- if (v3_handle_cr4_write(info) == -1) {
- return -1;
- }
- break;
- }
- case VMEXIT_CR4_READ:
- {
+ if (v3_handle_cr4_write(info) == -1) {
+ return -1;
+ }
+ break;
+ case VMEXIT_CR4_READ:
#ifdef DEBUG_CTRL_REGS
- PrintDebug("CR4 Read\n");
+ PrintDebug("CR4 Read\n");
#endif
- if (v3_handle_cr4_read(info) == -1) {
- return -1;
- }
- break;
- }
-
- case VMEXIT_EXCP14:
- {
- addr_t fault_addr = guest_ctrl->exit_info2;
- pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
+ if (v3_handle_cr4_read(info) == -1) {
+ return -1;
+ }
+ break;
+ case VMEXIT_EXCP14: {
+ addr_t fault_addr = guest_ctrl->exit_info2;
+ pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
#ifdef DEBUG_SHADOW_PAGING
- PrintDebug("PageFault at %p (error=%d)\n",
- (void *)fault_addr, *(uint_t *)error_code);
+ PrintDebug("PageFault at %p (error=%d)\n",
+ (void *)fault_addr, *(uint_t *)error_code);
#endif
- if (info->shdw_pg_mode == SHADOW_PAGING) {
- if (v3_handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
- return -1;
- }
- } else {
- PrintError("Page fault in un implemented paging mode\n");
- return -1;
- }
- break;
- }
- case VMEXIT_NPF:
- {
- PrintError("Currently unhandled Nested Page Fault\n");
- return -1;
-
- break;
- }
- case VMEXIT_INVLPG:
- {
- if (info->shdw_pg_mode == SHADOW_PAGING) {
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
+ if (v3_handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
+ return -1;
+ }
+ } else {
+ PrintError("Page fault in un implemented paging mode\n");
+ return -1;
+ }
+ break;
+ }
+ case VMEXIT_NPF:
+
+ PrintError("Currently unhandled Nested Page Fault\n");
+ return -1;
+
+ break;
+ case VMEXIT_INVLPG:
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
#ifdef DEBUG_SHADOW_PAGING
- PrintDebug("Invlpg\n");
+ PrintDebug("Invlpg\n");
#endif
- if (v3_handle_shadow_invlpg(info) == -1) {
- return -1;
- }
- }
-
- /*
- (exit_code == VMEXIT_INVLPGA) ||
- */
- break;
- }
-
-
-
- case VMEXIT_VMMCALL:
- {
- /*
- * Hypercall
- */
-
- if (v3_handle_hypercall(info) == -1) {
- return -1;
- }
-
- // VMMCALL is a 3 byte op
- info->rip += 3;
- break;
- }
-
-
- case VMEXIT_INTR:
- {
- // handled by interrupt dispatch earlier
- break;
- }
- case VMEXIT_SMI:
- {
- // handle_svm_smi(info); // ignored for now
- break;
- }
- case VMEXIT_HLT:
- {
+ if (v3_handle_shadow_invlpg(info) == -1) {
+ return -1;
+ }
+ }
+ break;
+ case VMEXIT_VMMCALL:
+ /*
+ * Hypercall
+ */
+
+ if (v3_handle_hypercall(info) == -1) {
+ return -1;
+ }
+
+ // VMMCALL is a 3 byte op
+ info->rip += 3;
+ break;
+ case VMEXIT_INTR:
+ // handled by interrupt dispatch earlier
+ break;
+ case VMEXIT_SMI:
+ // handle_svm_smi(info); // ignored for now
+ break;
+ case VMEXIT_HLT:
#ifdef DEBUG_HALT
- PrintDebug("Guest halted\n");
+ PrintDebug("Guest halted\n");
#endif
- if (v3_handle_svm_halt(info) == -1) {
- return -1;
- }
- break;
- }
- case VMEXIT_PAUSE: {
- //PrintDebug("Guest paused\n");
- if (v3_handle_svm_pause(info) == -1) {
- return -1;
- }
- }
- break;
-
-
-
-
- case VMEXIT_WBINVD:
- {
+ if (v3_handle_svm_halt(info) == -1) {
+ return -1;
+ }
+ break;
+ case VMEXIT_PAUSE:
+ //PrintDebug("Guest paused\n");
+ if (v3_handle_svm_pause(info) == -1) {
+ return -1;
+ }
+ break;
+ case VMEXIT_WBINVD:
#ifdef DEBUG_EMULATOR
- PrintDebug("WBINVD\n");
+ PrintDebug("WBINVD\n");
#endif
- if (v3_handle_svm_wbinvd(info) == -1) {
- return -1;
- }
- break;
- }
-
-
+ if (v3_handle_svm_wbinvd(info) == -1) {
+ return -1;
+ }
+ break;
+
- /* Exits Following this line are NOT HANDLED */
- /*=======================================================================*/
- default:
- {
- addr_t rip_addr;
-
- PrintDebug("Unhandled SVM Exit: %s\n", vmexit_code_to_str(exit_code));
-
- rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
-
-
- PrintError("SVM Returned:(VMCB=%p)\n", (void *)(info->vmm_data));
- PrintError("RIP: %p\n", (void *)(addr_t)(guest_state->rip));
- PrintError("RIP Linear: %p\n", (void *)(addr_t)(rip_addr));
-
- PrintError("SVM Returned: Exit Code: %p\n", (void *)(addr_t)exit_code);
-
- PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
- PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
-
- PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
- PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
-
-
- if (info->shdw_pg_mode == SHADOW_PAGING) {
- PrintHostPageTables(info, info->ctrl_regs.cr3);
- //PrintGuestPageTables(info, info->shdw_pg_state.guest_cr3);
- }
-
- return -1;
-
+ /* Exits Following this line are NOT HANDLED */
+ /*=======================================================================*/
+
+ default: {
+
+ addr_t rip_addr;
+
+ PrintDebug("Unhandled SVM Exit: %s\n", vmexit_code_to_str(exit_code));
+
+ rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
+
+
+ PrintError("SVM Returned:(VMCB=%p)\n", (void *)(info->vmm_data));
+ PrintError("RIP: %p\n", (void *)(addr_t)(guest_state->rip));
+ PrintError("RIP Linear: %p\n", (void *)(addr_t)(rip_addr));
+
+ PrintError("SVM Returned: Exit Code: %p\n", (void *)(addr_t)exit_code);
+
+ PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
+ PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
+
+ PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
+ PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
+
+
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
+ PrintHostPageTables(info, info->ctrl_regs.cr3);
+ //PrintGuestPageTables(info, info->shdw_pg_state.guest_cr3);
+ }
+
+ return -1;
+ }
}
- break;
-
- }
- // END OF SWITCH (EXIT_CODE)
+ // END OF SWITCH (EXIT_CODE)
- if (info->enable_profiler) {
- rdtscll(info->profiler.end_time);
- v3_profile_exit(info, exit_code);
- }
+ if (info->enable_profiler) {
+ rdtscll(info->profiler.end_time);
+ v3_profile_exit(info, exit_code);
+ }
- // Update the low level state
-
- if (v3_intr_pending(info)) {
-
- switch (v3_get_intr_type(info)) {
- case EXTERNAL_IRQ:
- {
- uint_t irq = v3_get_intr_number(info);
-
- // check to see if ==-1 (non exists)
-
- /*
- guest_ctrl->EVENTINJ.vector = irq;
- guest_ctrl->EVENTINJ.valid = 1;
- guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
- */
-
- guest_ctrl->guest_ctrl.V_IRQ = 1;
- guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
- guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
- guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
+ // Update the low level state
+
+ if (v3_intr_pending(info)) {
+
+ switch (v3_get_intr_type(info)) {
+ case EXTERNAL_IRQ: {
+ uint_t irq = v3_get_intr_number(info);
+
+ // check to see if ==-1 (non exists)
+
+ /*
+ guest_ctrl->EVENTINJ.vector = irq;
+ guest_ctrl->EVENTINJ.valid = 1;
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
+ */
+
+ guest_ctrl->guest_ctrl.V_IRQ = 1;
+ guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
+ guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
+ guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
#ifdef DEBUG_INTERRUPTS
- PrintDebug("Injecting Interrupt %d (EIP=%p)\n",
- guest_ctrl->guest_ctrl.V_INTR_VECTOR,
- (void *)(addr_t)info->rip);
+ PrintDebug("Injecting Interrupt %d (EIP=%p)\n",
+ guest_ctrl->guest_ctrl.V_INTR_VECTOR,
+ (void *)(addr_t)info->rip);
#endif
- v3_injecting_intr(info, irq, EXTERNAL_IRQ);
-
- break;
- }
- case NMI:
- guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
- break;
- case EXCEPTION:
- {
- uint_t excp = v3_get_intr_number(info);
-
- guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
-
- if (info->intr_state.excp_error_code_valid) { //PAD
- guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
- guest_ctrl->EVENTINJ.ev = 1;
+ v3_injecting_intr(info, irq, EXTERNAL_IRQ);
+
+ break;
+ }
+ case NMI:
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
+ break;
+ case EXCEPTION: {
+ uint_t excp = v3_get_intr_number(info);
+
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
+
+ if (info->intr_state.excp_error_code_valid) { //PAD
+ guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
+ guest_ctrl->EVENTINJ.ev = 1;
#ifdef DEBUG_INTERRUPTS
- PrintDebug("Injecting error code %x\n", guest_ctrl->EVENTINJ.error_code);
+ PrintDebug("Injecting error code %x\n", guest_ctrl->EVENTINJ.error_code);
#endif
+ }
+
+ guest_ctrl->EVENTINJ.vector = excp;
+
+ guest_ctrl->EVENTINJ.valid = 1;
+#ifdef DEBUG_INTERRUPTS
+ PrintDebug("Injecting Interrupt %d (EIP=%p)\n",
+ guest_ctrl->EVENTINJ.vector,
+ (void *)(addr_t)info->rip);
+#endif
+ v3_injecting_intr(info, excp, EXCEPTION);
+ break;
+ }
+ case SOFTWARE_INTR:
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
+ break;
+ case VIRTUAL_INTR:
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
+ break;
+
+ case INVALID_INTR:
+ default:
+ PrintError("Attempted to issue an invalid interrupt\n");
+ return -1;
}
- guest_ctrl->EVENTINJ.vector = excp;
-
- guest_ctrl->EVENTINJ.valid = 1;
+ } else {
#ifdef DEBUG_INTERRUPTS
- PrintDebug("Injecting Interrupt %d (EIP=%p)\n",
- guest_ctrl->EVENTINJ.vector,
- (void *)(addr_t)info->rip);
+ PrintDebug("No interrupts/exceptions pending\n");
#endif
- v3_injecting_intr(info, excp, EXCEPTION);
- break;
- }
- case SOFTWARE_INTR:
- guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
- break;
- case VIRTUAL_INTR:
- guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
- break;
-
- case INVALID_INTR:
- default:
- PrintError("Attempted to issue an invalid interrupt\n");
- return -1;
}
+
+ guest_state->cr0 = info->ctrl_regs.cr0;
+ 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;
+
+ guest_state->cpl = info->cpl;
- } else {
-#ifdef DEBUG_INTERRUPTS
- PrintDebug("No interrupts/exceptions pending\n");
-#endif
- }
-
- guest_state->cr0 = info->ctrl_regs.cr0;
- 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;
-
- guest_state->cpl = info->cpl;
-
- guest_state->rax = info->vm_regs.rax;
- guest_state->rip = info->rip;
- guest_state->rsp = info->vm_regs.rsp;
-
+ guest_state->rax = info->vm_regs.rax;
+ guest_state->rip = info->rip;
+ guest_state->rsp = info->vm_regs.rsp;
- set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
- if (exit_code == VMEXIT_INTR) {
- //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
- }
+ set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
- return 0;
+ if (exit_code == VMEXIT_INTR) {
+ //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
+ }
+
+ return 0;
}
const char * vmexit_code_to_str(uint_t exit_code) {
- switch(exit_code) {
- case VMEXIT_CR0_READ:
- return VMEXIT_CR0_READ_STR;
- case VMEXIT_CR1_READ:
- return VMEXIT_CR1_READ_STR;
- case VMEXIT_CR2_READ:
- return VMEXIT_CR2_READ_STR;
- case VMEXIT_CR3_READ:
- return VMEXIT_CR3_READ_STR;
- case VMEXIT_CR4_READ:
- return VMEXIT_CR4_READ_STR;
- case VMEXIT_CR5_READ:
- return VMEXIT_CR5_READ_STR;
- case VMEXIT_CR6_READ:
- return VMEXIT_CR6_READ_STR;
- case VMEXIT_CR7_READ:
- return VMEXIT_CR7_READ_STR;
- case VMEXIT_CR8_READ:
- return VMEXIT_CR8_READ_STR;
- case VMEXIT_CR9_READ:
- return VMEXIT_CR9_READ_STR;
- case VMEXIT_CR10_READ:
- return VMEXIT_CR10_READ_STR;
- case VMEXIT_CR11_READ:
- return VMEXIT_CR11_READ_STR;
- case VMEXIT_CR12_READ:
- return VMEXIT_CR12_READ_STR;
- case VMEXIT_CR13_READ:
- return VMEXIT_CR13_READ_STR;
- case VMEXIT_CR14_READ:
- return VMEXIT_CR14_READ_STR;
- case VMEXIT_CR15_READ:
- return VMEXIT_CR15_READ_STR;
- case VMEXIT_CR0_WRITE:
- return VMEXIT_CR0_WRITE_STR;
- case VMEXIT_CR1_WRITE:
- return VMEXIT_CR1_WRITE_STR;
- case VMEXIT_CR2_WRITE:
- return VMEXIT_CR2_WRITE_STR;
- case VMEXIT_CR3_WRITE:
- return VMEXIT_CR3_WRITE_STR;
- case VMEXIT_CR4_WRITE:
- return VMEXIT_CR4_WRITE_STR;
- case VMEXIT_CR5_WRITE:
- return VMEXIT_CR5_WRITE_STR;
- case VMEXIT_CR6_WRITE:
- return VMEXIT_CR6_WRITE_STR;
- case VMEXIT_CR7_WRITE:
- return VMEXIT_CR7_WRITE_STR;
- case VMEXIT_CR8_WRITE:
- return VMEXIT_CR8_WRITE_STR;
- case VMEXIT_CR9_WRITE:
- return VMEXIT_CR9_WRITE_STR;
- case VMEXIT_CR10_WRITE:
- return VMEXIT_CR10_WRITE_STR;
- case VMEXIT_CR11_WRITE:
- return VMEXIT_CR11_WRITE_STR;
- case VMEXIT_CR12_WRITE:
- return VMEXIT_CR12_WRITE_STR;
- case VMEXIT_CR13_WRITE:
- return VMEXIT_CR13_WRITE_STR;
- case VMEXIT_CR14_WRITE:
- return VMEXIT_CR14_WRITE_STR;
- case VMEXIT_CR15_WRITE:
- return VMEXIT_CR15_WRITE_STR;
- case VMEXIT_DR0_READ:
- return VMEXIT_DR0_READ_STR;
- case VMEXIT_DR1_READ:
- return VMEXIT_DR1_READ_STR;
- case VMEXIT_DR2_READ:
- return VMEXIT_DR2_READ_STR;
- case VMEXIT_DR3_READ:
- return VMEXIT_DR3_READ_STR;
- case VMEXIT_DR4_READ:
- return VMEXIT_DR4_READ_STR;
- case VMEXIT_DR5_READ:
- return VMEXIT_DR5_READ_STR;
- case VMEXIT_DR6_READ:
- return VMEXIT_DR6_READ_STR;
- case VMEXIT_DR7_READ:
- return VMEXIT_DR7_READ_STR;
- case VMEXIT_DR8_READ:
- return VMEXIT_DR8_READ_STR;
- case VMEXIT_DR9_READ:
- return VMEXIT_DR9_READ_STR;
- case VMEXIT_DR10_READ:
- return VMEXIT_DR10_READ_STR;
- case VMEXIT_DR11_READ:
- return VMEXIT_DR11_READ_STR;
- case VMEXIT_DR12_READ:
- return VMEXIT_DR12_READ_STR;
- case VMEXIT_DR13_READ:
- return VMEXIT_DR13_READ_STR;
- case VMEXIT_DR14_READ:
- return VMEXIT_DR14_READ_STR;
- case VMEXIT_DR15_READ:
- return VMEXIT_DR15_READ_STR;
- case VMEXIT_DR0_WRITE:
- return VMEXIT_DR0_WRITE_STR;
- case VMEXIT_DR1_WRITE:
- return VMEXIT_DR1_WRITE_STR;
- case VMEXIT_DR2_WRITE:
- return VMEXIT_DR2_WRITE_STR;
- case VMEXIT_DR3_WRITE:
- return VMEXIT_DR3_WRITE_STR;
- case VMEXIT_DR4_WRITE:
- return VMEXIT_DR4_WRITE_STR;
- case VMEXIT_DR5_WRITE:
- return VMEXIT_DR5_WRITE_STR;
- case VMEXIT_DR6_WRITE:
- return VMEXIT_DR6_WRITE_STR;
- case VMEXIT_DR7_WRITE:
- return VMEXIT_DR7_WRITE_STR;
- case VMEXIT_DR8_WRITE:
- return VMEXIT_DR8_WRITE_STR;
- case VMEXIT_DR9_WRITE:
- return VMEXIT_DR9_WRITE_STR;
- case VMEXIT_DR10_WRITE:
- return VMEXIT_DR10_WRITE_STR;
- case VMEXIT_DR11_WRITE:
- return VMEXIT_DR11_WRITE_STR;
- case VMEXIT_DR12_WRITE:
- return VMEXIT_DR12_WRITE_STR;
- case VMEXIT_DR13_WRITE:
- return VMEXIT_DR13_WRITE_STR;
- case VMEXIT_DR14_WRITE:
- return VMEXIT_DR14_WRITE_STR;
- case VMEXIT_DR15_WRITE:
- return VMEXIT_DR15_WRITE_STR;
- case VMEXIT_EXCP0:
- return VMEXIT_EXCP0_STR;
- case VMEXIT_EXCP1:
- return VMEXIT_EXCP1_STR;
- case VMEXIT_EXCP2:
- return VMEXIT_EXCP2_STR;
- case VMEXIT_EXCP3:
- return VMEXIT_EXCP3_STR;
- case VMEXIT_EXCP4:
- return VMEXIT_EXCP4_STR;
- case VMEXIT_EXCP5:
- return VMEXIT_EXCP5_STR;
- case VMEXIT_EXCP6:
- return VMEXIT_EXCP6_STR;
- case VMEXIT_EXCP7:
- return VMEXIT_EXCP7_STR;
- case VMEXIT_EXCP8:
- return VMEXIT_EXCP8_STR;
- case VMEXIT_EXCP9:
- return VMEXIT_EXCP9_STR;
- case VMEXIT_EXCP10:
- return VMEXIT_EXCP10_STR;
- case VMEXIT_EXCP11:
- return VMEXIT_EXCP11_STR;
- case VMEXIT_EXCP12:
- return VMEXIT_EXCP12_STR;
- case VMEXIT_EXCP13:
- return VMEXIT_EXCP13_STR;
- case VMEXIT_EXCP14:
- return VMEXIT_EXCP14_STR;
- case VMEXIT_EXCP15:
- return VMEXIT_EXCP15_STR;
- case VMEXIT_EXCP16:
- return VMEXIT_EXCP16_STR;
- case VMEXIT_EXCP17:
- return VMEXIT_EXCP17_STR;
- case VMEXIT_EXCP18:
- return VMEXIT_EXCP18_STR;
- case VMEXIT_EXCP19:
- return VMEXIT_EXCP19_STR;
- case VMEXIT_EXCP20:
- return VMEXIT_EXCP20_STR;
- case VMEXIT_EXCP21:
- return VMEXIT_EXCP21_STR;
- case VMEXIT_EXCP22:
- return VMEXIT_EXCP22_STR;
- case VMEXIT_EXCP23:
- return VMEXIT_EXCP23_STR;
- case VMEXIT_EXCP24:
- return VMEXIT_EXCP24_STR;
- case VMEXIT_EXCP25:
- return VMEXIT_EXCP25_STR;
- case VMEXIT_EXCP26:
- return VMEXIT_EXCP26_STR;
- case VMEXIT_EXCP27:
- return VMEXIT_EXCP27_STR;
- case VMEXIT_EXCP28:
- return VMEXIT_EXCP28_STR;
- case VMEXIT_EXCP29:
- return VMEXIT_EXCP29_STR;
- case VMEXIT_EXCP30:
- return VMEXIT_EXCP30_STR;
- case VMEXIT_EXCP31:
- return VMEXIT_EXCP31_STR;
- case VMEXIT_INTR:
- return VMEXIT_INTR_STR;
- case VMEXIT_NMI:
- return VMEXIT_NMI_STR;
- case VMEXIT_SMI:
- return VMEXIT_SMI_STR;
- case VMEXIT_INIT:
- return VMEXIT_INIT_STR;
- case VMEXIT_VINITR:
- return VMEXIT_VINITR_STR;
- case VMEXIT_CR0_SEL_WRITE:
- return VMEXIT_CR0_SEL_WRITE_STR;
- case VMEXIT_IDTR_READ:
- return VMEXIT_IDTR_READ_STR;
- case VMEXIT_GDTR_READ:
- return VMEXIT_GDTR_READ_STR;
- case VMEXIT_LDTR_READ:
- return VMEXIT_LDTR_READ_STR;
- case VMEXIT_TR_READ:
- return VMEXIT_TR_READ_STR;
- case VMEXIT_IDTR_WRITE:
- return VMEXIT_IDTR_WRITE_STR;
- case VMEXIT_GDTR_WRITE:
- return VMEXIT_GDTR_WRITE_STR;
- case VMEXIT_LDTR_WRITE:
- return VMEXIT_LDTR_WRITE_STR;
- case VMEXIT_TR_WRITE:
- return VMEXIT_TR_WRITE_STR;
- case VMEXIT_RDTSC:
- return VMEXIT_RDTSC_STR;
- case VMEXIT_RDPMC:
- return VMEXIT_RDPMC_STR;
- case VMEXIT_PUSHF:
- return VMEXIT_PUSHF_STR;
- case VMEXIT_POPF:
- return VMEXIT_POPF_STR;
- case VMEXIT_CPUID:
- return VMEXIT_CPUID_STR;
- case VMEXIT_RSM:
- return VMEXIT_RSM_STR;
- case VMEXIT_IRET:
- return VMEXIT_IRET_STR;
- case VMEXIT_SWINT:
- return VMEXIT_SWINT_STR;
- case VMEXIT_INVD:
- return VMEXIT_INVD_STR;
- case VMEXIT_PAUSE:
- return VMEXIT_PAUSE_STR;
- case VMEXIT_HLT:
- return VMEXIT_HLT_STR;
- case VMEXIT_INVLPG:
- return VMEXIT_INVLPG_STR;
- case VMEXIT_INVLPGA:
- return VMEXIT_INVLPGA_STR;
- case VMEXIT_IOIO:
- return VMEXIT_IOIO_STR;
- case VMEXIT_MSR:
- return VMEXIT_MSR_STR;
- case VMEXIT_TASK_SWITCH:
- return VMEXIT_TASK_SWITCH_STR;
- case VMEXIT_FERR_FREEZE:
- return VMEXIT_FERR_FREEZE_STR;
- case VMEXIT_SHUTDOWN:
- return VMEXIT_SHUTDOWN_STR;
- case VMEXIT_VMRUN:
- return VMEXIT_VMRUN_STR;
- case VMEXIT_VMMCALL:
- return VMEXIT_VMMCALL_STR;
- case VMEXIT_VMLOAD:
- return VMEXIT_VMLOAD_STR;
- case VMEXIT_VMSAVE:
- return VMEXIT_VMSAVE_STR;
- case VMEXIT_STGI:
- return VMEXIT_STGI_STR;
- case VMEXIT_CLGI:
- return VMEXIT_CLGI_STR;
- case VMEXIT_SKINIT:
- return VMEXIT_SKINIT_STR;
- case VMEXIT_RDTSCP:
- return VMEXIT_RDTSCP_STR;
- case VMEXIT_ICEBP:
- return VMEXIT_ICEBP_STR;
- case VMEXIT_WBINVD:
- return VMEXIT_WBINVD_STR;
- case VMEXIT_MONITOR:
- return VMEXIT_MONITOR_STR;
- case VMEXIT_MWAIT:
- return VMEXIT_MWAIT_STR;
- case VMEXIT_MWAIT_CONDITIONAL:
- return VMEXIT_MWAIT_CONDITIONAL_STR;
- case VMEXIT_NPF:
- return VMEXIT_NPF_STR;
- case VMEXIT_INVALID_VMCB:
- return VMEXIT_INVALID_VMCB_STR;
- }
- return NULL;
+ switch(exit_code) {
+ case VMEXIT_CR0_READ:
+ return VMEXIT_CR0_READ_STR;
+ case VMEXIT_CR1_READ:
+ return VMEXIT_CR1_READ_STR;
+ case VMEXIT_CR2_READ:
+ return VMEXIT_CR2_READ_STR;
+ case VMEXIT_CR3_READ:
+ return VMEXIT_CR3_READ_STR;
+ case VMEXIT_CR4_READ:
+ return VMEXIT_CR4_READ_STR;
+ case VMEXIT_CR5_READ:
+ return VMEXIT_CR5_READ_STR;
+ case VMEXIT_CR6_READ:
+ return VMEXIT_CR6_READ_STR;
+ case VMEXIT_CR7_READ:
+ return VMEXIT_CR7_READ_STR;
+ case VMEXIT_CR8_READ:
+ return VMEXIT_CR8_READ_STR;
+ case VMEXIT_CR9_READ:
+ return VMEXIT_CR9_READ_STR;
+ case VMEXIT_CR10_READ:
+ return VMEXIT_CR10_READ_STR;
+ case VMEXIT_CR11_READ:
+ return VMEXIT_CR11_READ_STR;
+ case VMEXIT_CR12_READ:
+ return VMEXIT_CR12_READ_STR;
+ case VMEXIT_CR13_READ:
+ return VMEXIT_CR13_READ_STR;
+ case VMEXIT_CR14_READ:
+ return VMEXIT_CR14_READ_STR;
+ case VMEXIT_CR15_READ:
+ return VMEXIT_CR15_READ_STR;
+ case VMEXIT_CR0_WRITE:
+ return VMEXIT_CR0_WRITE_STR;
+ case VMEXIT_CR1_WRITE:
+ return VMEXIT_CR1_WRITE_STR;
+ case VMEXIT_CR2_WRITE:
+ return VMEXIT_CR2_WRITE_STR;
+ case VMEXIT_CR3_WRITE:
+ return VMEXIT_CR3_WRITE_STR;
+ case VMEXIT_CR4_WRITE:
+ return VMEXIT_CR4_WRITE_STR;
+ case VMEXIT_CR5_WRITE:
+ return VMEXIT_CR5_WRITE_STR;
+ case VMEXIT_CR6_WRITE:
+ return VMEXIT_CR6_WRITE_STR;
+ case VMEXIT_CR7_WRITE:
+ return VMEXIT_CR7_WRITE_STR;
+ case VMEXIT_CR8_WRITE:
+ return VMEXIT_CR8_WRITE_STR;
+ case VMEXIT_CR9_WRITE:
+ return VMEXIT_CR9_WRITE_STR;
+ case VMEXIT_CR10_WRITE:
+ return VMEXIT_CR10_WRITE_STR;
+ case VMEXIT_CR11_WRITE:
+ return VMEXIT_CR11_WRITE_STR;
+ case VMEXIT_CR12_WRITE:
+ return VMEXIT_CR12_WRITE_STR;
+ case VMEXIT_CR13_WRITE:
+ return VMEXIT_CR13_WRITE_STR;
+ case VMEXIT_CR14_WRITE:
+ return VMEXIT_CR14_WRITE_STR;
+ case VMEXIT_CR15_WRITE:
+ return VMEXIT_CR15_WRITE_STR;
+ case VMEXIT_DR0_READ:
+ return VMEXIT_DR0_READ_STR;
+ case VMEXIT_DR1_READ:
+ return VMEXIT_DR1_READ_STR;
+ case VMEXIT_DR2_READ:
+ return VMEXIT_DR2_READ_STR;
+ case VMEXIT_DR3_READ:
+ return VMEXIT_DR3_READ_STR;
+ case VMEXIT_DR4_READ:
+ return VMEXIT_DR4_READ_STR;
+ case VMEXIT_DR5_READ:
+ return VMEXIT_DR5_READ_STR;
+ case VMEXIT_DR6_READ:
+ return VMEXIT_DR6_READ_STR;
+ case VMEXIT_DR7_READ:
+ return VMEXIT_DR7_READ_STR;
+ case VMEXIT_DR8_READ:
+ return VMEXIT_DR8_READ_STR;
+ case VMEXIT_DR9_READ:
+ return VMEXIT_DR9_READ_STR;
+ case VMEXIT_DR10_READ:
+ return VMEXIT_DR10_READ_STR;
+ case VMEXIT_DR11_READ:
+ return VMEXIT_DR11_READ_STR;
+ case VMEXIT_DR12_READ:
+ return VMEXIT_DR12_READ_STR;
+ case VMEXIT_DR13_READ:
+ return VMEXIT_DR13_READ_STR;
+ case VMEXIT_DR14_READ:
+ return VMEXIT_DR14_READ_STR;
+ case VMEXIT_DR15_READ:
+ return VMEXIT_DR15_READ_STR;
+ case VMEXIT_DR0_WRITE:
+ return VMEXIT_DR0_WRITE_STR;
+ case VMEXIT_DR1_WRITE:
+ return VMEXIT_DR1_WRITE_STR;
+ case VMEXIT_DR2_WRITE:
+ return VMEXIT_DR2_WRITE_STR;
+ case VMEXIT_DR3_WRITE:
+ return VMEXIT_DR3_WRITE_STR;
+ case VMEXIT_DR4_WRITE:
+ return VMEXIT_DR4_WRITE_STR;
+ case VMEXIT_DR5_WRITE:
+ return VMEXIT_DR5_WRITE_STR;
+ case VMEXIT_DR6_WRITE:
+ return VMEXIT_DR6_WRITE_STR;
+ case VMEXIT_DR7_WRITE:
+ return VMEXIT_DR7_WRITE_STR;
+ case VMEXIT_DR8_WRITE:
+ return VMEXIT_DR8_WRITE_STR;
+ case VMEXIT_DR9_WRITE:
+ return VMEXIT_DR9_WRITE_STR;
+ case VMEXIT_DR10_WRITE:
+ return VMEXIT_DR10_WRITE_STR;
+ case VMEXIT_DR11_WRITE:
+ return VMEXIT_DR11_WRITE_STR;
+ case VMEXIT_DR12_WRITE:
+ return VMEXIT_DR12_WRITE_STR;
+ case VMEXIT_DR13_WRITE:
+ return VMEXIT_DR13_WRITE_STR;
+ case VMEXIT_DR14_WRITE:
+ return VMEXIT_DR14_WRITE_STR;
+ case VMEXIT_DR15_WRITE:
+ return VMEXIT_DR15_WRITE_STR;
+ case VMEXIT_EXCP0:
+ return VMEXIT_EXCP0_STR;
+ case VMEXIT_EXCP1:
+ return VMEXIT_EXCP1_STR;
+ case VMEXIT_EXCP2:
+ return VMEXIT_EXCP2_STR;
+ case VMEXIT_EXCP3:
+ return VMEXIT_EXCP3_STR;
+ case VMEXIT_EXCP4:
+ return VMEXIT_EXCP4_STR;
+ case VMEXIT_EXCP5:
+ return VMEXIT_EXCP5_STR;
+ case VMEXIT_EXCP6:
+ return VMEXIT_EXCP6_STR;
+ case VMEXIT_EXCP7:
+ return VMEXIT_EXCP7_STR;
+ case VMEXIT_EXCP8:
+ return VMEXIT_EXCP8_STR;
+ case VMEXIT_EXCP9:
+ return VMEXIT_EXCP9_STR;
+ case VMEXIT_EXCP10:
+ return VMEXIT_EXCP10_STR;
+ case VMEXIT_EXCP11:
+ return VMEXIT_EXCP11_STR;
+ case VMEXIT_EXCP12:
+ return VMEXIT_EXCP12_STR;
+ case VMEXIT_EXCP13:
+ return VMEXIT_EXCP13_STR;
+ case VMEXIT_EXCP14:
+ return VMEXIT_EXCP14_STR;
+ case VMEXIT_EXCP15:
+ return VMEXIT_EXCP15_STR;
+ case VMEXIT_EXCP16:
+ return VMEXIT_EXCP16_STR;
+ case VMEXIT_EXCP17:
+ return VMEXIT_EXCP17_STR;
+ case VMEXIT_EXCP18:
+ return VMEXIT_EXCP18_STR;
+ case VMEXIT_EXCP19:
+ return VMEXIT_EXCP19_STR;
+ case VMEXIT_EXCP20:
+ return VMEXIT_EXCP20_STR;
+ case VMEXIT_EXCP21:
+ return VMEXIT_EXCP21_STR;
+ case VMEXIT_EXCP22:
+ return VMEXIT_EXCP22_STR;
+ case VMEXIT_EXCP23:
+ return VMEXIT_EXCP23_STR;
+ case VMEXIT_EXCP24:
+ return VMEXIT_EXCP24_STR;
+ case VMEXIT_EXCP25:
+ return VMEXIT_EXCP25_STR;
+ case VMEXIT_EXCP26:
+ return VMEXIT_EXCP26_STR;
+ case VMEXIT_EXCP27:
+ return VMEXIT_EXCP27_STR;
+ case VMEXIT_EXCP28:
+ return VMEXIT_EXCP28_STR;
+ case VMEXIT_EXCP29:
+ return VMEXIT_EXCP29_STR;
+ case VMEXIT_EXCP30:
+ return VMEXIT_EXCP30_STR;
+ case VMEXIT_EXCP31:
+ return VMEXIT_EXCP31_STR;
+ case VMEXIT_INTR:
+ return VMEXIT_INTR_STR;
+ case VMEXIT_NMI:
+ return VMEXIT_NMI_STR;
+ case VMEXIT_SMI:
+ return VMEXIT_SMI_STR;
+ case VMEXIT_INIT:
+ return VMEXIT_INIT_STR;
+ case VMEXIT_VINITR:
+ return VMEXIT_VINITR_STR;
+ case VMEXIT_CR0_SEL_WRITE:
+ return VMEXIT_CR0_SEL_WRITE_STR;
+ case VMEXIT_IDTR_READ:
+ return VMEXIT_IDTR_READ_STR;
+ case VMEXIT_GDTR_READ:
+ return VMEXIT_GDTR_READ_STR;
+ case VMEXIT_LDTR_READ:
+ return VMEXIT_LDTR_READ_STR;
+ case VMEXIT_TR_READ:
+ return VMEXIT_TR_READ_STR;
+ case VMEXIT_IDTR_WRITE:
+ return VMEXIT_IDTR_WRITE_STR;
+ case VMEXIT_GDTR_WRITE:
+ return VMEXIT_GDTR_WRITE_STR;
+ case VMEXIT_LDTR_WRITE:
+ return VMEXIT_LDTR_WRITE_STR;
+ case VMEXIT_TR_WRITE:
+ return VMEXIT_TR_WRITE_STR;
+ case VMEXIT_RDTSC:
+ return VMEXIT_RDTSC_STR;
+ case VMEXIT_RDPMC:
+ return VMEXIT_RDPMC_STR;
+ case VMEXIT_PUSHF:
+ return VMEXIT_PUSHF_STR;
+ case VMEXIT_POPF:
+ return VMEXIT_POPF_STR;
+ case VMEXIT_CPUID:
+ return VMEXIT_CPUID_STR;
+ case VMEXIT_RSM:
+ return VMEXIT_RSM_STR;
+ case VMEXIT_IRET:
+ return VMEXIT_IRET_STR;
+ case VMEXIT_SWINT:
+ return VMEXIT_SWINT_STR;
+ case VMEXIT_INVD:
+ return VMEXIT_INVD_STR;
+ case VMEXIT_PAUSE:
+ return VMEXIT_PAUSE_STR;
+ case VMEXIT_HLT:
+ return VMEXIT_HLT_STR;
+ case VMEXIT_INVLPG:
+ return VMEXIT_INVLPG_STR;
+ case VMEXIT_INVLPGA:
+ return VMEXIT_INVLPGA_STR;
+ case VMEXIT_IOIO:
+ return VMEXIT_IOIO_STR;
+ case VMEXIT_MSR:
+ return VMEXIT_MSR_STR;
+ case VMEXIT_TASK_SWITCH:
+ return VMEXIT_TASK_SWITCH_STR;
+ case VMEXIT_FERR_FREEZE:
+ return VMEXIT_FERR_FREEZE_STR;
+ case VMEXIT_SHUTDOWN:
+ return VMEXIT_SHUTDOWN_STR;
+ case VMEXIT_VMRUN:
+ return VMEXIT_VMRUN_STR;
+ case VMEXIT_VMMCALL:
+ return VMEXIT_VMMCALL_STR;
+ case VMEXIT_VMLOAD:
+ return VMEXIT_VMLOAD_STR;
+ case VMEXIT_VMSAVE:
+ return VMEXIT_VMSAVE_STR;
+ case VMEXIT_STGI:
+ return VMEXIT_STGI_STR;
+ case VMEXIT_CLGI:
+ return VMEXIT_CLGI_STR;
+ case VMEXIT_SKINIT:
+ return VMEXIT_SKINIT_STR;
+ case VMEXIT_RDTSCP:
+ return VMEXIT_RDTSCP_STR;
+ case VMEXIT_ICEBP:
+ return VMEXIT_ICEBP_STR;
+ case VMEXIT_WBINVD:
+ return VMEXIT_WBINVD_STR;
+ case VMEXIT_MONITOR:
+ return VMEXIT_MONITOR_STR;
+ case VMEXIT_MWAIT:
+ return VMEXIT_MWAIT_STR;
+ case VMEXIT_MWAIT_CONDITIONAL:
+ return VMEXIT_MWAIT_CONDITIONAL_STR;
+ case VMEXIT_NPF:
+ return VMEXIT_NPF_STR;
+ case VMEXIT_INVALID_VMCB:
+ return VMEXIT_INVALID_VMCB_STR;
+ }
+ return NULL;
}
// This should package up an IO request and call vmm_handle_io
int v3_handle_svm_io_in(struct guest_info * info) {
- vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
- // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
- struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
- struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
- int read_size = 0;
+ struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
+ int read_size = 0;
- if (hook == NULL) {
- PrintError("Hook Not present for in on port %x\n", io_info->port);
- // error, we should not have exited on this port
- return -1;
- }
+ if (hook == NULL) {
+ PrintError("Hook Not present for in on port %x\n", io_info->port);
+ // error, we should not have exited on this port
+ return -1;
+ }
- if (io_info->sz8) {
- read_size = 1;
- } else if (io_info->sz16) {
- read_size = 2;
- } else if (io_info->sz32) {
- read_size = 4;
- }
+ if (io_info->sz8) {
+ read_size = 1;
+ } else if (io_info->sz16) {
+ read_size = 2;
+ } else if (io_info->sz32) {
+ read_size = 4;
+ }
- PrintDebug("IN of %d bytes on port %d (0x%x)\n", read_size, io_info->port, io_info->port);
+ PrintDebug("IN of %d bytes on port %d (0x%x)\n", read_size, io_info->port, io_info->port);
- if (hook->read(io_info->port, &(info->vm_regs.rax), read_size, hook->priv_data) != read_size) {
- // not sure how we handle errors.....
- PrintError("Read Failure for in on port %x\n", io_info->port);
- return -1;
- }
+ if (hook->read(io_info->port, &(info->vm_regs.rax), read_size, hook->priv_data) != read_size) {
+ // not sure how we handle errors.....
+ PrintError("Read Failure for in on port %x\n", io_info->port);
+ return -1;
+ }
- info->rip = ctrl_area->exit_info2;
+ info->rip = ctrl_area->exit_info2;
- return 0;
+ return 0;
}
* In that if we do wrap around the effect will manifest in the higher bits of the register
*/
int v3_handle_svm_io_ins(struct guest_info * info) {
- vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
- vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
- struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
+ struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
- struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
- int read_size = 0;
+ struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
+ int read_size = 0;
+ addr_t dst_addr = 0;
+ uint_t rep_num = 1;
+ ullong_t mask = 0;
+ struct v3_segment *theseg = &(info->segments.es); // default is ES
+ addr_t inst_ptr;
+
+
+ // This is kind of hacky...
+ // direction can equal either 1 or -1
+ // We will multiply the final added offset by this value to go the correct direction
+ int direction = 1;
+ struct rflags * flags = (struct rflags *)&(guest_state->rflags);
+
+ if (flags->df) {
+ direction = -1;
+ }
+
- addr_t dst_addr = 0;
- uint_t rep_num = 1;
- ullong_t mask = 0;
+ if (hook == NULL) {
+ PrintError("Hook Not present for ins on port %x\n", io_info->port);
+ // error, we should not have exited on this port
+ return -1;
+ }
- // This is kind of hacky...
- // direction can equal either 1 or -1
- // We will multiply the final added offset by this value to go the correct direction
- int direction = 1;
- struct rflags * flags = (struct rflags *)&(guest_state->rflags);
- if (flags->df) {
- direction = -1;
- }
+ if (guest_va_to_host_va(info, get_addr_linear(info, info->rip, &(info->segments.cs)), &inst_ptr) == -1) {
+ PrintError("Can't access instruction\n");
+ return -1;
+ }
+ while (is_prefix_byte(*((char*)inst_ptr))) {
+ switch (*((char*)inst_ptr)) {
+ case PREFIX_CS_OVERRIDE:
+ theseg = &(info->segments.cs);
+ break;
+ case PREFIX_SS_OVERRIDE:
+ theseg = &(info->segments.ss);
+ break;
+ case PREFIX_DS_OVERRIDE:
+ theseg = &(info->segments.ds);
+ break;
+ case PREFIX_ES_OVERRIDE:
+ theseg = &(info->segments.es);
+ break;
+ case PREFIX_FS_OVERRIDE:
+ theseg = &(info->segments.fs);
+ break;
+ case PREFIX_GS_OVERRIDE:
+ theseg = &(info->segments.gs);
+ break;
+ default:
+ break;
+ }
+ inst_ptr++;
+ }
- if (hook == NULL) {
- PrintError("Hook Not present for ins on port %x\n", io_info->port);
- // error, we should not have exited on this port
- return -1;
- }
- struct v3_segment *theseg = &(info->segments.es); // default is ES
+ PrintDebug("INS on port %d (0x%x)\n", io_info->port, io_info->port);
+
+ if (io_info->sz8) {
+ read_size = 1;
+ } else if (io_info->sz16) {
+ read_size = 2;
+ } else if (io_info->sz32) {
+ read_size = 4;
+ } else {
+ PrintError("io_info Invalid Size\n");
+ return -1;
+ }
+
- addr_t inst_ptr;
-
- if (guest_va_to_host_va(info, get_addr_linear(info, info->rip, &(info->segments.cs)), &inst_ptr) == -1) {
- PrintError("Can't access instruction\n");
- return -1;
- }
-
- while (is_prefix_byte(*((char*)inst_ptr))) {
- switch (*((char*)inst_ptr)) {
- case PREFIX_CS_OVERRIDE:
- theseg = &(info->segments.cs);
- break;
- case PREFIX_SS_OVERRIDE:
- theseg = &(info->segments.ss);
- break;
- case PREFIX_DS_OVERRIDE:
- theseg = &(info->segments.ds);
- break;
- case PREFIX_ES_OVERRIDE:
- theseg = &(info->segments.es);
- break;
- case PREFIX_FS_OVERRIDE:
- theseg = &(info->segments.fs);
- break;
- case PREFIX_GS_OVERRIDE:
- theseg = &(info->segments.gs);
- break;
- default:
- break;
+ if (io_info->addr16) {
+ mask = 0xffff;
+ } else if (io_info->addr32) {
+ mask = 0xffffffff;
+ } else if (io_info->addr64) {
+ mask = 0xffffffffffffffffLL;
+ } else {
+ // This value should be set depending on the host register size...
+ mask = get_gpr_mask(info);
+
+ PrintDebug("INS io_info invalid address size, mask=0x%p, io_info=0x%p\n",
+ (void *)(addr_t)mask, (void *)(addr_t)(io_info));
+ // PrintDebug("INS Aborted... Check implementation\n");
+ //return -1;
}
- inst_ptr++;
- }
+ if (io_info->rep) {
+ // rep_num = info->vm_regs.rcx & mask;
+ rep_num = info->vm_regs.rcx;
+ }
- PrintDebug("INS on port %d (0x%x)\n", io_info->port, io_info->port);
- if (io_info->sz8) {
- read_size = 1;
- } else if (io_info->sz16) {
- read_size = 2;
- } else if (io_info->sz32) {
- read_size = 4;
- } else {
- PrintError("io_info Invalid Size\n");
- return -1;
- }
+ PrintDebug("INS size=%d for %d steps\n", read_size, rep_num);
-
- if (io_info->addr16) {
- mask = 0xffff;
- } else if (io_info->addr32) {
- mask = 0xffffffff;
- } else if (io_info->addr64) {
- mask = 0xffffffffffffffffLL;
- } else {
- // This value should be set depending on the host register size...
- mask = get_gpr_mask(info);
-
- PrintDebug("INS io_info invalid address size, mask=0x%p, io_info=0x%p\n",
- (void *)(addr_t)mask, (void *)(addr_t)(io_info));
- // PrintDebug("INS Aborted... Check implementation\n");
- //return -1;
- }
-
- if (io_info->rep) {
- // rep_num = info->vm_regs.rcx & mask;
- rep_num = info->vm_regs.rcx;
- }
-
-
- PrintDebug("INS size=%d for %d steps\n", read_size, rep_num);
-
- while (rep_num > 0) {
- addr_t host_addr;
- dst_addr = get_addr_linear(info, info->vm_regs.rdi & mask, theseg);
+ while (rep_num > 0) {
+ addr_t host_addr;
+ dst_addr = get_addr_linear(info, info->vm_regs.rdi & mask, theseg);
- PrintDebug("Writing 0x%p\n", (void *)dst_addr);
+ PrintDebug("Writing 0x%p\n", (void *)dst_addr);
- if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
- // either page fault or gpf...
- PrintError("Could not convert Guest VA to host VA\n");
- return -1;
- }
+ if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
+ // either page fault or gpf...
+ PrintError("Could not convert Guest VA to host VA\n");
+ return -1;
+ }
- if (hook->read(io_info->port, (char*)host_addr, read_size, hook->priv_data) != read_size) {
- // not sure how we handle errors.....
- PrintError("Read Failure for ins on port %x\n", io_info->port);
- return -1;
- }
+ if (hook->read(io_info->port, (char*)host_addr, read_size, hook->priv_data) != read_size) {
+ // not sure how we handle errors.....
+ PrintError("Read Failure for ins on port %x\n", io_info->port);
+ return -1;
+ }
- info->vm_regs.rdi += read_size * direction;
+ info->vm_regs.rdi += read_size * direction;
- if (io_info->rep)
- info->vm_regs.rcx--;
+ if (io_info->rep)
+ info->vm_regs.rcx--;
- rep_num--;
- }
+ rep_num--;
+ }
- info->rip = ctrl_area->exit_info2;
+ info->rip = ctrl_area->exit_info2;
- return 0;
+ return 0;
}
int v3_handle_svm_io_out(struct guest_info * info) {
- vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
- // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
- struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
- struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
- int write_size = 0;
+ struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
+ int write_size = 0;
- if (hook == NULL) {
- PrintError("Hook Not present for out on port %x\n", io_info->port);
- // error, we should not have exited on this port
- return -1;
- }
+ if (hook == NULL) {
+ PrintError("Hook Not present for out on port %x\n", io_info->port);
+ // error, we should not have exited on this port
+ return -1;
+ }
- if (io_info->sz8) {
- write_size = 1;
- } else if (io_info->sz16) {
- write_size = 2;
- } else if (io_info->sz32) {
- write_size = 4;
- }
+ if (io_info->sz8) {
+ write_size = 1;
+ } else if (io_info->sz16) {
+ write_size = 2;
+ } else if (io_info->sz32) {
+ write_size = 4;
+ }
- PrintDebug("OUT of %d bytes on port %d (0x%x)\n", write_size, io_info->port, io_info->port);
+ PrintDebug("OUT of %d bytes on port %d (0x%x)\n", write_size, io_info->port, io_info->port);
- if (hook->write(io_info->port, &(info->vm_regs.rax), write_size, hook->priv_data) != write_size) {
- // not sure how we handle errors.....
- PrintError("Write Failure for out on port %x\n", io_info->port);
- return -1;
- }
+ if (hook->write(io_info->port, &(info->vm_regs.rax), write_size, hook->priv_data) != write_size) {
+ // not sure how we handle errors.....
+ PrintError("Write Failure for out on port %x\n", io_info->port);
+ return -1;
+ }
- info->rip = ctrl_area->exit_info2;
+ info->rip = ctrl_area->exit_info2;
- return 0;
+ return 0;
}
*/
int v3_handle_svm_io_outs(struct guest_info * info) {
- vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
- vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
- struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
+ struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
- struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
- int write_size = 0;
-
- addr_t dst_addr = 0;
- uint_t rep_num = 1;
- ullong_t mask = 0;
-
-
-
- // This is kind of hacky...
- // direction can equal either 1 or -1
- // We will multiply the final added offset by this value to go the correct direction
- int direction = 1;
- struct rflags * flags = (struct rflags *)&(guest_state->rflags);
- if (flags->df) {
- direction = -1;
- }
-
-
- if (hook == NULL) {
- PrintError("Hook Not present for outs on port %x\n", io_info->port);
- // error, we should not have exited on this port
- return -1;
- }
-
- PrintDebug("OUTS on port %d (0x%x)\n", io_info->port, io_info->port);
-
- if (io_info->sz8) {
- write_size = 1;
- } else if (io_info->sz16) {
- write_size = 2;
- } else if (io_info->sz32) {
- write_size = 4;
- }
-
-
- if (io_info->addr16) {
- mask = 0xffff;
- } else if (io_info->addr32) {
- mask = 0xffffffff;
- } else if (io_info->addr64) {
- mask = 0xffffffffffffffffLL;
- } else {
- // This value should be set depending on the host register size...
- mask = get_gpr_mask(info);
-
- PrintDebug("OUTS io_info invalid address size, mask=0%p, io_info=0x%p\n",
- (void *)(addr_t)mask, (void *)(addr_t)io_info);
- // PrintDebug("INS Aborted... Check implementation\n");
- //return -1;
- // should never happen
- //PrintDebug("Invalid Address length\n");
- //return -1;
- }
-
- if (io_info->rep) {
- rep_num = info->vm_regs.rcx & mask;
- }
-
- struct v3_segment *theseg = &(info->segments.es); // default is ES
-
- addr_t inst_ptr;
-
- if (guest_va_to_host_va(info,get_addr_linear(info,info->rip,&(info->segments.cs)),&inst_ptr)==-1) {
- PrintError("Can't access instruction\n");
- return -1;
- }
-
- while (is_prefix_byte(*((char*)inst_ptr))) {
- switch (*((char*)inst_ptr)) {
- case PREFIX_CS_OVERRIDE:
- theseg = &(info->segments.cs);
- break;
- case PREFIX_SS_OVERRIDE:
- theseg = &(info->segments.ss);
- break;
- case PREFIX_DS_OVERRIDE:
- theseg = &(info->segments.ds);
- break;
- case PREFIX_ES_OVERRIDE:
- theseg = &(info->segments.es);
- break;
- case PREFIX_FS_OVERRIDE:
- theseg = &(info->segments.fs);
- break;
- case PREFIX_GS_OVERRIDE:
- theseg = &(info->segments.gs);
- break;
- default:
- break;
+ struct v3_io_hook * hook = v3_get_io_hook(info, io_info->port);
+ int write_size = 0;
+ addr_t dst_addr = 0;
+ uint_t rep_num = 1;
+ ullong_t mask = 0;
+ addr_t inst_ptr;
+ struct v3_segment * theseg = &(info->segments.es); // default is ES
+
+ // This is kind of hacky...
+ // direction can equal either 1 or -1
+ // We will multiply the final added offset by this value to go the correct direction
+ int direction = 1;
+ struct rflags * flags = (struct rflags *)&(guest_state->rflags);
+
+ if (flags->df) {
+ direction = -1;
}
- inst_ptr++;
- }
- PrintDebug("OUTS size=%d for %d steps\n", write_size, rep_num);
- while (rep_num > 0) {
- addr_t host_addr;
+ if (hook == NULL) {
+ PrintError("Hook Not present for outs on port %x\n", io_info->port);
+ // error, we should not have exited on this port
+ return -1;
+ }
+ PrintDebug("OUTS on port %d (0x%x)\n", io_info->port, io_info->port);
+ if (io_info->sz8) {
+ write_size = 1;
+ } else if (io_info->sz16) {
+ write_size = 2;
+ } else if (io_info->sz32) {
+ write_size = 4;
+ }
- dst_addr = get_addr_linear(info, (info->vm_regs.rsi & mask), theseg);
-
- if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
- // either page fault or gpf...
+
+ if (io_info->addr16) {
+ mask = 0xffff;
+ } else if (io_info->addr32) {
+ mask = 0xffffffff;
+ } else if (io_info->addr64) {
+ mask = 0xffffffffffffffffLL;
+ } else {
+ // This value should be set depending on the host register size...
+ mask = get_gpr_mask(info);
+
+ PrintDebug("OUTS io_info invalid address size, mask=0%p, io_info=0x%p\n",
+ (void *)(addr_t)mask, (void *)(addr_t)io_info);
+ // PrintDebug("INS Aborted... Check implementation\n");
+ //return -1;
+ // should never happen
+ //PrintDebug("Invalid Address length\n");
+ //return -1;
+ }
+
+ if (io_info->rep) {
+ rep_num = info->vm_regs.rcx & mask;
+ }
+
+
+
+
+ if (guest_va_to_host_va(info,get_addr_linear(info,info->rip,&(info->segments.cs)),&inst_ptr)==-1) {
+ PrintError("Can't access instruction\n");
+ return -1;
}
- if (hook->write(io_info->port, (char*)host_addr, write_size, hook->priv_data) != write_size) {
- // not sure how we handle errors.....
- PrintError("Write Failure for outs on port %x\n", io_info->port);
- return -1;
+ while (is_prefix_byte(*((char*)inst_ptr))) {
+ switch (*((char*)inst_ptr)) {
+ case PREFIX_CS_OVERRIDE:
+ theseg = &(info->segments.cs);
+ break;
+ case PREFIX_SS_OVERRIDE:
+ theseg = &(info->segments.ss);
+ break;
+ case PREFIX_DS_OVERRIDE:
+ theseg = &(info->segments.ds);
+ break;
+ case PREFIX_ES_OVERRIDE:
+ theseg = &(info->segments.es);
+ break;
+ case PREFIX_FS_OVERRIDE:
+ theseg = &(info->segments.fs);
+ break;
+ case PREFIX_GS_OVERRIDE:
+ theseg = &(info->segments.gs);
+ break;
+ default:
+ break;
+ }
+ inst_ptr++;
}
- info->vm_regs.rsi += write_size * direction;
+ PrintDebug("OUTS size=%d for %d steps\n", write_size, rep_num);
- if (io_info->rep)
- info->vm_regs.rcx--;
+ while (rep_num > 0) {
+ addr_t host_addr;
+
+ dst_addr = get_addr_linear(info, (info->vm_regs.rsi & mask), theseg);
- rep_num--;
- }
+ if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
+ // either page fault or gpf...
+ }
+
+ if (hook->write(io_info->port, (char*)host_addr, write_size, hook->priv_data) != write_size) {
+ // not sure how we handle errors.....
+ PrintError("Write Failure for outs on port %x\n", io_info->port);
+ return -1;
+ }
+
+ info->vm_regs.rsi += write_size * direction;
+
+ if (io_info->rep) {
+ info->vm_regs.rcx--;
+ }
+
+ rep_num--;
+ }
- info->rip = ctrl_area->exit_info2;
+ info->rip = ctrl_area->exit_info2;
- return 0;
+ return 0;
}
static int get_bitmap_index(uint_t msr) {
- if ((msr >= PENTIUM_MSRS_START) &&
- (msr <= PENTIUM_MSRS_END)) {
- return (PENTIUM_MSRS_INDEX + (msr - PENTIUM_MSRS_START));
- } else if ((msr >= AMD_6_GEN_MSRS_START) &&
- (msr <= AMD_6_GEN_MSRS_END)) {
- return (AMD_6_GEN_MSRS_INDEX + (msr - AMD_6_GEN_MSRS_START));
- } else if ((msr >= AMD_7_8_GEN_MSRS_START) &&
- (msr <= AMD_7_8_GEN_MSRS_END)) {
- return (AMD_7_8_GEN_MSRS_INDEX + (msr - AMD_7_8_GEN_MSRS_START));
- } else {
- PrintError("MSR out of range (MSR=0x%x)\n", msr);
- return -1;
- }
+ if ((msr >= PENTIUM_MSRS_START) &&
+ (msr <= PENTIUM_MSRS_END)) {
+ return (PENTIUM_MSRS_INDEX + (msr - PENTIUM_MSRS_START));
+ } else if ((msr >= AMD_6_GEN_MSRS_START) &&
+ (msr <= AMD_6_GEN_MSRS_END)) {
+ return (AMD_6_GEN_MSRS_INDEX + (msr - AMD_6_GEN_MSRS_START));
+ } else if ((msr >= AMD_7_8_GEN_MSRS_START) &&
+ (msr <= AMD_7_8_GEN_MSRS_END)) {
+ return (AMD_7_8_GEN_MSRS_INDEX + (msr - AMD_7_8_GEN_MSRS_START));
+ } else {
+ PrintError("MSR out of range (MSR=0x%x)\n", msr);
+ return -1;
+ }
}
addr_t v3_init_svm_msr_map(struct guest_info * info) {
- uchar_t * msr_bitmap = (uchar_t*)V3_VAddr(V3_AllocPages(2));
- struct v3_msr_map * msr_map = &(info->msr_map);
- struct v3_msr_hook * hook = NULL;
+ uchar_t * msr_bitmap = (uchar_t*)V3_VAddr(V3_AllocPages(2));
+ struct v3_msr_map * msr_map = &(info->msr_map);
+ struct v3_msr_hook * hook = NULL;
- memset(msr_bitmap, 0, PAGE_SIZE * 2);
+ memset(msr_bitmap, 0, PAGE_SIZE * 2);
- list_for_each_entry(hook, &(msr_map->hook_list), link) {
- int index = get_bitmap_index(hook->msr);
- uint_t byte_offset = index / 4;
- uint_t bit_offset = (index % 4) * 2;
- uchar_t val = 0;
- uchar_t mask = ~0x3;
+ list_for_each_entry(hook, &(msr_map->hook_list), link) {
+ int index = get_bitmap_index(hook->msr);
+ uint_t byte_offset = index / 4;
+ uint_t bit_offset = (index % 4) * 2;
+ uchar_t val = 0;
+ uchar_t mask = ~0x3;
- if (hook->read) {
- val |= 0x1;
- }
+ if (hook->read) {
+ val |= 0x1;
+ }
- if (hook->write) {
- val |= 0x2;
- }
+ if (hook->write) {
+ val |= 0x2;
+ }
- val = val << bit_offset;
- mask = mask << bit_offset;
+ val = val << bit_offset;
+ mask = mask << bit_offset;
- *(msr_bitmap + byte_offset) &= mask;
- *(msr_bitmap + byte_offset) |= val;
- }
+ *(msr_bitmap + byte_offset) &= mask;
+ *(msr_bitmap + byte_offset) |= val;
+ }
- return (addr_t)V3_PAddr(msr_bitmap);
+ return (addr_t)V3_PAddr(msr_bitmap);
}
int v3_handle_msr_write(struct guest_info * info) {
- uint_t msr_num = info->vm_regs.rcx;
- struct v3_msr msr_val;
- struct v3_msr_hook * hook = NULL;
+ uint_t msr_num = info->vm_regs.rcx;
+ struct v3_msr msr_val;
+ struct v3_msr_hook * hook = NULL;
- hook = v3_get_msr_hook(info, msr_num);
+ hook = v3_get_msr_hook(info, msr_num);
- if (!hook) {
- PrintError("Hook for MSR write %d not found\n", msr_num);
- return -1;
- }
+ if (!hook) {
+ PrintError("Hook for MSR write %d not found\n", msr_num);
+ return -1;
+ }
- msr_val.value = 0;
- msr_val.lo = info->vm_regs.rax;
- msr_val.hi = info->vm_regs.rdx;
+ msr_val.value = 0;
+ msr_val.lo = info->vm_regs.rax;
+ msr_val.hi = info->vm_regs.rdx;
- if (hook->write(msr_num, msr_val, hook->priv_data) == -1) {
- PrintError("Error in MSR hook Write\n");
- return -1;
- }
+ if (hook->write(msr_num, msr_val, hook->priv_data) == -1) {
+ PrintError("Error in MSR hook Write\n");
+ return -1;
+ }
- return 0;
+ return 0;
}
int v3_handle_msr_read(struct guest_info * info) {
- uint_t msr_num = info->vm_regs.rcx;
- struct v3_msr msr_val;
- struct v3_msr_hook * hook = NULL;
+ uint_t msr_num = info->vm_regs.rcx;
+ struct v3_msr msr_val;
+ struct v3_msr_hook * hook = NULL;
- hook = v3_get_msr_hook(info, msr_num);
+ hook = v3_get_msr_hook(info, msr_num);
- if (!hook) {
- PrintError("Hook for MSR read %d not found\n", msr_num);
- return -1;
- }
+ if (!hook) {
+ PrintError("Hook for MSR read %d not found\n", msr_num);
+ return -1;
+ }
- msr_val.value = 0;
+ msr_val.value = 0;
- if (hook->read(msr_num, &msr_val, hook->priv_data) == -1) {
- PrintError("Error in MSR hook Read\n");
- return -1;
- }
+ if (hook->read(msr_num, &msr_val, hook->priv_data) == -1) {
+ PrintError("Error in MSR hook Read\n");
+ return -1;
+ }
- info->vm_regs.rax = msr_val.lo;
- info->vm_regs.rdx = msr_val.hi;
+ info->vm_regs.rax = msr_val.lo;
+ info->vm_regs.rdx = msr_val.hi;
- return 0;
+ return 0;
}
#include <palacios/vmm_intr.h>
-int v3_handle_svm_pause(struct guest_info * info)
-{
- // handled as a nop
-
- info->rip+=2;
-
- return 0;
+int v3_handle_svm_pause(struct guest_info * info) {
+ // handled as a nop
+ info->rip+=2;
+ return 0;
}
int v3_handle_svm_wbinvd(struct guest_info * info) {
- if (info->cpl != 0) {
- PrintDebug("WBINVD: cpl != 0, injecting GPF\n");
- v3_raise_exception(info, GPF_EXCEPTION);
- } else {
- info->rip += 2;
- asm("wbinvd");
- }
-
- return 0;
+ if (info->cpl != 0) {
+ PrintDebug("WBINVD: cpl != 0, injecting GPF\n");
+ v3_raise_exception(info, GPF_EXCEPTION);
+ } else {
+ info->rip += 2;
+ asm("wbinvd");
+ }
+
+ return 0;
}
static struct vm_device * v3_allocate_device() {
- struct vm_device * dev = NULL;
- dev = (struct vm_device*)V3_Malloc(sizeof(struct vm_device));
+ struct vm_device * dev = NULL;
+ dev = (struct vm_device*)V3_Malloc(sizeof(struct vm_device));
- V3_ASSERT(dev != NULL);
+ V3_ASSERT(dev != NULL);
- dev->ops = NULL;
- memset(dev->name, 0, 32);
- dev->vm = NULL;
- dev->private_data = NULL;
+ dev->ops = NULL;
+ memset(dev->name, 0, 32);
+ dev->vm = NULL;
+ dev->private_data = NULL;
- INIT_LIST_HEAD(&(dev->io_hooks));
- dev->num_io_hooks = 0;
+ INIT_LIST_HEAD(&(dev->io_hooks));
+ dev->num_io_hooks = 0;
- INIT_LIST_HEAD(&(dev->mem_hooks));
- dev->num_mem_hooks = 0;
+ INIT_LIST_HEAD(&(dev->mem_hooks));
+ dev->num_mem_hooks = 0;
- INIT_LIST_HEAD(&(dev->irq_hooks));
- dev->num_irq_hooks = 0;
+ INIT_LIST_HEAD(&(dev->irq_hooks));
+ dev->num_irq_hooks = 0;
- return dev;
+ return dev;
}
struct vm_device * v3_create_device(char * name, struct vm_device_ops * ops, void * private_data) {
- struct vm_device * dev = v3_allocate_device();
+ struct vm_device * dev = v3_allocate_device();
- strncpy(dev->name, name, 32);
- dev->ops = ops;
- dev->private_data = private_data;
+ strncpy(dev->name, name, 32);
+ dev->ops = ops;
+ dev->private_data = private_data;
- return dev;
+ return dev;
}
void v3_free_device(struct vm_device * dev) {
- V3_Free(dev);
+ V3_Free(dev);
}
v3_vm_cpu_mode_t v3_get_cpu_mode(struct guest_info * info) {
- struct cr0_32 * cr0;
- struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
- struct efer_64 * efer = (struct efer_64 *)&(info->guest_efer);
- struct v3_segment * cs = &(info->segments.cs);
-
- if (info->shdw_pg_mode == SHADOW_PAGING) {
- cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
- } else if (info->shdw_pg_mode == NESTED_PAGING) {
- cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
- } else {
- PrintError("Invalid Paging Mode...\n");
- V3_ASSERT(0);
- return -1;
- }
-
- if (cr0->pe == 0) {
- return REAL;
- } else if ((cr4->pae == 0) && (efer->lme == 0)) {
- return PROTECTED;
- } else if (efer->lme == 0) {
- return PROTECTED_PAE;
- } else if ((efer->lme == 1) && (cs->long_mode == 1)) {
- return LONG;
- } else {
- // What about LONG_16_COMPAT???
- return LONG_32_COMPAT;
- }
+ struct cr0_32 * cr0;
+ struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
+ struct efer_64 * efer = (struct efer_64 *)&(info->guest_efer);
+ struct v3_segment * cs = &(info->segments.cs);
+
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
+ cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+ } else if (info->shdw_pg_mode == NESTED_PAGING) {
+ cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
+ } else {
+ PrintError("Invalid Paging Mode...\n");
+ V3_ASSERT(0);
+ return -1;
+ }
+
+ if (cr0->pe == 0) {
+ return REAL;
+ } else if ((cr4->pae == 0) && (efer->lme == 0)) {
+ return PROTECTED;
+ } else if (efer->lme == 0) {
+ return PROTECTED_PAE;
+ } else if ((efer->lme == 1) && (cs->long_mode == 1)) {
+ return LONG;
+ } else {
+ // What about LONG_16_COMPAT???
+ return LONG_32_COMPAT;
+ }
}
// Get address width in bytes
uint_t v3_get_addr_width(struct guest_info * info) {
- struct cr0_32 * cr0;
- struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
- struct efer_64 * efer = (struct efer_64 *)&(info->guest_efer);
- struct v3_segment * cs = &(info->segments.cs);
-
- if (info->shdw_pg_mode == SHADOW_PAGING) {
- cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
- } else if (info->shdw_pg_mode == NESTED_PAGING) {
- cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
- } else {
- PrintError("Invalid Paging Mode...\n");
- V3_ASSERT(0);
- return -1;
- }
-
- if (cr0->pe == 0) {
- return 2;
- } else if ((cr4->pae == 0) && (efer->lme == 0)) {
- return 4;
- } else if (efer->lme == 0) {
- return 4;
- } else if ((efer->lme == 1) && (cs->long_mode == 1)) {
- return 8;
- } else {
- // What about LONG_16_COMPAT???
- return 4;
- }
+ struct cr0_32 * cr0;
+ struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
+ struct efer_64 * efer = (struct efer_64 *)&(info->guest_efer);
+ struct v3_segment * cs = &(info->segments.cs);
+
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
+ cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+ } else if (info->shdw_pg_mode == NESTED_PAGING) {
+ cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
+ } else {
+ PrintError("Invalid Paging Mode...\n");
+ V3_ASSERT(0);
+ return -1;
+ }
+
+ if (cr0->pe == 0) {
+ return 2;
+ } else if ((cr4->pae == 0) && (efer->lme == 0)) {
+ return 4;
+ } else if (efer->lme == 0) {
+ return 4;
+ } else if ((efer->lme == 1) && (cs->long_mode == 1)) {
+ return 8;
+ } else {
+ // What about LONG_16_COMPAT???
+ return 4;
+ }
}
static const uchar_t LONG_16_COMPAT_STR[] = "16bit Compat";
const uchar_t * v3_cpu_mode_to_str(v3_vm_cpu_mode_t mode) {
- switch (mode) {
- case REAL:
- return REAL_STR;
- case PROTECTED:
- return PROTECTED_STR;
- case PROTECTED_PAE:
- return PROTECTED_PAE_STR;
- case LONG:
- return LONG_STR;
- case LONG_32_COMPAT:
- return LONG_32_COMPAT_STR;
- case LONG_16_COMPAT:
- return LONG_16_COMPAT_STR;
- default:
- return NULL;
- }
+ switch (mode) {
+ case REAL:
+ return REAL_STR;
+ case PROTECTED:
+ return PROTECTED_STR;
+ case PROTECTED_PAE:
+ return PROTECTED_PAE_STR;
+ case LONG:
+ return LONG_STR;
+ case LONG_32_COMPAT:
+ return LONG_32_COMPAT_STR;
+ case LONG_16_COMPAT:
+ return LONG_16_COMPAT_STR;
+ default:
+ return NULL;
+ }
}
v3_vm_mem_mode_t v3_get_mem_mode(struct guest_info * info) {
- struct cr0_32 * cr0;
-
- if (info->shdw_pg_mode == SHADOW_PAGING) {
- cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
- } else if (info->shdw_pg_mode == NESTED_PAGING) {
- cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
- } else {
- PrintError("Invalid Paging Mode...\n");
- V3_ASSERT(0);
- return -1;
- }
-
- if (cr0->pg == 0) {
- return PHYSICAL_MEM;
- } else {
- return VIRTUAL_MEM;
- }
+ struct cr0_32 * cr0;
+
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
+ cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+ } else if (info->shdw_pg_mode == NESTED_PAGING) {
+ cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
+ } else {
+ PrintError("Invalid Paging Mode...\n");
+ V3_ASSERT(0);
+ return -1;
+ }
+
+ if (cr0->pg == 0) {
+ return PHYSICAL_MEM;
+ } else {
+ return VIRTUAL_MEM;
+ }
}
static const uchar_t PHYS_MEM_STR[] = "Physical Memory";
static const uchar_t VIRT_MEM_STR[] = "Virtual Memory";
const uchar_t * v3_mem_mode_to_str(v3_vm_mem_mode_t mode) {
- switch (mode) {
- case PHYSICAL_MEM:
- return PHYS_MEM_STR;
- case VIRTUAL_MEM:
- return VIRT_MEM_STR;
- default:
- return NULL;
- }
+ switch (mode) {
+ case PHYSICAL_MEM:
+ return PHYS_MEM_STR;
+ case VIRTUAL_MEM:
+ return VIRT_MEM_STR;
+ default:
+ return NULL;
+ }
}
void v3_print_segments(struct guest_info * info) {
- struct v3_segments * segs = &(info->segments);
- int i = 0;
- struct v3_segment * seg_ptr;
+ struct v3_segments * segs = &(info->segments);
+ int i = 0;
+ struct v3_segment * seg_ptr;
- seg_ptr=(struct v3_segment *)segs;
+ seg_ptr=(struct v3_segment *)segs;
- char *seg_names[] = {"CS", "DS" , "ES", "FS", "GS", "SS" , "LDTR", "GDTR", "IDTR", "TR", NULL};
- PrintDebug("Segments\n");
+ char *seg_names[] = {"CS", "DS" , "ES", "FS", "GS", "SS" , "LDTR", "GDTR", "IDTR", "TR", NULL};
+ PrintDebug("Segments\n");
- for (i = 0; seg_names[i] != NULL; i++) {
+ for (i = 0; seg_names[i] != NULL; i++) {
- PrintDebug("\t%s: Sel=%x, base=%p, limit=%x (long_mode=%d, db=%d)\n", seg_names[i], seg_ptr[i].selector,
- (void *)(addr_t)seg_ptr[i].base, seg_ptr[i].limit,
- seg_ptr[i].long_mode, seg_ptr[i].db);
+ PrintDebug("\t%s: Sel=%x, base=%p, limit=%x (long_mode=%d, db=%d)\n", seg_names[i], seg_ptr[i].selector,
+ (void *)(addr_t)seg_ptr[i].base, seg_ptr[i].limit,
+ seg_ptr[i].long_mode, seg_ptr[i].db);
- }
+ }
}
void v3_print_ctrl_regs(struct guest_info * info) {
- struct v3_ctrl_regs * regs = &(info->ctrl_regs);
- int i = 0;
- v3_reg_t * reg_ptr;
- char * reg_names[] = {"CR0", "CR2", "CR3", "CR4", "CR8", "FLAGS", NULL};
- vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(info->vmm_data);
+ struct v3_ctrl_regs * regs = &(info->ctrl_regs);
+ int i = 0;
+ v3_reg_t * reg_ptr;
+ char * reg_names[] = {"CR0", "CR2", "CR3", "CR4", "CR8", "FLAGS", NULL};
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(info->vmm_data);
- reg_ptr= (v3_reg_t *)regs;
+ reg_ptr= (v3_reg_t *)regs;
- PrintDebug("32 bit Ctrl Regs:\n");
+ PrintDebug("32 bit Ctrl Regs:\n");
- for (i = 0; reg_names[i] != NULL; i++) {
- PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);
- }
+ for (i = 0; reg_names[i] != NULL; i++) {
+ PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);
+ }
- PrintDebug("\tEFER=0x%p\n", (void*)(addr_t)(guest_state->efer));
+ PrintDebug("\tEFER=0x%p\n", (void*)(addr_t)(guest_state->efer));
}
#ifdef __V3_32BIT__
void v3_print_GPRs(struct guest_info * info) {
- struct v3_gprs * regs = &(info->vm_regs);
- int i = 0;
- v3_reg_t * reg_ptr;
- char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", NULL};
+ struct v3_gprs * regs = &(info->vm_regs);
+ int i = 0;
+ v3_reg_t * reg_ptr;
+ char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", NULL};
- reg_ptr= (v3_reg_t *)regs;
+ reg_ptr= (v3_reg_t *)regs;
- PrintDebug("32 bit GPRs:\n");
+ PrintDebug("32 bit GPRs:\n");
- for (i = 0; reg_names[i] != NULL; i++) {
- PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);
- }
+ for (i = 0; reg_names[i] != NULL; i++) {
+ PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);
+ }
}
#elif __V3_64BIT__
void v3_print_GPRs(struct guest_info * info) {
- struct v3_gprs * regs = &(info->vm_regs);
- int i = 0;
- v3_reg_t * reg_ptr;
- char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", \
- "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", NULL};
+ struct v3_gprs * regs = &(info->vm_regs);
+ int i = 0;
+ v3_reg_t * reg_ptr;
+ char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", \
+ "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", NULL};
- reg_ptr= (v3_reg_t *)regs;
+ reg_ptr= (v3_reg_t *)regs;
- PrintDebug("64 bit GPRs:\n");
+ PrintDebug("64 bit GPRs:\n");
- for (i = 0; reg_names[i] != NULL; i++) {
- PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);
- }
+ for (i = 0; reg_names[i] != NULL; i++) {
+ PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);
+ }
}
/**********************************/
int host_va_to_host_pa(addr_t host_va, addr_t * host_pa) {
- if ((os_hooks) && (os_hooks)->vaddr_to_paddr) {
+ if ((os_hooks) && (os_hooks)->vaddr_to_paddr) {
- *host_pa = (addr_t)(os_hooks)->vaddr_to_paddr((void *)host_va);
+ *host_pa = (addr_t)(os_hooks)->vaddr_to_paddr((void *)host_va);
- if (*host_pa == 0) {
- PrintError("In HVA->HPA: Invalid HVA(%p)->HPA lookup\n",
- (void *)host_va);
- return -1;
+ if (*host_pa == 0) {
+ PrintError("In HVA->HPA: Invalid HVA(%p)->HPA lookup\n",
+ (void *)host_va);
+ return -1;
+ }
+ } else {
+ PrintError("In HVA->HPA: os_hooks not defined\n");
+ return -1;
}
- } else {
- PrintError("In HVA->HPA: os_hooks not defined\n");
- return -1;
- }
- return 0;
+ return 0;
}
int host_pa_to_host_va(addr_t host_pa, addr_t * host_va) {
- if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {
+ if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {
- *host_va = (addr_t)(os_hooks)->paddr_to_vaddr((void *)host_pa);
+ *host_va = (addr_t)(os_hooks)->paddr_to_vaddr((void *)host_pa);
- if (*host_va == 0) {
- PrintError("In HPA->HVA: Invalid HPA(%p)->HVA lookup\n",
- (void *)host_pa);
- return -1;
+ if (*host_va == 0) {
+ PrintError("In HPA->HVA: Invalid HPA(%p)->HVA lookup\n",
+ (void *)host_pa);
+ return -1;
+ }
+ } else {
+ PrintError("In HPA->HVA: os_hooks not defined\n");
+ return -1;
}
- } else {
- PrintError("In HPA->HVA: os_hooks not defined\n");
- return -1;
- }
- return 0;
+ return 0;
}
int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_pa) {
- struct v3_shadow_region * shdw_reg = v3_get_shadow_region(guest_info, guest_pa);
+ struct v3_shadow_region * shdw_reg = v3_get_shadow_region(guest_info, guest_pa);
- *host_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
+ *host_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
- if ((shdw_reg == NULL) ||
- (shdw_reg->host_type == SHDW_REGION_INVALID) ||
- (shdw_reg->host_type == SHDW_REGION_FULL_HOOK)){
- PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (reg_type=%s)\n",
- (void *)guest_pa, v3_shdw_region_type_to_str(shdw_reg->host_type));
- return -1;
- }
+ if ((shdw_reg == NULL) ||
+ (shdw_reg->host_type == SHDW_REGION_INVALID) ||
+ (shdw_reg->host_type == SHDW_REGION_FULL_HOOK)){
+ PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (reg_type=%s)\n",
+ (void *)guest_pa, v3_shdw_region_type_to_str(shdw_reg->host_type));
+ return -1;
+ }
- return 0;
+ return 0;
}
// For now we ignore it
//
int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
- *guest_pa = 0;
- PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
+ *guest_pa = 0;
+ PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
- return -1;
+ return -1;
}
/* !! Currently not implemented !! */
// This will return negative until we implement host_pa_to_guest_pa()
int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
- addr_t host_pa = 0;
- *guest_pa = 0;
+ addr_t host_pa = 0;
+ *guest_pa = 0;
- if (host_va_to_host_pa(host_va, &host_pa) != 0) {
- PrintError("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
- (void *)host_va);
- return -1;
- }
+ if (host_va_to_host_pa(host_va, &host_pa) != 0) {
+ PrintError("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
+ (void *)host_va);
+ return -1;
+ }
- if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
- PrintError("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
- (void *)host_pa);
- return -1;
- }
+ if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
+ PrintError("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
+ (void *)host_pa);
+ return -1;
+ }
- return 0;
+ return 0;
}
int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
- addr_t host_pa = 0;
+ addr_t host_pa = 0;
- *host_va = 0;
+ *host_va = 0;
- if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
- PrintError("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
- (void *)guest_pa);
- return -1;
- }
+ if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
+ PrintError("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
+ (void *)guest_pa);
+ return -1;
+ }
- if (host_pa_to_host_va(host_pa, host_va) != 0) {
- PrintError("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
- (void *)host_pa);
- return -1;
- }
+ if (host_pa_to_host_va(host_pa, host_va) != 0) {
+ PrintError("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
+ (void *)host_pa);
+ return -1;
+ }
- return 0;
+ return 0;
}
int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
- v3_reg_t guest_cr3 = 0;
+ v3_reg_t guest_cr3 = 0;
- if (guest_info->mem_mode == PHYSICAL_MEM) {
- // guest virtual address is the same as the physical
- *guest_pa = guest_va;
- return 0;
- }
-
- if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
- guest_cr3 = guest_info->shdw_pg_state.guest_cr3;
- } else {
- guest_cr3 = guest_info->ctrl_regs.cr3;
- }
-
-
- // Guest Is in Paged mode
- switch (guest_info->cpu_mode) {
- case PROTECTED:
- if (v3_translate_guest_pt_32(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
- PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n",
- (void *)guest_va, (void *)(addr_t)guest_cr3);
- return -1;
+ if (guest_info->mem_mode == PHYSICAL_MEM) {
+ // guest virtual address is the same as the physical
+ *guest_pa = guest_va;
+ return 0;
}
- break;
- case PROTECTED_PAE:
- if (v3_translate_guest_pt_32pae(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
- PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n",
- (void *)guest_va, (void *)(addr_t)guest_cr3);
- return -1;
+
+ if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
+ guest_cr3 = guest_info->shdw_pg_state.guest_cr3;
+ } else {
+ guest_cr3 = guest_info->ctrl_regs.cr3;
}
- break;
- case LONG:
- case LONG_32_COMPAT:
- case LONG_16_COMPAT:
- if (v3_translate_guest_pt_64(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
- PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n",
- (void *)guest_va, (void *)(addr_t)guest_cr3);
- return -1;
+
+
+ // Guest Is in Paged mode
+ switch (guest_info->cpu_mode) {
+ case PROTECTED:
+ if (v3_translate_guest_pt_32(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
+ PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n",
+ (void *)guest_va, (void *)(addr_t)guest_cr3);
+ return -1;
+ }
+ break;
+ case PROTECTED_PAE:
+ if (v3_translate_guest_pt_32pae(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
+ PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n",
+ (void *)guest_va, (void *)(addr_t)guest_cr3);
+ return -1;
+ }
+ break;
+ case LONG:
+ case LONG_32_COMPAT:
+ case LONG_16_COMPAT:
+ if (v3_translate_guest_pt_64(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
+ PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n",
+ (void *)guest_va, (void *)(addr_t)guest_cr3);
+ return -1;
+ }
+ break;
+ default:
+ return -1;
}
- break;
- default:
- return -1;
- }
- return 0;
+ return 0;
}
* For now we ignore it...
*/
int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
- *guest_va = 0;
- PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
- return -1;
+ *guest_va = 0;
+ PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
+ return -1;
}
int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
- addr_t guest_pa = 0;
+ addr_t guest_pa = 0;
- *host_pa = 0;
+ *host_pa = 0;
- if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
- PrintError("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
- (void *)guest_va);
- return -1;
- }
+ if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
+ PrintError("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
+ (void *)guest_va);
+ return -1;
+ }
- if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
- PrintError("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
- (void *)guest_pa);
- return -1;
- }
+ if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
+ PrintError("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
+ (void *)guest_pa);
+ return -1;
+ }
- return 0;
+ return 0;
}
/* !! Currently not implemented !! */
int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
- addr_t guest_pa = 0;
+ addr_t guest_pa = 0;
- *guest_va = 0;
+ *guest_va = 0;
- if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
- PrintError("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
- (void *)host_pa);
- return -1;
- }
+ if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
+ PrintError("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
+ (void *)host_pa);
+ return -1;
+ }
- if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
- PrintError("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
- (void *)guest_pa);
- return -1;
- }
+ if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
+ PrintError("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
+ (void *)guest_pa);
+ return -1;
+ }
- return 0;
+ return 0;
}
int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
- addr_t guest_pa = 0;
- addr_t host_pa = 0;
+ addr_t guest_pa = 0;
+ addr_t host_pa = 0;
- *host_va = 0;
+ *host_va = 0;
- if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
- PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
- (void *)guest_va);
- return -1;
- }
+ if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
+ PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
+ (void *)guest_va);
+ return -1;
+ }
- if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
- PrintError("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
- (void *)guest_pa);
- return -1;
- }
+ if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
+ PrintError("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
+ (void *)guest_pa);
+ return -1;
+ }
- if (host_pa_to_host_va(host_pa, host_va) != 0) {
- PrintError("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
- (void *)host_pa);
- return -1;
- }
+ if (host_pa_to_host_va(host_pa, host_va) != 0) {
+ PrintError("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
+ (void *)host_pa);
+ return -1;
+ }
- return 0;
+ return 0;
}
/* !! Currently not implemented !! */
int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
- addr_t host_pa = 0;
- addr_t guest_pa = 0;
+ addr_t host_pa = 0;
+ addr_t guest_pa = 0;
- *guest_va = 0;
+ *guest_va = 0;
- if (host_va_to_host_pa(host_va, &host_pa) != 0) {
- PrintError("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
- (void *)host_va);
- return -1;
- }
+ if (host_va_to_host_pa(host_va, &host_pa) != 0) {
+ PrintError("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
+ (void *)host_va);
+ return -1;
+ }
- if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
- PrintError("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
- (void *)host_va);
- return -1;
- }
+ if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
+ PrintError("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
+ (void *)host_va);
+ return -1;
+ }
- if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
- PrintError("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
- (void *)guest_pa);
- return -1;
- }
+ if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
+ PrintError("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
+ (void *)guest_pa);
+ return -1;
+ }
- return 0;
+ return 0;
}
* except for the tiny little issue of crossing page boundries.....
*/
int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest) {
- addr_t cursor = guest_va;
- int bytes_read = 0;
+ addr_t cursor = guest_va;
+ int bytes_read = 0;
- while (count > 0) {
- int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
- int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
- addr_t host_addr = 0;
+ while (count > 0) {
+ int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
+ int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
+ addr_t host_addr = 0;
- if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
- PrintDebug("Invalid GVA(%p)->HVA lookup\n", (void *)cursor);
- return bytes_read;
- }
+ if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
+ PrintDebug("Invalid GVA(%p)->HVA lookup\n", (void *)cursor);
+ return bytes_read;
+ }
- memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
+ memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
- bytes_read += bytes_to_copy;
- count -= bytes_to_copy;
- cursor += bytes_to_copy;
- }
+ bytes_read += bytes_to_copy;
+ count -= bytes_to_copy;
+ cursor += bytes_to_copy;
+ }
- return bytes_read;
+ return bytes_read;
}
* except for the tiny little issue of crossing page boundries.....
*/
int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest) {
- addr_t cursor = guest_pa;
- int bytes_read = 0;
+ addr_t cursor = guest_pa;
+ int bytes_read = 0;
- while (count > 0) {
- int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
- int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
- addr_t host_addr = 0;
+ while (count > 0) {
+ int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
+ int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
+ addr_t host_addr = 0;
- if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
- return bytes_read;
- }
+ if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
+ return bytes_read;
+ }
- /*
- PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
- PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
- PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
- PrintDebug("guest_pa=0x%x\n", guest_pa);
- */
+ /*
+ PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
+ PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
+ PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
+ PrintDebug("guest_pa=0x%x\n", guest_pa);
+ */
- memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
+ memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
- bytes_read += bytes_to_copy;
- count -= bytes_to_copy;
- cursor += bytes_to_copy;
- }
+ bytes_read += bytes_to_copy;
+ count -= bytes_to_copy;
+ cursor += bytes_to_copy;
+ }
- return bytes_read;
+ return bytes_read;
}
* except for the tiny little issue of crossing page boundries.....
*/
int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src) {
- addr_t cursor = guest_pa;
- int bytes_written = 0;
+ addr_t cursor = guest_pa;
+ int bytes_written = 0;
- while (count > 0) {
- int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
- int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
- addr_t host_addr;
+ while (count > 0) {
+ int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
+ int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
+ addr_t host_addr;
- if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
- return bytes_written;
- }
+ if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
+ return bytes_written;
+ }
- memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
+ memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
- bytes_written += bytes_to_copy;
- count -= bytes_to_copy;
- cursor += bytes_to_copy;
- }
+ bytes_written += bytes_to_copy;
+ count -= bytes_to_copy;
+ cursor += bytes_to_copy;
+ }
- return bytes_written;
+ return bytes_written;
}
void set_vmcb_segment(struct vmcb_selector * vmcb_seg, struct v3_segment * seg) {
- vmcb_seg->selector = seg->selector;
- vmcb_seg->limit = seg->limit;
- vmcb_seg->base = seg->base;
- vmcb_seg->attrib.fields.type = seg->type;
- vmcb_seg->attrib.fields.S = seg->system;
- vmcb_seg->attrib.fields.dpl = seg->dpl;
- vmcb_seg->attrib.fields.P = seg->present;
- vmcb_seg->attrib.fields.avl = seg->avail;
- vmcb_seg->attrib.fields.L = seg->long_mode;
- vmcb_seg->attrib.fields.db = seg->db;
- vmcb_seg->attrib.fields.G = seg->granularity;
+ vmcb_seg->selector = seg->selector;
+ vmcb_seg->limit = seg->limit;
+ vmcb_seg->base = seg->base;
+ vmcb_seg->attrib.fields.type = seg->type;
+ vmcb_seg->attrib.fields.S = seg->system;
+ vmcb_seg->attrib.fields.dpl = seg->dpl;
+ vmcb_seg->attrib.fields.P = seg->present;
+ vmcb_seg->attrib.fields.avl = seg->avail;
+ vmcb_seg->attrib.fields.L = seg->long_mode;
+ vmcb_seg->attrib.fields.db = seg->db;
+ vmcb_seg->attrib.fields.G = seg->granularity;
}
void get_vmcb_segment(struct vmcb_selector * vmcb_seg, struct v3_segment * seg) {
- seg->selector = vmcb_seg->selector;
- seg->limit = vmcb_seg->limit;
- seg->base = vmcb_seg->base;
- seg->type = vmcb_seg->attrib.fields.type;
- seg->system = vmcb_seg->attrib.fields.S;
- seg->dpl = vmcb_seg->attrib.fields.dpl;
- seg->present = vmcb_seg->attrib.fields.P;
- seg->avail = vmcb_seg->attrib.fields.avl;
- seg->long_mode = vmcb_seg->attrib.fields.L;
- seg->db = vmcb_seg->attrib.fields.db;
- seg->granularity = vmcb_seg->attrib.fields.G;
+ seg->selector = vmcb_seg->selector;
+ seg->limit = vmcb_seg->limit;
+ seg->base = vmcb_seg->base;
+ seg->type = vmcb_seg->attrib.fields.type;
+ seg->system = vmcb_seg->attrib.fields.S;
+ seg->dpl = vmcb_seg->attrib.fields.dpl;
+ seg->present = vmcb_seg->attrib.fields.P;
+ seg->avail = vmcb_seg->attrib.fields.avl;
+ seg->long_mode = vmcb_seg->attrib.fields.L;
+ seg->db = vmcb_seg->attrib.fields.db;
+ seg->granularity = vmcb_seg->attrib.fields.G;
}
void set_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs) {
- vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb);
-
- set_vmcb_segment(&(guest_area->cs), &(segs->cs));
- set_vmcb_segment(&(guest_area->ds), &(segs->ds));
- set_vmcb_segment(&(guest_area->es), &(segs->es));
- set_vmcb_segment(&(guest_area->fs), &(segs->fs));
- set_vmcb_segment(&(guest_area->gs), &(segs->gs));
- set_vmcb_segment(&(guest_area->ss), &(segs->ss));
- set_vmcb_segment(&(guest_area->ldtr), &(segs->ldtr));
- set_vmcb_segment(&(guest_area->gdtr), &(segs->gdtr));
- set_vmcb_segment(&(guest_area->idtr), &(segs->idtr));
- set_vmcb_segment(&(guest_area->tr), &(segs->tr));
+ vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb);
+
+ set_vmcb_segment(&(guest_area->cs), &(segs->cs));
+ set_vmcb_segment(&(guest_area->ds), &(segs->ds));
+ set_vmcb_segment(&(guest_area->es), &(segs->es));
+ set_vmcb_segment(&(guest_area->fs), &(segs->fs));
+ set_vmcb_segment(&(guest_area->gs), &(segs->gs));
+ set_vmcb_segment(&(guest_area->ss), &(segs->ss));
+ set_vmcb_segment(&(guest_area->ldtr), &(segs->ldtr));
+ set_vmcb_segment(&(guest_area->gdtr), &(segs->gdtr));
+ set_vmcb_segment(&(guest_area->idtr), &(segs->idtr));
+ set_vmcb_segment(&(guest_area->tr), &(segs->tr));
}
void get_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs) {
- vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb);
-
- get_vmcb_segment(&(guest_area->cs), &(segs->cs));
- get_vmcb_segment(&(guest_area->ds), &(segs->ds));
- get_vmcb_segment(&(guest_area->es), &(segs->es));
- get_vmcb_segment(&(guest_area->fs), &(segs->fs));
- get_vmcb_segment(&(guest_area->gs), &(segs->gs));
- get_vmcb_segment(&(guest_area->ss), &(segs->ss));
- get_vmcb_segment(&(guest_area->ldtr), &(segs->ldtr));
- get_vmcb_segment(&(guest_area->gdtr), &(segs->gdtr));
- get_vmcb_segment(&(guest_area->idtr), &(segs->idtr));
- get_vmcb_segment(&(guest_area->tr), &(segs->tr));
+ vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb);
+
+ get_vmcb_segment(&(guest_area->cs), &(segs->cs));
+ get_vmcb_segment(&(guest_area->ds), &(segs->ds));
+ get_vmcb_segment(&(guest_area->es), &(segs->es));
+ get_vmcb_segment(&(guest_area->fs), &(segs->fs));
+ get_vmcb_segment(&(guest_area->gs), &(segs->gs));
+ get_vmcb_segment(&(guest_area->ss), &(segs->ss));
+ get_vmcb_segment(&(guest_area->ldtr), &(segs->ldtr));
+ get_vmcb_segment(&(guest_area->gdtr), &(segs->gdtr));
+ get_vmcb_segment(&(guest_area->idtr), &(segs->idtr));
+ get_vmcb_segment(&(guest_area->tr), &(segs->tr));
}
void PrintDebugVMCB(vmcb_t * vmcb) {
- reg_ex_t tmp_reg;
+ reg_ex_t tmp_reg;
- vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
- vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb);
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
+ vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb);
- PrintDebug("VMCB (0x%p)\n", (void *)vmcb);
+ PrintDebug("VMCB (0x%p)\n", (void *)vmcb);
- PrintDebug("--Control Area--\n");
- PrintDebug("CR Reads: %x\n", *(ushort_t*)&(ctrl_area->cr_reads));
- PrintDebug("CR Writes: %x\n", *(ushort_t*)&(ctrl_area->cr_writes));
- PrintDebug("DR Reads: %x\n", *(ushort_t*)&(ctrl_area->dr_reads));
- PrintDebug("DR Writes: %x\n", *(ushort_t*)&(ctrl_area->dr_writes));
+ PrintDebug("--Control Area--\n");
+ PrintDebug("CR Reads: %x\n", *(ushort_t*)&(ctrl_area->cr_reads));
+ PrintDebug("CR Writes: %x\n", *(ushort_t*)&(ctrl_area->cr_writes));
+ PrintDebug("DR Reads: %x\n", *(ushort_t*)&(ctrl_area->dr_reads));
+ PrintDebug("DR Writes: %x\n", *(ushort_t*)&(ctrl_area->dr_writes));
- PrintDebug("Exception Bitmap: %x (at 0x%p)\n", *(uint_t*)&(ctrl_area->exceptions), (void *)&(ctrl_area->exceptions));
- PrintDebug("\tDivide-by-Zero: %d\n", ctrl_area->exceptions.de);
- PrintDebug("\tDebug: %d\n", ctrl_area->exceptions.db);
- PrintDebug("\tNon-maskable interrupts: %d\n", ctrl_area->exceptions.nmi);
- PrintDebug("\tBreakpoint: %d\n", ctrl_area->exceptions.bp);
- PrintDebug("\tOverflow: %d\n", ctrl_area->exceptions.of);
- PrintDebug("\tBound-Range: %d\n", ctrl_area->exceptions.br);
- PrintDebug("\tInvalid Opcode: %d\n", ctrl_area->exceptions.ud);
- PrintDebug("\tDevice not available: %d\n", ctrl_area->exceptions.nm);
- PrintDebug("\tDouble Fault: %d\n", ctrl_area->exceptions.df);
- PrintDebug("\tInvalid TSS: %d\n", ctrl_area->exceptions.ts);
- PrintDebug("\tSegment not present: %d\n", ctrl_area->exceptions.np);
- PrintDebug("\tStack: %d\n", ctrl_area->exceptions.ss);
- PrintDebug("\tGPF: %d\n", ctrl_area->exceptions.gp);
- PrintDebug("\tPage Fault: %d\n", ctrl_area->exceptions.pf);
- PrintDebug("\tFloating Point: %d\n", ctrl_area->exceptions.mf);
- PrintDebug("\tAlignment Check: %d\n", ctrl_area->exceptions.ac);
- PrintDebug("\tMachine Check: %d\n", ctrl_area->exceptions.mc);
- PrintDebug("\tSIMD floating point: %d\n", ctrl_area->exceptions.xf);
- PrintDebug("\tSecurity: %d\n", ctrl_area->exceptions.sx);
-
- PrintDebug("Instructions bitmap: %.8x (at 0x%p)\n", *(uint_t*)&(ctrl_area->instrs), &(ctrl_area->instrs));
- PrintDebug("\tINTR: %d\n", ctrl_area->instrs.INTR);
- PrintDebug("\tNMI: %d\n", ctrl_area->instrs.NMI);
- PrintDebug("\tSMI: %d\n", ctrl_area->instrs.SMI);
- PrintDebug("\tINIT: %d\n", ctrl_area->instrs.INIT);
- PrintDebug("\tVINTR: %d\n", ctrl_area->instrs.VINTR);
- PrintDebug("\tCR0: %d\n", ctrl_area->instrs.CR0);
- PrintDebug("\tRD_IDTR: %d\n", ctrl_area->instrs.RD_IDTR);
- PrintDebug("\tRD_GDTR: %d\n", ctrl_area->instrs.RD_GDTR);
- PrintDebug("\tRD_LDTR: %d\n", ctrl_area->instrs.RD_LDTR);
- PrintDebug("\tRD_TR: %d\n", ctrl_area->instrs.RD_TR);
- PrintDebug("\tWR_IDTR: %d\n", ctrl_area->instrs.WR_IDTR);
- PrintDebug("\tWR_GDTR: %d\n", ctrl_area->instrs.WR_GDTR);
- PrintDebug("\tWR_LDTR: %d\n", ctrl_area->instrs.WR_LDTR);
- PrintDebug("\tWR_TR: %d\n", ctrl_area->instrs.WR_TR);
- PrintDebug("\tRDTSC: %d\n", ctrl_area->instrs.RDTSC);
- PrintDebug("\tRDPMC: %d\n", ctrl_area->instrs.RDPMC);
- PrintDebug("\tPUSHF: %d\n", ctrl_area->instrs.PUSHF);
- PrintDebug("\tPOPF: %d\n", ctrl_area->instrs.POPF);
- PrintDebug("\tCPUID: %d\n", ctrl_area->instrs.CPUID);
- PrintDebug("\tRSM: %d\n", ctrl_area->instrs.RSM);
- PrintDebug("\tIRET: %d\n", ctrl_area->instrs.IRET);
- PrintDebug("\tINTn: %d\n", ctrl_area->instrs.INTn);
- PrintDebug("\tINVD: %d\n", ctrl_area->instrs.INVD);
- PrintDebug("\tPAUSE: %d\n", ctrl_area->instrs.PAUSE);
- PrintDebug("\tHLT: %d\n", ctrl_area->instrs.HLT);
- PrintDebug("\tINVLPG: %d\n", ctrl_area->instrs.INVLPG);
- PrintDebug("\tINVLPGA: %d\n", ctrl_area->instrs.INVLPGA);
- PrintDebug("\tIOIO_PROT: %d\n", ctrl_area->instrs.IOIO_PROT);
- PrintDebug("\tMSR_PROT: %d\n", ctrl_area->instrs.MSR_PROT);
- PrintDebug("\ttask_switch: %d\n", ctrl_area->instrs.task_switch);
- PrintDebug("\tFERR_FREEZE: %d\n", ctrl_area->instrs.FERR_FREEZE);
- PrintDebug("\tshutdown_evts: %d\n", ctrl_area->instrs.shutdown_evts);
-
- PrintDebug("SVM Instruction Bitmap: %x (at 0x%p)\n", *(uint_t*)&(ctrl_area->svm_instrs), &(ctrl_area->svm_instrs));
- PrintDebug("\tVMRUN: %d\n", ctrl_area->svm_instrs.VMRUN);
- PrintDebug("\tVMMCALL: %d\n", ctrl_area->svm_instrs.VMMCALL);
- PrintDebug("\tVMLOAD: %d\n", ctrl_area->svm_instrs.VMLOAD);
- PrintDebug("\tVMSAVE: %d\n", ctrl_area->svm_instrs.VMSAVE);
- PrintDebug("\tSTGI: %d\n", ctrl_area->svm_instrs.STGI);
- PrintDebug("\tCLGI: %d\n", ctrl_area->svm_instrs.CLGI);
- PrintDebug("\tSKINIT: %d\n", ctrl_area->svm_instrs.SKINIT);
- PrintDebug("\tRDTSCP: %d\n", ctrl_area->svm_instrs.RDTSCP);
- PrintDebug("\tICEBP: %d\n", ctrl_area->svm_instrs.ICEBP);
- PrintDebug("\tWBINVD: %d\n", ctrl_area->svm_instrs.WBINVD);
- PrintDebug("\tMONITOR: %d\n", ctrl_area->svm_instrs.MONITOR);
- PrintDebug("\tMWAIT_always: %d\n", ctrl_area->svm_instrs.MWAIT_always);
- PrintDebug("\tMWAIT_if_armed: %d\n", ctrl_area->svm_instrs.MWAIT_if_armed);
-
-
-
- tmp_reg.r_reg = ctrl_area->IOPM_BASE_PA;
- PrintDebug("IOPM_BASE_PA: lo: 0x%x, hi: 0x%x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high);
- tmp_reg.r_reg = ctrl_area->MSRPM_BASE_PA;
- PrintDebug("MSRPM_BASE_PA: lo: 0x%x, hi: 0x%x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high);
- tmp_reg.r_reg = ctrl_area->TSC_OFFSET;
- PrintDebug("TSC_OFFSET: lo: 0x%x, hi: 0x%x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high);
-
- PrintDebug("guest_ASID: %d\n", ctrl_area->guest_ASID);
- PrintDebug("TLB_CONTROL: %d\n", ctrl_area->TLB_CONTROL);
-
-
- PrintDebug("Guest Control Bitmap: %x (at 0x%p)\n", *(uint_t*)&(ctrl_area->guest_ctrl), &(ctrl_area->guest_ctrl));
- PrintDebug("\tV_TPR: %d\n", ctrl_area->guest_ctrl.V_TPR);
- PrintDebug("\tV_IRQ: %d\n", ctrl_area->guest_ctrl.V_IRQ);
- PrintDebug("\tV_INTR_PRIO: %d\n", ctrl_area->guest_ctrl.V_INTR_PRIO);
- PrintDebug("\tV_IGN_TPR: %d\n", ctrl_area->guest_ctrl.V_IGN_TPR);
- PrintDebug("\tV_INTR_MASKING: %d\n", ctrl_area->guest_ctrl.V_INTR_MASKING);
- PrintDebug("\tV_INTR_VECTOR: %d\n", ctrl_area->guest_ctrl.V_INTR_VECTOR);
-
- PrintDebug("Interrupt_shadow: %d\n", ctrl_area->interrupt_shadow);
-
-
- tmp_reg.r_reg = ctrl_area->exit_code;
- PrintDebug("exit_code: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = ctrl_area->exit_info1;
- PrintDebug("exit_info1: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = ctrl_area->exit_info2;
- PrintDebug("exit_info2: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("Exit Int Info: (at 0x%p)\n", &(ctrl_area->exit_int_info));
- PrintDebug("Vector: %d\n", ctrl_area->exit_int_info.vector);
- PrintDebug("(type=%d) (ev=%d) (valid=%d)\n", ctrl_area->exit_int_info.type,
- ctrl_area->exit_int_info.ev, ctrl_area->exit_int_info.valid);
- PrintDebug("Error Code: %d\n", ctrl_area->exit_int_info.error_code);
-
-
- tmp_reg.r_reg = ctrl_area->NP_ENABLE;
- PrintDebug("NP_ENABLE: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
- PrintDebug("Event Injection: (at 0x%p)\n", &(ctrl_area->EVENTINJ));
- PrintDebug("Vector: %d\n", ctrl_area->EVENTINJ.vector);
- PrintDebug("(type=%d) (ev=%d) (valid=%d)\n", ctrl_area->EVENTINJ.type,
- ctrl_area->EVENTINJ.ev, ctrl_area->EVENTINJ.valid);
- PrintDebug("Error Code: %d\n", ctrl_area->EVENTINJ.error_code);
-
-
- tmp_reg.r_reg = ctrl_area->N_CR3;
- PrintDebug("N_CR3: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
- PrintDebug("LBR_VIRTUALIZATION_ENABLE: %d\n", ctrl_area->LBR_VIRTUALIZATION_ENABLE);
-
-
- PrintDebug("\n--Guest Saved State--\n");
-
- PrintDebug("es Selector (at 0x%p): \n", &(guest_area->es));
- PrintDebug("\tSelector: %d\n", guest_area->es.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->es.attrib.fields.type, guest_area->es.attrib.fields.S,
- guest_area->es.attrib.fields.dpl, guest_area->es.attrib.fields.P,
- guest_area->es.attrib.fields.avl, guest_area->es.attrib.fields.L,
- guest_area->es.attrib.fields.db, guest_area->es.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->es.limit);
- tmp_reg.r_reg = guest_area->es.base;
- PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("cs Selector (at 0x%p): \n", &(guest_area->cs));
- PrintDebug("\tSelector: %d\n", guest_area->cs.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->cs.attrib.fields.type, guest_area->cs.attrib.fields.S,
- guest_area->cs.attrib.fields.dpl, guest_area->cs.attrib.fields.P,
- guest_area->cs.attrib.fields.avl, guest_area->cs.attrib.fields.L,
- guest_area->cs.attrib.fields.db, guest_area->cs.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->cs.limit);
- tmp_reg.r_reg = guest_area->cs.base;
- PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("ss Selector (at 0x%p): \n", &(guest_area->ss));
- PrintDebug("\tSelector: %d\n", guest_area->ss.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->ss.attrib.fields.type, guest_area->ss.attrib.fields.S,
- guest_area->ss.attrib.fields.dpl, guest_area->ss.attrib.fields.P,
- guest_area->ss.attrib.fields.avl, guest_area->ss.attrib.fields.L,
- guest_area->ss.attrib.fields.db, guest_area->ss.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->ss.limit);
- tmp_reg.r_reg = guest_area->ss.base;
- PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("ds Selector (at 0x%p): \n", &(guest_area->ds));
- PrintDebug("\tSelector: %d\n", guest_area->ds.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->ds.attrib.fields.type, guest_area->ds.attrib.fields.S,
- guest_area->ds.attrib.fields.dpl, guest_area->ds.attrib.fields.P,
- guest_area->ds.attrib.fields.avl, guest_area->ds.attrib.fields.L,
- guest_area->ds.attrib.fields.db, guest_area->ds.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->ds.limit);
- tmp_reg.r_reg = guest_area->ds.base;
- PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("fs Selector (at 0x%p): \n", &(guest_area->fs));
- PrintDebug("\tSelector: %d\n", guest_area->fs.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->fs.attrib.fields.type, guest_area->fs.attrib.fields.S,
- guest_area->fs.attrib.fields.dpl, guest_area->fs.attrib.fields.P,
- guest_area->fs.attrib.fields.avl, guest_area->fs.attrib.fields.L,
- guest_area->fs.attrib.fields.db, guest_area->fs.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->fs.limit);
- tmp_reg.r_reg = guest_area->fs.base;
- PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("gs Selector (at 0x%p): \n", &(guest_area->gs));
- PrintDebug("\tSelector: %d\n", guest_area->gs.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->gs.attrib.fields.type, guest_area->gs.attrib.fields.S,
- guest_area->gs.attrib.fields.dpl, guest_area->gs.attrib.fields.P,
- guest_area->gs.attrib.fields.avl, guest_area->gs.attrib.fields.L,
- guest_area->gs.attrib.fields.db, guest_area->gs.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->gs.limit);
- tmp_reg.r_reg = guest_area->gs.base;
- PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("gdtr Selector (at 0x%p): \n", &(guest_area->gdtr));
- PrintDebug("\tSelector: %d\n", guest_area->gdtr.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->gdtr.attrib.fields.type, guest_area->gdtr.attrib.fields.S,
- guest_area->gdtr.attrib.fields.dpl, guest_area->gdtr.attrib.fields.P,
- guest_area->gdtr.attrib.fields.avl, guest_area->gdtr.attrib.fields.L,
- guest_area->gdtr.attrib.fields.db, guest_area->gdtr.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->gdtr.limit);
- tmp_reg.r_reg = guest_area->gdtr.base;
- PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("ldtr Selector (at 0x%p): \n", &(guest_area->ldtr));
- PrintDebug("\tSelector: %d\n", guest_area->ldtr.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->ldtr.attrib.fields.type, guest_area->ldtr.attrib.fields.S,
- guest_area->ldtr.attrib.fields.dpl, guest_area->ldtr.attrib.fields.P,
- guest_area->ldtr.attrib.fields.avl, guest_area->ldtr.attrib.fields.L,
- guest_area->ldtr.attrib.fields.db, guest_area->ldtr.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->ldtr.limit);
- tmp_reg.r_reg = guest_area->ldtr.base;
- PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("idtr Selector (at 0x%p): \n", &(guest_area->idtr));
- PrintDebug("\tSelector: %d\n", guest_area->idtr.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->idtr.attrib.fields.type, guest_area->idtr.attrib.fields.S,
- guest_area->idtr.attrib.fields.dpl, guest_area->idtr.attrib.fields.P,
- guest_area->idtr.attrib.fields.avl, guest_area->idtr.attrib.fields.L,
- guest_area->idtr.attrib.fields.db, guest_area->idtr.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->idtr.limit);
- tmp_reg.r_reg = guest_area->idtr.base;
- PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("tr Selector (at 0x%p): \n", &(guest_area->tr));
- PrintDebug("\tSelector: %d\n", guest_area->tr.selector);
- PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
- guest_area->tr.attrib.fields.type, guest_area->tr.attrib.fields.S,
- guest_area->tr.attrib.fields.dpl, guest_area->tr.attrib.fields.P,
- guest_area->tr.attrib.fields.avl, guest_area->tr.attrib.fields.L,
- guest_area->tr.attrib.fields.db, guest_area->tr.attrib.fields.G);
- PrintDebug("\tlimit: %u\n", guest_area->tr.limit);
- tmp_reg.r_reg = guest_area->tr.base;
- PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- PrintDebug("cpl: %d\n", guest_area->cpl);
+ PrintDebug("Exception Bitmap: %x (at 0x%p)\n", *(uint_t*)&(ctrl_area->exceptions), (void *)&(ctrl_area->exceptions));
+ PrintDebug("\tDivide-by-Zero: %d\n", ctrl_area->exceptions.de);
+ PrintDebug("\tDebug: %d\n", ctrl_area->exceptions.db);
+ PrintDebug("\tNon-maskable interrupts: %d\n", ctrl_area->exceptions.nmi);
+ PrintDebug("\tBreakpoint: %d\n", ctrl_area->exceptions.bp);
+ PrintDebug("\tOverflow: %d\n", ctrl_area->exceptions.of);
+ PrintDebug("\tBound-Range: %d\n", ctrl_area->exceptions.br);
+ PrintDebug("\tInvalid Opcode: %d\n", ctrl_area->exceptions.ud);
+ PrintDebug("\tDevice not available: %d\n", ctrl_area->exceptions.nm);
+ PrintDebug("\tDouble Fault: %d\n", ctrl_area->exceptions.df);
+ PrintDebug("\tInvalid TSS: %d\n", ctrl_area->exceptions.ts);
+ PrintDebug("\tSegment not present: %d\n", ctrl_area->exceptions.np);
+ PrintDebug("\tStack: %d\n", ctrl_area->exceptions.ss);
+ PrintDebug("\tGPF: %d\n", ctrl_area->exceptions.gp);
+ PrintDebug("\tPage Fault: %d\n", ctrl_area->exceptions.pf);
+ PrintDebug("\tFloating Point: %d\n", ctrl_area->exceptions.mf);
+ PrintDebug("\tAlignment Check: %d\n", ctrl_area->exceptions.ac);
+ PrintDebug("\tMachine Check: %d\n", ctrl_area->exceptions.mc);
+ PrintDebug("\tSIMD floating point: %d\n", ctrl_area->exceptions.xf);
+ PrintDebug("\tSecurity: %d\n", ctrl_area->exceptions.sx);
+
+ PrintDebug("Instructions bitmap: %.8x (at 0x%p)\n", *(uint_t*)&(ctrl_area->instrs), &(ctrl_area->instrs));
+ PrintDebug("\tINTR: %d\n", ctrl_area->instrs.INTR);
+ PrintDebug("\tNMI: %d\n", ctrl_area->instrs.NMI);
+ PrintDebug("\tSMI: %d\n", ctrl_area->instrs.SMI);
+ PrintDebug("\tINIT: %d\n", ctrl_area->instrs.INIT);
+ PrintDebug("\tVINTR: %d\n", ctrl_area->instrs.VINTR);
+ PrintDebug("\tCR0: %d\n", ctrl_area->instrs.CR0);
+ PrintDebug("\tRD_IDTR: %d\n", ctrl_area->instrs.RD_IDTR);
+ PrintDebug("\tRD_GDTR: %d\n", ctrl_area->instrs.RD_GDTR);
+ PrintDebug("\tRD_LDTR: %d\n", ctrl_area->instrs.RD_LDTR);
+ PrintDebug("\tRD_TR: %d\n", ctrl_area->instrs.RD_TR);
+ PrintDebug("\tWR_IDTR: %d\n", ctrl_area->instrs.WR_IDTR);
+ PrintDebug("\tWR_GDTR: %d\n", ctrl_area->instrs.WR_GDTR);
+ PrintDebug("\tWR_LDTR: %d\n", ctrl_area->instrs.WR_LDTR);
+ PrintDebug("\tWR_TR: %d\n", ctrl_area->instrs.WR_TR);
+ PrintDebug("\tRDTSC: %d\n", ctrl_area->instrs.RDTSC);
+ PrintDebug("\tRDPMC: %d\n", ctrl_area->instrs.RDPMC);
+ PrintDebug("\tPUSHF: %d\n", ctrl_area->instrs.PUSHF);
+ PrintDebug("\tPOPF: %d\n", ctrl_area->instrs.POPF);
+ PrintDebug("\tCPUID: %d\n", ctrl_area->instrs.CPUID);
+ PrintDebug("\tRSM: %d\n", ctrl_area->instrs.RSM);
+ PrintDebug("\tIRET: %d\n", ctrl_area->instrs.IRET);
+ PrintDebug("\tINTn: %d\n", ctrl_area->instrs.INTn);
+ PrintDebug("\tINVD: %d\n", ctrl_area->instrs.INVD);
+ PrintDebug("\tPAUSE: %d\n", ctrl_area->instrs.PAUSE);
+ PrintDebug("\tHLT: %d\n", ctrl_area->instrs.HLT);
+ PrintDebug("\tINVLPG: %d\n", ctrl_area->instrs.INVLPG);
+ PrintDebug("\tINVLPGA: %d\n", ctrl_area->instrs.INVLPGA);
+ PrintDebug("\tIOIO_PROT: %d\n", ctrl_area->instrs.IOIO_PROT);
+ PrintDebug("\tMSR_PROT: %d\n", ctrl_area->instrs.MSR_PROT);
+ PrintDebug("\ttask_switch: %d\n", ctrl_area->instrs.task_switch);
+ PrintDebug("\tFERR_FREEZE: %d\n", ctrl_area->instrs.FERR_FREEZE);
+ PrintDebug("\tshutdown_evts: %d\n", ctrl_area->instrs.shutdown_evts);
+
+ PrintDebug("SVM Instruction Bitmap: %x (at 0x%p)\n", *(uint_t*)&(ctrl_area->svm_instrs), &(ctrl_area->svm_instrs));
+ PrintDebug("\tVMRUN: %d\n", ctrl_area->svm_instrs.VMRUN);
+ PrintDebug("\tVMMCALL: %d\n", ctrl_area->svm_instrs.VMMCALL);
+ PrintDebug("\tVMLOAD: %d\n", ctrl_area->svm_instrs.VMLOAD);
+ PrintDebug("\tVMSAVE: %d\n", ctrl_area->svm_instrs.VMSAVE);
+ PrintDebug("\tSTGI: %d\n", ctrl_area->svm_instrs.STGI);
+ PrintDebug("\tCLGI: %d\n", ctrl_area->svm_instrs.CLGI);
+ PrintDebug("\tSKINIT: %d\n", ctrl_area->svm_instrs.SKINIT);
+ PrintDebug("\tRDTSCP: %d\n", ctrl_area->svm_instrs.RDTSCP);
+ PrintDebug("\tICEBP: %d\n", ctrl_area->svm_instrs.ICEBP);
+ PrintDebug("\tWBINVD: %d\n", ctrl_area->svm_instrs.WBINVD);
+ PrintDebug("\tMONITOR: %d\n", ctrl_area->svm_instrs.MONITOR);
+ PrintDebug("\tMWAIT_always: %d\n", ctrl_area->svm_instrs.MWAIT_always);
+ PrintDebug("\tMWAIT_if_armed: %d\n", ctrl_area->svm_instrs.MWAIT_if_armed);
+
+
+
+ tmp_reg.r_reg = ctrl_area->IOPM_BASE_PA;
+ PrintDebug("IOPM_BASE_PA: lo: 0x%x, hi: 0x%x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high);
+ tmp_reg.r_reg = ctrl_area->MSRPM_BASE_PA;
+ PrintDebug("MSRPM_BASE_PA: lo: 0x%x, hi: 0x%x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high);
+ tmp_reg.r_reg = ctrl_area->TSC_OFFSET;
+ PrintDebug("TSC_OFFSET: lo: 0x%x, hi: 0x%x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high);
+
+ PrintDebug("guest_ASID: %d\n", ctrl_area->guest_ASID);
+ PrintDebug("TLB_CONTROL: %d\n", ctrl_area->TLB_CONTROL);
+
+
+ PrintDebug("Guest Control Bitmap: %x (at 0x%p)\n", *(uint_t*)&(ctrl_area->guest_ctrl), &(ctrl_area->guest_ctrl));
+ PrintDebug("\tV_TPR: %d\n", ctrl_area->guest_ctrl.V_TPR);
+ PrintDebug("\tV_IRQ: %d\n", ctrl_area->guest_ctrl.V_IRQ);
+ PrintDebug("\tV_INTR_PRIO: %d\n", ctrl_area->guest_ctrl.V_INTR_PRIO);
+ PrintDebug("\tV_IGN_TPR: %d\n", ctrl_area->guest_ctrl.V_IGN_TPR);
+ PrintDebug("\tV_INTR_MASKING: %d\n", ctrl_area->guest_ctrl.V_INTR_MASKING);
+ PrintDebug("\tV_INTR_VECTOR: %d\n", ctrl_area->guest_ctrl.V_INTR_VECTOR);
+
+ PrintDebug("Interrupt_shadow: %d\n", ctrl_area->interrupt_shadow);
+
+
+ tmp_reg.r_reg = ctrl_area->exit_code;
+ PrintDebug("exit_code: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = ctrl_area->exit_info1;
+ PrintDebug("exit_info1: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = ctrl_area->exit_info2;
+ PrintDebug("exit_info2: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("Exit Int Info: (at 0x%p)\n", &(ctrl_area->exit_int_info));
+ PrintDebug("Vector: %d\n", ctrl_area->exit_int_info.vector);
+ PrintDebug("(type=%d) (ev=%d) (valid=%d)\n", ctrl_area->exit_int_info.type,
+ ctrl_area->exit_int_info.ev, ctrl_area->exit_int_info.valid);
+ PrintDebug("Error Code: %d\n", ctrl_area->exit_int_info.error_code);
+
+
+ tmp_reg.r_reg = ctrl_area->NP_ENABLE;
+ PrintDebug("NP_ENABLE: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+ PrintDebug("Event Injection: (at 0x%p)\n", &(ctrl_area->EVENTINJ));
+ PrintDebug("Vector: %d\n", ctrl_area->EVENTINJ.vector);
+ PrintDebug("(type=%d) (ev=%d) (valid=%d)\n", ctrl_area->EVENTINJ.type,
+ ctrl_area->EVENTINJ.ev, ctrl_area->EVENTINJ.valid);
+ PrintDebug("Error Code: %d\n", ctrl_area->EVENTINJ.error_code);
+
+
+ tmp_reg.r_reg = ctrl_area->N_CR3;
+ PrintDebug("N_CR3: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+ PrintDebug("LBR_VIRTUALIZATION_ENABLE: %d\n", ctrl_area->LBR_VIRTUALIZATION_ENABLE);
+
+
+ PrintDebug("\n--Guest Saved State--\n");
+
+ PrintDebug("es Selector (at 0x%p): \n", &(guest_area->es));
+ PrintDebug("\tSelector: %d\n", guest_area->es.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->es.attrib.fields.type, guest_area->es.attrib.fields.S,
+ guest_area->es.attrib.fields.dpl, guest_area->es.attrib.fields.P,
+ guest_area->es.attrib.fields.avl, guest_area->es.attrib.fields.L,
+ guest_area->es.attrib.fields.db, guest_area->es.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->es.limit);
+ tmp_reg.r_reg = guest_area->es.base;
+ PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("cs Selector (at 0x%p): \n", &(guest_area->cs));
+ PrintDebug("\tSelector: %d\n", guest_area->cs.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->cs.attrib.fields.type, guest_area->cs.attrib.fields.S,
+ guest_area->cs.attrib.fields.dpl, guest_area->cs.attrib.fields.P,
+ guest_area->cs.attrib.fields.avl, guest_area->cs.attrib.fields.L,
+ guest_area->cs.attrib.fields.db, guest_area->cs.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->cs.limit);
+ tmp_reg.r_reg = guest_area->cs.base;
+ PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("ss Selector (at 0x%p): \n", &(guest_area->ss));
+ PrintDebug("\tSelector: %d\n", guest_area->ss.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->ss.attrib.fields.type, guest_area->ss.attrib.fields.S,
+ guest_area->ss.attrib.fields.dpl, guest_area->ss.attrib.fields.P,
+ guest_area->ss.attrib.fields.avl, guest_area->ss.attrib.fields.L,
+ guest_area->ss.attrib.fields.db, guest_area->ss.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->ss.limit);
+ tmp_reg.r_reg = guest_area->ss.base;
+ PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("ds Selector (at 0x%p): \n", &(guest_area->ds));
+ PrintDebug("\tSelector: %d\n", guest_area->ds.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->ds.attrib.fields.type, guest_area->ds.attrib.fields.S,
+ guest_area->ds.attrib.fields.dpl, guest_area->ds.attrib.fields.P,
+ guest_area->ds.attrib.fields.avl, guest_area->ds.attrib.fields.L,
+ guest_area->ds.attrib.fields.db, guest_area->ds.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->ds.limit);
+ tmp_reg.r_reg = guest_area->ds.base;
+ PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("fs Selector (at 0x%p): \n", &(guest_area->fs));
+ PrintDebug("\tSelector: %d\n", guest_area->fs.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->fs.attrib.fields.type, guest_area->fs.attrib.fields.S,
+ guest_area->fs.attrib.fields.dpl, guest_area->fs.attrib.fields.P,
+ guest_area->fs.attrib.fields.avl, guest_area->fs.attrib.fields.L,
+ guest_area->fs.attrib.fields.db, guest_area->fs.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->fs.limit);
+ tmp_reg.r_reg = guest_area->fs.base;
+ PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("gs Selector (at 0x%p): \n", &(guest_area->gs));
+ PrintDebug("\tSelector: %d\n", guest_area->gs.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->gs.attrib.fields.type, guest_area->gs.attrib.fields.S,
+ guest_area->gs.attrib.fields.dpl, guest_area->gs.attrib.fields.P,
+ guest_area->gs.attrib.fields.avl, guest_area->gs.attrib.fields.L,
+ guest_area->gs.attrib.fields.db, guest_area->gs.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->gs.limit);
+ tmp_reg.r_reg = guest_area->gs.base;
+ PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("gdtr Selector (at 0x%p): \n", &(guest_area->gdtr));
+ PrintDebug("\tSelector: %d\n", guest_area->gdtr.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->gdtr.attrib.fields.type, guest_area->gdtr.attrib.fields.S,
+ guest_area->gdtr.attrib.fields.dpl, guest_area->gdtr.attrib.fields.P,
+ guest_area->gdtr.attrib.fields.avl, guest_area->gdtr.attrib.fields.L,
+ guest_area->gdtr.attrib.fields.db, guest_area->gdtr.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->gdtr.limit);
+ tmp_reg.r_reg = guest_area->gdtr.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("ldtr Selector (at 0x%p): \n", &(guest_area->ldtr));
+ PrintDebug("\tSelector: %d\n", guest_area->ldtr.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->ldtr.attrib.fields.type, guest_area->ldtr.attrib.fields.S,
+ guest_area->ldtr.attrib.fields.dpl, guest_area->ldtr.attrib.fields.P,
+ guest_area->ldtr.attrib.fields.avl, guest_area->ldtr.attrib.fields.L,
+ guest_area->ldtr.attrib.fields.db, guest_area->ldtr.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->ldtr.limit);
+ tmp_reg.r_reg = guest_area->ldtr.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("idtr Selector (at 0x%p): \n", &(guest_area->idtr));
+ PrintDebug("\tSelector: %d\n", guest_area->idtr.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->idtr.attrib.fields.type, guest_area->idtr.attrib.fields.S,
+ guest_area->idtr.attrib.fields.dpl, guest_area->idtr.attrib.fields.P,
+ guest_area->idtr.attrib.fields.avl, guest_area->idtr.attrib.fields.L,
+ guest_area->idtr.attrib.fields.db, guest_area->idtr.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->idtr.limit);
+ tmp_reg.r_reg = guest_area->idtr.base;
+ PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("tr Selector (at 0x%p): \n", &(guest_area->tr));
+ PrintDebug("\tSelector: %d\n", guest_area->tr.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->tr.attrib.fields.type, guest_area->tr.attrib.fields.S,
+ guest_area->tr.attrib.fields.dpl, guest_area->tr.attrib.fields.P,
+ guest_area->tr.attrib.fields.avl, guest_area->tr.attrib.fields.L,
+ guest_area->tr.attrib.fields.db, guest_area->tr.attrib.fields.G);
+ PrintDebug("\tlimit: %u\n", guest_area->tr.limit);
+ tmp_reg.r_reg = guest_area->tr.base;
+ PrintDebug("\tBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("cpl: %d\n", guest_area->cpl);
- tmp_reg.r_reg = guest_area->efer;
- PrintDebug("EFER: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
- tmp_reg.r_reg = guest_area->cr4;
- PrintDebug("CR4: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->cr3;
- PrintDebug("CR3: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->cr0;
- PrintDebug("CR0: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->dr7;
- PrintDebug("DR7: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->dr6;
- PrintDebug("DR6: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->rflags;
- PrintDebug("RFLAGS: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->rip;
- PrintDebug("RIP: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
- tmp_reg.r_reg = guest_area->rsp;
- PrintDebug("RSP: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->efer;
+ PrintDebug("EFER: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+ tmp_reg.r_reg = guest_area->cr4;
+ PrintDebug("CR4: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->cr3;
+ PrintDebug("CR3: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->cr0;
+ PrintDebug("CR0: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->dr7;
+ PrintDebug("DR7: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->dr6;
+ PrintDebug("DR6: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->rflags;
+ PrintDebug("RFLAGS: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->rip;
+ PrintDebug("RIP: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ tmp_reg.r_reg = guest_area->rsp;
+ PrintDebug("RSP: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->rax;
- PrintDebug("RAX: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->star;
- PrintDebug("STAR: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->lstar;
- PrintDebug("LSTAR: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->cstar;
- PrintDebug("CSTAR: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->sfmask;
- PrintDebug("SFMASK: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->KernelGsBase;
- PrintDebug("KernelGsBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->sysenter_cs;
- PrintDebug("sysenter_cs: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->sysenter_esp;
- PrintDebug("sysenter_esp: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->sysenter_eip;
- PrintDebug("sysenter_eip: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->cr2;
- PrintDebug("CR2: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
- tmp_reg.r_reg = guest_area->g_pat;
- PrintDebug("g_pat: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->dbgctl;
- PrintDebug("dbgctl: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->br_from;
- PrintDebug("br_from: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->br_to;
- PrintDebug("br_to: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->lastexcpfrom;
- PrintDebug("lastexcpfrom: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = guest_area->lastexcpto;
- PrintDebug("lastexcpto: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
-
-
-
-
-
-
+ tmp_reg.r_reg = guest_area->rax;
+ PrintDebug("RAX: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->star;
+ PrintDebug("STAR: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->lstar;
+ PrintDebug("LSTAR: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->cstar;
+ PrintDebug("CSTAR: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->sfmask;
+ PrintDebug("SFMASK: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->KernelGsBase;
+ PrintDebug("KernelGsBase: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->sysenter_cs;
+ PrintDebug("sysenter_cs: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->sysenter_esp;
+ PrintDebug("sysenter_esp: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->sysenter_eip;
+ PrintDebug("sysenter_eip: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->cr2;
+ PrintDebug("CR2: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+ tmp_reg.r_reg = guest_area->g_pat;
+ PrintDebug("g_pat: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->dbgctl;
+ PrintDebug("dbgctl: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->br_from;
+ PrintDebug("br_from: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->br_to;
+ PrintDebug("br_to: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->lastexcpfrom;
+ PrintDebug("lastexcpfrom: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->lastexcpto;
+ PrintDebug("lastexcpto: hi: 0x%x, lo: 0x%x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
}
static struct guest_info * allocate_guest() {
- void * info = V3_Malloc(sizeof(struct guest_info));
- memset(info, 0, sizeof(struct guest_info));
- return info;
+ void * info = V3_Malloc(sizeof(struct guest_info));
+ memset(info, 0, sizeof(struct guest_info));
+ return info;
}
void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops) {
- os_hooks = hooks;
+ os_hooks = hooks;
- v3_cpu_type = V3_INVALID_CPU;
+ v3_cpu_type = V3_INVALID_CPU;
#ifdef INSTRUMENT_VMM
- v3_init_instrumentation();
+ v3_init_instrumentation();
#endif
- if (v3_is_svm_capable()) {
-
- PrintDebug("Machine is SVM Capable\n");
- vmm_ops->allocate_guest = &allocate_guest;
- vmm_ops->config_guest = &v3_config_guest;
- v3_init_SVM(vmm_ops);
-
- /*
- } else if (is_vmx_capable()) {
- vmm_cpu_type = VMM_VMX_CPU;
- PrintDebug("Machine is VMX Capable\n");
- //Init_VMX();*/
- } else {
- PrintDebug("CPU has no virtualization Extensions\n");
- }
+ if (v3_is_svm_capable()) {
+
+ PrintDebug("Machine is SVM Capable\n");
+ vmm_ops->allocate_guest = &allocate_guest;
+ vmm_ops->config_guest = &v3_config_guest;
+ v3_init_SVM(vmm_ops);
+
+ /*
+ } else if (is_vmx_capable()) {
+ vmm_cpu_type = VMM_VMX_CPU;
+ PrintDebug("Machine is VMX Capable\n");
+ //Init_VMX();*/
+ } else {
+ PrintDebug("CPU has no virtualization Extensions\n");
+ }
}
static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
- return length;
- // memcpy((void*)guest_addr, src, length);
- PrintDebug("Write of %d bytes to %p\n", length, (void *)guest_addr);
- PrintDebug("Write Value = %p\n", (void *)*(addr_t *)src);
-
- return length;
+ return length;
+ // memcpy((void*)guest_addr, src, length);
+ PrintDebug("Write of %d bytes to %p\n", length, (void *)guest_addr);
+ PrintDebug("Write Value = %p\n", (void *)*(addr_t *)src);
+
+ return length;
}
int v3_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
- extern v3_cpu_arch_t v3_cpu_type;
-
- // Initialize the subsystem data strutures
- v3_init_time(info);
- v3_init_io_map(info);
- v3_init_msr_map(info);
- v3_init_interrupt_state(info);
- v3_init_dev_mgr(info);
- v3_init_host_events(info);
-
- v3_init_decoder(info);
-
- v3_init_shadow_map(info);
-
- v3_init_hypercall_map(info);
-
-
- if (v3_cpu_type == V3_SVM_REV3_CPU) {
- info->shdw_pg_mode = NESTED_PAGING;
- } else {
- v3_init_shadow_page_state(info);
- info->shdw_pg_mode = SHADOW_PAGING;
- }
+ extern v3_cpu_arch_t v3_cpu_type;
+
+ // Initialize the subsystem data strutures
+ v3_init_time(info);
+ v3_init_io_map(info);
+ v3_init_msr_map(info);
+ v3_init_interrupt_state(info);
+ v3_init_dev_mgr(info);
+ v3_init_host_events(info);
+
+ v3_init_decoder(info);
+
+ v3_init_shadow_map(info);
+
+ v3_init_hypercall_map(info);
+
- // Initial CPU operating mode
- info->cpu_mode = REAL;
- info->mem_mode = PHYSICAL_MEM;
-
- // Amount of ram the Guest will have, rounded to a 4K page boundary
- info->mem_size = config_ptr->mem_size & ~(addr_t)0xfff;
-
- // Configure the memory map for the guest
- if (setup_memory_map(info, config_ptr) == -1) {
- PrintError("Setting up guest memory map failed...\n");
- return -1;
- }
-
- // Configure the devices for the guest
- setup_devices(info, config_ptr);
-
-
+ if (v3_cpu_type == V3_SVM_REV3_CPU) {
+ info->shdw_pg_mode = NESTED_PAGING;
+ } else {
+ v3_init_shadow_page_state(info);
+ info->shdw_pg_mode = SHADOW_PAGING;
+ }
+
+ // Initial CPU operating mode
+ info->cpu_mode = REAL;
+ info->mem_mode = PHYSICAL_MEM;
+
+ // Amount of ram the Guest will have, rounded to a 4K page boundary
+ info->mem_size = config_ptr->mem_size & ~(addr_t)0xfff;
+
+ // Configure the memory map for the guest
+ if (setup_memory_map(info, config_ptr) == -1) {
+ PrintError("Setting up guest memory map failed...\n");
+ return -1;
+ }
+
+ // Configure the devices for the guest
+ setup_devices(info, config_ptr);
+
- if (config_ptr->enable_profiling) {
- info->enable_profiler = 1;
- v3_init_profiler(info);
- } else {
- info->enable_profiler = 0;
- }
- //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
+ if (config_ptr->enable_profiling) {
+ info->enable_profiler = 1;
+ v3_init_profiler(info);
+ } else {
+ info->enable_profiler = 0;
+ }
- // Setup initial cpu register state
- info->rip = 0xfff0;
- info->vm_regs.rsp = 0x0;
+ //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
+
+ // Setup initial cpu register state
+ info->rip = 0xfff0;
+ info->vm_regs.rsp = 0x0;
-
- return 0;
+
+ return 0;
}
* We need to make sure the memory map extends to cover it
*/
static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr) {
- addr_t mem_pages = info->mem_size >> 12;
-
- PrintDebug("Setting up memory map (memory size=%dMB)\n", (uint_t)(info->mem_size / (1024 * 1024)));
-
- // Fill up to the 640K hole
- if (mem_pages >= 160) {
- if (v3_add_shadow_mem(info, 0x0, 0xa0000, (addr_t)V3_AllocPages(160)) == -1) {
- PrintError("Could not map full conventional memory\n");
- return -1;
+ addr_t mem_pages = info->mem_size >> 12;
+
+ PrintDebug("Setting up memory map (memory size=%dMB)\n", (uint_t)(info->mem_size / (1024 * 1024)));
+
+ // Fill up to the 640K hole
+ if (mem_pages >= 160) {
+ if (v3_add_shadow_mem(info, 0x0, 0xa0000, (addr_t)V3_AllocPages(160)) == -1) {
+ PrintError("Could not map full conventional memory\n");
+ return -1;
+ }
+ } else {
+ // Less than 640k of memory
+ if (v3_add_shadow_mem(info, 0x0, (mem_pages * PAGE_SIZE), (addr_t)V3_AllocPages(mem_pages)) == -1) {
+ PrintError("Could not map subset of conventional memory\n");
+ return -1;
+ };
}
- } else {
- // Less than 640k of memory
- if (v3_add_shadow_mem(info, 0x0, (mem_pages * PAGE_SIZE), (addr_t)V3_AllocPages(mem_pages)) == -1) {
- PrintError("Could not map subset of conventional memory\n");
- return -1;
- };
- }
#define VGABIOS_START 0x000c0000
#define ROMBIOS_START 0x000f0000
-
- // VGA frame buffer
- if (1) {
- if (v3_add_shadow_mem(info, 0xa0000, 0xc0000, 0xa0000) == -1) {
- PrintError("Could not map VGA framebuffer\n");
- return -1;
- }
- } else {
- v3_hook_write_mem(info, 0xa0000, 0xc0000, 0xa0000, passthrough_mem_write, NULL);
- }
-
-
- /* layout vgabios */
- {
- uint_t num_pages = (config_ptr->vgabios_size + PAGE_SIZE - 1) / PAGE_SIZE;
- void * guest_mem = V3_AllocPages(num_pages);
- addr_t vgabios_end = VGABIOS_START + (num_pages * PAGE_SIZE);
-
- PrintDebug("Layout Region %d bytes\n", config_ptr->vgabios_size);
- memcpy(V3_VAddr(guest_mem), config_ptr->vgabios, config_ptr->vgabios_size);
-
- if (v3_add_shadow_mem(info, VGABIOS_START, vgabios_end, (addr_t)guest_mem) == -1) {
- PrintError("Could not map VGABIOS\n");
- return -1;
- }
-
- PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n",
- (void *)VGABIOS_START,
- (void *)vgabios_end,
- (void *)guest_mem);
-
-
- // Fill in the space between the VGABIOS and the ROMBIOS
- // We'll just back this to shadow memory for now....
- if (v3_add_shadow_mem(info, vgabios_end, ROMBIOS_START,
- (addr_t)V3_AllocPages((ROMBIOS_START - vgabios_end) / PAGE_SIZE)) == -1) {
- PrintError("Could not map VGABIOS->ROMBIOS gap\n");
- return -1;
- }
- }
-
- /* layout rombios */
- {
- uint_t num_pages = (config_ptr->rombios_size + PAGE_SIZE - 1) / PAGE_SIZE;
- void * guest_mem = V3_AllocPages(num_pages);
- addr_t rombios_end = ROMBIOS_START + (num_pages * PAGE_SIZE);
-
- PrintDebug("Layout Region %d bytes\n", config_ptr->rombios_size);
- memcpy(V3_VAddr(guest_mem), config_ptr->rombios, config_ptr->rombios_size);
-
- if (v3_add_shadow_mem(info, ROMBIOS_START, rombios_end, (addr_t)guest_mem) == -1) {
- PrintError("Could not map ROMBIOS\n");
- return -1;
+
+ // VGA frame buffer
+ if (1) {
+ if (v3_add_shadow_mem(info, 0xa0000, 0xc0000, 0xa0000) == -1) {
+ PrintError("Could not map VGA framebuffer\n");
+ return -1;
+ }
+ } else {
+ v3_hook_write_mem(info, 0xa0000, 0xc0000, 0xa0000, passthrough_mem_write, NULL);
+ }
+
+
+ /* layout vgabios */
+ {
+ uint_t num_pages = (config_ptr->vgabios_size + PAGE_SIZE - 1) / PAGE_SIZE;
+ void * guest_mem = V3_AllocPages(num_pages);
+ addr_t vgabios_end = VGABIOS_START + (num_pages * PAGE_SIZE);
+
+ PrintDebug("Layout Region %d bytes\n", config_ptr->vgabios_size);
+ memcpy(V3_VAddr(guest_mem), config_ptr->vgabios, config_ptr->vgabios_size);
+
+ if (v3_add_shadow_mem(info, VGABIOS_START, vgabios_end, (addr_t)guest_mem) == -1) {
+ PrintError("Could not map VGABIOS\n");
+ return -1;
+ }
+
+ PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n",
+ (void *)VGABIOS_START,
+ (void *)vgabios_end,
+ (void *)guest_mem);
+
+
+ // Fill in the space between the VGABIOS and the ROMBIOS
+ // We'll just back this to shadow memory for now....
+ if (v3_add_shadow_mem(info, vgabios_end, ROMBIOS_START,
+ (addr_t)V3_AllocPages((ROMBIOS_START - vgabios_end) / PAGE_SIZE)) == -1) {
+ PrintError("Could not map VGABIOS->ROMBIOS gap\n");
+ return -1;
+ }
}
- PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n",
- (void *)ROMBIOS_START,
- (void *)rombios_end,
- (void *)guest_mem);
-
- if (rombios_end != 0x100000) {
- PrintError("ROMBIOS must reach the 1MB barrier....\n");
- return -1;
+ /* layout rombios */
+ {
+ uint_t num_pages = (config_ptr->rombios_size + PAGE_SIZE - 1) / PAGE_SIZE;
+ void * guest_mem = V3_AllocPages(num_pages);
+ addr_t rombios_end = ROMBIOS_START + (num_pages * PAGE_SIZE);
+
+ PrintDebug("Layout Region %d bytes\n", config_ptr->rombios_size);
+ memcpy(V3_VAddr(guest_mem), config_ptr->rombios, config_ptr->rombios_size);
+
+ if (v3_add_shadow_mem(info, ROMBIOS_START, rombios_end, (addr_t)guest_mem) == -1) {
+ PrintError("Could not map ROMBIOS\n");
+ return -1;
+ }
+
+ PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n",
+ (void *)ROMBIOS_START,
+ (void *)rombios_end,
+ (void *)guest_mem);
+
+ if (rombios_end != 0x100000) {
+ PrintError("ROMBIOS must reach the 1MB barrier....\n");
+ return -1;
+ }
}
- }
- // Fill in the extended memory map....
- {
- int num_ext_pages = mem_pages - (0x100000 / PAGE_SIZE);
-
- if (num_ext_pages > 0) {
- if (v3_add_shadow_mem(info, 0x100000, info->mem_size, (addr_t)V3_AllocPages(num_ext_pages)) == -1) {
- PrintError("Could not allocate extended shadow memory\n");
- return -1;
- }
+ // Fill in the extended memory map....
+ {
+ int num_ext_pages = mem_pages - (0x100000 / PAGE_SIZE);
+
+ if (num_ext_pages > 0) {
+ if (v3_add_shadow_mem(info, 0x100000, info->mem_size, (addr_t)V3_AllocPages(num_ext_pages)) == -1) {
+ PrintError("Could not allocate extended shadow memory\n");
+ return -1;
+ }
+ }
}
- }
-
- print_shadow_map(info);
+
+ print_shadow_map(info);
- return 0;
+ return 0;
}
if (use_ramdisk) {
- PrintDebug("Creating Ramdisk\n");
- ramdisk = v3_create_ramdisk();
- cdrom = v3_create_cdrom(ramdisk, config_ptr->ramdisk, config_ptr->ramdisk_size);
+ PrintDebug("Creating Ramdisk\n");
+ ramdisk = v3_create_ramdisk();
+ cdrom = v3_create_cdrom(ramdisk, config_ptr->ramdisk, config_ptr->ramdisk_size);
}
if (use_generic) {
- generic = configure_generic(info, config_ptr);
+ generic = configure_generic(info, config_ptr);
}
v3_attach_device(info, ioapic);
if (use_ramdisk) {
- v3_attach_device(info, ramdisk);
- v3_attach_device(info, cdrom);
+ v3_attach_device(info, ramdisk);
+ v3_attach_device(info, cdrom);
}
if (use_generic) {
- // Important that this be attached last!
- v3_attach_device(info, generic);
+ // Important that this be attached last!
+ v3_attach_device(info, generic);
}
PrintDebugDevMgr(info);
if (!use_ramdisk) {
- PrintDebug("Hooking IDE IRQs\n");
-
- //primary ide
- v3_hook_passthrough_irq(info, 14);
-
- // secondary ide
- v3_hook_passthrough_irq(info, 15);
+ PrintDebug("Hooking IDE IRQs\n");
+
+ //primary ide
+ v3_hook_passthrough_irq(info, 14);
+
+ // secondary ide
+ v3_hook_passthrough_irq(info, 15);
}
- return 0;
+ return 0;
}
static struct vm_device * configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) {
- PrintDebug("Creating Generic Device\n");
- struct vm_device * generic = v3_create_generic();
-
- // Make the DMA controller invisible
- v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE); // DMA 1 channels 0,1,2,3 (address, counter)
- v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE); // DMA 2 channels 4,5,6,7 (address, counter)
- v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 0 page register
- v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 1 page register
- v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 2 page register
- v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 3 page register
- v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 4 page register
- v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 5 page register
- v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 6 page register
- v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 7 page register
- v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE); // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
- v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE); // DMA 2 misc registers
-
-
-
-
- // Make the Serial ports invisible
-
- v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE); // COM 1
- v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE); // COM 2
-
+ PrintDebug("Creating Generic Device\n");
+ struct vm_device * generic = v3_create_generic();
+
+ // Make the DMA controller invisible
+ v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE); // DMA 1 channels 0,1,2,3 (address, counter)
+ v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE); // DMA 2 channels 4,5,6,7 (address, counter)
+ v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 0 page register
+ v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 1 page register
+ v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 2 page register
+ v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 3 page register
+ v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 4 page register
+ v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 5 page register
+ v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 6 page register
+ v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 7 page register
+ v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE); // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
+ v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE); // DMA 2 misc registers
+
+
+
+
+ // Make the Serial ports invisible
+
+ v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE); // COM 1
+ v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE); // COM 2
+
- v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE); // COM 3
- v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE); // COM 4
+ v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE); // COM 3
+ v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE); // COM 4
- // Make the PCI bus invisible (at least it's configuration)
-
- v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
- v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
-
-
-
+ // Make the PCI bus invisible (at least it's configuration)
+
+ v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
+ v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
+
+
+
#if 0
- if (!use_ramdisk) {
+ if (!use_ramdisk) {
// Monitor the IDE controllers (very slow)
v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
- }
+ }
- v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
- v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
+ v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
+ v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
#endif
#if 0
-
- // Make the floppy controllers invisible
-
- v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
- v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
- v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
- v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
- v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
- v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
-
+
+ // Make the floppy controllers invisible
+
+ v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
+ v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
+ v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
+ v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
+ v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
+ v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
+
#endif
#if 1
- // Make the parallel port invisible
+ // Make the parallel port invisible
- v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
+ v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
#endif
#if 1
- // Monitor graphics card operations
-
- v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
- v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
+ // Monitor graphics card operations
+
+ v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
+ v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
#endif
#if 1
- // Make the ISA PNP features invisible
-
- v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
- v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
- v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
+ // Make the ISA PNP features invisible
+
+ v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
+ v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
+ v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
#endif
#if 1
- // Monitor any network card (realtek ne2000) operations
- v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
+ // Monitor any network card (realtek ne2000) operations
+ v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
#endif
#if 1
- // Make any Bus master ide controller invisible
-
- v3_generic_add_port_range(generic, 0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE);
+ // Make any Bus master ide controller invisible
+
+ v3_generic_add_port_range(generic, 0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE);
#endif
- // v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
-
-
- return generic;
+ // v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
+
+ return generic;
}
#include <palacios/vmm.h>
-void PrintDebugHex(uchar_t x)
-{
- unsigned char z;
+void PrintDebugHex(uchar_t x) {
+ unsigned char z;
- z = (x >> 4) & 0xf ;
- PrintDebug("%x", z);
- z = x & 0xf;
- PrintDebug("%x", z);
+ z = (x >> 4) & 0xf ;
+ PrintDebug("%x", z);
+ z = x & 0xf;
+ PrintDebug("%x", z);
}
-void PrintDebugMemDump(uchar_t *start, int n)
-{
- int i, j;
+void PrintDebugMemDump(uchar_t *start, int n) {
+ int i, j;
- for (i = 0; i < n; i += 16) {
- PrintDebug("%p", (void *)(start + i));
+ for (i = 0; i < n; i += 16) {
+ PrintDebug("%p", (void *)(start + i));
- for (j = i; (j < (i + 16)) && (j < n); j += 2) {
- PrintDebug(" ");
- PrintDebugHex(*((uchar_t *)(start + j)));
+ for (j = i; (j < (i + 16)) && (j < n); j += 2) {
+ PrintDebug(" ");
+ PrintDebugHex(*((uchar_t *)(start + j)));
- if ((j + 1) < n) {
- PrintDebugHex(*((uchar_t *)(start + j + 1)));
- }
+ if ((j + 1) < n) {
+ PrintDebugHex(*((uchar_t *)(start + j + 1)));
+ }
- }
+ }
- PrintDebug(" ");
+ PrintDebug(" ");
- for (j = i; (j < (i + 16)) && (j < n); j++) {
- PrintDebug("%c", ((start[j] >= 32) && (start[j] <= 126)) ? start[j] : '.');
- }
+ for (j = i; (j < (i + 16)) && (j < n); j++) {
+ PrintDebug("%c", ((start[j] >= 32) && (start[j] <= 126)) ? start[j] : '.');
+ }
- PrintDebug("\n");
- }
+ PrintDebug("\n");
+ }
}
int v3_opcode_cmp(const uchar_t * op1, const uchar_t * op2) {
- if (op1[0] != op2[0]) {
- return op1[0] - op2[0];;
- } else {
- return memcmp(op1 + 1, op2 + 1, op1[0]);
- }
+ if (op1[0] != op2[0]) {
+ return op1[0] - op2[0];;
+ } else {
+ return memcmp(op1 + 1, op2 + 1, op1[0]);
+ }
}
void v3_get_prefixes(uchar_t * instr, struct x86_prefixes * prefixes) {
- while (1) {
- switch (*instr) {
- case 0xF0: // lock
- prefixes->lock = 1;
- break;
-
- case 0xF2: // REPNE/REPNZ
- prefixes->repnz = 1;
- prefixes->repne = 1;
- break;
-
- case 0xF3: // REP or REPE/REPZ
- prefixes->rep = 1;
- prefixes->repe = 1;
- prefixes->repz = 1;
- break;
-
- case 0x2E: // CS override or Branch hint not taken (with Jcc instrs)
- prefixes->cs_override = 1;
- prefixes->br_not_taken = 1;
- break;
-
- case 0x36: // SS override
- prefixes->ss_override = 1;
- break;
-
- case 0x3E: // DS override or Branch hint taken (with Jcc instrs)
- prefixes->ds_override = 1;
- prefixes->br_taken = 1;
- break;
-
- case 0x26: // ES override
- prefixes->es_override = 1;
- break;
-
- case 0x64: // FS override
- prefixes->fs_override = 1;
- break;
+ while (1) {
+ switch (*instr) {
+ case 0xF0: // lock
+ prefixes->lock = 1;
+ break;
+
+ case 0xF2: // REPNE/REPNZ
+ prefixes->repnz = 1;
+ prefixes->repne = 1;
+ break;
+
+ case 0xF3: // REP or REPE/REPZ
+ prefixes->rep = 1;
+ prefixes->repe = 1;
+ prefixes->repz = 1;
+ break;
+
+ case 0x2E: // CS override or Branch hint not taken (with Jcc instrs)
+ prefixes->cs_override = 1;
+ prefixes->br_not_taken = 1;
+ break;
+
+ case 0x36: // SS override
+ prefixes->ss_override = 1;
+ break;
+
+ case 0x3E: // DS override or Branch hint taken (with Jcc instrs)
+ prefixes->ds_override = 1;
+ prefixes->br_taken = 1;
+ break;
+
+ case 0x26: // ES override
+ prefixes->es_override = 1;
+ break;
+
+ case 0x64: // FS override
+ prefixes->fs_override = 1;
+ break;
- case 0x65: // GS override
- prefixes->gs_override = 1;
- break;
+ case 0x65: // GS override
+ prefixes->gs_override = 1;
+ break;
- case 0x66: // operand size override
- prefixes->op_size = 1;
- break;
+ case 0x66: // operand size override
+ prefixes->op_size = 1;
+ break;
- case 0x67: // address size override
- prefixes->addr_size = 1;
- break;
+ case 0x67: // address size override
+ prefixes->addr_size = 1;
+ break;
- default:
- return;
- }
+ default:
+ return;
+ }
- instr++;
- }
+ instr++;
+ }
}
void v3_strip_rep_prefix(uchar_t * instr, int length) {
- int read_ctr = 0;
- int write_ctr = 0;
- int found = 0;
-
- while (read_ctr < length) {
- if ((!found) &&
- ( (instr[read_ctr] == 0xF2) ||
- (instr[read_ctr] == 0xF3))) {
- read_ctr++;
- found = 1;
- } else {
- instr[write_ctr] = instr[read_ctr];
- write_ctr++;
- read_ctr++;
+ int read_ctr = 0;
+ int write_ctr = 0;
+ int found = 0;
+
+ while (read_ctr < length) {
+ if ((!found) &&
+ ( (instr[read_ctr] == 0xF2) ||
+ (instr[read_ctr] == 0xF3))) {
+ read_ctr++;
+ found = 1;
+ } else {
+ instr[write_ctr] = instr[read_ctr];
+ write_ctr++;
+ read_ctr++;
+ }
}
- }
}
int v3_init_dev_mgr(struct guest_info * info) {
- struct vmm_dev_mgr * mgr = &(info->dev_mgr);
- INIT_LIST_HEAD(&(mgr->dev_list));
- mgr->num_devs = 0;
+ struct vmm_dev_mgr * mgr = &(info->dev_mgr);
+ INIT_LIST_HEAD(&(mgr->dev_list));
+ mgr->num_devs = 0;
- INIT_LIST_HEAD(&(mgr->io_hooks));
- mgr->num_io_hooks = 0;
+ INIT_LIST_HEAD(&(mgr->io_hooks));
+ mgr->num_io_hooks = 0;
- INIT_LIST_HEAD(&(mgr->mem_hooks));
- mgr->num_mem_hooks = 0;
+ INIT_LIST_HEAD(&(mgr->mem_hooks));
+ mgr->num_mem_hooks = 0;
- INIT_LIST_HEAD(&(mgr->msr_hooks));
- mgr->num_msr_hook = 0;
+ INIT_LIST_HEAD(&(mgr->msr_hooks));
+ mgr->num_msr_hook = 0;
- return 0;
+ return 0;
}
int v3_dev_mgr_deinit(struct guest_info * info) {
- struct vm_device * dev;
- struct vmm_dev_mgr * mgr = &(info->dev_mgr);
- struct vm_device * tmp;
+ struct vm_device * dev;
+ struct vmm_dev_mgr * mgr = &(info->dev_mgr);
+ struct vm_device * tmp;
- list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
- v3_unattach_device(dev);
- v3_free_device(dev);
- }
+ list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
+ v3_unattach_device(dev);
+ v3_free_device(dev);
+ }
- return 0;
+ return 0;
}
int v3_attach_device(struct guest_info * vm, struct vm_device * dev) {
- struct vmm_dev_mgr *mgr= &(vm->dev_mgr);
+ struct vmm_dev_mgr *mgr= &(vm->dev_mgr);
- dev->vm = vm;
+ dev->vm = vm;
- list_add(&(dev->dev_link), &(mgr->dev_list));
- mgr->num_devs++;
+ list_add(&(dev->dev_link), &(mgr->dev_list));
+ mgr->num_devs++;
- dev->ops->init(dev);
+ dev->ops->init(dev);
- return 0;
+ return 0;
}
int v3_unattach_device(struct vm_device * dev) {
- struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
+ struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
- dev->ops->deinit(dev);
+ dev->ops->deinit(dev);
- list_del(&(dev->dev_link));
- mgr->num_devs--;
+ list_del(&(dev->dev_link));
+ mgr->num_devs--;
- dev->vm = NULL;
+ dev->vm = NULL;
- return 0;
+ return 0;
}
/* IO HOOKS */
static struct dev_io_hook * dev_mgr_find_io_hook(struct vmm_dev_mgr * mgr, ushort_t port) {
- struct dev_io_hook * tmp = NULL;
+ struct dev_io_hook * tmp = NULL;
- list_for_each_entry(tmp, &(mgr->io_hooks), mgr_list) {
- if (tmp->port == port) {
- return tmp;
+ list_for_each_entry(tmp, &(mgr->io_hooks), mgr_list) {
+ if (tmp->port == port) {
+ return tmp;
+ }
}
- }
- return NULL;
+ return NULL;
}
int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev),
int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev)) {
- struct dev_io_hook *hook = (struct dev_io_hook *)V3_Malloc(sizeof(struct dev_io_hook));
- struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
+ struct dev_io_hook *hook = (struct dev_io_hook *)V3_Malloc(sizeof(struct dev_io_hook));
+ struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
- if (!hook) {
- return -1;
- }
+ if (!hook) {
+ return -1;
+ }
- if (v3_hook_io_port(dev->vm, port,
- (int (*)(ushort_t, void *, uint_t, void *))read,
- (int (*)(ushort_t, void *, uint_t, void *))write,
- (void *)dev) == 0) {
+ if (v3_hook_io_port(dev->vm, port,
+ (int (*)(ushort_t, void *, uint_t, void *))read,
+ (int (*)(ushort_t, void *, uint_t, void *))write,
+ (void *)dev) == 0) {
- hook->dev = dev;
- hook->port = port;
- hook->read = read;
- hook->write = write;
+ hook->dev = dev;
+ hook->port = port;
+ hook->read = read;
+ hook->write = write;
- list_add(&(hook->mgr_list), &(mgr->io_hooks));
- mgr->num_io_hooks++;
+ list_add(&(hook->mgr_list), &(mgr->io_hooks));
+ mgr->num_io_hooks++;
- list_add(&(hook->dev_list), &(dev->io_hooks));
- dev->num_io_hooks++;
- } else {
+ list_add(&(hook->dev_list), &(dev->io_hooks));
+ dev->num_io_hooks++;
+ } else {
- return -1;
- }
+ return -1;
+ }
- return 0;
+ return 0;
}
int v3_dev_unhook_io(struct vm_device *dev,
- ushort_t port) {
- struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
- struct dev_io_hook * hook = dev_mgr_find_io_hook(mgr, port);
+ ushort_t port) {
+ struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
+ struct dev_io_hook * hook = dev_mgr_find_io_hook(mgr, port);
- if (!hook) {
- return -1;
- }
+ if (!hook) {
+ return -1;
+ }
- list_del(&(hook->mgr_list));
- mgr->num_io_hooks--;
+ list_del(&(hook->mgr_list));
+ mgr->num_io_hooks--;
- list_del(&(hook->dev_list));
- dev->num_io_hooks--;
+ list_del(&(hook->dev_list));
+ dev->num_io_hooks--;
- return v3_unhook_io_port(dev->vm, port);
+ return v3_unhook_io_port(dev->vm, port);
}
void *end)
{
- struct dev_mem_hook * hook = (struct dev_mem_hook*)V3_Malloc(sizeof(struct dev_mem_hook));
- // V3_Malloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
+ struct dev_mem_hook * hook = (struct dev_mem_hook*)V3_Malloc(sizeof(struct dev_mem_hook));
+ // V3_Malloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
- if (!hook) {
- return -1;
- }
+ if (!hook) {
+ return -1;
+ }
- /* not implemented yet
- hook_memory(vm->mem_map,
- guest_physical_address_start,
- guest_physical_address_end,
- read,
- write,
- device);
+ /* not implemented yet
+ hook_memory(vm->mem_map,
+ guest_physical_address_start,
+ guest_physical_address_end,
+ read,
+ write,
+ device);
- */
+ */
- return -1; // remove when hook_memory works
+ return -1; // remove when hook_memory works
- hook->addr_start = start;
- hook->addr_end = end;
+ hook->addr_start = start;
+ hook->addr_end = end;
- return 0;
+ return 0;
}
static int dev_mgr_unhook_mem(struct vm_device *dev,
addr_t start,
addr_t end) {
- /*
- struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
- struct dev_mem_hook *hook = dev_mgr_find_mem_hook(mgr, start, end);
+ /*
+ struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
+ struct dev_mem_hook *hook = dev_mgr_find_mem_hook(mgr, start, end);
- if (!hook) {
- // Very bad - unhooking something that doesn't exist!
+ if (!hook) {
+ // Very bad - unhooking something that doesn't exist!
+ return -1;
+ }
+ */
+
+ /* not implemented yet
+ return unhook_mem_port(vm->mem_map,
+ guest_physical_start,
+ guest_physical_end) ;
+
+ */
return -1;
- }
- */
-
- /* not implemented yet
- return unhook_mem_port(vm->mem_map,
- guest_physical_start,
- guest_physical_end) ;
-
- */
- return -1;
}
#endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#ifdef DEBUG_DEV_MGR
void PrintDebugDevMgr(struct guest_info * info) {
- struct vmm_dev_mgr * mgr = &(info->dev_mgr);
- struct vm_device * dev;
- PrintDebug("%d devices registered with manager\n", mgr->num_devs);
+ struct vmm_dev_mgr * mgr = &(info->dev_mgr);
+ struct vm_device * dev;
+ PrintDebug("%d devices registered with manager\n", mgr->num_devs);
- list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
- PrintDebugDev(dev);
- PrintDebug("next..\n");
- }
+ list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
+ PrintDebugDev(dev);
+ PrintDebug("next..\n");
+ }
- return;
+ return;
}
void PrintDebugDev(struct vm_device * dev) {
- PrintDebug("Device: %s\n", dev->name);
- PrintDebugDevIO(dev);
+ PrintDebug("Device: %s\n", dev->name);
+ PrintDebugDevIO(dev);
}
void PrintDebugDevMgrIO(struct vmm_dev_mgr * mgr) {
}
void PrintDebugDevIO(struct vm_device * dev) {
- struct dev_io_hook * hook;
+ struct dev_io_hook * hook;
- PrintDebug("IO Hooks(%d) for Device: %s\n", dev->num_io_hooks, dev->name);
+ PrintDebug("IO Hooks(%d) for Device: %s\n", dev->num_io_hooks, dev->name);
- list_for_each_entry(hook, &(dev->io_hooks), dev_list) {
- PrintDebug("\tPort: 0x%x (read=0x%p), (write=0x%p)\n", hook->port,
- (void *)(addr_t)(hook->read),
- (void *)(addr_t)(hook->write));
- }
+ list_for_each_entry(hook, &(dev->io_hooks), dev_list) {
+ PrintDebug("\tPort: 0x%x (read=0x%p), (write=0x%p)\n", hook->port,
+ (void *)(addr_t)(hook->read),
+ (void *)(addr_t)(hook->write));
+ }
- return;
+ return;
}
#else
#include <palacios/vm_guest.h>
static addr_t create_generic_pt_page() {
- void * page = 0;
- page = V3_VAddr(V3_AllocPages(1));
- memset(page, 0, PAGE_SIZE);
+ void * page = 0;
+ page = V3_VAddr(V3_AllocPages(1));
+ memset(page, 0, PAGE_SIZE);
- return (addr_t)page;
+ return (addr_t)page;
}
// Inline handler functions for each cpu mode
addr_t v3_create_direct_passthrough_pts(struct guest_info * info) {
- return create_generic_pt_page();
+ return create_generic_pt_page();
}
int v3_handle_passthrough_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
- v3_vm_cpu_mode_t mode = v3_get_cpu_mode(info);
-
- switch(mode) {
- case REAL:
- case PROTECTED:
- return handle_passthrough_pagefault_32(info, fault_addr, error_code);
- case PROTECTED_PAE:
- return handle_passthrough_pagefault_32pae(info, fault_addr, error_code);
- case LONG:
- break;
- case LONG_32_COMPAT:
- break;
- default:
- PrintError("Unknown CPU Mode\n");
- break;
- }
- return -1;
+ v3_vm_cpu_mode_t mode = v3_get_cpu_mode(info);
+
+ switch(mode) {
+ case REAL:
+ case PROTECTED:
+ return handle_passthrough_pagefault_32(info, fault_addr, error_code);
+ case PROTECTED_PAE:
+ return handle_passthrough_pagefault_32pae(info, fault_addr, error_code);
+ case LONG:
+ break;
+ case LONG_32_COMPAT:
+ break;
+ default:
+ PrintError("Unknown CPU Mode\n");
+ break;
+ }
+ return -1;
}
static inline int handle_passthrough_pagefault_32(struct guest_info * info,
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;
- addr_t host_addr = 0;
-
- int pde_index = PDE32_INDEX(fault_addr);
- int pte_index = PTE32_INDEX(fault_addr);
-
- struct v3_shadow_region * region = v3_get_shadow_region(info, fault_addr);
-
- if ((region == NULL) ||
- (region->host_type == SHDW_REGION_INVALID)) {
- PrintError("Invalid region in passthrough page fault 32, addr=%p\n",
- (void *)fault_addr);
- return -1;
- }
-
- host_addr = v3_get_shadow_addr(region, fault_addr);
-
- // Fix up the PDE entry
- if (pde[pde_index].present == 0) {
- pte = (pte32_t *)create_generic_pt_page();
+ // 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;
+ addr_t host_addr = 0;
- pde[pde_index].present = 1;
- pde[pde_index].writable = 1;
- pde[pde_index].user_page = 1;
- pde[pde_index].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
-
- } else {
- pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
- }
-
- // Fix up the PTE entry
- if (pte[pte_index].present == 0) {
-
- pte[pte_index].user_page = 1;
-
- if (region->host_type == SHDW_REGION_ALLOCATED) {
- // Full access
- pte[pte_index].present = 1;
- pte[pte_index].writable = 1;
-
- pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
- } else if (region->host_type == SHDW_REGION_WRITE_HOOK) {
- // Only trap writes
- pte[pte_index].present = 1;
- pte[pte_index].writable = 0;
-
- pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
- } else if (region->host_type == SHDW_REGION_FULL_HOOK) {
- // trap all accesses
- return v3_handle_mem_full_hook(info, fault_addr, fault_addr, region, error_code);
+ int pde_index = PDE32_INDEX(fault_addr);
+ int pte_index = PTE32_INDEX(fault_addr);
+
+ struct v3_shadow_region * region = v3_get_shadow_region(info, fault_addr);
+
+ if ((region == NULL) ||
+ (region->host_type == SHDW_REGION_INVALID)) {
+ PrintError("Invalid region in passthrough page fault 32, addr=%p\n",
+ (void *)fault_addr);
+ return -1;
+ }
+
+ host_addr = v3_get_shadow_addr(region, fault_addr);
+
+ // Fix up the PDE entry
+ if (pde[pde_index].present == 0) {
+ pte = (pte32_t *)create_generic_pt_page();
+
+ pde[pde_index].present = 1;
+ pde[pde_index].writable = 1;
+ pde[pde_index].user_page = 1;
+ pde[pde_index].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
+
} else {
- PrintError("Unknown Region Type...\n");
- return -1;
+ pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
}
- }
-
- if ( (region->host_type == SHDW_REGION_WRITE_HOOK) &&
- (error_code.write == 1) ) {
- return v3_handle_mem_wr_hook(info, fault_addr, fault_addr, region, error_code);
- }
-
+ // Fix up the PTE entry
+ if (pte[pte_index].present == 0) {
+
+ pte[pte_index].user_page = 1;
+
+ if (region->host_type == SHDW_REGION_ALLOCATED) {
+ // Full access
+ pte[pte_index].present = 1;
+ pte[pte_index].writable = 1;
+
+ pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+ } else if (region->host_type == SHDW_REGION_WRITE_HOOK) {
+ // Only trap writes
+ pte[pte_index].present = 1;
+ pte[pte_index].writable = 0;
+
+ pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+ } else if (region->host_type == SHDW_REGION_FULL_HOOK) {
+ // trap all accesses
+ return v3_handle_mem_full_hook(info, fault_addr, fault_addr, region, error_code);
+ } else {
+ PrintError("Unknown Region Type...\n");
+ return -1;
+ }
+ }
+
+ if ( (region->host_type == SHDW_REGION_WRITE_HOOK) &&
+ (error_code.write == 1) ) {
+ return v3_handle_mem_wr_hook(info, fault_addr, fault_addr, region, error_code);
+ }
- return 0;
+
+ return 0;
}
static inline int handle_passthrough_pagefault_32pae(struct guest_info * info,
addr_t fault_addr,
pf_error_t error_code) {
- pdpe32pae_t * pdpe = CR3_TO_PDPE32PAE_VA(info->ctrl_regs.cr3);
- pde32pae_t * pde = NULL;
- pte32pae_t * pte = NULL;
- addr_t host_addr = 0;
+ pdpe32pae_t * pdpe = CR3_TO_PDPE32PAE_VA(info->ctrl_regs.cr3);
+ pde32pae_t * pde = NULL;
+ pte32pae_t * pte = NULL;
+ addr_t host_addr = 0;
- int pdpe_index = PDPE32PAE_INDEX(fault_addr);
- int pde_index = PDE32PAE_INDEX(fault_addr);
- int pte_index = PTE32PAE_INDEX(fault_addr);
+ int pdpe_index = PDPE32PAE_INDEX(fault_addr);
+ int pde_index = PDE32PAE_INDEX(fault_addr);
+ int pte_index = PTE32PAE_INDEX(fault_addr);
- struct v3_shadow_region * region = v3_get_shadow_region(info, fault_addr);
+ struct v3_shadow_region * region = v3_get_shadow_region(info, fault_addr);
- if ((region == NULL) ||
- (region->host_type == SHDW_REGION_INVALID)) {
- PrintError("Invalid region in passthrough page fault 32PAE, addr=%p\n",
- (void *)fault_addr);
- return -1;
- }
-
- host_addr = v3_get_shadow_addr(region, fault_addr);
-
- // Fix up the PDPE entry
- if (pdpe[pdpe_index].present == 0) {
- pde = (pde32pae_t *)create_generic_pt_page();
+ if ((region == NULL) ||
+ (region->host_type == SHDW_REGION_INVALID)) {
+ PrintError("Invalid region in passthrough page fault 32PAE, addr=%p\n",
+ (void *)fault_addr);
+ return -1;
+ }
+
+ host_addr = v3_get_shadow_addr(region, fault_addr);
+
+ // Fix up the PDPE entry
+ if (pdpe[pdpe_index].present == 0) {
+ pde = (pde32pae_t *)create_generic_pt_page();
- pdpe[pdpe_index].present = 1;
- // Set default PDPE Flags...
- pdpe[pdpe_index].pd_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pde));
- } else {
- pde = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pdpe[pdpe_index].pd_base_addr));
- }
+ pdpe[pdpe_index].present = 1;
+ // Set default PDPE Flags...
+ pdpe[pdpe_index].pd_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pde));
+ } else {
+ pde = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pdpe[pdpe_index].pd_base_addr));
+ }
- // Fix up the PDE entry
- if (pde[pde_index].present == 0) {
- pte = (pte32pae_t *)create_generic_pt_page();
+ // Fix up the PDE entry
+ if (pde[pde_index].present == 0) {
+ pte = (pte32pae_t *)create_generic_pt_page();
- pde[pde_index].present = 1;
- pde[pde_index].writable = 1;
- pde[pde_index].user_page = 1;
+ pde[pde_index].present = 1;
+ pde[pde_index].writable = 1;
+ pde[pde_index].user_page = 1;
- pde[pde_index].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
- } else {
- pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
- }
+ pde[pde_index].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
+ } else {
+ pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
+ }
- // Fix up the PTE entry
- if (pte[pte_index].present == 0) {
- pte[pte_index].user_page = 1;
+ // Fix up the PTE entry
+ if (pte[pte_index].present == 0) {
+ pte[pte_index].user_page = 1;
- if (region->host_type == SHDW_REGION_ALLOCATED) {
- // Full access
- pte[pte_index].present = 1;
- pte[pte_index].writable = 1;
+ if (region->host_type == SHDW_REGION_ALLOCATED) {
+ // Full access
+ pte[pte_index].present = 1;
+ pte[pte_index].writable = 1;
- pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+ pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
- } else if (region->host_type == SHDW_REGION_WRITE_HOOK) {
- // Only trap writes
- pte[pte_index].present = 1;
- pte[pte_index].writable = 0;
+ } else if (region->host_type == SHDW_REGION_WRITE_HOOK) {
+ // Only trap writes
+ pte[pte_index].present = 1;
+ pte[pte_index].writable = 0;
- pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+ pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
- } else if (region->host_type == SHDW_REGION_FULL_HOOK) {
- // trap all accesses
- return v3_handle_mem_full_hook(info, fault_addr, fault_addr, region, error_code);
+ } else if (region->host_type == SHDW_REGION_FULL_HOOK) {
+ // trap all accesses
+ return v3_handle_mem_full_hook(info, fault_addr, fault_addr, region, error_code);
- } else {
- PrintError("Unknown Region Type...\n");
- return -1;
+ } else {
+ PrintError("Unknown Region Type...\n");
+ return -1;
+ }
}
- }
- if ( (region->host_type == SHDW_REGION_WRITE_HOOK) &&
- (error_code.write == 1) ) {
- return v3_handle_mem_wr_hook(info, fault_addr, fault_addr, region, error_code);
- }
+ if ( (region->host_type == SHDW_REGION_WRITE_HOOK) &&
+ (error_code.write == 1) ) {
+ return v3_handle_mem_wr_hook(info, fault_addr, fault_addr, region, error_code);
+ }
- return 0;
+ return 0;
}
addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
void * priv_data) {
- uint_t emulation_length = 0;
- addr_t tmp_rcx = 0;
- addr_t src_addr = 0;
-
- if (dec_instr->dst_operand.operand != write_gva) {
- PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
- (void *)dec_instr->dst_operand.operand, (void *)write_gva);
- return -1;
- }
+ uint_t emulation_length = 0;
+ addr_t tmp_rcx = 0;
+ addr_t src_addr = 0;
+
+ if (dec_instr->dst_operand.operand != write_gva) {
+ PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+ (void *)dec_instr->dst_operand.operand, (void *)write_gva);
+ return -1;
+ }
- 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 < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
+ dec_instr->str_op_length :
+ (0x1000 - PAGE_OFFSET_4KB(write_gva)));
- /* ** Fix emulation length so that it doesn't overrun over the src page either ** */
- tmp_rcx = emulation_length;
+ /* ** Fix emulation length so that it doesn't overrun over the src page either ** */
+ tmp_rcx = emulation_length;
- if (dec_instr->op_type == V3_OP_MOVS) {
-
- // figure out addresses here....
- if (info->mem_mode == PHYSICAL_MEM) {
- if (guest_pa_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
- PrintError("Could not translate write Source (Physical) to host VA\n");
- return -1;
- }
- } else {
- if (guest_va_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
- PrintError("Could not translate write Source (Virtual) to host VA\n");
- return -1;
- }
- }
-
- if (dec_instr->dst_operand.size == 1) {
- movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
- } else if (dec_instr->dst_operand.size == 2) {
- movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
- } else if (dec_instr->dst_operand.size == 4) {
- movs32((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+ if (dec_instr->op_type == V3_OP_MOVS) {
+
+ // figure out addresses here....
+ if (info->mem_mode == PHYSICAL_MEM) {
+ if (guest_pa_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
+ PrintError("Could not translate write Source (Physical) to host VA\n");
+ return -1;
+ }
+ } else {
+ if (guest_va_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
+ PrintError("Could not translate write Source (Virtual) to host VA\n");
+ return -1;
+ }
+ }
+
+ if (dec_instr->dst_operand.size == 1) {
+ movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+ } else if (dec_instr->dst_operand.size == 2) {
+ movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+ } else if (dec_instr->dst_operand.size == 4) {
+ movs32((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
#ifdef __V3_64BIT__
- } else if (dec_instr->dst_operand.size == 8) {
- movs64((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+ } else if (dec_instr->dst_operand.size == 8) {
+ movs64((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
#endif
- } else {
- PrintError("Invalid operand length\n");
- return -1;
- }
-
- info->vm_regs.rdi += emulation_length;
- info->vm_regs.rsi += emulation_length;
-
- // RCX is only modified if the rep prefix is present
- if (dec_instr->prefixes.rep == 1) {
- info->vm_regs.rcx -= emulation_length;
- }
-
- } else if (dec_instr->op_type == V3_OP_STOS) {
-
- if (dec_instr->dst_operand.size == 1) {
- stos8((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
- } else if (dec_instr->dst_operand.size == 2) {
- stos16((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
- } else if (dec_instr->dst_operand.size == 4) {
- stos32((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+ } else {
+ PrintError("Invalid operand length\n");
+ return -1;
+ }
+
+ info->vm_regs.rdi += emulation_length;
+ info->vm_regs.rsi += emulation_length;
+
+ // RCX is only modified if the rep prefix is present
+ if (dec_instr->prefixes.rep == 1) {
+ info->vm_regs.rcx -= emulation_length;
+ }
+
+ } else if (dec_instr->op_type == V3_OP_STOS) {
+
+ if (dec_instr->dst_operand.size == 1) {
+ stos8((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+ } else if (dec_instr->dst_operand.size == 2) {
+ stos16((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+ } else if (dec_instr->dst_operand.size == 4) {
+ stos32((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
#ifdef __V3_64BIT__
- } else if (dec_instr->dst_operand.size == 8) {
- stos64((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+ } else if (dec_instr->dst_operand.size == 8) {
+ stos64((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
#endif
- } else {
- PrintError("Invalid operand length\n");
- return -1;
- }
+ } else {
+ PrintError("Invalid operand length\n");
+ return -1;
+ }
- info->vm_regs.rdi += emulation_length;
+ info->vm_regs.rdi += emulation_length;
- // RCX is only modified if the rep prefix is present
- if (dec_instr->prefixes.rep == 1) {
- info->vm_regs.rcx -= emulation_length;
- }
+ // RCX is only modified if the rep prefix is present
+ if (dec_instr->prefixes.rep == 1) {
+ info->vm_regs.rcx -= emulation_length;
+ }
- } else {
- PrintError("Unimplemented String operation\n");
- return -1;
- }
+ } else {
+ PrintError("Unimplemented String operation\n");
+ return -1;
+ }
- if (write_fn(write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
- PrintError("Did not fully read hooked data\n");
- return -1;
- }
+ if (write_fn(write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
+ PrintError("Did not fully read hooked data\n");
+ return -1;
+ }
- if (emulation_length == dec_instr->str_op_length) {
- info->rip += dec_instr->instr_length;
- }
+ if (emulation_length == dec_instr->str_op_length) {
+ info->rip += dec_instr->instr_length;
+ }
- return emulation_length;
+ return emulation_length;
}
addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
void * priv_data) {
- addr_t src_addr = 0;
- addr_t em_dst_addr = 0;
- int src_op_len = 0;
- int dst_op_len = 0;
- PrintDebug("Emulating XCHG write\n");
-
- if (dec_instr->src_operand.type == MEM_OPERAND) {
- if (dec_instr->src_operand.operand != write_gva) {
- PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
- (void *)dec_instr->src_operand.operand, (void *)write_gva);
- return -1;
- }
+ addr_t src_addr = 0;
+ addr_t em_dst_addr = 0;
+ int src_op_len = 0;
+ int dst_op_len = 0;
+ PrintDebug("Emulating XCHG write\n");
+
+ if (dec_instr->src_operand.type == MEM_OPERAND) {
+ if (dec_instr->src_operand.operand != write_gva) {
+ PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+ (void *)dec_instr->src_operand.operand, (void *)write_gva);
+ return -1;
+ }
- src_addr = dst_addr;
- } else if (dec_instr->src_operand.type == REG_OPERAND) {
- src_addr = dec_instr->src_operand.operand;
- } else {
- src_addr = (addr_t)&(dec_instr->src_operand.operand);
- }
+ src_addr = dst_addr;
+ } else if (dec_instr->src_operand.type == REG_OPERAND) {
+ src_addr = dec_instr->src_operand.operand;
+ } else {
+ src_addr = (addr_t)&(dec_instr->src_operand.operand);
+ }
- if (dec_instr->dst_operand.type == MEM_OPERAND) {
- if (dec_instr->dst_operand.operand != write_gva) {
- PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
- (void *)dec_instr->dst_operand.operand, (void *)write_gva);
- return -1;
- }
+ if (dec_instr->dst_operand.type == MEM_OPERAND) {
+ if (dec_instr->dst_operand.operand != write_gva) {
+ PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+ (void *)dec_instr->dst_operand.operand, (void *)write_gva);
+ return -1;
+ }
- em_dst_addr = dst_addr;
- } else if (dec_instr->src_operand.type == REG_OPERAND) {
- em_dst_addr = dec_instr->src_operand.operand;
- } else {
- em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
- }
+ em_dst_addr = dst_addr;
+ } else if (dec_instr->src_operand.type == REG_OPERAND) {
+ em_dst_addr = dec_instr->src_operand.operand;
+ } else {
+ em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
+ }
- dst_op_len = dec_instr->dst_operand.size;
- src_op_len = dec_instr->src_operand.size;
+ dst_op_len = dec_instr->dst_operand.size;
+ src_op_len = dec_instr->src_operand.size;
- PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
- (void *)dst_addr, (void *)src_addr);
+ PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
+ (void *)dst_addr, (void *)src_addr);
- if (run_op(info, dec_instr->op_type, src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
- PrintError("Instruction Emulation Failed\n");
- return -1;
- }
+ if (run_op(info, dec_instr->op_type, src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
+ PrintError("Instruction Emulation Failed\n");
+ return -1;
+ }
- if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
- PrintError("Did not fully write hooked data\n");
- return -1;
- }
+ if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
+ PrintError("Did not fully write hooked data\n");
+ return -1;
+ }
- info->rip += dec_instr->instr_length;
+ info->rip += dec_instr->instr_length;
- return dst_op_len;
+ return dst_op_len;
}
int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
void * priv_data) {
- addr_t em_src_addr = 0;
- addr_t em_dst_addr = 0;
- int src_op_len = 0;
- int dst_op_len = 0;
-
- PrintDebug("Emulating XCHG Read\n");
-
- if (dec_instr->src_operand.type == MEM_OPERAND) {
- if (dec_instr->src_operand.operand != read_gva) {
- PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
- (void *)dec_instr->src_operand.operand, (void *)read_gva);
- return -1;
- }
+ addr_t em_src_addr = 0;
+ addr_t em_dst_addr = 0;
+ int src_op_len = 0;
+ int dst_op_len = 0;
+
+ PrintDebug("Emulating XCHG Read\n");
+
+ if (dec_instr->src_operand.type == MEM_OPERAND) {
+ if (dec_instr->src_operand.operand != read_gva) {
+ PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+ (void *)dec_instr->src_operand.operand, (void *)read_gva);
+ return -1;
+ }
- em_src_addr = src_addr;
- } else if (dec_instr->src_operand.type == REG_OPERAND) {
- em_src_addr = dec_instr->src_operand.operand;
- } else {
- em_src_addr = (addr_t)&(dec_instr->src_operand.operand);
- }
+ em_src_addr = src_addr;
+ } else if (dec_instr->src_operand.type == REG_OPERAND) {
+ em_src_addr = dec_instr->src_operand.operand;
+ } else {
+ em_src_addr = (addr_t)&(dec_instr->src_operand.operand);
+ }
- if (dec_instr->dst_operand.type == MEM_OPERAND) {
- if (dec_instr->dst_operand.operand != read_gva) {
- PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
- (void *)dec_instr->dst_operand.operand, (void *)read_gva);
- return -1;
- }
+ if (dec_instr->dst_operand.type == MEM_OPERAND) {
+ if (dec_instr->dst_operand.operand != read_gva) {
+ PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+ (void *)dec_instr->dst_operand.operand, (void *)read_gva);
+ return -1;
+ }
- em_dst_addr = src_addr;
- } else if (dec_instr->src_operand.type == REG_OPERAND) {
- em_dst_addr = dec_instr->src_operand.operand;
- } else {
- em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
- }
+ em_dst_addr = src_addr;
+ } else if (dec_instr->src_operand.type == REG_OPERAND) {
+ em_dst_addr = dec_instr->src_operand.operand;
+ } else {
+ em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
+ }
- dst_op_len = dec_instr->dst_operand.size;
- src_op_len = dec_instr->src_operand.size;
+ dst_op_len = dec_instr->dst_operand.size;
+ src_op_len = dec_instr->src_operand.size;
- PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
- (void *)em_dst_addr, (void *)em_src_addr);
+ PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
+ (void *)em_dst_addr, (void *)em_src_addr);
- if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
- PrintError("Did not fully read hooked data\n");
- return -1;
- }
+ if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
+ PrintError("Did not fully read hooked data\n");
+ return -1;
+ }
- if (run_op(info, dec_instr->op_type, em_src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
- PrintError("Instruction Emulation Failed\n");
- return -1;
- }
+ if (run_op(info, dec_instr->op_type, em_src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
+ PrintError("Instruction Emulation Failed\n");
+ return -1;
+ }
- if (write_fn(read_gpa, (void *)src_addr, dst_op_len, priv_data) != dst_op_len) {
- PrintError("Did not fully write hooked data\n");
- return -1;
- }
+ if (write_fn(read_gpa, (void *)src_addr, dst_op_len, priv_data) != dst_op_len) {
+ PrintError("Did not fully write hooked data\n");
+ return -1;
+ }
- info->rip += dec_instr->instr_length;
+ info->rip += dec_instr->instr_length;
- return dst_op_len;
+ return dst_op_len;
}
int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
- int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
- void * priv_data) {
- struct x86_instr dec_instr;
- uchar_t instr[15];
- int ret = 0;
- addr_t src_addr = 0;
- int src_op_len = 0;
- 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);
-
- 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) {
- return -1;
- }
-
- if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
- PrintError("Decoding Error\n");
- // Kick off single step emulator
- return -1;
- }
-
- /*
- * Instructions needing to be special cased.... *
- */
- if (dec_instr.is_str_op) {
- return emulate_string_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
- } else if (dec_instr.op_type == V3_OP_XCHG) {
- return emulate_xchg_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
- }
+ int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
+ void * priv_data) {
+ struct x86_instr dec_instr;
+ uchar_t instr[15];
+ int ret = 0;
+ addr_t src_addr = 0;
+ int src_op_len = 0;
+ 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);
+
+ 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) {
+ return -1;
+ }
+ if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
+ PrintError("Decoding Error\n");
+ // Kick off single step emulator
+ return -1;
+ }
+
+ /*
+ * Instructions needing to be special cased.... *
+ */
+ if (dec_instr.is_str_op) {
+ return emulate_string_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
+ } else if (dec_instr.op_type == V3_OP_XCHG) {
+ return emulate_xchg_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
+ }
- if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
- (dec_instr.dst_operand.operand != write_gva)) {
- PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
- (void *)dec_instr.dst_operand.operand, (void *)write_gva);
- return -1;
- }
- if (dec_instr.src_operand.type == MEM_OPERAND) {
- if (info->mem_mode == PHYSICAL_MEM) {
- if (guest_pa_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
- PrintError("Could not translate write Source (Physical) to host VA\n");
+ if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
+ (dec_instr.dst_operand.operand != write_gva)) {
+ PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+ (void *)dec_instr.dst_operand.operand, (void *)write_gva);
return -1;
- }
+ }
+
+
+ if (dec_instr.src_operand.type == MEM_OPERAND) {
+ if (info->mem_mode == PHYSICAL_MEM) {
+ if (guest_pa_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
+ PrintError("Could not translate write Source (Physical) to host VA\n");
+ return -1;
+ }
+ } else {
+ if (guest_va_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
+ PrintError("Could not translate write Source (Virtual) to host VA\n");
+ return -1;
+ }
+ }
+ } else if (dec_instr.src_operand.type == REG_OPERAND) {
+ src_addr = dec_instr.src_operand.operand;
} else {
- if (guest_va_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
- PrintError("Could not translate write Source (Virtual) to host VA\n");
- return -1;
- }
+ src_addr = (addr_t)&(dec_instr.src_operand.operand);
}
- } else if (dec_instr.src_operand.type == REG_OPERAND) {
- src_addr = dec_instr.src_operand.operand;
- } else {
- src_addr = (addr_t)&(dec_instr.src_operand.operand);
- }
- dst_op_len = dec_instr.dst_operand.size;
- src_op_len = dec_instr.src_operand.size;
+ dst_op_len = dec_instr.dst_operand.size;
+ src_op_len = dec_instr.src_operand.size;
- PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
- (void *)dst_addr, (void *)src_addr);
+ PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
+ (void *)dst_addr, (void *)src_addr);
- if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
- PrintError("Instruction Emulation Failed\n");
- return -1;
- }
+ if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
+ PrintError("Instruction Emulation Failed\n");
+ return -1;
+ }
- if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
- PrintError("Did not fully write hooked data\n");
- return -1;
- }
+ if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
+ PrintError("Did not fully write hooked data\n");
+ return -1;
+ }
- info->rip += dec_instr.instr_length;
+ info->rip += dec_instr.instr_length;
- return dst_op_len;
+ return dst_op_len;
}
int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
void * priv_data) {
- struct x86_instr dec_instr;
- uchar_t instr[15];
- int ret = 0;
- addr_t dst_addr = 0;
- int src_op_len = 0;
- int dst_op_len = 0;
-
- PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
- PrintDebug("GVA=%p\n", (void *)read_gva);
-
- 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) {
- return -1;
- }
-
- if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
- PrintError("Decoding Error\n");
- // Kick off single step emulator
- return -1;
- }
+ struct x86_instr dec_instr;
+ uchar_t instr[15];
+ int ret = 0;
+ addr_t dst_addr = 0;
+ int src_op_len = 0;
+ int dst_op_len = 0;
+
+ PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
+ PrintDebug("GVA=%p\n", (void *)read_gva);
+
+ 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) {
+ return -1;
+ }
+
+ if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
+ PrintError("Decoding Error\n");
+ // Kick off single step emulator
+ return -1;
+ }
- if (dec_instr.is_str_op) {
- PrintError("String operations not implemented on fully hooked regions\n");
- return -1;
- } else if (dec_instr.op_type == V3_OP_XCHG) {
- return emulate_xchg_read_op(info, &dec_instr, read_gva, read_gpa, src_addr, read_fn, write_fn, priv_data);
- }
-
-
- 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);
- return -1;
- }
-
-
- if (dec_instr.dst_operand.type == MEM_OPERAND) {
- if (info->mem_mode == PHYSICAL_MEM) {
- if (guest_pa_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
- PrintError("Could not translate Read Destination (Physical) to host VA\n");
+ if (dec_instr.is_str_op) {
+ PrintError("String operations not implemented on fully hooked regions\n");
return -1;
- }
- } else {
- if (guest_va_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
- PrintError("Could not translate Read Destination (Virtual) to host VA\n");
+ } else if (dec_instr.op_type == V3_OP_XCHG) {
+ return emulate_xchg_read_op(info, &dec_instr, read_gva, read_gpa, src_addr, read_fn, write_fn, priv_data);
+ }
+
+
+ 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);
return -1;
- }
}
- } else if (dec_instr.dst_operand.type == REG_OPERAND) {
- dst_addr = dec_instr.dst_operand.operand;
- } else {
- dst_addr = (addr_t)&(dec_instr.dst_operand.operand);
- }
- src_op_len = dec_instr.src_operand.size;
- dst_op_len = dec_instr.dst_operand.size;
- PrintDebug("Dst_Addr = %p, SRC Addr = %p\n",
- (void *)dst_addr, (void *)src_addr);
+ if (dec_instr.dst_operand.type == MEM_OPERAND) {
+ if (info->mem_mode == PHYSICAL_MEM) {
+ if (guest_pa_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
+ PrintError("Could not translate Read Destination (Physical) to host VA\n");
+ return -1;
+ }
+ } else {
+ if (guest_va_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
+ PrintError("Could not translate Read Destination (Virtual) to host VA\n");
+ return -1;
+ }
+ }
+ } else if (dec_instr.dst_operand.type == REG_OPERAND) {
+ dst_addr = dec_instr.dst_operand.operand;
+ } else {
+ dst_addr = (addr_t)&(dec_instr.dst_operand.operand);
+ }
- if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
- PrintError("Did not fully read hooked data\n");
- return -1;
- }
+ src_op_len = dec_instr.src_operand.size;
+ dst_op_len = dec_instr.dst_operand.size;
- if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
- PrintError("Instruction Emulation Failed\n");
- return -1;
- }
+ PrintDebug("Dst_Addr = %p, SRC Addr = %p\n",
+ (void *)dst_addr, (void *)src_addr);
- info->rip += dec_instr.instr_length;
+ if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
+ PrintError("Did not fully read hooked data\n");
+ return -1;
+ }
- return src_op_len;
+ if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
+ PrintError("Instruction Emulation Failed\n");
+ return -1;
+ }
+
+ info->rip += dec_instr.instr_length;
+
+ return src_op_len;
}
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:
- adc8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_ADD:
- add8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_AND:
- and8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_OR:
- or8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_XOR:
- xor8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SUB:
- sub8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
-
- case V3_OP_MOV:
- mov8((addr_t *)dst_addr, (addr_t *)src_addr);
- break;
-
- case V3_OP_MOVZX:
- movzx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
- break;
- case V3_OP_MOVSX:
- movsx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
- break;
-
- case V3_OP_NOT:
- not8((addr_t *)dst_addr);
- break;
- case V3_OP_XCHG:
- xchg8((addr_t *)dst_addr, (addr_t *)src_addr);
- break;
+ if (src_op_size == 1) {
+ PrintDebug("Executing 8 bit instruction\n");
+
+ switch (op_type) {
+ case V3_OP_ADC:
+ adc8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_ADD:
+ add8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_AND:
+ and8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_OR:
+ or8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_XOR:
+ xor8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SUB:
+ sub8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+
+ case V3_OP_MOV:
+ mov8((addr_t *)dst_addr, (addr_t *)src_addr);
+ break;
+
+ case V3_OP_MOVZX:
+ movzx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
+ break;
+ case V3_OP_MOVSX:
+ movsx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
+ break;
+
+ case V3_OP_NOT:
+ not8((addr_t *)dst_addr);
+ break;
+ case V3_OP_XCHG:
+ xchg8((addr_t *)dst_addr, (addr_t *)src_addr);
+ break;
- case V3_OP_INC:
- inc8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_DEC:
- dec8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_NEG:
- neg8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETB:
- setb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETBE:
- setbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETL:
- setl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETLE:
- setle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETNB:
- setnb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETNBE:
- setnbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETNL:
- setnl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETNLE:
- setnle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETNO:
- setno8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETNP:
- setnp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETNS:
- setns8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETNZ:
- setnz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETO:
- seto8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETP:
- setp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETS:
- sets8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SETZ:
- setz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
-
- default:
- PrintError("Unknown 8 bit instruction\n");
- return -1;
- }
-
- } else if (src_op_size == 2) {
- PrintDebug("Executing 16 bit instruction\n");
-
- switch (op_type) {
- case V3_OP_ADC:
- adc16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_ADD:
- add16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_AND:
- and16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_OR:
- or16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_XOR:
- xor16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SUB:
- sub16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
-
-
- case V3_OP_INC:
- inc16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_DEC:
- dec16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_NEG:
- neg16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
-
- case V3_OP_MOV:
- mov16((addr_t *)dst_addr, (addr_t *)src_addr);
- break;
- case V3_OP_MOVZX:
- movzx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
- break;
- case V3_OP_MOVSX:
- movsx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
- break;
- case V3_OP_NOT:
- not16((addr_t *)dst_addr);
- break;
- case V3_OP_XCHG:
- xchg16((addr_t *)dst_addr, (addr_t *)src_addr);
- break;
+ case V3_OP_INC:
+ inc8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_DEC:
+ dec8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_NEG:
+ neg8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETB:
+ setb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETBE:
+ setbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETL:
+ setl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETLE:
+ setle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETNB:
+ setnb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETNBE:
+ setnbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETNL:
+ setnl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETNLE:
+ setnle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETNO:
+ setno8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETNP:
+ setnp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETNS:
+ setns8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETNZ:
+ setnz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETO:
+ seto8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETP:
+ setp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETS:
+ sets8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SETZ:
+ setz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+
+ default:
+ PrintError("Unknown 8 bit instruction\n");
+ return -1;
+ }
+
+ } else if (src_op_size == 2) {
+ PrintDebug("Executing 16 bit instruction\n");
+
+ switch (op_type) {
+ case V3_OP_ADC:
+ adc16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_ADD:
+ add16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_AND:
+ and16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_OR:
+ or16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_XOR:
+ xor16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SUB:
+ sub16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+
+
+ case V3_OP_INC:
+ inc16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_DEC:
+ dec16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_NEG:
+ neg16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+
+ case V3_OP_MOV:
+ mov16((addr_t *)dst_addr, (addr_t *)src_addr);
+ break;
+ case V3_OP_MOVZX:
+ movzx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
+ break;
+ case V3_OP_MOVSX:
+ movsx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
+ break;
+ case V3_OP_NOT:
+ not16((addr_t *)dst_addr);
+ break;
+ case V3_OP_XCHG:
+ xchg16((addr_t *)dst_addr, (addr_t *)src_addr);
+ break;
- default:
- PrintError("Unknown 16 bit instruction\n");
- return -1;
- }
-
- } else if (src_op_size == 4) {
- PrintDebug("Executing 32 bit instruction\n");
-
- switch (op_type) {
- case V3_OP_ADC:
- adc32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_ADD:
- add32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_AND:
- and32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_OR:
- or32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_XOR:
- xor32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SUB:
- sub32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
-
- case V3_OP_INC:
- inc32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_DEC:
- dec32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_NEG:
- neg32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
-
- case V3_OP_MOV:
- mov32((addr_t *)dst_addr, (addr_t *)src_addr);
- break;
-
- case V3_OP_NOT:
- not32((addr_t *)dst_addr);
- break;
- case V3_OP_XCHG:
- xchg32((addr_t *)dst_addr, (addr_t *)src_addr);
- break;
+ default:
+ PrintError("Unknown 16 bit instruction\n");
+ return -1;
+ }
+
+ } else if (src_op_size == 4) {
+ PrintDebug("Executing 32 bit instruction\n");
+
+ switch (op_type) {
+ case V3_OP_ADC:
+ adc32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_ADD:
+ add32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_AND:
+ and32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_OR:
+ or32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_XOR:
+ xor32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SUB:
+ sub32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+
+ case V3_OP_INC:
+ inc32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_DEC:
+ dec32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_NEG:
+ neg32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+
+ case V3_OP_MOV:
+ mov32((addr_t *)dst_addr, (addr_t *)src_addr);
+ break;
+
+ case V3_OP_NOT:
+ not32((addr_t *)dst_addr);
+ break;
+ case V3_OP_XCHG:
+ xchg32((addr_t *)dst_addr, (addr_t *)src_addr);
+ break;
- default:
- PrintError("Unknown 32 bit instruction\n");
- return -1;
- }
+ default:
+ PrintError("Unknown 32 bit instruction\n");
+ return -1;
+ }
#ifdef __V3_64BIT__
- } else if (src_op_size == 8) {
- PrintDebug("Executing 64 bit instruction\n");
-
- switch (op_type) {
- case V3_OP_ADC:
- adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_ADD:
- add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_AND:
- and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_OR:
- or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_XOR:
- xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_SUB:
- sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
-
- case V3_OP_INC:
- inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_DEC:
- dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
- case V3_OP_NEG:
- neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
- break;
-
- case V3_OP_MOV:
- mov64((addr_t *)dst_addr, (addr_t *)src_addr);
- break;
-
- case V3_OP_NOT:
- not64((addr_t *)dst_addr);
- break;
- case V3_OP_XCHG:
- xchg64((addr_t *)dst_addr, (addr_t *)src_addr);
- break;
+ } else if (src_op_size == 8) {
+ PrintDebug("Executing 64 bit instruction\n");
+
+ switch (op_type) {
+ case V3_OP_ADC:
+ adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_ADD:
+ add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_AND:
+ and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_OR:
+ or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_XOR:
+ xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_SUB:
+ sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+
+ case V3_OP_INC:
+ inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_DEC:
+ dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+ case V3_OP_NEG:
+ neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
+ break;
+
+ case V3_OP_MOV:
+ mov64((addr_t *)dst_addr, (addr_t *)src_addr);
+ break;
+
+ case V3_OP_NOT:
+ not64((addr_t *)dst_addr);
+ break;
+ case V3_OP_XCHG:
+ xchg64((addr_t *)dst_addr, (addr_t *)src_addr);
+ break;
- default:
- PrintError("Unknown 64 bit instruction\n");
- return -1;
- }
+ default:
+ PrintError("Unknown 64 bit instruction\n");
+ return -1;
+ }
#endif
- } else {
- PrintError("Invalid Operation Size\n");
- return -1;
- }
+ } else {
+ PrintError("Invalid Operation Size\n");
+ return -1;
+ }
- return 0;
+ return 0;
}
struct hash_entry {
- addr_t key;
- addr_t value;
- uint_t hash;
- struct hash_entry * next;
+ addr_t key;
+ addr_t value;
+ uint_t hash;
+ struct hash_entry * next;
};
struct hashtable {
uint_t do_hash(struct hashtable * htable, addr_t key) {
- /* Aim to protect against poor hash functions by adding logic here
- * - logic taken from java 1.4 hashtable source */
- uint_t i = htable->hash_fn(key);
- i += ~(i << 9);
- i ^= ((i >> 14) | (i << 18)); /* >>> */
- i += (i << 4);
- i ^= ((i >> 10) | (i << 22)); /* >>> */
-
- return i;
+ /* Aim to protect against poor hash functions by adding logic here
+ * - logic taken from java 1.4 hashtable source */
+ uint_t i = htable->hash_fn(key);
+ i += ~(i << 9);
+ i ^= ((i >> 14) | (i << 18)); /* >>> */
+ i += (i << 4);
+ i ^= ((i >> 10) | (i << 22)); /* >>> */
+
+ return i;
}
#endif
ulong_t hash_long(ulong_t val, uint_t bits) {
- ulong_t hash = val;
+ ulong_t hash = val;
#ifdef __V3_64BIT__
- /* Sigh, gcc can't optimise this alone like it does for 32 bits. */
- ulong_t n = hash;
- n <<= 18;
- hash -= n;
- n <<= 33;
- hash -= n;
- n <<= 3;
- hash += n;
- n <<= 3;
- hash -= n;
- n <<= 4;
- hash += n;
- n <<= 2;
- hash += n;
+ /* Sigh, gcc can't optimise this alone like it does for 32 bits. */
+ ulong_t n = hash;
+ n <<= 18;
+ hash -= n;
+ n <<= 33;
+ hash -= n;
+ n <<= 3;
+ hash += n;
+ n <<= 3;
+ hash -= n;
+ n <<= 4;
+ hash += n;
+ n <<= 2;
+ hash += n;
#else
- /* On some cpus multiply is faster, on others gcc will do shifts */
- hash *= GOLDEN_RATIO_PRIME;
+ /* On some cpus multiply is faster, on others gcc will do shifts */
+ hash *= GOLDEN_RATIO_PRIME;
#endif
- /* High bits are more random, so use them. */
- return hash >> (BITS_PER_LONG - bits);
+ /* High bits are more random, so use them. */
+ return hash >> (BITS_PER_LONG - bits);
}
/* HASH GENERIC MEMORY BUFFER */
/* ELF HEADER HASH FUNCTION */
ulong_t hash_buffer(uchar_t * msg, uint_t length) {
- ulong_t hash = 0;
- ulong_t temp = 0;
- uint_t i;
-
- for (i = 0; i < length; i++) {
- hash = (hash << 4) + *(msg + i) + i;
- if ((temp = (hash & 0xF0000000))) {
- hash ^= (temp >> 24);
+ ulong_t hash = 0;
+ ulong_t temp = 0;
+ uint_t i;
+
+ for (i = 0; i < length; i++) {
+ hash = (hash << 4) + *(msg + i) + i;
+ if ((temp = (hash & 0xF0000000))) {
+ hash ^= (temp >> 24);
+ }
+ hash &= ~temp;
}
- hash &= ~temp;
- }
- return hash;
+ return hash;
}
/*****************************************************************************/
/* indexFor */
static inline uint_t indexFor(uint_t table_length, uint_t hash_value) {
- return (hash_value % table_length);
+ return (hash_value % table_length);
};
/* Only works if table_length == 2^N */
static void * tmp_realloc(void * old_ptr, uint_t old_size, uint_t new_size) {
- void * new_buf = V3_Malloc(new_size);
+ void * new_buf = V3_Malloc(new_size);
- if (new_buf == NULL) {
- return NULL;
- }
+ if (new_buf == NULL) {
+ return NULL;
+ }
- memcpy(new_buf, old_ptr, old_size);
- V3_Free(old_ptr);
+ memcpy(new_buf, old_ptr, old_size);
+ V3_Free(old_ptr);
- return new_buf;
+ return new_buf;
}
/*
-Credit for primes table: Aaron Krowne
- http://br.endernet.org/~akrowne/
- http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+ Credit for primes table: Aaron Krowne
+ http://br.endernet.org/~akrowne/
+ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
*/
static const uint_t primes[] = {
- 53, 97, 193, 389,
- 769, 1543, 3079, 6151,
- 12289, 24593, 49157, 98317,
- 196613, 393241, 786433, 1572869,
- 3145739, 6291469, 12582917, 25165843,
- 50331653, 100663319, 201326611, 402653189,
- 805306457, 1610612741 };
+ 53, 97, 193, 389,
+ 769, 1543, 3079, 6151,
+ 12289, 24593, 49157, 98317,
+ 196613, 393241, 786433, 1572869,
+ 3145739, 6291469, 12582917, 25165843,
+ 50331653, 100663319, 201326611, 402653189,
+ 805306457, 1610612741 };
const uint_t prime_table_length = sizeof(primes) / sizeof(primes[0]);
/* Check requested hashtable isn't too large */
if (min_size > (1u << 30)) {
- return NULL;
+ return NULL;
}
/* Enforce size as prime */
for (prime_index = 0; prime_index < prime_table_length; prime_index++) {
if (primes[prime_index] > min_size) {
- size = primes[prime_index];
- break;
+ size = primes[prime_index];
+ break;
}
}
htable = (struct hashtable *)V3_Malloc(sizeof(struct hashtable));
if (htable == NULL) {
- return NULL; /*oom*/
+ return NULL; /*oom*/
}
htable->table = (struct hash_entry **)V3_Malloc(sizeof(struct hash_entry*) * size);
if (htable->table == NULL) {
- V3_Free(htable);
- return NULL; /*oom*/
+ V3_Free(htable);
+ return NULL; /*oom*/
}
/* Check we're not hitting max capacity */
if (htable->prime_index == (prime_table_length - 1)) {
- return 0;
+ return 0;
}
new_size = primes[++(htable->prime_index)];
for (i = 0; i < htable->table_length; i++) {
- while ((tmp_entry = htable->table[i]) != NULL) {
- htable->table[i] = tmp_entry->next;
+ while ((tmp_entry = htable->table[i]) != NULL) {
+ htable->table[i] = tmp_entry->next;
- index = indexFor(new_size, tmp_entry->hash);
+ index = indexFor(new_size, tmp_entry->hash);
- tmp_entry->next = new_table[index];
+ tmp_entry->next = new_table[index];
- new_table[index] = tmp_entry;
- }
+ new_table[index] = tmp_entry;
+ }
}
V3_Free(htable->table);
htable->table = new_table;
} else {
- /* Plan B: realloc instead */
+ /* Plan B: realloc instead */
- //new_table = (struct hash_entry **)realloc(htable->table, new_size * sizeof(struct hash_entry *));
- new_table = (struct hash_entry **)tmp_realloc(htable->table, primes[htable->prime_index - 1],
- new_size * sizeof(struct hash_entry *));
+ //new_table = (struct hash_entry **)realloc(htable->table, new_size * sizeof(struct hash_entry *));
+ new_table = (struct hash_entry **)tmp_realloc(htable->table, primes[htable->prime_index - 1],
+ new_size * sizeof(struct hash_entry *));
- if (new_table == NULL) {
- (htable->prime_index)--;
- return 0;
- }
+ if (new_table == NULL) {
+ (htable->prime_index)--;
+ return 0;
+ }
- htable->table = new_table;
+ htable->table = new_table;
- memset(new_table[htable->table_length], 0, new_size - htable->table_length);
+ memset(new_table[htable->table_length], 0, new_size - htable->table_length);
- for (i = 0; i < htable->table_length; i++) {
+ for (i = 0; i < htable->table_length; i++) {
- for (entry_ptr = &(new_table[i]), tmp_entry = *entry_ptr;
- tmp_entry != NULL;
- tmp_entry = *entry_ptr) {
+ for (entry_ptr = &(new_table[i]), tmp_entry = *entry_ptr;
+ tmp_entry != NULL;
+ tmp_entry = *entry_ptr) {
- index = indexFor(new_size, tmp_entry->hash);
+ index = indexFor(new_size, tmp_entry->hash);
- if (i == index) {
- entry_ptr = &(tmp_entry->next);
- } else {
- *entry_ptr = tmp_entry->next;
- tmp_entry->next = new_table[index];
- new_table[index] = tmp_entry;
- }
+ if (i == index) {
+ entry_ptr = &(tmp_entry->next);
+ } else {
+ *entry_ptr = tmp_entry->next;
+ tmp_entry->next = new_table[index];
+ new_table[index] = tmp_entry;
+ }
+ }
}
- }
}
htable->table_length = new_size;
struct hash_entry * new_entry;
if (++(htable->entry_count) > htable->load_limit) {
- /* Ignore the return value. If expand fails, we should
- * still try cramming just this value into the existing table
- * -- we may not have memory for a larger table, but one more
- * element may be ok. Next time we insert, we'll try expanding again.*/
- hashtable_expand(htable);
+ /* Ignore the return value. If expand fails, we should
+ * still try cramming just this value into the existing table
+ * -- we may not have memory for a larger table, but one more
+ * element may be ok. Next time we insert, we'll try expanding again.*/
+ hashtable_expand(htable);
}
new_entry = (struct hash_entry *)V3_Malloc(sizeof(struct hash_entry));
if (new_entry == NULL) {
- (htable->entry_count)--;
- return 0; /*oom*/
+ (htable->entry_count)--;
+ return 0; /*oom*/
}
new_entry->hash = do_hash(htable, key);
/* Check hash value to short circuit heavier comparison */
if ((hash_value == tmp_entry->hash) && (htable->eq_fn(key, tmp_entry->key))) {
- if (free_value) {
- V3_Free((void *)(tmp_entry->value));
- }
+ if (free_value) {
+ V3_Free((void *)(tmp_entry->value));
+ }
- tmp_entry->value = value;
- return -1;
+ tmp_entry->value = value;
+ return -1;
}
tmp_entry = tmp_entry->next;
}
/* Check hash value to short circuit heavier comparison */
if ((hash_value == tmp_entry->hash) && (htable->eq_fn(key, tmp_entry->key))) {
- tmp_entry->value += value;
- return -1;
+ tmp_entry->value += value;
+ return -1;
}
tmp_entry = tmp_entry->next;
}
/* Check hash value to short circuit heavier comparison */
if ((hash_value == tmp_entry->hash) && (htable->eq_fn(key, tmp_entry->key))) {
- tmp_entry->value -= value;
- return -1;
+ tmp_entry->value -= value;
+ return -1;
}
tmp_entry = tmp_entry->next;
}
/*****************************************************************************/
/* returns value associated with key */
addr_t hashtable_search(struct hashtable * htable, addr_t key) {
- struct hash_entry * cursor;
- uint_t hash_value;
- uint_t index;
+ struct hash_entry * cursor;
+ uint_t hash_value;
+ uint_t index;
- hash_value = do_hash(htable, key);
+ hash_value = do_hash(htable, key);
- index = indexFor(htable->table_length, hash_value);
+ index = indexFor(htable->table_length, hash_value);
- cursor = htable->table[index];
+ cursor = htable->table[index];
- while (cursor != NULL) {
- /* Check hash value to short circuit heavier comparison */
- if ((hash_value == cursor->hash) &&
- (htable->eq_fn(key, cursor->key))) {
- return cursor->value;
- }
+ while (cursor != NULL) {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hash_value == cursor->hash) &&
+ (htable->eq_fn(key, cursor->key))) {
+ return cursor->value;
+ }
- cursor = cursor->next;
- }
+ cursor = cursor->next;
+ }
- return (addr_t)NULL;
+ return (addr_t)NULL;
}
/*****************************************************************************/
/* returns value associated with key */
addr_t hashtable_remove(struct hashtable * htable, addr_t key, int free_key) {
- /* TODO: consider compacting the table when the load factor drops enough,
- * or provide a 'compact' method. */
+ /* TODO: consider compacting the table when the load factor drops enough,
+ * or provide a 'compact' method. */
- struct hash_entry * cursor;
- struct hash_entry ** entry_ptr;
- addr_t value;
- uint_t hash_value;
- uint_t index;
+ struct hash_entry * cursor;
+ struct hash_entry ** entry_ptr;
+ addr_t value;
+ uint_t hash_value;
+ uint_t index;
- hash_value = do_hash(htable, key);
+ hash_value = do_hash(htable, key);
- index = indexFor(htable->table_length, hash_value);
+ index = indexFor(htable->table_length, hash_value);
- entry_ptr = &(htable->table[index]);
- cursor = *entry_ptr;
+ entry_ptr = &(htable->table[index]);
+ cursor = *entry_ptr;
- while (cursor != NULL) {
- /* Check hash value to short circuit heavier comparison */
- if ((hash_value == cursor->hash) &&
- (htable->eq_fn(key, cursor->key))) {
+ while (cursor != NULL) {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hash_value == cursor->hash) &&
+ (htable->eq_fn(key, cursor->key))) {
- *entry_ptr = cursor->next;
- htable->entry_count--;
- value = cursor->value;
+ *entry_ptr = cursor->next;
+ htable->entry_count--;
+ value = cursor->value;
- if (free_key) {
- freekey((void *)(cursor->key));
- }
- V3_Free(cursor);
+ if (free_key) {
+ freekey((void *)(cursor->key));
+ }
+ V3_Free(cursor);
- return value;
- }
+ return value;
+ }
- entry_ptr = &(cursor->next);
- cursor = cursor->next;
- }
- return (addr_t)NULL;
+ entry_ptr = &(cursor->next);
+ cursor = cursor->next;
+ }
+ return (addr_t)NULL;
}
/*****************************************************************************/
/* destroy */
void hashtable_destroy(struct hashtable * htable, int free_values, int free_keys) {
- uint_t i;
- struct hash_entry * cursor;;
- struct hash_entry **table = htable->table;
+ uint_t i;
+ struct hash_entry * cursor;;
+ struct hash_entry **table = htable->table;
- if (free_values) {
- for (i = 0; i < htable->table_length; i++) {
- cursor = table[i];
+ if (free_values) {
+ for (i = 0; i < htable->table_length; i++) {
+ cursor = table[i];
- while (cursor != NULL) {
- struct hash_entry * tmp;
-
- tmp = cursor;
- cursor = cursor->next;
-
- if (free_keys) {
- freekey((void *)(tmp->key));
+ while (cursor != NULL) {
+ struct hash_entry * tmp;
+
+ tmp = cursor;
+ cursor = cursor->next;
+
+ if (free_keys) {
+ freekey((void *)(tmp->key));
+ }
+ V3_Free((void *)(tmp->value));
+ V3_Free(tmp);
+ }
}
- V3_Free((void *)(tmp->value));
- V3_Free(tmp);
- }
- }
- } else {
- for (i = 0; i < htable->table_length; i++) {
- cursor = table[i];
+ } else {
+ for (i = 0; i < htable->table_length; i++) {
+ cursor = table[i];
- while (cursor != NULL) {
- struct hash_entry * tmp;
+ while (cursor != NULL) {
+ struct hash_entry * tmp;
- tmp = cursor;
- cursor = cursor->next;
+ tmp = cursor;
+ cursor = cursor->next;
- if (free_keys) {
- freekey((void *)(tmp->key));
+ if (free_keys) {
+ freekey((void *)(tmp->key));
+ }
+ V3_Free(tmp);
+ }
}
- V3_Free(tmp);
- }
}
- }
- V3_Free(htable->table);
- V3_Free(htable);
+ V3_Free(htable->table);
+ V3_Free(htable);
}
struct hashtable_iter * create_hashtable_iterator(struct hashtable * htable) {
- uint_t i;
- uint_t table_length;
+ uint_t i;
+ uint_t table_length;
- struct hashtable_iter * iter = (struct hashtable_iter *)V3_Malloc(sizeof(struct hashtable_iter));
+ struct hashtable_iter * iter = (struct hashtable_iter *)V3_Malloc(sizeof(struct hashtable_iter));
- if (iter == NULL) {
- return NULL;
- }
+ if (iter == NULL) {
+ return NULL;
+ }
- iter->htable = htable;
- iter->entry = NULL;
- iter->parent = NULL;
- table_length = htable->table_length;
- iter->index = table_length;
+ iter->htable = htable;
+ iter->entry = NULL;
+ iter->parent = NULL;
+ table_length = htable->table_length;
+ iter->index = table_length;
- if (htable->entry_count == 0) {
- return iter;
- }
+ if (htable->entry_count == 0) {
+ return iter;
+ }
- for (i = 0; i < table_length; i++) {
- if (htable->table[i] != NULL) {
- iter->entry = htable->table[i];
- iter->index = i;
- break;
+ for (i = 0; i < table_length; i++) {
+ if (htable->table[i] != NULL) {
+ iter->entry = htable->table[i];
+ iter->index = i;
+ break;
+ }
}
- }
- return iter;
+ return iter;
}
addr_t hashtable_get_iter_key(struct hashtable_iter * iter) {
- return iter->entry->key;
+ return iter->entry->key;
}
addr_t hashtable_get_iter_value(struct hashtable_iter * iter) {
- return iter->entry->value;
+ return iter->entry->value;
}
/* advance - advance the iterator to the next element
* returns zero if advanced to end of table */
int hashtable_iterator_advance(struct hashtable_iter * iter) {
- uint_t j;
- uint_t table_length;
- struct hash_entry ** table;
- struct hash_entry * next;
+ uint_t j;
+ uint_t table_length;
+ struct hash_entry ** table;
+ struct hash_entry * next;
- if (iter->entry == NULL) {
- return 0; /* stupidity check */
- }
+ if (iter->entry == NULL) {
+ return 0; /* stupidity check */
+ }
- next = iter->entry->next;
+ next = iter->entry->next;
- if (next != NULL) {
- iter->parent = iter->entry;
- iter->entry = next;
- return -1;
- }
+ if (next != NULL) {
+ iter->parent = iter->entry;
+ iter->entry = next;
+ return -1;
+ }
- table_length = iter->htable->table_length;
- iter->parent = NULL;
+ table_length = iter->htable->table_length;
+ iter->parent = NULL;
- if (table_length <= (j = ++(iter->index))) {
- iter->entry = NULL;
- return 0;
- }
+ if (table_length <= (j = ++(iter->index))) {
+ iter->entry = NULL;
+ return 0;
+ }
- table = iter->htable->table;
+ table = iter->htable->table;
- while ((next = table[j]) == NULL) {
- if (++j >= table_length) {
- iter->index = table_length;
- iter->entry = NULL;
- return 0;
+ while ((next = table[j]) == NULL) {
+ if (++j >= table_length) {
+ iter->index = table_length;
+ iter->entry = NULL;
+ return 0;
+ }
}
- }
- iter->index = j;
- iter->entry = next;
+ iter->index = j;
+ iter->entry = next;
- return -1;
+ return -1;
}
* beware memory leaks if you don't.
* Returns zero if end of iteration. */
int hashtable_iterator_remove(struct hashtable_iter * iter, int free_key) {
- struct hash_entry * remember_entry;
- struct hash_entry * remember_parent;
- int ret;
-
- /* Do the removal */
- if ((iter->parent) == NULL) {
- /* element is head of a chain */
- iter->htable->table[iter->index] = iter->entry->next;
- } else {
- /* element is mid-chain */
- iter->parent->next = iter->entry->next;
- }
+ struct hash_entry * remember_entry;
+ struct hash_entry * remember_parent;
+ int ret;
+
+ /* Do the removal */
+ if ((iter->parent) == NULL) {
+ /* element is head of a chain */
+ iter->htable->table[iter->index] = iter->entry->next;
+ } else {
+ /* element is mid-chain */
+ iter->parent->next = iter->entry->next;
+ }
- /* itr->e is now outside the hashtable */
- remember_entry = iter->entry;
- iter->htable->entry_count--;
- if (free_key) {
- freekey((void *)(remember_entry->key));
- }
+ /* itr->e is now outside the hashtable */
+ remember_entry = iter->entry;
+ iter->htable->entry_count--;
+ if (free_key) {
+ freekey((void *)(remember_entry->key));
+ }
- /* Advance the iterator, correcting the parent */
- remember_parent = iter->parent;
- ret = hashtable_iterator_advance(iter);
+ /* Advance the iterator, correcting the parent */
+ remember_parent = iter->parent;
+ ret = hashtable_iterator_advance(iter);
- if (iter->parent == remember_entry) {
- iter->parent = remember_parent;
- }
+ if (iter->parent == remember_entry) {
+ iter->parent = remember_parent;
+ }
- V3_Free(remember_entry);
- return ret;
+ V3_Free(remember_entry);
+ return ret;
}
/* returns zero if not found */
int hashtable_iterator_search(struct hashtable_iter * iter,
struct hashtable * htable, addr_t key) {
- struct hash_entry * entry;
- struct hash_entry * parent;
- uint_t hash_value;
- uint_t index;
+ struct hash_entry * entry;
+ struct hash_entry * parent;
+ uint_t hash_value;
+ uint_t index;
- hash_value = do_hash(htable, key);
- index = indexFor(htable->table_length, hash_value);
+ hash_value = do_hash(htable, key);
+ index = indexFor(htable->table_length, hash_value);
- entry = htable->table[index];
- parent = NULL;
+ entry = htable->table[index];
+ parent = NULL;
- while (entry != NULL) {
- /* Check hash value to short circuit heavier comparison */
- if ((hash_value == entry->hash) &&
- (htable->eq_fn(key, entry->key))) {
- iter->index = index;
- iter->entry = entry;
- iter->parent = parent;
- iter->htable = htable;
- return -1;
+ while (entry != NULL) {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hash_value == entry->hash) &&
+ (htable->eq_fn(key, entry->key))) {
+ iter->index = index;
+ iter->entry = entry;
+ iter->parent = parent;
+ iter->htable = htable;
+ return -1;
+ }
+ parent = entry;
+ entry = entry->next;
}
- parent = entry;
- entry = entry->next;
- }
- return 0;
+ return 0;
}
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
int v3_init_host_events(struct guest_info * info) {
- struct v3_host_events * host_evts = &(info->host_event_hooks);
+ struct v3_host_events * host_evts = &(info->host_event_hooks);
- INIT_LIST_HEAD(&(host_evts->keyboard_events));
- INIT_LIST_HEAD(&(host_evts->mouse_events));
- INIT_LIST_HEAD(&(host_evts->timer_events));
+ INIT_LIST_HEAD(&(host_evts->keyboard_events));
+ INIT_LIST_HEAD(&(host_evts->mouse_events));
+ INIT_LIST_HEAD(&(host_evts->timer_events));
- return 0;
+ return 0;
}
union v3_host_event_handler cb,
void * private_data) {
- struct v3_host_events * host_evts = &(info->host_event_hooks);
- struct v3_host_event_hook * hook = NULL;
-
- hook = (struct v3_host_event_hook *)V3_Malloc(sizeof(struct v3_host_event_hook));
- if (hook == NULL) {
- PrintError("Could not allocate event hook\n");
- return -1;
- }
-
- hook->cb = cb;
- hook->private_data = private_data;
-
- switch (event_type) {
- case HOST_KEYBOARD_EVT:
- list_add(&(hook->link), &(host_evts->keyboard_events));
- break;
- case HOST_MOUSE_EVT:
- list_add(&(hook->link), &(host_evts->mouse_events));
- break;
- case HOST_TIMER_EVT:
- list_add(&(hook->link), &(host_evts->timer_events));
- break;
- }
-
- return 0;
+ struct v3_host_events * host_evts = &(info->host_event_hooks);
+ struct v3_host_event_hook * hook = NULL;
+
+ hook = (struct v3_host_event_hook *)V3_Malloc(sizeof(struct v3_host_event_hook));
+ if (hook == NULL) {
+ PrintError("Could not allocate event hook\n");
+ return -1;
+ }
+
+ hook->cb = cb;
+ hook->private_data = private_data;
+
+ switch (event_type) {
+ case HOST_KEYBOARD_EVT:
+ list_add(&(hook->link), &(host_evts->keyboard_events));
+ break;
+ case HOST_MOUSE_EVT:
+ list_add(&(hook->link), &(host_evts->mouse_events));
+ break;
+ case HOST_TIMER_EVT:
+ list_add(&(hook->link), &(host_evts->timer_events));
+ break;
+ }
+
+ return 0;
}
int v3_deliver_keyboard_event(struct guest_info * info,
struct v3_keyboard_event * evt) {
- struct v3_host_events * host_evts = &(info->host_event_hooks);
- struct v3_host_event_hook * hook = NULL;
+ struct v3_host_events * host_evts = &(info->host_event_hooks);
+ struct v3_host_event_hook * hook = NULL;
- list_for_each_entry(hook, &(host_evts->keyboard_events), link) {
- if (hook->cb.keyboard_handler(info, evt, hook->private_data) == -1) {
- return -1;
+ list_for_each_entry(hook, &(host_evts->keyboard_events), link) {
+ if (hook->cb.keyboard_handler(info, evt, hook->private_data) == -1) {
+ return -1;
+ }
}
- }
- return 0;
+ return 0;
}
int v3_deliver_mouse_event(struct guest_info * info,
struct v3_mouse_event * evt) {
- struct v3_host_events * host_evts = &(info->host_event_hooks);
- struct v3_host_event_hook * hook = NULL;
+ struct v3_host_events * host_evts = &(info->host_event_hooks);
+ struct v3_host_event_hook * hook = NULL;
- list_for_each_entry(hook, &(host_evts->mouse_events), link) {
- if (hook->cb.mouse_handler(info, evt, hook->private_data) == -1) {
- return -1;
+ list_for_each_entry(hook, &(host_evts->mouse_events), link) {
+ if (hook->cb.mouse_handler(info, evt, hook->private_data) == -1) {
+ return -1;
+ }
}
- }
- return 0;
+ return 0;
}
int v3_deliver_timer_event(struct guest_info * info,
struct v3_timer_event * evt) {
- struct v3_host_events * host_evts = &(info->host_event_hooks);
- struct v3_host_event_hook * hook = NULL;
+ struct v3_host_events * host_evts = &(info->host_event_hooks);
+ struct v3_host_event_hook * hook = NULL;
- list_for_each_entry(hook, &(host_evts->timer_events), link) {
- if (hook->cb.timer_handler(info, evt, hook->private_data) == -1) {
- return -1;
+ list_for_each_entry(hook, &(host_evts->timer_events), link) {
+ if (hook->cb.timer_handler(info, evt, hook->private_data) == -1) {
+ return -1;
+ }
}
- }
- return 0;
+ return 0;
}
void v3_init_hypercall_map(struct guest_info * info) {
- info->hcall_map.rb_node = NULL;
+ info->hcall_map.rb_node = NULL;
}
struct hypercall {
- uint_t id;
+ uint_t id;
- int (*hcall_fn)(struct guest_info * info, uint_t hcall_id, void * priv_data);
- void * priv_data;
+ int (*hcall_fn)(struct guest_info * info, uint_t hcall_id, void * priv_data);
+ void * priv_data;
- struct rb_node tree_node;
+ struct rb_node tree_node;
};
static inline struct hypercall * __insert_hypercall(struct guest_info * info, struct hypercall * hcall) {
- struct rb_node ** p = &(info->hcall_map.rb_node);
- struct rb_node * parent = NULL;
- struct hypercall * tmp_hcall = NULL;
-
- while (*p) {
- parent = *p;
- tmp_hcall = rb_entry(parent, struct hypercall, tree_node);
-
- if (hcall->id < tmp_hcall->id) {
- p = &(*p)->rb_left;
- } else if (hcall->id > tmp_hcall->id) {
- p = &(*p)->rb_right;
- } else {
- return tmp_hcall;
+ struct rb_node ** p = &(info->hcall_map.rb_node);
+ struct rb_node * parent = NULL;
+ struct hypercall * tmp_hcall = NULL;
+
+ while (*p) {
+ parent = *p;
+ tmp_hcall = rb_entry(parent, struct hypercall, tree_node);
+
+ if (hcall->id < tmp_hcall->id) {
+ p = &(*p)->rb_left;
+ } else if (hcall->id > tmp_hcall->id) {
+ p = &(*p)->rb_right;
+ } else {
+ return tmp_hcall;
+ }
}
- }
- rb_link_node(&(hcall->tree_node), parent, p);
+ rb_link_node(&(hcall->tree_node), parent, p);
- return NULL;
+ return NULL;
}
static inline struct hypercall * insert_hypercall(struct guest_info * info, struct hypercall * hcall) {
- struct hypercall * ret;
+ struct hypercall * ret;
- if ((ret = __insert_hypercall(info, hcall))) {
- return ret;
- }
+ if ((ret = __insert_hypercall(info, hcall))) {
+ return ret;
+ }
- v3_rb_insert_color(&(hcall->tree_node), &(info->hcall_map));
+ v3_rb_insert_color(&(hcall->tree_node), &(info->hcall_map));
- return NULL;
+ return NULL;
}
static struct hypercall * get_hypercall(struct guest_info * info, uint_t id) {
- struct rb_node * n = info->hcall_map.rb_node;
- struct hypercall * hcall = NULL;
+ struct rb_node * n = info->hcall_map.rb_node;
+ struct hypercall * hcall = NULL;
- while (n) {
- hcall = rb_entry(n, struct hypercall, tree_node);
+ while (n) {
+ hcall = rb_entry(n, struct hypercall, tree_node);
- if (id < hcall->id) {
- n = n->rb_left;
- } else if (id > hcall->id) {
- n = n->rb_right;
- } else {
- return hcall;
+ if (id < hcall->id) {
+ n = n->rb_left;
+ } else if (id > hcall->id) {
+ n = n->rb_right;
+ } else {
+ return hcall;
+ }
}
- }
- return NULL;
+ return NULL;
}
int (*hypercall)(struct guest_info * info, uint_t hcall_id, void * priv_data),
void * priv_data) {
- struct hypercall * hcall = (struct hypercall *)V3_Malloc(sizeof(struct hypercall));
+ struct hypercall * hcall = (struct hypercall *)V3_Malloc(sizeof(struct hypercall));
- hcall->id = hypercall_id;
- hcall->priv_data = priv_data;
- hcall->hcall_fn = hypercall;
+ hcall->id = hypercall_id;
+ hcall->priv_data = priv_data;
+ hcall->hcall_fn = hypercall;
- if (insert_hypercall(info, hcall)) {
- V3_Free(hcall);
- return -1;
- }
+ if (insert_hypercall(info, hcall)) {
+ V3_Free(hcall);
+ return -1;
+ }
- return 0;
+ return 0;
}
int v3_handle_hypercall(struct guest_info * info) {
- uint_t hypercall_id = *(uint_t *)&info->vm_regs.rax;
+ uint_t hypercall_id = *(uint_t *)&info->vm_regs.rax;
- struct hypercall * hcall = get_hypercall(info, hypercall_id);
+ struct hypercall * hcall = get_hypercall(info, hypercall_id);
- if (!hcall) {
- PrintError("Invalid Hypercall (%d not registered)\n", hypercall_id);
- return -1;
- }
+ if (!hcall) {
+ PrintError("Invalid Hypercall (%d not registered)\n", hypercall_id);
+ return -1;
+ }
- return hcall->hcall_fn(info, hypercall_id, hcall->priv_data);
+ return hcall->hcall_fn(info, hypercall_id, hcall->priv_data);
}
static struct v3_ringbuf * func_ring = NULL;
struct instrumented_func {
- ullong_t time;
- uint_t exiting;
- void * called_fn;
- void * calling_fn;
+ ullong_t time;
+ uint_t exiting;
+ void * called_fn;
+ void * calling_fn;
} __attribute__((packed));
void __cyg_profile_func_exit(void * this, void * callsite) __attribute__((__no_instrument_function__));
void v3_init_instrumentation() {
- PrintDebug("Creating Ring Buffer (unit size = %d)\n", (uint_t)sizeof(struct instrumented_func));
- // initialize
- func_ring = v3_create_ringbuf(sizeof(struct instrumented_func) * RING_SIZE); //dequeue at every 4095
+ PrintDebug("Creating Ring Buffer (unit size = %d)\n", (uint_t)sizeof(struct instrumented_func));
+ // initialize
+ func_ring = v3_create_ringbuf(sizeof(struct instrumented_func) * RING_SIZE); //dequeue at every 4095
}
- __attribute__((__no_instrument_function__))
-void __cyg_profile_func_enter(void * this, void * callsite) {
+__attribute__((__no_instrument_function__))
+ void __cyg_profile_func_enter(void * this, void * callsite) {
- if (func_ring != NULL) {
+ if (func_ring != NULL) {
- struct instrumented_func tmp_fn;
- ullong_t now = 0;
+ struct instrumented_func tmp_fn;
+ ullong_t now = 0;
- rdtscll(now);
+ rdtscll(now);
- //PrintDebug("Entering Function\n");
+ //PrintDebug("Entering Function\n");
- if (v3_ringbuf_avail_space(func_ring) < sizeof(struct instrumented_func)) {
- print_instrumentation();
- }
+ if (v3_ringbuf_avail_space(func_ring) < sizeof(struct instrumented_func)) {
+ print_instrumentation();
+ }
- tmp_fn.time = now - last; // current tsc
- tmp_fn.exiting = 0; //enter to be 0
- tmp_fn.called_fn = this; //this
- tmp_fn.calling_fn = callsite; //callsite
+ tmp_fn.time = now - last; // current tsc
+ tmp_fn.exiting = 0; //enter to be 0
+ tmp_fn.called_fn = this; //this
+ tmp_fn.calling_fn = callsite; //callsite
- // PrintDebug("Writing Function: fn_data=%p, size=%d\n",
- // (void *)&tmp_fn, (uint_t)sizeof(struct instrumented_func));
- v3_ringbuf_write(func_ring, (uchar_t *)&tmp_fn, sizeof(struct instrumented_func));
+ // PrintDebug("Writing Function: fn_data=%p, size=%d\n",
+ // (void *)&tmp_fn, (uint_t)sizeof(struct instrumented_func));
+ v3_ringbuf_write(func_ring, (uchar_t *)&tmp_fn, sizeof(struct instrumented_func));
- rdtscll(last);
- }
+ rdtscll(last);
+ }
}
- __attribute__((__no_instrument_function__))
-void __cyg_profile_func_exit(void * this, void * callsite){
+__attribute__((__no_instrument_function__))
+ void __cyg_profile_func_exit(void * this, void * callsite){
- if (func_ring != NULL) {
+ if (func_ring != NULL) {
- struct instrumented_func tmp_fn;
- ullong_t now = 0;
+ struct instrumented_func tmp_fn;
+ ullong_t now = 0;
- rdtscll(now);
+ rdtscll(now);
- // PrintDebug("Exiting Function\n");
+ // PrintDebug("Exiting Function\n");
- if (v3_ringbuf_avail_space(func_ring) < sizeof(struct instrumented_func)) {
- print_instrumentation();
- }
+ if (v3_ringbuf_avail_space(func_ring) < sizeof(struct instrumented_func)) {
+ print_instrumentation();
+ }
- tmp_fn.time = now - last; // current tsc
- tmp_fn.exiting = 1; //exit to be 0
- tmp_fn.called_fn = this; //this
- tmp_fn.calling_fn = callsite; //callsite
-
- // PrintDebug("Writing Function: fn_data=%p, size=%d\n",
- // (void *)&tmp_fn, (uint_t)sizeof(struct instrumented_func));
- v3_ringbuf_write(func_ring, (uchar_t *)&tmp_fn, sizeof(struct instrumented_func));
+ tmp_fn.time = now - last; // current tsc
+ tmp_fn.exiting = 1; //exit to be 0
+ tmp_fn.called_fn = this; //this
+ tmp_fn.calling_fn = callsite; //callsite
+
+ // PrintDebug("Writing Function: fn_data=%p, size=%d\n",
+ // (void *)&tmp_fn, (uint_t)sizeof(struct instrumented_func));
+ v3_ringbuf_write(func_ring, (uchar_t *)&tmp_fn, sizeof(struct instrumented_func));
- rdtscll(last);
- }
+ rdtscll(last);
+ }
}
static void print_instrumentation() {
- struct instrumented_func tmp_fn;
+ struct instrumented_func tmp_fn;
- // PrintDebug("Printing Instrumentation\n");
- while (v3_ringbuf_data_len(func_ring) >= sizeof(struct instrumented_func)) {
+ // PrintDebug("Printing Instrumentation\n");
+ while (v3_ringbuf_data_len(func_ring) >= sizeof(struct instrumented_func)) {
- v3_ringbuf_read(func_ring, (uchar_t *)&tmp_fn, sizeof(struct instrumented_func));
+ v3_ringbuf_read(func_ring, (uchar_t *)&tmp_fn, sizeof(struct instrumented_func));
- PrintDebug("CYG_PROF: %d %p %p %p\n",
- tmp_fn.exiting,
- (void *)(addr_t)(tmp_fn.time),
- tmp_fn.called_fn,
- tmp_fn.calling_fn);
- }
+ PrintDebug("CYG_PROF: %d %p %p %p\n",
+ tmp_fn.exiting,
+ (void *)(addr_t)(tmp_fn.time),
+ tmp_fn.called_fn,
+ tmp_fn.calling_fn);
+ }
}
struct intr_controller {
- struct intr_ctrl_ops * ctrl_ops;
+ struct intr_ctrl_ops * ctrl_ops;
- void * priv_data;
- struct list_head ctrl_node;
+ void * priv_data;
+ struct list_head ctrl_node;
};
void v3_init_interrupt_state(struct guest_info * info) {
- info->intr_state.excp_pending = 0;
- info->intr_state.excp_num = 0;
- info->intr_state.excp_error_code = 0;
+ info->intr_state.excp_pending = 0;
+ info->intr_state.excp_num = 0;
+ info->intr_state.excp_error_code = 0;
- INIT_LIST_HEAD(&(info->intr_state.controller_list));
+ INIT_LIST_HEAD(&(info->intr_state.controller_list));
- memset((uchar_t *)(info->intr_state.hooks), 0, sizeof(struct v3_irq_hook *) * 256);
+ memset((uchar_t *)(info->intr_state.hooks), 0, sizeof(struct v3_irq_hook *) * 256);
}
void v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state) {
- struct intr_controller * ctrlr = (struct intr_controller *)V3_Malloc(sizeof(struct intr_controller));
+ struct intr_controller * ctrlr = (struct intr_controller *)V3_Malloc(sizeof(struct intr_controller));
- ctrlr->priv_data = state;
- ctrlr->ctrl_ops = ops;
+ ctrlr->priv_data = state;
+ ctrlr->ctrl_ops = ops;
- list_add(&(ctrlr->ctrl_node), &(info->intr_state.controller_list));
+ list_add(&(ctrlr->ctrl_node), &(info->intr_state.controller_list));
}
static inline struct v3_irq_hook * get_irq_hook(struct guest_info * info, uint_t irq) {
- V3_ASSERT(irq <= 256);
- return info->intr_state.hooks[irq];
+ V3_ASSERT(irq <= 256);
+ return info->intr_state.hooks[irq];
}
int (*handler)(struct guest_info * info, struct v3_interrupt * intr, void * priv_data),
void * priv_data)
{
- struct v3_irq_hook * hook = (struct v3_irq_hook *)V3_Malloc(sizeof(struct v3_irq_hook));
+ struct v3_irq_hook * hook = (struct v3_irq_hook *)V3_Malloc(sizeof(struct v3_irq_hook));
- if (hook == NULL) {
- return -1;
- }
+ if (hook == NULL) {
+ return -1;
+ }
- if (get_irq_hook(info, irq) != NULL) {
- PrintError("IRQ %d already hooked\n", irq);
- return -1;
- }
+ if (get_irq_hook(info, irq) != NULL) {
+ PrintError("IRQ %d already hooked\n", irq);
+ return -1;
+ }
- hook->handler = handler;
- hook->priv_data = priv_data;
+ hook->handler = handler;
+ hook->priv_data = priv_data;
- info->intr_state.hooks[irq] = hook;
-
- if (V3_Hook_Interrupt(info, irq)) {
- PrintError("hook_irq: failed to hook irq %d\n", irq);
- return -1;
- } else {
- PrintDebug("hook_irq: hooked irq %d\n", irq);
- return 0;
- }
+ info->intr_state.hooks[irq] = hook;
+
+ if (V3_Hook_Interrupt(info, irq)) {
+ PrintError("hook_irq: failed to hook irq %d\n", irq);
+ return -1;
+ } else {
+ PrintDebug("hook_irq: hooked irq %d\n", irq);
+ return 0;
+ }
}
static int passthrough_irq_handler(struct guest_info * info, struct v3_interrupt * intr, void * priv_data)
{
- PrintDebug("[passthrough_irq_handler] raise_irq=%d (guest=0x%p)\n",
- intr->irq, (void *)info);
- return v3_raise_irq(info, intr->irq);
+ PrintDebug("[passthrough_irq_handler] raise_irq=%d (guest=0x%p)\n",
+ intr->irq, (void *)info);
+ return v3_raise_irq(info, intr->irq);
}
int v3_hook_passthrough_irq(struct guest_info * info, uint_t irq)
{
- int rc = v3_hook_irq(info, irq, passthrough_irq_handler, NULL);
+ int rc = v3_hook_irq(info, irq, passthrough_irq_handler, NULL);
- if (rc) {
- PrintError("guest_irq_injection: failed to hook irq 0x%x (guest=0x%p)\n", irq, (void *)info);
- return -1;
- } else {
- PrintDebug("guest_irq_injection: hooked irq 0x%x (guest=0x%p)\n", irq, (void *)info);
- return 0;
- }
+ if (rc) {
+ PrintError("guest_irq_injection: failed to hook irq 0x%x (guest=0x%p)\n", irq, (void *)info);
+ return -1;
+ } else {
+ PrintDebug("guest_irq_injection: hooked irq 0x%x (guest=0x%p)\n", irq, (void *)info);
+ return 0;
+ }
}
int v3_deliver_irq(struct guest_info * info, struct v3_interrupt * intr) {
- PrintDebug("v3_deliver_irq: irq=%d state=0x%p, \n", intr->irq, (void *)intr);
+ PrintDebug("v3_deliver_irq: irq=%d state=0x%p, \n", intr->irq, (void *)intr);
- struct v3_irq_hook * hook = get_irq_hook(info, intr->irq);
+ struct v3_irq_hook * hook = get_irq_hook(info, intr->irq);
- if (hook == NULL) {
- PrintError("Attempting to deliver interrupt to non registered hook(irq=%d)\n", intr->irq);
- return -1;
- }
+ if (hook == NULL) {
+ PrintError("Attempting to deliver interrupt to non registered hook(irq=%d)\n", intr->irq);
+ return -1;
+ }
- return hook->handler(info, intr, hook->priv_data);
+ return hook->handler(info, intr, hook->priv_data);
}
int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code) {
- struct v3_intr_state * intr_state = &(info->intr_state);
-
- if (intr_state->excp_pending == 0) {
- intr_state->excp_pending = 1;
- intr_state->excp_num = excp;
- intr_state->excp_error_code = error_code;
- intr_state->excp_error_code_valid = 1;
- PrintDebug("[v3_raise_exception_with_error] error code: %x\n", error_code);
- } else {
- PrintError("exception already pending, currently not implemented\n");
- return -1;
- }
-
- return 0;
+ struct v3_intr_state * intr_state = &(info->intr_state);
+
+ if (intr_state->excp_pending == 0) {
+ intr_state->excp_pending = 1;
+ intr_state->excp_num = excp;
+ intr_state->excp_error_code = error_code;
+ intr_state->excp_error_code_valid = 1;
+ PrintDebug("[v3_raise_exception_with_error] error code: %x\n", error_code);
+ } else {
+ PrintError("exception already pending, currently not implemented\n");
+ return -1;
+ }
+
+ return 0;
}
int v3_raise_exception(struct guest_info * info, uint_t excp) {
- struct v3_intr_state * intr_state = &(info->intr_state);
- PrintDebug("[v3_raise_exception]\n");
- if (intr_state->excp_pending == 0) {
- intr_state->excp_pending = 1;
- intr_state->excp_num = excp;
- intr_state->excp_error_code = 0;
- intr_state->excp_error_code_valid = 0;
- } else {
- PrintError("exception already pending, currently not implemented\n");
- return -1;
- }
-
- return 0;
+ struct v3_intr_state * intr_state = &(info->intr_state);
+ PrintDebug("[v3_raise_exception]\n");
+ if (intr_state->excp_pending == 0) {
+ intr_state->excp_pending = 1;
+ intr_state->excp_num = excp;
+ intr_state->excp_error_code = 0;
+ intr_state->excp_error_code_valid = 0;
+ } else {
+ PrintError("exception already pending, currently not implemented\n");
+ return -1;
+ }
+
+ return 0;
}
int v3_lower_irq(struct guest_info * info, int irq) {
- struct intr_controller * ctrl = NULL;
- struct v3_intr_state * intr_state = &(info->intr_state);
+ struct intr_controller * ctrl = NULL;
+ struct v3_intr_state * intr_state = &(info->intr_state);
- PrintDebug("[v3_lower_irq]\n");
+ PrintDebug("[v3_lower_irq]\n");
- list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
- ctrl->ctrl_ops->lower_intr(ctrl->priv_data, irq);
- }
+ list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+ ctrl->ctrl_ops->lower_intr(ctrl->priv_data, irq);
+ }
- return 0;
+ return 0;
}
int v3_raise_irq(struct guest_info * info, int irq) {
- struct intr_controller * ctrl = NULL;
- struct v3_intr_state * intr_state = &(info->intr_state);
+ struct intr_controller * ctrl = NULL;
+ struct v3_intr_state * intr_state = &(info->intr_state);
- PrintDebug("[v3_raise_irq (%d)]\n", irq);
+ PrintDebug("[v3_raise_irq (%d)]\n", irq);
- list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
- ctrl->ctrl_ops->raise_intr(ctrl->priv_data, irq);
- }
+ list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+ ctrl->ctrl_ops->raise_intr(ctrl->priv_data, irq);
+ }
- return 0;
+ return 0;
}
int v3_intr_pending(struct guest_info * info) {
- struct v3_intr_state * intr_state = &(info->intr_state);
+ struct v3_intr_state * intr_state = &(info->intr_state);
- // PrintDebug("[intr_pending]\n");
- if (intr_state->excp_pending == 1) {
- return 1;
- } else {
- struct intr_controller * ctrl = NULL;
-
- list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
- if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
+ // PrintDebug("[intr_pending]\n");
+ if (intr_state->excp_pending == 1) {
return 1;
- }
+ } else {
+ struct intr_controller * ctrl = NULL;
+
+ list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+ if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
+ return 1;
+ }
+ }
}
- }
- return 0;
+ return 0;
}
uint_t v3_get_intr_number(struct guest_info * info) {
- struct v3_intr_state * intr_state = &(info->intr_state);
+ struct v3_intr_state * intr_state = &(info->intr_state);
- if (intr_state->excp_pending == 1) {
- return intr_state->excp_num;
- } else {
- struct intr_controller * ctrl = NULL;
+ if (intr_state->excp_pending == 1) {
+ return intr_state->excp_num;
+ } else {
+ struct intr_controller * ctrl = NULL;
- list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
- if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data)) {
- uint_t intr_num = ctrl->ctrl_ops->get_intr_number(ctrl->priv_data);
+ list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+ if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data)) {
+ uint_t intr_num = ctrl->ctrl_ops->get_intr_number(ctrl->priv_data);
- PrintDebug("[get_intr_number] intr_number = %d\n", intr_num);
+ PrintDebug("[get_intr_number] intr_number = %d\n", intr_num);
- return intr_num;
- }
+ return intr_num;
+ }
+ }
}
- }
- return 0;
+ return 0;
}
intr_type_t v3_get_intr_type(struct guest_info * info) {
- struct v3_intr_state * intr_state = &(info->intr_state);
-
- if (intr_state->excp_pending) {
- PrintDebug("[get_intr_type] Exception\n");
- return EXCEPTION;
- } else {
- struct intr_controller * ctrl = NULL;
-
- list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
- if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
- PrintDebug("[get_intr_type] External_irq\n");
- return EXTERNAL_IRQ;
- }
+ struct v3_intr_state * intr_state = &(info->intr_state);
+
+ if (intr_state->excp_pending) {
+ PrintDebug("[get_intr_type] Exception\n");
+ return EXCEPTION;
+ } else {
+ struct intr_controller * ctrl = NULL;
+
+ list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+ if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
+ PrintDebug("[get_intr_type] External_irq\n");
+ return EXTERNAL_IRQ;
+ }
+ }
}
- }
- PrintDebug("[get_intr_type] Invalid_Intr\n");
- return INVALID_INTR;
+ PrintDebug("[get_intr_type] Invalid_Intr\n");
+ return INVALID_INTR;
}
int v3_injecting_intr(struct guest_info * info, uint_t intr_num, intr_type_t type) {
- struct v3_intr_state * intr_state = &(info->intr_state);
-
- if (type == EXCEPTION) {
- PrintDebug("[injecting_intr] Exception\n");
- intr_state->excp_pending = 0;
- intr_state->excp_num = 0;
- intr_state->excp_error_code = 0;
- intr_state->excp_error_code_valid = 0;
+ struct v3_intr_state * intr_state = &(info->intr_state);
+
+ if (type == EXCEPTION) {
+ PrintDebug("[injecting_intr] Exception\n");
+ intr_state->excp_pending = 0;
+ intr_state->excp_num = 0;
+ intr_state->excp_error_code = 0;
+ intr_state->excp_error_code_valid = 0;
- } else if (type == EXTERNAL_IRQ) {
- struct intr_controller * ctrl = NULL;
+ } else if (type == EXTERNAL_IRQ) {
+ struct intr_controller * ctrl = NULL;
- PrintDebug("[injecting_intr] External_Irq with intr_num = %x\n", intr_num);
- list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
- ctrl->ctrl_ops->begin_irq(ctrl->priv_data, intr_num);
+ PrintDebug("[injecting_intr] External_Irq with intr_num = %x\n", intr_num);
+ list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+ ctrl->ctrl_ops->begin_irq(ctrl->priv_data, intr_num);
+ }
}
- }
- return 0;
+ return 0;
}
void v3_init_shadow_map(struct guest_info * info) {
- v3_shdw_map_t * map = &(info->mem_map);
+ v3_shdw_map_t * map = &(info->mem_map);
- map->shdw_regions.rb_node = NULL;
- map->hook_hva = (addr_t)V3_VAddr(V3_AllocPages(1));
+ map->shdw_regions.rb_node = NULL;
+ map->hook_hva = (addr_t)V3_VAddr(V3_AllocPages(1));
}
void v3_delete_shadow_map(struct guest_info * info) {
- struct rb_node * node = v3_rb_first(&(info->mem_map.shdw_regions));
- struct v3_shadow_region * reg;
- struct rb_node * tmp_node = NULL;
+ struct rb_node * node = v3_rb_first(&(info->mem_map.shdw_regions));
+ struct v3_shadow_region * reg;
+ struct rb_node * tmp_node = NULL;
- while (node) {
- reg = rb_entry(node, struct v3_shadow_region, tree_node);
- tmp_node = node;
- node = v3_rb_next(node);
+ while (node) {
+ reg = rb_entry(node, struct v3_shadow_region, tree_node);
+ tmp_node = node;
+ node = v3_rb_next(node);
- v3_delete_shadow_region(info, reg);
- }
+ v3_delete_shadow_region(info, reg);
+ }
}
addr_t guest_addr_end,
addr_t host_addr)
{
- struct v3_shadow_region * entry = (struct v3_shadow_region *)V3_Malloc(sizeof(struct v3_shadow_region));
-
- entry->guest_start = guest_addr_start;
- entry->guest_end = guest_addr_end;
- entry->host_type = SHDW_REGION_ALLOCATED;
- entry->host_addr = host_addr;
- entry->write_hook = NULL;
- entry->read_hook = NULL;
- entry->priv_data = NULL;
-
- if (insert_shadow_region(info, entry)) {
- V3_Free(entry);
- return -1;
- }
-
- return 0;
+ struct v3_shadow_region * entry = (struct v3_shadow_region *)V3_Malloc(sizeof(struct v3_shadow_region));
+
+ entry->guest_start = guest_addr_start;
+ entry->guest_end = guest_addr_end;
+ entry->host_type = SHDW_REGION_ALLOCATED;
+ entry->host_addr = host_addr;
+ entry->write_hook = NULL;
+ entry->read_hook = NULL;
+ entry->priv_data = NULL;
+
+ if (insert_shadow_region(info, entry)) {
+ V3_Free(entry);
+ return -1;
+ }
+
+ return 0;
}
int (*write)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
void * priv_data) {
- struct v3_shadow_region * entry = (struct v3_shadow_region *)V3_Malloc(sizeof(struct v3_shadow_region));
+ struct v3_shadow_region * entry = (struct v3_shadow_region *)V3_Malloc(sizeof(struct v3_shadow_region));
- entry->guest_start = guest_addr_start;
- entry->guest_end = guest_addr_end;
- entry->host_type = SHDW_REGION_WRITE_HOOK;
- entry->host_addr = host_addr;
- entry->write_hook = write;
- entry->read_hook = NULL;
- entry->priv_data = priv_data;
+ entry->guest_start = guest_addr_start;
+ entry->guest_end = guest_addr_end;
+ entry->host_type = SHDW_REGION_WRITE_HOOK;
+ entry->host_addr = host_addr;
+ entry->write_hook = write;
+ entry->read_hook = NULL;
+ entry->priv_data = priv_data;
- if (insert_shadow_region(info, entry)) {
- V3_Free(entry);
- return -1;
- }
+ if (insert_shadow_region(info, entry)) {
+ V3_Free(entry);
+ return -1;
+ }
- return 0;
+ return 0;
}
int v3_hook_full_mem(struct guest_info * info, addr_t guest_addr_start, addr_t guest_addr_end,
int (*write)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
void * priv_data) {
- struct v3_shadow_region * entry = (struct v3_shadow_region *)V3_Malloc(sizeof(struct v3_shadow_region));
-
- entry->guest_start = guest_addr_start;
- entry->guest_end = guest_addr_end;
- entry->host_type = SHDW_REGION_FULL_HOOK;
- entry->host_addr = (addr_t)NULL;
- entry->write_hook = write;
- entry->read_hook = read;
- entry->priv_data = priv_data;
+ struct v3_shadow_region * entry = (struct v3_shadow_region *)V3_Malloc(sizeof(struct v3_shadow_region));
+
+ entry->guest_start = guest_addr_start;
+ entry->guest_end = guest_addr_end;
+ entry->host_type = SHDW_REGION_FULL_HOOK;
+ entry->host_addr = (addr_t)NULL;
+ entry->write_hook = write;
+ entry->read_hook = read;
+ entry->priv_data = priv_data;
- if (insert_shadow_region(info, entry)) {
- V3_Free(entry);
- return -1;
- }
+ if (insert_shadow_region(info, entry)) {
+ V3_Free(entry);
+ return -1;
+ }
- return 0;
+ return 0;
}
static inline
struct v3_shadow_region * __insert_shadow_region(struct guest_info * info,
struct v3_shadow_region * region) {
- struct rb_node ** p = &(info->mem_map.shdw_regions.rb_node);
- struct rb_node * parent = NULL;
- struct v3_shadow_region * tmp_region;
-
- while (*p) {
- parent = *p;
- tmp_region = rb_entry(parent, struct v3_shadow_region, tree_node);
-
- if (region->guest_end <= tmp_region->guest_start) {
- p = &(*p)->rb_left;
- } else if (region->guest_start >= tmp_region->guest_end) {
- p = &(*p)->rb_right;
- } else {
- return tmp_region;
+ struct rb_node ** p = &(info->mem_map.shdw_regions.rb_node);
+ struct rb_node * parent = NULL;
+ struct v3_shadow_region * tmp_region;
+
+ while (*p) {
+ parent = *p;
+ tmp_region = rb_entry(parent, struct v3_shadow_region, tree_node);
+
+ if (region->guest_end <= tmp_region->guest_start) {
+ p = &(*p)->rb_left;
+ } else if (region->guest_start >= tmp_region->guest_end) {
+ p = &(*p)->rb_right;
+ } else {
+ return tmp_region;
+ }
}
- }
- rb_link_node(&(region->tree_node), parent, p);
+ rb_link_node(&(region->tree_node), parent, p);
- return NULL;
+ return NULL;
}
static inline
struct v3_shadow_region * insert_shadow_region(struct guest_info * info,
struct v3_shadow_region * region) {
- struct v3_shadow_region * ret;
+ struct v3_shadow_region * ret;
- if ((ret = __insert_shadow_region(info, region))) {
- return ret;
- }
+ if ((ret = __insert_shadow_region(info, region))) {
+ return ret;
+ }
- v3_rb_insert_color(&(region->tree_node), &(info->mem_map.shdw_regions));
+ v3_rb_insert_color(&(region->tree_node), &(info->mem_map.shdw_regions));
- return NULL;
+ return NULL;
}
addr_t fault_gva, addr_t fault_gpa,
pf_error_t access_info)
{
- struct v3_shadow_region * reg = v3_get_shadow_region(info, fault_gpa);
+ struct v3_shadow_region * reg = v3_get_shadow_region(info, fault_gpa);
- PrintDebug("Handling Special Page Fault\n");
+ PrintDebug("Handling Special Page Fault\n");
- switch (reg->host_type) {
- case SHDW_REGION_WRITE_HOOK:
- return v3_handle_mem_wr_hook(info, fault_gva, fault_gpa, reg, access_info);
- case SHDW_REGION_FULL_HOOK:
- return v3_handle_mem_full_hook(info, fault_gva, fault_gpa, reg, access_info);
- default:
- return -1;
- }
+ switch (reg->host_type) {
+ case SHDW_REGION_WRITE_HOOK:
+ return v3_handle_mem_wr_hook(info, fault_gva, fault_gpa, reg, access_info);
+ case SHDW_REGION_FULL_HOOK:
+ return v3_handle_mem_full_hook(info, fault_gva, fault_gpa, reg, access_info);
+ default:
+ return -1;
+ }
- return 0;
+ return 0;
}
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 = (addr_t)V3_VAddr((void *)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");
- return -1;
- }
+ 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");
+ return -1;
+ }
- return 0;
+ return 0;
}
int v3_handle_mem_full_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 op_addr = info->mem_map.hook_hva;
+ addr_t op_addr = info->mem_map.hook_hva;
- if (access_info.write == 1) {
- if (v3_emulate_write_op(info, guest_va, guest_pa, op_addr, reg->write_hook, reg->priv_data) == -1) {
- PrintError("Write Full Hook emulation failed\n");
- return -1;
- }
- } else {
- if (v3_emulate_read_op(info, guest_va, guest_pa, op_addr, reg->read_hook, reg->write_hook, reg->priv_data) == -1) {
- PrintError("Read Full Hook emulation failed\n");
- return -1;
+ if (access_info.write == 1) {
+ if (v3_emulate_write_op(info, guest_va, guest_pa, op_addr, reg->write_hook, reg->priv_data) == -1) {
+ PrintError("Write Full Hook emulation failed\n");
+ return -1;
+ }
+ } else {
+ if (v3_emulate_read_op(info, guest_va, guest_pa, op_addr, reg->read_hook, reg->write_hook, reg->priv_data) == -1) {
+ PrintError("Read Full Hook emulation failed\n");
+ return -1;
+ }
}
- }
- return 0;
+ return 0;
}
struct v3_shadow_region * v3_get_shadow_region(struct guest_info * info, addr_t guest_addr) {
- struct rb_node * n = info->mem_map.shdw_regions.rb_node;
- struct v3_shadow_region * reg = NULL;
-
- while (n) {
- reg = rb_entry(n, struct v3_shadow_region, tree_node);
-
- if (guest_addr < reg->guest_start) {
- n = n->rb_left;
- } else if (guest_addr >= reg->guest_end) {
- n = n->rb_right;
- } else {
- return reg;
+ struct rb_node * n = info->mem_map.shdw_regions.rb_node;
+ struct v3_shadow_region * reg = NULL;
+
+ while (n) {
+ reg = rb_entry(n, struct v3_shadow_region, tree_node);
+
+ if (guest_addr < reg->guest_start) {
+ n = n->rb_left;
+ } else if (guest_addr >= reg->guest_end) {
+ n = n->rb_right;
+ } else {
+ return reg;
+ }
}
- }
- return NULL;
+ return NULL;
}
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) ) {
- return (guest_addr - reg->guest_start) + reg->host_addr;
- } else {
- PrintError("MEM Region Invalid\n");
- return 0;
- }
+ 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");
+ return 0;
+ }
}
void v3_delete_shadow_region(struct guest_info * info, struct v3_shadow_region * reg) {
- if (reg != NULL) {
- v3_rb_erase(&(reg->tree_node), &(info->mem_map.shdw_regions));
+ if (reg != NULL) {
+ v3_rb_erase(&(reg->tree_node), &(info->mem_map.shdw_regions));
- V3_Free(reg);
- }
+ V3_Free(reg);
+ }
}
void print_shadow_map(struct guest_info * info) {
- struct rb_node * node = v3_rb_first(&(info->mem_map.shdw_regions));
- struct v3_shadow_region * reg;
- int i = 0;
+ struct rb_node * node = v3_rb_first(&(info->mem_map.shdw_regions));
+ struct v3_shadow_region * reg;
+ int i = 0;
- PrintDebug("Memory Layout:\n");
+ PrintDebug("Memory Layout:\n");
- do {
- reg = rb_entry(node, struct v3_shadow_region, tree_node);
+ do {
+ reg = rb_entry(node, struct v3_shadow_region, tree_node);
- PrintDebug("%d: 0x%p - 0x%p -> 0x%p\n", i,
- (void *)(reg->guest_start),
- (void *)(reg->guest_end - 1),
- (void *)(reg->host_addr));
+ PrintDebug("%d: 0x%p - 0x%p -> 0x%p\n", i,
+ (void *)(reg->guest_start),
+ (void *)(reg->guest_end - 1),
+ (void *)(reg->host_addr));
- PrintDebug("\t(%s) (WriteHook = 0x%p) (ReadHook = 0x%p)\n",
- v3_shdw_region_type_to_str(reg->host_type),
- (void *)(reg->write_hook),
- (void *)(reg->read_hook));
+ PrintDebug("\t(%s) (WriteHook = 0x%p) (ReadHook = 0x%p)\n",
+ v3_shdw_region_type_to_str(reg->host_type),
+ (void *)(reg->write_hook),
+ (void *)(reg->read_hook));
- i++;
- } while ((node = v3_rb_next(node)));
+ i++;
+ } while ((node = v3_rb_next(node)));
}
const uchar_t * v3_shdw_region_type_to_str(v3_shdw_region_type_t type) {
- switch (type) {
- case SHDW_REGION_WRITE_HOOK:
- return SHDW_REGION_WRITE_HOOK_STR;
- case SHDW_REGION_FULL_HOOK:
- return SHDW_REGION_FULL_HOOK_STR;
- case SHDW_REGION_ALLOCATED:
- return SHDW_REGION_ALLOCATED_STR;
- default:
- return SHDW_REGION_INVALID_STR;
- }
+ switch (type) {
+ case SHDW_REGION_WRITE_HOOK:
+ return SHDW_REGION_WRITE_HOOK_STR;
+ case SHDW_REGION_FULL_HOOK:
+ return SHDW_REGION_FULL_HOOK_STR;
+ case SHDW_REGION_ALLOCATED:
+ return SHDW_REGION_ALLOCATED_STR;
+ default:
+ return SHDW_REGION_INVALID_STR;
+ }
}
void v3_init_msr_map(struct guest_info * info) {
- struct v3_msr_map * msr_map = &(info->msr_map);
+ struct v3_msr_map * msr_map = &(info->msr_map);
- INIT_LIST_HEAD(&(msr_map->hook_list));
- msr_map->num_hooks = 0;
+ INIT_LIST_HEAD(&(msr_map->hook_list));
+ msr_map->num_hooks = 0;
}
int (*write)(uint_t msr, struct v3_msr src, void * priv_data),
void * priv_data) {
- struct v3_msr_map * msr_map = &(info->msr_map);
- struct v3_msr_hook * hook = NULL;
+ struct v3_msr_map * msr_map = &(info->msr_map);
+ struct v3_msr_hook * hook = NULL;
- hook = (struct v3_msr_hook *)V3_Malloc(sizeof(struct v3_msr_hook));
- if (hook == NULL) {
- PrintError("Could not allocate msr hook for MSR %d\n", msr);
- return -1;
- }
+ hook = (struct v3_msr_hook *)V3_Malloc(sizeof(struct v3_msr_hook));
+ if (hook == NULL) {
+ PrintError("Could not allocate msr hook for MSR %d\n", msr);
+ return -1;
+ }
- hook->read = read;
- hook->write = write;
- hook->msr = msr;
- hook->priv_data = priv_data;
+ hook->read = read;
+ hook->write = write;
+ hook->msr = msr;
+ hook->priv_data = priv_data;
- msr_map->num_hooks++;
+ msr_map->num_hooks++;
- list_add(&(hook->link), &(msr_map->hook_list));
+ list_add(&(hook->link), &(msr_map->hook_list));
- return 0;
+ return 0;
}
int v3_unhook_msr(struct guest_info * info, uint_t msr) {
- return -1;
+ return -1;
}
struct v3_msr_hook * v3_get_msr_hook(struct guest_info * info, uint_t msr) {
- struct v3_msr_map * msr_map = &(info->msr_map);
- struct v3_msr_hook * hook = NULL;
+ struct v3_msr_map * msr_map = &(info->msr_map);
+ struct v3_msr_hook * hook = NULL;
- list_for_each_entry(hook, &(msr_map->hook_list), link) {
- if (hook->msr == msr) {
- return hook;
+ list_for_each_entry(hook, &(msr_map->hook_list), link) {
+ if (hook->msr == msr) {
+ return hook;
+ }
}
- }
- return NULL;
+ return NULL;
}
void v3_print_msr_map(struct guest_info * info) {
- struct v3_msr_map * msr_map = &(info->msr_map);
- struct v3_msr_hook * hook = NULL;
+ struct v3_msr_map * msr_map = &(info->msr_map);
+ struct v3_msr_hook * hook = NULL;
- list_for_each_entry(hook, &(msr_map->hook_list), link) {
- PrintDebug("MSR HOOK (MSR=%d) (read=0x%p) (write=0x%p)\n",
- hook->msr, hook->read, hook->write);
- }
+ list_for_each_entry(hook, &(msr_map->hook_list), link) {
+ PrintDebug("MSR HOOK (MSR=%d) (read=0x%p) (write=0x%p)\n",
+ hook->msr, hook->read, hook->write);
+ }
}
void delete_page_tables_32(pde32_t * pde) {
- int i;
+ int i;
- if (pde == NULL) {
- return;
- }
- PrintDebug("Deleting Page Tables -- PDE (%p)\n", pde);
+ if (pde == NULL) {
+ return;
+ }
+ PrintDebug("Deleting Page Tables -- PDE (%p)\n", pde);
- for (i = 0; (i < MAX_PDE32_ENTRIES); i++) {
- if (pde[i].present) {
- // We double cast, first to an addr_t to handle 64 bit issues, then to the pointer
+ for (i = 0; (i < MAX_PDE32_ENTRIES); i++) {
+ if (pde[i].present) {
+ // We double cast, first to an addr_t to handle 64 bit issues, then to the pointer
- pte32_t * pte = (pte32_t *)((addr_t)(uint_t)(pde[i].pt_base_addr << PAGE_POWER));
+ pte32_t * pte = (pte32_t *)((addr_t)(uint_t)(pde[i].pt_base_addr << PAGE_POWER));
- V3_FreePage(pte);
+ V3_FreePage(pte);
+ }
}
- }
- V3_FreePage(V3_PAddr(pde));
+ V3_FreePage(V3_PAddr(pde));
}
void delete_page_tables_32PAE(pdpe32pae_t * pdpe) {
- PrintError("Unimplemented function\n");
+ PrintError("Unimplemented function\n");
}
void delete_page_tables_64(pml4e64_t * pml4) {
- PrintError("Unimplemented function\n");
+ PrintError("Unimplemented function\n");
}
static int translate_pt_32_cb(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data) {
- addr_t * paddr = (addr_t *)private_data;
-
- switch (type) {
- case PAGE_PD32:
- case PAGE_PT32:
- return 0;
- case PAGE_4MB:
- *paddr = page_pa + PAGE_OFFSET_4MB(vaddr);
- return 0;
- case PAGE_4KB:
- *paddr = page_pa + PAGE_OFFSET_4KB(vaddr);
- return 0;
- default:
- PrintError("Inavlid page type (%s) in tranlate pt 32 callback\n", v3_page_type_to_str(type));
- return -1;
- }
+ addr_t * paddr = (addr_t *)private_data;
+
+ switch (type) {
+ case PAGE_PD32:
+ case PAGE_PT32:
+ return 0;
+ case PAGE_4MB:
+ *paddr = page_pa + PAGE_OFFSET_4MB(vaddr);
+ return 0;
+ case PAGE_4KB:
+ *paddr = page_pa + PAGE_OFFSET_4KB(vaddr);
+ return 0;
+ default:
+ PrintError("Inavlid page type (%s) in tranlate pt 32 callback\n", v3_page_type_to_str(type));
+ return -1;
+ }
}
static int translate_pt_32pae_cb(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data) {
- addr_t * paddr = (addr_t *)private_data;
+ addr_t * paddr = (addr_t *)private_data;
- switch (type) {
- case PAGE_PDP32PAE:
- case PAGE_PD32PAE:
- case PAGE_PT32PAE:
- return 0;
- case PAGE_2MB:
- *paddr = page_pa + PAGE_OFFSET_2MB(vaddr);
- return 0;
- case PAGE_4KB:
- *paddr = page_pa + PAGE_OFFSET_4KB(vaddr);
- return 0;
- default:
- PrintError("Inavlid page type (%s) in translate pt 32pae callback\n", v3_page_type_to_str(type));
- return -1;
- }
+ switch (type) {
+ case PAGE_PDP32PAE:
+ case PAGE_PD32PAE:
+ case PAGE_PT32PAE:
+ return 0;
+ case PAGE_2MB:
+ *paddr = page_pa + PAGE_OFFSET_2MB(vaddr);
+ return 0;
+ case PAGE_4KB:
+ *paddr = page_pa + PAGE_OFFSET_4KB(vaddr);
+ return 0;
+ default:
+ PrintError("Inavlid page type (%s) in translate pt 32pae callback\n", v3_page_type_to_str(type));
+ return -1;
+ }
}
static int translate_pt_64_cb(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data) {
- addr_t * paddr = (addr_t *)private_data;
-
- switch (type) {
- case PAGE_PML464:
- case PAGE_PDP64:
- case PAGE_PD64:
- case PAGE_PT64:
- return 0;
- case PAGE_1GB:
- *paddr = page_pa + PAGE_OFFSET_1GB(vaddr);
- return 0;
- case PAGE_2MB:
- *paddr = page_pa + PAGE_OFFSET_2MB(vaddr);
- return 0;
- case PAGE_4KB:
- *paddr = page_pa + PAGE_OFFSET_4KB(vaddr);
- return 0;
- default:
- PrintError("Inavlid page type (%s) in translate pt 64 callback\n", v3_page_type_to_str(type));
- return -1;
- }
+ addr_t * paddr = (addr_t *)private_data;
+
+ switch (type) {
+ case PAGE_PML464:
+ case PAGE_PDP64:
+ case PAGE_PD64:
+ case PAGE_PT64:
+ return 0;
+ case PAGE_1GB:
+ *paddr = page_pa + PAGE_OFFSET_1GB(vaddr);
+ return 0;
+ case PAGE_2MB:
+ *paddr = page_pa + PAGE_OFFSET_2MB(vaddr);
+ return 0;
+ case PAGE_4KB:
+ *paddr = page_pa + PAGE_OFFSET_4KB(vaddr);
+ return 0;
+ default:
+ PrintError("Inavlid page type (%s) in translate pt 64 callback\n", v3_page_type_to_str(type));
+ return -1;
+ }
}
int v3_translate_host_pt_32(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr, addr_t * paddr) {
- return v3_drill_host_pt_32(info, host_cr3, vaddr, translate_pt_32_cb, paddr);
+ return v3_drill_host_pt_32(info, host_cr3, vaddr, translate_pt_32_cb, paddr);
}
int v3_translate_guest_pt_32(struct guest_info * info, v3_reg_t guest_cr3, addr_t vaddr, addr_t * paddr) {
- return v3_drill_guest_pt_32(info, guest_cr3, vaddr, translate_pt_32_cb, paddr);
+ return v3_drill_guest_pt_32(info, guest_cr3, vaddr, translate_pt_32_cb, paddr);
}
int v3_translate_host_pt_32pae(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr, addr_t * paddr) {
- return v3_drill_host_pt_32pae(info, host_cr3, vaddr, translate_pt_32pae_cb, paddr);
+ return v3_drill_host_pt_32pae(info, host_cr3, vaddr, translate_pt_32pae_cb, paddr);
}
int v3_translate_guest_pt_32pae(struct guest_info * info, v3_reg_t guest_cr3, addr_t vaddr, addr_t * paddr) {
- return v3_drill_guest_pt_32pae(info, guest_cr3, vaddr, translate_pt_32pae_cb, paddr);
+ return v3_drill_guest_pt_32pae(info, guest_cr3, vaddr, translate_pt_32pae_cb, paddr);
}
int v3_translate_host_pt_64(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr, addr_t * paddr) {
- return v3_drill_host_pt_64(info, host_cr3, vaddr, translate_pt_64_cb, paddr);
+ return v3_drill_host_pt_64(info, host_cr3, vaddr, translate_pt_64_cb, paddr);
}
int v3_translate_guest_pt_64(struct guest_info * info, v3_reg_t guest_cr3, addr_t vaddr, addr_t * paddr) {
- return v3_drill_guest_pt_64(info, guest_cr3, vaddr, translate_pt_64_cb, paddr);
+ return v3_drill_guest_pt_64(info, guest_cr3, vaddr, translate_pt_64_cb, paddr);
}
struct pt_find_data {
- page_type_t type;
- addr_t * pt_page_ptr;
- addr_t * pt_page_pa;
+ page_type_t type;
+ addr_t * pt_page_ptr;
+ addr_t * pt_page_pa;
};
static int find_pt_cb(struct guest_info * info, page_type_t type, addr_t vaddr,
addr_t page_ptr, addr_t page_pa, void * private_data) {
- struct pt_find_data * pt_data = (struct pt_find_data *)private_data;
+ struct pt_find_data * pt_data = (struct pt_find_data *)private_data;
- PrintDebug("FIND_PT Type=%s, page_pa = %p\n",
- v3_page_type_to_str(type),
- (void *)page_pa);
+ PrintDebug("FIND_PT Type=%s, page_pa = %p\n",
+ v3_page_type_to_str(type),
+ (void *)page_pa);
- if (type == pt_data->type) {
- *(pt_data->pt_page_ptr) = page_ptr;
- *(pt_data->pt_page_pa) = page_pa;
- return 1;
- }
+ if (type == pt_data->type) {
+ *(pt_data->pt_page_ptr) = page_ptr;
+ *(pt_data->pt_page_pa) = page_pa;
+ return 1;
+ }
- return 0;
+ return 0;
}
int v3_find_host_pt_32_page(struct guest_info * info, v3_reg_t host_cr3, page_type_t type, addr_t vaddr,
addr_t * page_ptr, addr_t * page_pa) {
- struct pt_find_data data;
+ struct pt_find_data data;
- data.type = type;
- data.pt_page_ptr = page_ptr;
- data.pt_page_pa = page_pa;
+ data.type = type;
+ data.pt_page_ptr = page_ptr;
+ data.pt_page_pa = page_pa;
- return v3_drill_host_pt_32(info, host_cr3, vaddr, find_pt_cb, &data);
+ return v3_drill_host_pt_32(info, host_cr3, vaddr, find_pt_cb, &data);
}
int v3_find_host_pt_32pae_page(struct guest_info * info, v3_reg_t host_cr3, page_type_t type, addr_t vaddr,
addr_t * page_ptr, addr_t * page_pa) {
- struct pt_find_data data;
+ struct pt_find_data data;
- data.type = type;
- data.pt_page_ptr = page_ptr;
- data.pt_page_pa = page_pa;
+ data.type = type;
+ data.pt_page_ptr = page_ptr;
+ data.pt_page_pa = page_pa;
- return v3_drill_host_pt_32pae(info, host_cr3, vaddr, find_pt_cb, &data);
+ return v3_drill_host_pt_32pae(info, host_cr3, vaddr, find_pt_cb, &data);
}
int v3_find_host_pt_64_page(struct guest_info * info, v3_reg_t host_cr3, page_type_t type, addr_t vaddr,
addr_t * page_ptr, addr_t * page_pa) {
- struct pt_find_data data;
+ struct pt_find_data data;
- data.type = type;
- data.pt_page_ptr = page_ptr;
- data.pt_page_pa = page_pa;
+ data.type = type;
+ data.pt_page_ptr = page_ptr;
+ data.pt_page_pa = page_pa;
- return v3_drill_host_pt_64(info, host_cr3, vaddr, find_pt_cb, &data);
+ return v3_drill_host_pt_64(info, host_cr3, vaddr, find_pt_cb, &data);
}
int v3_find_guest_pt_32_page(struct guest_info * info, v3_reg_t guest_cr3, page_type_t type, addr_t vaddr,
addr_t * page_ptr, addr_t * page_pa) {
- struct pt_find_data data;
+ struct pt_find_data data;
- data.type = type;
- data.pt_page_ptr = page_ptr;
- data.pt_page_pa = page_pa;
+ data.type = type;
+ data.pt_page_ptr = page_ptr;
+ data.pt_page_pa = page_pa;
- return v3_drill_guest_pt_32(info, guest_cr3, vaddr, find_pt_cb, &data);
+ return v3_drill_guest_pt_32(info, guest_cr3, vaddr, find_pt_cb, &data);
}
int v3_find_guest_pt_32pae_page(struct guest_info * info, v3_reg_t guest_cr3, page_type_t type, addr_t vaddr,
addr_t * page_ptr, addr_t * page_pa) {
- struct pt_find_data data;
+ struct pt_find_data data;
- data.type = type;
- data.pt_page_ptr = page_ptr;
- data.pt_page_pa = page_pa;
+ data.type = type;
+ data.pt_page_ptr = page_ptr;
+ data.pt_page_pa = page_pa;
- return v3_drill_guest_pt_32pae(info, guest_cr3, vaddr, find_pt_cb, &data);
+ return v3_drill_guest_pt_32pae(info, guest_cr3, vaddr, find_pt_cb, &data);
}
int v3_find_guest_pt_64_page(struct guest_info * info, v3_reg_t guest_cr3, page_type_t type, addr_t vaddr,
addr_t * page_ptr, addr_t * page_pa) {
- struct pt_find_data data;
+ struct pt_find_data data;
- data.type = type;
- data.pt_page_ptr = page_ptr;
- data.pt_page_pa = page_pa;
+ data.type = type;
+ data.pt_page_ptr = page_ptr;
+ data.pt_page_pa = page_pa;
- return v3_drill_guest_pt_64(info, guest_cr3, vaddr, find_pt_cb, &data);
+ return v3_drill_guest_pt_64(info, guest_cr3, vaddr, find_pt_cb, &data);
}
struct pt_check_data {
- pf_error_t access_type;
- pt_access_status_t * access_status;
+ pf_error_t access_type;
+ pt_access_status_t * access_status;
};
static int check_pt_32_cb(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data) {
- struct pt_check_data * chk_data = (struct pt_check_data *)private_data;
-
- switch (type) {
- case PAGE_PD32:
- *(chk_data->access_status) = v3_can_access_pde32((pde32_t *)page_ptr, vaddr, chk_data->access_type);
- break;
- case PAGE_PT32:
- *(chk_data->access_status) = v3_can_access_pte32((pte32_t *)page_ptr, vaddr, chk_data->access_type);
- break;
- case PAGE_4MB:
- case PAGE_4KB:
- return 0;
- default:
- PrintError("Inavlid page type (%s) in check pt 32 callback\n", v3_page_type_to_str(type));
- return -1;
- }
+ struct pt_check_data * chk_data = (struct pt_check_data *)private_data;
+
+ switch (type) {
+ case PAGE_PD32:
+ *(chk_data->access_status) = v3_can_access_pde32((pde32_t *)page_ptr, vaddr, chk_data->access_type);
+ break;
+ case PAGE_PT32:
+ *(chk_data->access_status) = v3_can_access_pte32((pte32_t *)page_ptr, vaddr, chk_data->access_type);
+ break;
+ case PAGE_4MB:
+ case PAGE_4KB:
+ return 0;
+ default:
+ PrintError("Inavlid page type (%s) in check pt 32 callback\n", v3_page_type_to_str(type));
+ return -1;
+ }
- if (chk_data->access_status != PT_ACCESS_OK) {
- return 1;
- }
+ if (chk_data->access_status != PT_ACCESS_OK) {
+ return 1;
+ }
- return 0;
+ return 0;
}
static int check_pt_32pae_cb(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data) {
- struct pt_check_data * chk_data = (struct pt_check_data *)private_data;
-
- switch (type) {
- case PAGE_PDP32PAE:
- *(chk_data->access_status) = v3_can_access_pdpe32pae((pdpe32pae_t *)page_ptr, vaddr, chk_data->access_type);
- break;
- case PAGE_PD32PAE:
- *(chk_data->access_status) = v3_can_access_pde32pae((pde32pae_t *)page_ptr, vaddr, chk_data->access_type);
- break;
- case PAGE_PT32PAE:
- *(chk_data->access_status) = v3_can_access_pte32pae((pte32pae_t *)page_ptr, vaddr, chk_data->access_type);
- break;
- case PAGE_2MB:
- case PAGE_4KB:
- return 0;
- default:
- PrintError("Inavlid page type (%s) in check pt 32pae callback\n", v3_page_type_to_str(type));
- return -1;
- }
+ struct pt_check_data * chk_data = (struct pt_check_data *)private_data;
+
+ switch (type) {
+ case PAGE_PDP32PAE:
+ *(chk_data->access_status) = v3_can_access_pdpe32pae((pdpe32pae_t *)page_ptr, vaddr, chk_data->access_type);
+ break;
+ case PAGE_PD32PAE:
+ *(chk_data->access_status) = v3_can_access_pde32pae((pde32pae_t *)page_ptr, vaddr, chk_data->access_type);
+ break;
+ case PAGE_PT32PAE:
+ *(chk_data->access_status) = v3_can_access_pte32pae((pte32pae_t *)page_ptr, vaddr, chk_data->access_type);
+ break;
+ case PAGE_2MB:
+ case PAGE_4KB:
+ return 0;
+ default:
+ PrintError("Inavlid page type (%s) in check pt 32pae callback\n", v3_page_type_to_str(type));
+ return -1;
+ }
- if (chk_data->access_status != PT_ACCESS_OK) {
- return 1;
- }
+ if (chk_data->access_status != PT_ACCESS_OK) {
+ return 1;
+ }
- return 0;
+ return 0;
}
static int check_pt_64_cb(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data) {
- struct pt_check_data * chk_data = (struct pt_check_data *)private_data;
-
- switch (type) {
- case PAGE_PML464:
- *(chk_data->access_status) = v3_can_access_pml4e64((pml4e64_t *)page_ptr, vaddr, chk_data->access_type);
- break;
- case PAGE_PDP64:
- *(chk_data->access_status) = v3_can_access_pdpe64((pdpe64_t *)page_ptr, vaddr, chk_data->access_type);
- break;
- case PAGE_PD64:
- *(chk_data->access_status) = v3_can_access_pde64((pde64_t *)page_ptr, vaddr, chk_data->access_type);
- break;
- case PAGE_PT64:
- *(chk_data->access_status) = v3_can_access_pte64((pte64_t *)page_ptr, vaddr, chk_data->access_type);
- break;
- case PAGE_1GB:
- case PAGE_2MB:
- case PAGE_4KB:
- return 0;
- default:
- PrintError("Inavlid page type (%s) in check pt 64 callback\n", v3_page_type_to_str(type));
- return -1;
- }
+ struct pt_check_data * chk_data = (struct pt_check_data *)private_data;
+
+ switch (type) {
+ case PAGE_PML464:
+ *(chk_data->access_status) = v3_can_access_pml4e64((pml4e64_t *)page_ptr, vaddr, chk_data->access_type);
+ break;
+ case PAGE_PDP64:
+ *(chk_data->access_status) = v3_can_access_pdpe64((pdpe64_t *)page_ptr, vaddr, chk_data->access_type);
+ break;
+ case PAGE_PD64:
+ *(chk_data->access_status) = v3_can_access_pde64((pde64_t *)page_ptr, vaddr, chk_data->access_type);
+ break;
+ case PAGE_PT64:
+ *(chk_data->access_status) = v3_can_access_pte64((pte64_t *)page_ptr, vaddr, chk_data->access_type);
+ break;
+ case PAGE_1GB:
+ case PAGE_2MB:
+ case PAGE_4KB:
+ return 0;
+ default:
+ PrintError("Inavlid page type (%s) in check pt 64 callback\n", v3_page_type_to_str(type));
+ return -1;
+ }
- if (chk_data->access_status != PT_ACCESS_OK) {
- return 1;
- }
+ if (chk_data->access_status != PT_ACCESS_OK) {
+ return 1;
+ }
- return 0;
+ return 0;
}
int v3_check_host_pt_32(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr, pf_error_t access_type, pt_access_status_t * access_status) {
- struct pt_check_data access_data;
+ struct pt_check_data access_data;
- access_data.access_type = access_type;
- access_data.access_status = access_status;
+ access_data.access_type = access_type;
+ access_data.access_status = access_status;
- return v3_drill_host_pt_32(info, host_cr3, vaddr, check_pt_32_cb, &access_data);
+ return v3_drill_host_pt_32(info, host_cr3, vaddr, check_pt_32_cb, &access_data);
}
int v3_check_host_pt_32pae(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr, pf_error_t access_type, pt_access_status_t * access_status) {
- struct pt_check_data access_data;
+ struct pt_check_data access_data;
- access_data.access_type = access_type;
- access_data.access_status = access_status;
+ access_data.access_type = access_type;
+ access_data.access_status = access_status;
- return v3_drill_host_pt_32pae(info, host_cr3, vaddr, check_pt_32pae_cb, &access_data);
+ return v3_drill_host_pt_32pae(info, host_cr3, vaddr, check_pt_32pae_cb, &access_data);
}
int v3_check_host_pt_64(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr, pf_error_t access_type, pt_access_status_t * access_status) {
- struct pt_check_data access_data;
+ struct pt_check_data access_data;
- access_data.access_type = access_type;
- access_data.access_status = access_status;
+ access_data.access_type = access_type;
+ access_data.access_status = access_status;
- return v3_drill_host_pt_64(info, host_cr3, vaddr, check_pt_64_cb, &access_data);
+ return v3_drill_host_pt_64(info, host_cr3, vaddr, check_pt_64_cb, &access_data);
}
int v3_check_guest_pt_32(struct guest_info * info, v3_reg_t guest_cr3, addr_t vaddr,
pf_error_t access_type, pt_access_status_t * access_status) {
- struct pt_check_data access_data;
+ struct pt_check_data access_data;
- access_data.access_type = access_type;
- access_data.access_status = access_status;
+ access_data.access_type = access_type;
+ access_data.access_status = access_status;
- return v3_drill_guest_pt_32(info, guest_cr3, vaddr, check_pt_32_cb, &access_data);
+ return v3_drill_guest_pt_32(info, guest_cr3, vaddr, check_pt_32_cb, &access_data);
}
int v3_check_guest_pt_32pae(struct guest_info * info, v3_reg_t guest_cr3, addr_t vaddr,
pf_error_t access_type, pt_access_status_t * access_status) {
- struct pt_check_data access_data;
+ struct pt_check_data access_data;
- access_data.access_type = access_type;
- access_data.access_status = access_status;
+ access_data.access_type = access_type;
+ access_data.access_status = access_status;
- return v3_drill_guest_pt_32pae(info, guest_cr3, vaddr, check_pt_32pae_cb, &access_data);
+ return v3_drill_guest_pt_32pae(info, guest_cr3, vaddr, check_pt_32pae_cb, &access_data);
}
int v3_check_guest_pt_64(struct guest_info * info, v3_reg_t guest_cr3, addr_t vaddr,
pf_error_t access_type, pt_access_status_t * access_status) {
- struct pt_check_data access_data;
+ struct pt_check_data access_data;
- access_data.access_type = access_type;
- access_data.access_status = access_status;
+ access_data.access_type = access_type;
+ access_data.access_status = access_status;
- return v3_drill_guest_pt_64(info, guest_cr3, vaddr, check_pt_64_cb, &access_data);
+ return v3_drill_guest_pt_64(info, guest_cr3, vaddr, check_pt_64_cb, &access_data);
}
static int get_data_page_type_cb(struct guest_info * info, page_type_t type,
addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data) {
- switch (type) {
- case PAGE_4KB:
- case PAGE_2MB:
- case PAGE_4MB:
- case PAGE_1GB:
- return 1;
- default:
- return 0;
- }
+ switch (type) {
+ case PAGE_4KB:
+ case PAGE_2MB:
+ case PAGE_4MB:
+ case PAGE_1GB:
+ return 1;
+ default:
+ return 0;
+ }
}
page_type_t v3_get_guest_data_page_type_32(struct guest_info * info, v3_reg_t cr3, addr_t vaddr) {
- return v3_drill_guest_pt_32(info, cr3, vaddr, get_data_page_type_cb, NULL);
+ return v3_drill_guest_pt_32(info, cr3, vaddr, get_data_page_type_cb, NULL);
}
page_type_t v3_get_guest_data_page_type_32pae(struct guest_info * info, v3_reg_t cr3, addr_t vaddr) {
- return v3_drill_guest_pt_32pae(info, cr3, vaddr, get_data_page_type_cb, NULL);
+ return v3_drill_guest_pt_32pae(info, cr3, vaddr, get_data_page_type_cb, NULL);
}
page_type_t v3_get_guest_data_page_type_64(struct guest_info * info, v3_reg_t cr3, addr_t vaddr) {
- return v3_drill_guest_pt_64(info, cr3, vaddr, get_data_page_type_cb, NULL);
+ return v3_drill_guest_pt_64(info, cr3, vaddr, get_data_page_type_cb, NULL);
}
page_type_t v3_get_host_data_page_type_32(struct guest_info * info, v3_reg_t cr3, addr_t vaddr) {
- return v3_drill_host_pt_32(info, cr3, vaddr, get_data_page_type_cb, NULL);
+ return v3_drill_host_pt_32(info, cr3, vaddr, get_data_page_type_cb, NULL);
}
page_type_t v3_get_host_data_page_type_32pae(struct guest_info * info, v3_reg_t cr3, addr_t vaddr) {
- return v3_drill_host_pt_32pae(info, cr3, vaddr, get_data_page_type_cb, NULL);
+ return v3_drill_host_pt_32pae(info, cr3, vaddr, get_data_page_type_cb, NULL);
}
page_type_t v3_get_host_data_page_type_64(struct guest_info * info, v3_reg_t cr3, addr_t vaddr) {
- return v3_drill_host_pt_64(info, cr3, vaddr, get_data_page_type_cb, NULL);
+ return v3_drill_host_pt_64(info, cr3, vaddr, get_data_page_type_cb, NULL);
}
**/
static pt_entry_type_t pde32_lookup(pde32_t * pd, addr_t addr, addr_t * entry) {
- pde32_t * pde_entry = &(pd[PDE32_INDEX(addr)]);
+ pde32_t * pde_entry = &(pd[PDE32_INDEX(addr)]);
- if (!pde_entry->present) {
- *entry = 0;
- return PT_ENTRY_NOT_PRESENT;
- } else if (pde_entry->large_page) {
- pde32_4MB_t * large_pde = (pde32_4MB_t *)pde_entry;
+ if (!pde_entry->present) {
+ *entry = 0;
+ return PT_ENTRY_NOT_PRESENT;
+ } else if (pde_entry->large_page) {
+ pde32_4MB_t * large_pde = (pde32_4MB_t *)pde_entry;
- *entry = BASE_TO_PAGE_ADDR_4MB(large_pde->page_base_addr);
+ *entry = BASE_TO_PAGE_ADDR_4MB(large_pde->page_base_addr);
- return PT_ENTRY_LARGE_PAGE;
- } else {
- *entry = BASE_TO_PAGE_ADDR(pde_entry->pt_base_addr);
- return PT_ENTRY_PAGE;
- }
+ return PT_ENTRY_LARGE_PAGE;
+ } else {
+ *entry = BASE_TO_PAGE_ADDR(pde_entry->pt_base_addr);
+ return PT_ENTRY_PAGE;
+ }
}
/* Takes a virtual addr (addr) and returns the physical addr (entry) as defined in the page table
*/
static pt_entry_type_t pte32_lookup(pte32_t * pt, addr_t addr, addr_t * entry) {
- pte32_t * pte_entry = &(pt[PTE32_INDEX(addr)]);
+ pte32_t * pte_entry = &(pt[PTE32_INDEX(addr)]);
- if (!pte_entry->present) {
- *entry = 0;
- // PrintDebug("Lookup at non present page (index=%d)\n", PTE32_INDEX(addr));
- return PT_ENTRY_NOT_PRESENT;
- } else {
- *entry = BASE_TO_PAGE_ADDR(pte_entry->page_base_addr);
+ if (!pte_entry->present) {
+ *entry = 0;
+ // PrintDebug("Lookup at non present page (index=%d)\n", PTE32_INDEX(addr));
+ return PT_ENTRY_NOT_PRESENT;
+ } else {
+ *entry = BASE_TO_PAGE_ADDR(pte_entry->page_base_addr);
- return PT_ENTRY_PAGE;
- }
+ return PT_ENTRY_PAGE;
+ }
}
*
**/
static pt_entry_type_t pdpe32pae_lookup(pdpe32pae_t * pdp, addr_t addr, addr_t * entry) {
- pdpe32pae_t * pdpe_entry = &(pdp[PDPE32PAE_INDEX(addr)]);
+ pdpe32pae_t * pdpe_entry = &(pdp[PDPE32PAE_INDEX(addr)]);
- if (!pdpe_entry->present) {
- *entry = 0;
- return PT_ENTRY_NOT_PRESENT;
- } else {
- *entry = BASE_TO_PAGE_ADDR(pdpe_entry->pd_base_addr);
- return PT_ENTRY_PAGE;
- }
+ if (!pdpe_entry->present) {
+ *entry = 0;
+ return PT_ENTRY_NOT_PRESENT;
+ } else {
+ *entry = BASE_TO_PAGE_ADDR(pdpe_entry->pd_base_addr);
+ return PT_ENTRY_PAGE;
+ }
}
static pt_entry_type_t pde32pae_lookup(pde32pae_t * pd, addr_t addr, addr_t * entry) {
- pde32pae_t * pde_entry = &(pd[PDE32PAE_INDEX(addr)]);
+ pde32pae_t * pde_entry = &(pd[PDE32PAE_INDEX(addr)]);
- if (!pde_entry->present) {
- *entry = 0;
- return PT_ENTRY_NOT_PRESENT;
- } else if (pde_entry->large_page) {
- pde32pae_2MB_t * large_pde = (pde32pae_2MB_t *)pde_entry;
+ if (!pde_entry->present) {
+ *entry = 0;
+ return PT_ENTRY_NOT_PRESENT;
+ } else if (pde_entry->large_page) {
+ pde32pae_2MB_t * large_pde = (pde32pae_2MB_t *)pde_entry;
- *entry = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
+ *entry = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
- return PT_ENTRY_LARGE_PAGE;
- } else {
- *entry = BASE_TO_PAGE_ADDR(pde_entry->pt_base_addr);
- return PT_ENTRY_PAGE;
- }
+ return PT_ENTRY_LARGE_PAGE;
+ } else {
+ *entry = BASE_TO_PAGE_ADDR(pde_entry->pt_base_addr);
+ return PT_ENTRY_PAGE;
+ }
}
static pt_entry_type_t pte32pae_lookup(pte32pae_t * pt, addr_t addr, addr_t * entry) {
- pte32pae_t * pte_entry = &(pt[PTE32PAE_INDEX(addr)]);
+ pte32pae_t * pte_entry = &(pt[PTE32PAE_INDEX(addr)]);
- if (!pte_entry->present) {
- *entry = 0;
- return PT_ENTRY_NOT_PRESENT;
- } else {
- *entry = BASE_TO_PAGE_ADDR(pte_entry->page_base_addr);
- return PT_ENTRY_PAGE;
- }
+ if (!pte_entry->present) {
+ *entry = 0;
+ return PT_ENTRY_NOT_PRESENT;
+ } else {
+ *entry = BASE_TO_PAGE_ADDR(pte_entry->page_base_addr);
+ return PT_ENTRY_PAGE;
+ }
}
*
**/
static pt_entry_type_t pml4e64_lookup(pml4e64_t * pml, addr_t addr, addr_t * entry) {
- pml4e64_t * pml_entry = &(pml[PML4E64_INDEX(addr)]);
+ pml4e64_t * pml_entry = &(pml[PML4E64_INDEX(addr)]);
- if (!pml_entry->present) {
- *entry = 0;
- return PT_ENTRY_NOT_PRESENT;
- } else {
- *entry = BASE_TO_PAGE_ADDR(pml_entry->pdp_base_addr);
- return PT_ENTRY_PAGE;
- }
+ if (!pml_entry->present) {
+ *entry = 0;
+ return PT_ENTRY_NOT_PRESENT;
+ } else {
+ *entry = BASE_TO_PAGE_ADDR(pml_entry->pdp_base_addr);
+ return PT_ENTRY_PAGE;
+ }
}
static pt_entry_type_t pdpe64_lookup(pdpe64_t * pdp, addr_t addr, addr_t * entry) {
- pdpe64_t * pdpe_entry = &(pdp[PDPE64_INDEX(addr)]);
+ pdpe64_t * pdpe_entry = &(pdp[PDPE64_INDEX(addr)]);
- if (!pdpe_entry->present) {
- *entry = 0;
- return PT_ENTRY_NOT_PRESENT;
- } else if (pdpe_entry->large_page) {
- PrintError("1 Gigabyte pages not supported\n");
- V3_ASSERT(0);
- return -1;
- } else {
- *entry = BASE_TO_PAGE_ADDR(pdpe_entry->pd_base_addr);
- return PT_ENTRY_PAGE;
- }
+ if (!pdpe_entry->present) {
+ *entry = 0;
+ return PT_ENTRY_NOT_PRESENT;
+ } else if (pdpe_entry->large_page) {
+ PrintError("1 Gigabyte pages not supported\n");
+ V3_ASSERT(0);
+ return -1;
+ } else {
+ *entry = BASE_TO_PAGE_ADDR(pdpe_entry->pd_base_addr);
+ return PT_ENTRY_PAGE;
+ }
}
static pt_entry_type_t pde64_lookup(pde64_t * pd, addr_t addr, addr_t * entry) {
- pde64_t * pde_entry = &(pd[PDE64_INDEX(addr)]);
+ pde64_t * pde_entry = &(pd[PDE64_INDEX(addr)]);
- if (!pde_entry->present) {
- *entry = 0;
- return PT_ENTRY_NOT_PRESENT;
- } else if (pde_entry->large_page) {
- pde64_2MB_t * large_pde = (pde64_2MB_t *)pde_entry;
+ if (!pde_entry->present) {
+ *entry = 0;
+ return PT_ENTRY_NOT_PRESENT;
+ } else if (pde_entry->large_page) {
+ pde64_2MB_t * large_pde = (pde64_2MB_t *)pde_entry;
- *entry = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
+ *entry = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
- return PT_ENTRY_LARGE_PAGE;
- } else {
- *entry = BASE_TO_PAGE_ADDR(pde_entry->pt_base_addr);
- return PT_ENTRY_PAGE;
- }
+ return PT_ENTRY_LARGE_PAGE;
+ } else {
+ *entry = BASE_TO_PAGE_ADDR(pde_entry->pt_base_addr);
+ return PT_ENTRY_PAGE;
+ }
}
static pt_entry_type_t pte64_lookup(pte64_t * pt, addr_t addr, addr_t * entry) {
- pte64_t * pte_entry = &(pt[PTE64_INDEX(addr)]);
+ pte64_t * pte_entry = &(pt[PTE64_INDEX(addr)]);
- if (!pte_entry->present) {
- *entry = 0;
- return PT_ENTRY_NOT_PRESENT;
- } else {
- *entry = BASE_TO_PAGE_ADDR(pte_entry->page_base_addr);
- return PT_ENTRY_PAGE;
- }
+ if (!pte_entry->present) {
+ *entry = 0;
+ return PT_ENTRY_NOT_PRESENT;
+ } else {
+ *entry = BASE_TO_PAGE_ADDR(pte_entry->page_base_addr);
+ return PT_ENTRY_PAGE;
+ }
}
static pt_access_status_t can_access_pt_entry(gen_pt_t * pt, pf_error_t access_type) {
- if (pt->present == 0) {
- return PT_ACCESS_NOT_PRESENT;
- } else if ((pt->writable == 0) && (access_type.write == 1)) {
- return PT_ACCESS_WRITE_ERROR;
- } else if ((pt->user_page == 0) && (access_type.user == 1)) {
- // Check CR0.WP?
- return PT_ACCESS_USER_ERROR;
- }
+ if (pt->present == 0) {
+ return PT_ACCESS_NOT_PRESENT;
+ } else if ((pt->writable == 0) && (access_type.write == 1)) {
+ return PT_ACCESS_WRITE_ERROR;
+ } else if ((pt->user_page == 0) && (access_type.user == 1)) {
+ // Check CR0.WP?
+ return PT_ACCESS_USER_ERROR;
+ }
- return PT_ACCESS_OK;
+ return PT_ACCESS_OK;
}
* 32 bit access checks
*/
pt_access_status_t inline v3_can_access_pde32(pde32_t * pde, addr_t addr, pf_error_t access_type) {
- gen_pt_t * entry = (gen_pt_t *)&pde[PDE32_INDEX(addr)];
- return can_access_pt_entry(entry, access_type);
+ gen_pt_t * entry = (gen_pt_t *)&pde[PDE32_INDEX(addr)];
+ return can_access_pt_entry(entry, access_type);
}
pt_access_status_t inline v3_can_access_pte32(pte32_t * pte, addr_t addr, pf_error_t access_type) {
- gen_pt_t * entry = (gen_pt_t *)&pte[PTE32_INDEX(addr)];
- return can_access_pt_entry(entry, access_type);
+ gen_pt_t * entry = (gen_pt_t *)&pte[PTE32_INDEX(addr)];
+ return can_access_pt_entry(entry, access_type);
}
* 32 bit PAE access checks
*/
pt_access_status_t inline v3_can_access_pdpe32pae(pdpe32pae_t * pdpe, addr_t addr, pf_error_t access_type) {
- gen_pt_t * entry = (gen_pt_t *)&pdpe[PDPE32PAE_INDEX(addr)];
- return can_access_pt_entry(entry, access_type);
+ gen_pt_t * entry = (gen_pt_t *)&pdpe[PDPE32PAE_INDEX(addr)];
+ return can_access_pt_entry(entry, access_type);
}
pt_access_status_t inline v3_can_access_pde32pae(pde32pae_t * pde, addr_t addr, pf_error_t access_type) {
- gen_pt_t * entry = (gen_pt_t *)&pde[PDE32PAE_INDEX(addr)];
- return can_access_pt_entry(entry, access_type);
+ gen_pt_t * entry = (gen_pt_t *)&pde[PDE32PAE_INDEX(addr)];
+ return can_access_pt_entry(entry, access_type);
}
pt_access_status_t inline v3_can_access_pte32pae(pte32pae_t * pte, addr_t addr, pf_error_t access_type) {
- gen_pt_t * entry = (gen_pt_t *)&pte[PTE32PAE_INDEX(addr)];
- return can_access_pt_entry(entry, access_type);
+ gen_pt_t * entry = (gen_pt_t *)&pte[PTE32PAE_INDEX(addr)];
+ return can_access_pt_entry(entry, access_type);
}
/*
* 64 Bit access checks
*/
pt_access_status_t inline v3_can_access_pml4e64(pml4e64_t * pmle, addr_t addr, pf_error_t access_type) {
- gen_pt_t * entry = (gen_pt_t *)&pmle[PML4E64_INDEX(addr)];
- return can_access_pt_entry(entry, access_type);
+ gen_pt_t * entry = (gen_pt_t *)&pmle[PML4E64_INDEX(addr)];
+ return can_access_pt_entry(entry, access_type);
}
pt_access_status_t inline v3_can_access_pdpe64(pdpe64_t * pdpe, addr_t addr, pf_error_t access_type) {
- gen_pt_t * entry = (gen_pt_t *)&pdpe[PDPE64_INDEX(addr)];
- return can_access_pt_entry(entry, access_type);
+ gen_pt_t * entry = (gen_pt_t *)&pdpe[PDPE64_INDEX(addr)];
+ return can_access_pt_entry(entry, access_type);
}
pt_access_status_t inline v3_can_access_pde64(pde64_t * pde, addr_t addr, pf_error_t access_type) {
- gen_pt_t * entry = (gen_pt_t *)&pde[PDE64_INDEX(addr)];
- return can_access_pt_entry(entry, access_type);
+ gen_pt_t * entry = (gen_pt_t *)&pde[PDE64_INDEX(addr)];
+ return can_access_pt_entry(entry, access_type);
}
pt_access_status_t inline v3_can_access_pte64(pte64_t * pte, addr_t addr, pf_error_t access_type) {
- gen_pt_t * entry = (gen_pt_t *)&pte[PTE64_INDEX(addr)];
- return can_access_pt_entry(entry, access_type);
+ gen_pt_t * entry = (gen_pt_t *)&pte[PTE64_INDEX(addr)];
+ return can_access_pt_entry(entry, access_type);
}
-
-
-
-
-/* We generate a page table to correspond to a given memory layout
- * pulling pages from the mem_list when necessary
- * If there are any gaps in the layout, we add them as unmapped pages
- */
-pde32_t * create_passthrough_pts_32(struct guest_info * guest_info) {
- addr_t current_page_addr = 0;
- int i, j;
-
- pde32_t * pde = V3_VAddr(V3_AllocPages(1));
-
- for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
- int pte_present = 0;
- pte32_t * pte = V3_VAddr(V3_AllocPages(1));
-
-
- for (j = 0; j < MAX_PTE32_ENTRIES; j++) {
- struct v3_shadow_region * region = v3_get_shadow_region(guest_info, current_page_addr);
-
- if (!region ||
- (region->host_type == SHDW_REGION_FULL_HOOK)) {
- pte[j].present = 0;
- pte[j].writable = 0;
- pte[j].user_page = 0;
- pte[j].write_through = 0;
- pte[j].cache_disable = 0;
- pte[j].accessed = 0;
- pte[j].dirty = 0;
- pte[j].pte_attr = 0;
- pte[j].global_page = 0;
- pte[j].vmm_info = 0;
- pte[j].page_base_addr = 0;
- } else {
- addr_t host_addr;
- pte[j].present = 1;
-
- if (region->host_type == SHDW_REGION_WRITE_HOOK) {
- pte[j].writable = 0;
- PrintDebug("Marking Write hook host_addr %p as RO\n", (void *)current_page_addr);
- } else {
- pte[j].writable = 1;
- }
-
- pte[j].user_page = 1;
- pte[j].write_through = 0;
- pte[j].cache_disable = 0;
- pte[j].accessed = 0;
- pte[j].dirty = 0;
- pte[j].pte_attr = 0;
- pte[j].global_page = 0;
- pte[j].vmm_info = 0;
-
- if (guest_pa_to_host_pa(guest_info, current_page_addr, &host_addr) == -1) {
- // BIG ERROR
- // PANIC
- return NULL;
- }
-
- pte[j].page_base_addr = host_addr >> 12;
-
- pte_present = 1;
- }
-
- current_page_addr += PAGE_SIZE;
- }
-
- if (pte_present == 0) {
- V3_FreePage(V3_PAddr(pte));
-
- pde[i].present = 0;
- pde[i].writable = 0;
- pde[i].user_page = 0;
- pde[i].write_through = 0;
- pde[i].cache_disable = 0;
- pde[i].accessed = 0;
- pde[i].reserved = 0;
- pde[i].large_page = 0;
- pde[i].global_page = 0;
- pde[i].vmm_info = 0;
- pde[i].pt_base_addr = 0;
- } else {
- pde[i].present = 1;
- pde[i].writable = 1;
- pde[i].user_page = 1;
- pde[i].write_through = 0;
- pde[i].cache_disable = 0;
- pde[i].accessed = 0;
- pde[i].reserved = 0;
- pde[i].large_page = 0;
- pde[i].global_page = 0;
- pde[i].vmm_info = 0;
- pde[i].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
+int v3_drill_host_pt_32(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr,
+ int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
+ void * private_data) {
+ pde32_t * host_pde = (pde32_t *)CR3_TO_PDE32_VA(host_cr3);
+ addr_t host_pde_pa = CR3_TO_PDE32_PA(host_cr3);
+ addr_t host_pte_pa = 0;
+ addr_t page_pa = 0;
+ int ret;
+
+ if ((ret = callback(info, PAGE_PD32, vaddr, (addr_t)host_pde, host_pde_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PD32;
}
- }
-
- return pde;
-}
-
-
-/* We generate a page table to correspond to a given memory layout
- * pulling pages from the mem_list when necessary
- * If there are any gaps in the layout, we add them as unmapped pages
- */
-pdpe32pae_t * create_passthrough_pts_32PAE(struct guest_info * guest_info) {
- addr_t current_page_addr = 0;
- int i, j, k;
-
- pdpe32pae_t * pdpe = V3_VAddr(V3_AllocPages(1));
- memset(pdpe, 0, PAGE_SIZE);
-
- for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) {
- int pde_present = 0;
- pde32pae_t * pde = V3_VAddr(V3_AllocPages(1));
-
- for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) {
-
-
- int pte_present = 0;
- pte32pae_t * pte = V3_VAddr(V3_AllocPages(1));
-
-
- for (k = 0; k < MAX_PTE32PAE_ENTRIES; k++) {
- struct v3_shadow_region * region = v3_get_shadow_region(guest_info, current_page_addr);
-
- if (!region ||
- (region->host_type == SHDW_REGION_FULL_HOOK)) {
- pte[k].present = 0;
- pte[k].writable = 0;
- pte[k].user_page = 0;
- pte[k].write_through = 0;
- pte[k].cache_disable = 0;
- pte[k].accessed = 0;
- pte[k].dirty = 0;
- pte[k].pte_attr = 0;
- pte[k].global_page = 0;
- pte[k].vmm_info = 0;
- pte[k].page_base_addr = 0;
- pte[k].rsvd = 0;
- } else {
- addr_t host_addr;
- pte[k].present = 1;
-
- if (region->host_type == SHDW_REGION_WRITE_HOOK) {
- pte[k].writable = 0;
- } else {
- pte[k].writable = 1;
- }
-
- pte[k].user_page = 1;
- pte[k].write_through = 0;
- pte[k].cache_disable = 0;
- pte[k].accessed = 0;
- pte[k].dirty = 0;
- pte[k].pte_attr = 0;
- pte[k].global_page = 0;
- pte[k].vmm_info = 0;
-
- if (guest_pa_to_host_pa(guest_info, current_page_addr, &host_addr) == -1) {
- // BIG ERROR
- // PANIC
- return NULL;
- }
-
- pte[k].page_base_addr = host_addr >> 12;
- pte[k].rsvd = 0;
-
- pte_present = 1;
- }
-
- current_page_addr += PAGE_SIZE;
- }
-
- if (pte_present == 0) {
- V3_FreePage(V3_PAddr(pte));
-
- pde[j].present = 0;
- pde[j].writable = 0;
- pde[j].user_page = 0;
- pde[j].write_through = 0;
- pde[j].cache_disable = 0;
- pde[j].accessed = 0;
- pde[j].avail = 0;
- pde[j].large_page = 0;
- pde[j].global_page = 0;
- pde[j].vmm_info = 0;
- pde[j].pt_base_addr = 0;
- pde[j].rsvd = 0;
- } else {
- pde[j].present = 1;
- pde[j].writable = 1;
- pde[j].user_page = 1;
- pde[j].write_through = 0;
- pde[j].cache_disable = 0;
- pde[j].accessed = 0;
- pde[j].avail = 0;
- pde[j].large_page = 0;
- pde[j].global_page = 0;
- pde[j].vmm_info = 0;
- pde[j].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
- pde[j].rsvd = 0;
-
- pde_present = 1;
- }
-
- }
-
- if (pde_present == 0) {
- V3_FreePage(V3_PAddr(pde));
-
- pdpe[i].present = 0;
- pdpe[i].rsvd = 0;
- pdpe[i].write_through = 0;
- pdpe[i].cache_disable = 0;
- pdpe[i].accessed = 0;
- pdpe[i].avail = 0;
- pdpe[i].rsvd2 = 0;
- pdpe[i].vmm_info = 0;
- pdpe[i].pd_base_addr = 0;
- pdpe[i].rsvd3 = 0;
- } else {
- pdpe[i].present = 1;
- pdpe[i].rsvd = 0;
- pdpe[i].write_through = 0;
- pdpe[i].cache_disable = 0;
- pdpe[i].accessed = 0;
- pdpe[i].avail = 0;
- pdpe[i].rsvd2 = 0;
- pdpe[i].vmm_info = 0;
- pdpe[i].pd_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pde));
- pdpe[i].rsvd3 = 0;
- }
+ switch (pde32_lookup(host_pde, vaddr, &host_pte_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_LARGE_PAGE:
+ if ((ret == callback(info, PAGE_4MB, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_4MB;
+ }
+ return 0;
+ case PT_ENTRY_PAGE:
+ if ((ret = callback(info, PAGE_PT32, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data) != 0)) {
+ return (ret == -1) ? -1 : PAGE_PT32;
+ }
- }
-
-
- return pdpe;
-}
-
-
-
-
-
-
-pml4e64_t * create_passthrough_pts_64(struct guest_info * info) {
- addr_t current_page_addr = 0;
- int i, j, k, m;
-
- pml4e64_t * pml = V3_VAddr(V3_AllocPages(1));
-
- for (i = 0; i < 1; i++) {
- int pdpe_present = 0;
- pdpe64_t * pdpe = V3_VAddr(V3_AllocPages(1));
-
- for (j = 0; j < 20; j++) {
- int pde_present = 0;
- pde64_t * pde = V3_VAddr(V3_AllocPages(1));
-
- for (k = 0; k < MAX_PDE64_ENTRIES; k++) {
- int pte_present = 0;
- pte64_t * pte = V3_VAddr(V3_AllocPages(1));
-
-
- for (m = 0; m < MAX_PTE64_ENTRIES; m++) {
- struct v3_shadow_region * region = v3_get_shadow_region(info, current_page_addr);
-
-
-
- if (!region ||
- (region->host_type == SHDW_REGION_FULL_HOOK)) {
- pte[m].present = 0;
- pte[m].writable = 0;
- pte[m].user_page = 0;
- pte[m].write_through = 0;
- pte[m].cache_disable = 0;
- pte[m].accessed = 0;
- pte[m].dirty = 0;
- pte[m].pte_attr = 0;
- pte[m].global_page = 0;
- pte[m].vmm_info = 0;
- pte[m].page_base_addr = 0;
- } else {
- addr_t host_addr;
- pte[m].present = 1;
-
- if (region->host_type == SHDW_REGION_WRITE_HOOK) {
- pte[m].writable = 0;
+ if (pte32_lookup(V3_VAddr((void *)host_pte_pa), vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
+ return -1;
} else {
- pte[m].writable = 1;
- }
-
- pte[m].user_page = 1;
- pte[m].write_through = 0;
- pte[m].cache_disable = 0;
- pte[m].accessed = 0;
- pte[m].dirty = 0;
- pte[m].pte_attr = 0;
- pte[m].global_page = 0;
- pte[m].vmm_info = 0;
-
- if (guest_pa_to_host_pa(info, current_page_addr, &host_addr) == -1) {
- // BIG ERROR
- // PANIC
- return NULL;
+ if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)PAGE_BASE_ADDR(page_pa)), page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_4KB;
+ }
+ return 0;
}
-
- pte[m].page_base_addr = PAGE_BASE_ADDR(host_addr);
-
- //PrintPTE64(current_page_addr, &(pte[m]));
-
- pte_present = 1;
- }
-
-
-
-
- current_page_addr += PAGE_SIZE;
- }
-
- if (pte_present == 0) {
- V3_FreePage(V3_PAddr(pte));
-
- pde[k].present = 0;
- pde[k].writable = 0;
- pde[k].user_page = 0;
- pde[k].write_through = 0;
- pde[k].cache_disable = 0;
- pde[k].accessed = 0;
- pde[k].avail = 0;
- pde[k].large_page = 0;
- //pde[k].global_page = 0;
- pde[k].vmm_info = 0;
- pde[k].pt_base_addr = 0;
- } else {
- pde[k].present = 1;
- pde[k].writable = 1;
- pde[k].user_page = 1;
- pde[k].write_through = 0;
- pde[k].cache_disable = 0;
- pde[k].accessed = 0;
- pde[k].avail = 0;
- pde[k].large_page = 0;
- //pde[k].global_page = 0;
- pde[k].vmm_info = 0;
- pde[k].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
-
- pde_present = 1;
- }
- }
-
- if (pde_present == 0) {
- V3_FreePage(V3_PAddr(pde));
-
- pdpe[j].present = 0;
- pdpe[j].writable = 0;
- pdpe[j].user_page = 0;
- pdpe[j].write_through = 0;
- pdpe[j].cache_disable = 0;
- pdpe[j].accessed = 0;
- pdpe[j].avail = 0;
- pdpe[j].large_page = 0;
- //pdpe[j].global_page = 0;
- pdpe[j].vmm_info = 0;
- pdpe[j].pd_base_addr = 0;
- } else {
- pdpe[j].present = 1;
- pdpe[j].writable = 1;
- pdpe[j].user_page = 1;
- pdpe[j].write_through = 0;
- pdpe[j].cache_disable = 0;
- pdpe[j].accessed = 0;
- pdpe[j].avail = 0;
- pdpe[j].large_page = 0;
- //pdpe[j].global_page = 0;
- pdpe[j].vmm_info = 0;
- pdpe[j].pd_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pde));
-
-
- pdpe_present = 1;
- }
-
}
-
- PrintDebug("PML index=%d\n", i);
-
- if (pdpe_present == 0) {
- V3_FreePage(V3_PAddr(pdpe));
-
- pml[i].present = 0;
- pml[i].writable = 0;
- pml[i].user_page = 0;
- pml[i].write_through = 0;
- pml[i].cache_disable = 0;
- pml[i].accessed = 0;
- pml[i].reserved = 0;
- //pml[i].large_page = 0;
- //pml[i].global_page = 0;
- pml[i].vmm_info = 0;
- pml[i].pdp_base_addr = 0;
- } else {
- pml[i].present = 1;
- pml[i].writable = 1;
- pml[i].user_page = 1;
- pml[i].write_through = 0;
- pml[i].cache_disable = 0;
- pml[i].accessed = 0;
- pml[i].reserved = 0;
- //pml[i].large_page = 0;
- //pml[i].global_page = 0;
- pml[i].vmm_info = 0;
- pml[i].pdp_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pdpe));
- }
- }
-
- return pml;
-}
-
-
-int v3_drill_host_pt_32(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr,
- int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
- void * private_data) {
- pde32_t * host_pde = (pde32_t *)CR3_TO_PDE32_VA(host_cr3);
- addr_t host_pde_pa = CR3_TO_PDE32_PA(host_cr3);
- addr_t host_pte_pa = 0;
- addr_t page_pa = 0;
- int ret;
-
- if ((ret = callback(info, PAGE_PD32, vaddr, (addr_t)host_pde, host_pde_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PD32;
- }
-
- switch (pde32_lookup(host_pde, vaddr, &host_pte_pa)) {
- case PT_ENTRY_NOT_PRESENT:
return -1;
- case PT_ENTRY_LARGE_PAGE:
- if ((ret == callback(info, PAGE_4MB, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_4MB;
- }
- return 0;
- case PT_ENTRY_PAGE:
- if ((ret = callback(info, PAGE_PT32, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data) != 0)) {
- return (ret == -1) ? -1 : PAGE_PT32;
- }
-
- if (pte32_lookup(V3_VAddr((void *)host_pte_pa), vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
- return -1;
- } else {
- if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)PAGE_BASE_ADDR(page_pa)), page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_4KB;
- }
- return 0;
- }
- }
- return -1;
}
int v3_drill_host_pt_32pae(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr,
int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
void * private_data) {
- pdpe32pae_t * host_pdpe = (pdpe32pae_t *)CR3_TO_PDPE32PAE_VA(host_cr3);
- addr_t host_pdpe_pa = CR3_TO_PDPE32PAE_PA(host_cr3);
- addr_t host_pde_pa = 0;
- addr_t host_pte_pa = 0;
- addr_t page_pa = 0;
- int ret;
-
- if ((ret = callback(info, PAGE_PDP32PAE, vaddr, (addr_t)host_pdpe, host_pdpe_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PDP32PAE;
- }
-
- switch (pdpe32pae_lookup(host_pdpe, vaddr, &host_pde_pa)) {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_PAGE:
-
- if ((ret = callback(info, PAGE_PD32PAE, vaddr, (addr_t)V3_VAddr((void *)host_pde_pa), host_pde_pa, private_data) != 0)) {
- return (ret == -1) ? -1 : PAGE_PD32PAE;
+ pdpe32pae_t * host_pdpe = (pdpe32pae_t *)CR3_TO_PDPE32PAE_VA(host_cr3);
+ addr_t host_pdpe_pa = CR3_TO_PDPE32PAE_PA(host_cr3);
+ addr_t host_pde_pa = 0;
+ addr_t host_pte_pa = 0;
+ addr_t page_pa = 0;
+ int ret;
+
+ if ((ret = callback(info, PAGE_PDP32PAE, vaddr, (addr_t)host_pdpe, host_pdpe_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PDP32PAE;
}
+
+ switch (pdpe32pae_lookup(host_pdpe, vaddr, &host_pde_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_PAGE:
+
+ if ((ret = callback(info, PAGE_PD32PAE, vaddr, (addr_t)V3_VAddr((void *)host_pde_pa), host_pde_pa, private_data) != 0)) {
+ return (ret == -1) ? -1 : PAGE_PD32PAE;
+ }
- switch (pde32pae_lookup(V3_VAddr((void *)host_pde_pa), vaddr, &host_pte_pa)) {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_LARGE_PAGE:
- if ((ret == callback(info, PAGE_2MB, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_2MB;
- }
- return 0;
- case PT_ENTRY_PAGE:
- if ((ret = callback(info, PAGE_PT32PAE, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data) != 0)) {
- return (ret == -1) ? -1 : PAGE_PT32PAE;
- }
-
- if (pte32pae_lookup(V3_VAddr((void *)host_pte_pa), vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
- return -1;
- } else {
- if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)PAGE_BASE_ADDR(page_pa)), page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_4KB;
- }
- return 0;
- }
+ switch (pde32pae_lookup(V3_VAddr((void *)host_pde_pa), vaddr, &host_pte_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_LARGE_PAGE:
+ if ((ret == callback(info, PAGE_2MB, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_2MB;
+ }
+ return 0;
+ case PT_ENTRY_PAGE:
+ if ((ret = callback(info, PAGE_PT32PAE, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data) != 0)) {
+ return (ret == -1) ? -1 : PAGE_PT32PAE;
+ }
+
+ if (pte32pae_lookup(V3_VAddr((void *)host_pte_pa), vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
+ return -1;
+ } else {
+ if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)PAGE_BASE_ADDR(page_pa)), page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_4KB;
+ }
+ return 0;
+ }
+ }
+ default:
+ return -1;
}
- default:
- return -1;
- }
- // should never get here
- return -1;
+ // should never get here
+ return -1;
}
int v3_drill_host_pt_64(struct guest_info * info, v3_reg_t host_cr3, addr_t vaddr,
int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
void * private_data) {
- pml4e64_t * host_pmle = (pml4e64_t *)CR3_TO_PML4E64_VA(host_cr3);
- addr_t host_pmle_pa = CR3_TO_PML4E64_PA(host_cr3);
- addr_t host_pdpe_pa = 0;
- addr_t host_pde_pa = 0;
- addr_t host_pte_pa = 0;
- addr_t page_pa = 0;
- int ret;
-
- if ((ret = callback(info, PAGE_PML464, vaddr, (addr_t)host_pmle, host_pmle_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PML464;
- }
-
- switch(pml4e64_lookup(host_pmle, vaddr, &host_pdpe_pa)) {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_PAGE:
-
- if ((ret = callback(info, PAGE_PDP64, vaddr, (addr_t)V3_VAddr((void *)host_pdpe_pa), host_pdpe_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PDP64;
+ pml4e64_t * host_pmle = (pml4e64_t *)CR3_TO_PML4E64_VA(host_cr3);
+ addr_t host_pmle_pa = CR3_TO_PML4E64_PA(host_cr3);
+ addr_t host_pdpe_pa = 0;
+ addr_t host_pde_pa = 0;
+ addr_t host_pte_pa = 0;
+ addr_t page_pa = 0;
+ int ret;
+
+ if ((ret = callback(info, PAGE_PML464, vaddr, (addr_t)host_pmle, host_pmle_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PML464;
}
- switch(pdpe64_lookup(V3_VAddr((void *)host_pdpe_pa), vaddr, &host_pde_pa)) {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_LARGE_PAGE:
- if ((ret == callback(info, PAGE_1GB, vaddr, (addr_t)V3_VAddr((void *)host_pde_pa), host_pde_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_1GB;
- }
- PrintError("1 Gigabyte Pages not supported\n");
- return 0;
- case PT_ENTRY_PAGE:
-
- if ((ret = callback(info, PAGE_PD64, vaddr, (addr_t)V3_VAddr((void *)host_pde_pa), host_pde_pa, private_data) != 0)) {
- return (ret == -1) ? -1 : PAGE_PD64;
- }
-
- switch (pde64_lookup(V3_VAddr((void *)host_pde_pa), vaddr, &host_pte_pa)) {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_LARGE_PAGE:
- if ((ret == callback(info, PAGE_2MB, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_2MB;
- }
- return 0;
- case PT_ENTRY_PAGE:
+ switch(pml4e64_lookup(host_pmle, vaddr, &host_pdpe_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_PAGE:
- if ((ret = callback(info, PAGE_PT64, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data) != 0)) {
- return (ret == -1) ? -1 : PAGE_PT64;
- }
+ if ((ret = callback(info, PAGE_PDP64, vaddr, (addr_t)V3_VAddr((void *)host_pdpe_pa), host_pdpe_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PDP64;
+ }
- if (pte64_lookup(V3_VAddr((void *)host_pte_pa), vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
- return -1;
- } else {
- if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)PAGE_BASE_ADDR(page_pa)), page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_4KB;
- }
- return 0;
- }
- }
+ switch(pdpe64_lookup(V3_VAddr((void *)host_pdpe_pa), vaddr, &host_pde_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_LARGE_PAGE:
+ if ((ret == callback(info, PAGE_1GB, vaddr, (addr_t)V3_VAddr((void *)host_pde_pa), host_pde_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_1GB;
+ }
+ PrintError("1 Gigabyte Pages not supported\n");
+ return 0;
+ case PT_ENTRY_PAGE:
+
+ if ((ret = callback(info, PAGE_PD64, vaddr, (addr_t)V3_VAddr((void *)host_pde_pa), host_pde_pa, private_data) != 0)) {
+ return (ret == -1) ? -1 : PAGE_PD64;
+ }
+
+ switch (pde64_lookup(V3_VAddr((void *)host_pde_pa), vaddr, &host_pte_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_LARGE_PAGE:
+ if ((ret == callback(info, PAGE_2MB, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_2MB;
+ }
+ return 0;
+ case PT_ENTRY_PAGE:
+
+ if ((ret = callback(info, PAGE_PT64, vaddr, (addr_t)V3_VAddr((void *)host_pte_pa), host_pte_pa, private_data) != 0)) {
+ return (ret == -1) ? -1 : PAGE_PT64;
+ }
+
+ if (pte64_lookup(V3_VAddr((void *)host_pte_pa), vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
+ return -1;
+ } else {
+ if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)PAGE_BASE_ADDR(page_pa)), page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_4KB;
+ }
+ return 0;
+ }
+ }
+ }
+ default:
+ return -1;
}
- default:
+ // should never get here
return -1;
- }
- // should never get here
- return -1;
}
int v3_drill_guest_pt_32(struct guest_info * info, v3_reg_t guest_cr3, addr_t vaddr,
int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
void * private_data) {
- addr_t guest_pde_pa = CR3_TO_PDE32_PA(guest_cr3);
- pde32_t * guest_pde = NULL;
- addr_t guest_pte_pa = 0;
- int ret;
+ addr_t guest_pde_pa = CR3_TO_PDE32_PA(guest_cr3);
+ pde32_t * guest_pde = NULL;
+ addr_t guest_pte_pa = 0;
+ int ret;
- if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
- PrintError("Could not get virtual address of Guest PDE32 (PA=%p)\n",
- (void *)guest_pde_pa);
- return -1;
- }
+ if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
+ PrintError("Could not get virtual address of Guest PDE32 (PA=%p)\n",
+ (void *)guest_pde_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PD32, vaddr, (addr_t)guest_pde, guest_pde_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PD32;
- }
+ if ((ret = callback(info, PAGE_PD32, vaddr, (addr_t)guest_pde, guest_pde_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PD32;
+ }
- switch (pde32_lookup(guest_pde, vaddr, &guest_pte_pa)) {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_LARGE_PAGE:
- {
- addr_t large_page_pa = (addr_t)guest_pte_pa;
- addr_t large_page_va = 0;
+ switch (pde32_lookup(guest_pde, vaddr, &guest_pte_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_LARGE_PAGE:
+ {
+ addr_t large_page_pa = (addr_t)guest_pte_pa;
+ addr_t large_page_va = 0;
- if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
- PrintError("Could not get virtual address of Guest Page 4MB (PA=%p)\n",
- (void *)large_page_va);
- return -1;
- }
+ if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
+ PrintError("Could not get virtual address of Guest Page 4MB (PA=%p)\n",
+ (void *)large_page_va);
+ return -1;
+ }
- if ((ret == callback(info, PAGE_4MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_4MB;
- }
- return 0;
- }
- case PT_ENTRY_PAGE:
- {
- pte32_t * guest_pte = NULL;
- addr_t page_pa;
-
- if (guest_pa_to_host_va(info, guest_pte_pa, (addr_t*)&guest_pte) == -1) {
- PrintError("Could not get virtual address of Guest PTE32 (PA=%p)\n",
- (void *)guest_pte_pa);
- return -1;
- }
-
- if ((ret = callback(info, PAGE_PT32, vaddr, (addr_t)guest_pte, guest_pte_pa, private_data) != 0)) {
- return (ret == -1) ? -1 : PAGE_PT32;
- }
-
- if (pte32_lookup(guest_pte, vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
- return -1;
- } else {
- addr_t page_va;
-
- if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
- PrintError("Could not get virtual address of Guest Page 4KB (PA=%p)\n",
- (void *)page_pa);
- return -1;
- }
+ if ((ret == callback(info, PAGE_4MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_4MB;
+ }
+ return 0;
+ }
+ case PT_ENTRY_PAGE:
+ {
+ pte32_t * guest_pte = NULL;
+ addr_t page_pa;
- if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_4KB;
- }
- return 0;
- }
+ if (guest_pa_to_host_va(info, guest_pte_pa, (addr_t*)&guest_pte) == -1) {
+ PrintError("Could not get virtual address of Guest PTE32 (PA=%p)\n",
+ (void *)guest_pte_pa);
+ return -1;
+ }
+
+ if ((ret = callback(info, PAGE_PT32, vaddr, (addr_t)guest_pte, guest_pte_pa, private_data) != 0)) {
+ return (ret == -1) ? -1 : PAGE_PT32;
+ }
+
+ if (pte32_lookup(guest_pte, vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
+ return -1;
+ } else {
+ addr_t page_va;
+
+ if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
+ PrintError("Could not get virtual address of Guest Page 4KB (PA=%p)\n",
+ (void *)page_pa);
+ return -1;
+ }
+
+ if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_4KB;
+ }
+ return 0;
+ }
+ }
}
- }
- // should never get here
- PrintError("End of drill function (guest 32)... Should never have gotten here...\n");
- return -1;
+ // should never get here
+ PrintError("End of drill function (guest 32)... Should never have gotten here...\n");
+ return -1;
}
int v3_drill_guest_pt_32pae(struct guest_info * info, v3_reg_t guest_cr3, addr_t vaddr,
- int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
- void * private_data) {
- addr_t guest_pdpe_pa = CR3_TO_PDPE32PAE_PA(guest_cr3);
- pdpe32pae_t * guest_pdpe = 0;
- addr_t guest_pde_pa = 0;
- int ret = 0;
-
- if (guest_pa_to_host_va(info, guest_pdpe_pa, (addr_t*)&guest_pdpe) == -1) {
- PrintError("Could not get virtual address of Guest PDPE32PAE (PA=%p)\n",
- (void *)guest_pdpe_pa);
- return -1;
- }
-
- if ((ret = callback(info, PAGE_PDP32PAE, vaddr, (addr_t)guest_pdpe, guest_pdpe_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PDP32PAE;
- }
-
- switch (pdpe32pae_lookup(guest_pdpe, vaddr, &guest_pde_pa))
- {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_PAGE:
- {
- pde32pae_t * guest_pde = NULL;
- addr_t guest_pte_pa = 0;
+ int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
+ void * private_data) {
+ addr_t guest_pdpe_pa = CR3_TO_PDPE32PAE_PA(guest_cr3);
+ pdpe32pae_t * guest_pdpe = 0;
+ addr_t guest_pde_pa = 0;
+ int ret = 0;
+
+ if (guest_pa_to_host_va(info, guest_pdpe_pa, (addr_t*)&guest_pdpe) == -1) {
+ PrintError("Could not get virtual address of Guest PDPE32PAE (PA=%p)\n",
+ (void *)guest_pdpe_pa);
+ return -1;
+ }
+
+ if ((ret = callback(info, PAGE_PDP32PAE, vaddr, (addr_t)guest_pdpe, guest_pdpe_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PDP32PAE;
+ }
+
+ switch (pdpe32pae_lookup(guest_pdpe, vaddr, &guest_pde_pa))
+ {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_PAGE:
+ {
+ pde32pae_t * guest_pde = NULL;
+ addr_t guest_pte_pa = 0;
- if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
- PrintError("Could not get virtual Address of Guest PDE32PAE (PA=%p)\n",
- (void *)guest_pde_pa);
- return -1;
- }
+ if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
+ PrintError("Could not get virtual Address of Guest PDE32PAE (PA=%p)\n",
+ (void *)guest_pde_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PD32PAE, vaddr, (addr_t)guest_pde, guest_pde_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PD32PAE;
- }
+ if ((ret = callback(info, PAGE_PD32PAE, vaddr, (addr_t)guest_pde, guest_pde_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PD32PAE;
+ }
- switch (pde32pae_lookup(guest_pde, vaddr, &guest_pte_pa))
- {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_LARGE_PAGE:
- {
- addr_t large_page_pa = (addr_t)guest_pte_pa;
- addr_t large_page_va = 0;
+ switch (pde32pae_lookup(guest_pde, vaddr, &guest_pte_pa))
+ {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_LARGE_PAGE:
+ {
+ addr_t large_page_pa = (addr_t)guest_pte_pa;
+ addr_t large_page_va = 0;
- if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest Page 2MB (PA=%p)\n",
- (void *)large_page_va);
+ if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest Page 2MB (PA=%p)\n",
+ (void *)large_page_va);
- }
+ }
- if ((ret == callback(info, PAGE_2MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_2MB;
- }
- return 0;
- }
- case PT_ENTRY_PAGE:
- {
- pte32pae_t * guest_pte = NULL;
- addr_t page_pa;
-
- if (guest_pa_to_host_va(info, guest_pte_pa, (addr_t *)&guest_pte) == -1) {
- PrintError("Could not get virtual Address of Guest PTE32PAE (PA=%p)\n",
- (void *)guest_pte_pa);
- return -1;
- }
-
- if ((ret = callback(info, PAGE_PT32PAE, vaddr, (addr_t)guest_pte, guest_pte_pa, private_data) != 0)) {
- return (ret == -1) ? -1 : PAGE_PT32PAE;
- }
-
- if (pte32pae_lookup(guest_pte, vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
- return -1;
- } else {
- addr_t page_va;
+ if ((ret == callback(info, PAGE_2MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_2MB;
+ }
+ return 0;
+ }
+ case PT_ENTRY_PAGE:
+ {
+ pte32pae_t * guest_pte = NULL;
+ addr_t page_pa;
+
+ if (guest_pa_to_host_va(info, guest_pte_pa, (addr_t *)&guest_pte) == -1) {
+ PrintError("Could not get virtual Address of Guest PTE32PAE (PA=%p)\n",
+ (void *)guest_pte_pa);
+ return -1;
+ }
+
+ if ((ret = callback(info, PAGE_PT32PAE, vaddr, (addr_t)guest_pte, guest_pte_pa, private_data) != 0)) {
+ return (ret == -1) ? -1 : PAGE_PT32PAE;
+ }
+
+ if (pte32pae_lookup(guest_pte, vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
+ return -1;
+ } else {
+ addr_t page_va;
- if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
- PrintError("Could not get virtual address of Guest Page 4KB (PA=%p)\n",
- (void *)page_pa);
- return -1;
- }
+ if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
+ PrintError("Could not get virtual address of Guest Page 4KB (PA=%p)\n",
+ (void *)page_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_4KB;
+ if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_4KB;
+ }
+ return 0;
+ }
+ }
+ }
}
- return 0;
- }
- }
- }
- }
- default:
- PrintError("Invalid page type for PD32PAE\n");
- return -1;
- }
+ default:
+ PrintError("Invalid page type for PD32PAE\n");
+ return -1;
+ }
- // should never get here
- PrintError("End of drill function (guest 32pae)... Should never have gotten here...\n");
- return -1;
+ // should never get here
+ PrintError("End of drill function (guest 32pae)... Should never have gotten here...\n");
+ return -1;
}
int v3_drill_guest_pt_64(struct guest_info * info, v3_reg_t guest_cr3, addr_t vaddr,
- int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
- void * private_data) {
- addr_t guest_pml4_pa = CR3_TO_PML4E64_PA(guest_cr3);
- pml4e64_t * guest_pmle = 0;
- addr_t guest_pdpe_pa = 0;
- int ret = 0;
-
- if (guest_pa_to_host_va(info, guest_pml4_pa, (addr_t*)&guest_pmle) == -1) {
- PrintError("Could not get virtual address of Guest PML4E64 (PA=%p)\n",
- (void *)guest_pml4_pa);
- return -1;
- }
+ int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
+ void * private_data) {
+ addr_t guest_pml4_pa = CR3_TO_PML4E64_PA(guest_cr3);
+ pml4e64_t * guest_pmle = 0;
+ addr_t guest_pdpe_pa = 0;
+ int ret = 0;
+
+ if (guest_pa_to_host_va(info, guest_pml4_pa, (addr_t*)&guest_pmle) == -1) {
+ PrintError("Could not get virtual address of Guest PML4E64 (PA=%p)\n",
+ (void *)guest_pml4_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PML464, vaddr, (addr_t)guest_pmle, guest_pml4_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PML464;
- }
+ if ((ret = callback(info, PAGE_PML464, vaddr, (addr_t)guest_pmle, guest_pml4_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PML464;
+ }
- switch (pml4e64_lookup(guest_pmle, vaddr, &guest_pdpe_pa)) {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_PAGE:
- {
- pdpe64_t * guest_pdp = NULL;
- addr_t guest_pde_pa = 0;
+ switch (pml4e64_lookup(guest_pmle, vaddr, &guest_pdpe_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_PAGE:
+ {
+ pdpe64_t * guest_pdp = NULL;
+ addr_t guest_pde_pa = 0;
- if (guest_pa_to_host_va(info, guest_pdpe_pa, (addr_t *)&guest_pdp) == -1) {
- PrintError("Could not get virtual address of Guest PDPE64 (PA=%p)\n",
- (void *)guest_pdpe_pa);
- return -1;
- }
+ if (guest_pa_to_host_va(info, guest_pdpe_pa, (addr_t *)&guest_pdp) == -1) {
+ PrintError("Could not get virtual address of Guest PDPE64 (PA=%p)\n",
+ (void *)guest_pdpe_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PDP64, vaddr, (addr_t)guest_pdp, guest_pdpe_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PDP64;
- }
+ if ((ret = callback(info, PAGE_PDP64, vaddr, (addr_t)guest_pdp, guest_pdpe_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PDP64;
+ }
- switch (pdpe64_lookup(guest_pdp, vaddr, &guest_pde_pa)) {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_LARGE_PAGE:
- {
- addr_t large_page_pa = (addr_t)guest_pde_pa;
- addr_t large_page_va = 0;
+ switch (pdpe64_lookup(guest_pdp, vaddr, &guest_pde_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_LARGE_PAGE:
+ {
+ addr_t large_page_pa = (addr_t)guest_pde_pa;
+ addr_t large_page_va = 0;
- if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest Page 1GB (PA=%p)\n",
- (void *)large_page_va);
+ if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest Page 1GB (PA=%p)\n",
+ (void *)large_page_va);
- }
+ }
- if ((ret == callback(info, PAGE_1GB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_1GB;
- }
- PrintError("1 Gigabyte Pages not supported\n");
- return 0;
- }
- case PT_ENTRY_PAGE:
- {
- pde64_t * guest_pde = NULL;
- addr_t guest_pte_pa = 0;
-
- if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
- PrintError("Could not get virtual address of guest PDE64 (PA=%p)\n",
- (void *)guest_pde_pa);
- return -1;
- }
+ if ((ret == callback(info, PAGE_1GB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_1GB;
+ }
+ PrintError("1 Gigabyte Pages not supported\n");
+ return 0;
+ }
+ case PT_ENTRY_PAGE:
+ {
+ pde64_t * guest_pde = NULL;
+ addr_t guest_pte_pa = 0;
+
+ if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
+ PrintError("Could not get virtual address of guest PDE64 (PA=%p)\n",
+ (void *)guest_pde_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PD64, vaddr, (addr_t)guest_pde, guest_pde_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_PD64;
- }
-
- switch (pde64_lookup(guest_pde, vaddr, &guest_pte_pa)) {
- case PT_ENTRY_NOT_PRESENT:
- return -1;
- case PT_ENTRY_LARGE_PAGE:
- {
- addr_t large_page_pa = (addr_t)guest_pte_pa;
- addr_t large_page_va = 0;
+ if ((ret = callback(info, PAGE_PD64, vaddr, (addr_t)guest_pde, guest_pde_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_PD64;
+ }
+
+ switch (pde64_lookup(guest_pde, vaddr, &guest_pte_pa)) {
+ case PT_ENTRY_NOT_PRESENT:
+ return -1;
+ case PT_ENTRY_LARGE_PAGE:
+ {
+ addr_t large_page_pa = (addr_t)guest_pte_pa;
+ addr_t large_page_va = 0;
- if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest Page 2MB (PA=%p)\n",
- (void *)large_page_va);
+ if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest Page 2MB (PA=%p)\n",
+ (void *)large_page_va);
- }
+ }
- if ((ret == callback(info, PAGE_2MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_2MB;
- }
- return 0;
- }
- case PT_ENTRY_PAGE:
- {
- pte64_t * guest_pte = NULL;
- addr_t page_pa;
+ if ((ret == callback(info, PAGE_2MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_2MB;
+ }
+ return 0;
+ }
+ case PT_ENTRY_PAGE:
+ {
+ pte64_t * guest_pte = NULL;
+ addr_t page_pa;
- if (guest_pa_to_host_va(info, guest_pte_pa, (addr_t *)&guest_pte) == -1) {
- PrintError("Could not get virtual address of guest PTE64 (PA=%p)\n",
- (void *)guest_pte_pa);
- return -1;
- }
-
- if ((ret = callback(info, PAGE_PT64, vaddr, (addr_t)guest_pte, guest_pte_pa, private_data) != 0)) {
- return (ret == -1) ? -1 : PAGE_PT64;
- }
+ if (guest_pa_to_host_va(info, guest_pte_pa, (addr_t *)&guest_pte) == -1) {
+ PrintError("Could not get virtual address of guest PTE64 (PA=%p)\n",
+ (void *)guest_pte_pa);
+ return -1;
+ }
+
+ if ((ret = callback(info, PAGE_PT64, vaddr, (addr_t)guest_pte, guest_pte_pa, private_data) != 0)) {
+ return (ret == -1) ? -1 : PAGE_PT64;
+ }
- if (pte64_lookup(guest_pte, vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
- return -1;
- } else {
- addr_t page_va;
+ if (pte64_lookup(guest_pte, vaddr, &page_pa) == PT_ENTRY_NOT_PRESENT) {
+ return -1;
+ } else {
+ addr_t page_va;
- if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
- PrintError("Could not get virtual address of Guest Page 4KB (PA=%p)\n",
- (void *)page_pa);
- return -1;
- }
+ if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
+ PrintError("Could not get virtual address of Guest Page 4KB (PA=%p)\n",
+ (void *)page_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
- return (ret == -1) ? -1 : PAGE_4KB;
+ if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
+ return (ret == -1) ? -1 : PAGE_4KB;
+ }
+
+ return 0;
+ }
+ }
+ }
+ }
}
-
- return 0;
- }
}
- }
- }
- }
+ default:
+ return -1;
}
- default:
- return -1;
- }
- // should never get here
- PrintError("End of drill function (guest 64)... Should never have gotten here...\n");
- return -1;
+ // should never get here
+ PrintError("End of drill function (guest 64)... Should never have gotten here...\n");
+ return -1;
}
int v3_walk_guest_pt_32(struct guest_info * info, v3_reg_t guest_cr3,
int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
void * private_data) {
- addr_t guest_pde_pa = CR3_TO_PDE32_PA(guest_cr3);
- pde32_t * guest_pde = NULL;
- int i, j;
- addr_t vaddr = 0;
- int ret = 0;
-
- if (!callback) {
- PrintError("Call back was not specified\n");
- return -1;
- }
+ addr_t guest_pde_pa = CR3_TO_PDE32_PA(guest_cr3);
+ pde32_t * guest_pde = NULL;
+ int i, j;
+ addr_t vaddr = 0;
+ int ret = 0;
+
+ if (!callback) {
+ PrintError("Call back was not specified\n");
+ return -1;
+ }
- if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
- PrintError("Could not get virtual address of Guest PDE32 (PA=%p)\n",
- (void *)guest_pde_pa);
- return -1;
- }
-
- if ((ret = callback(info, PAGE_PD32, vaddr, (addr_t)guest_pde, guest_pde_pa, private_data)) != 0) {
- return ret;
- }
-
- for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
- if (guest_pde[i].present) {
- if (guest_pde[i].large_page) {
- pde32_4MB_t * large_pde = (pde32_4MB_t *)&(guest_pde[i]);
- addr_t large_page_pa = BASE_TO_PAGE_ADDR_4MB(large_pde->page_base_addr);
- addr_t large_page_va = 0;
-
- if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest 4MB Page (PA=%p)\n",
- (void *)large_page_pa);
- // We'll let it through for data pages because they may be unmapped or hooked
- large_page_va = 0;
- }
+ if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
+ PrintError("Could not get virtual address of Guest PDE32 (PA=%p)\n",
+ (void *)guest_pde_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_4MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PD32, vaddr, (addr_t)guest_pde, guest_pde_pa, private_data)) != 0) {
+ return ret;
+ }
- vaddr += PAGE_SIZE_4MB;
- } else {
- addr_t pte_pa = BASE_TO_PAGE_ADDR(guest_pde[i].pt_base_addr);
- pte32_t * tmp_pte = NULL;
+ for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
+ if (guest_pde[i].present) {
+ if (guest_pde[i].large_page) {
+ pde32_4MB_t * large_pde = (pde32_4MB_t *)&(guest_pde[i]);
+ addr_t large_page_pa = BASE_TO_PAGE_ADDR_4MB(large_pde->page_base_addr);
+ addr_t large_page_va = 0;
- if (guest_pa_to_host_va(info, pte_pa, (addr_t *)&tmp_pte) == -1) {
- PrintError("Could not get virtual address of Guest PTE32 (PA=%p)\n",
- (void *)pte_pa);
- return -1;
- }
+ if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest 4MB Page (PA=%p)\n",
+ (void *)large_page_pa);
+ // We'll let it through for data pages because they may be unmapped or hooked
+ large_page_va = 0;
+ }
- if ((ret = callback(info, PAGE_PT32, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_4MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
+ return ret;
+ }
+
+ vaddr += PAGE_SIZE_4MB;
+ } else {
+ addr_t pte_pa = BASE_TO_PAGE_ADDR(guest_pde[i].pt_base_addr);
+ pte32_t * tmp_pte = NULL;
- for (j = 0; j < MAX_PTE32_ENTRIES; j++) {
- if (tmp_pte[j].present) {
- addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[j].page_base_addr);
- addr_t page_va = 0;
+ if (guest_pa_to_host_va(info, pte_pa, (addr_t *)&tmp_pte) == -1) {
+ PrintError("Could not get virtual address of Guest PTE32 (PA=%p)\n",
+ (void *)pte_pa);
+ return -1;
+ }
- if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest 4KB Page (PA=%p)\n",
- (void *)page_pa);
- // We'll let it through for data pages because they may be unmapped or hooked
- page_va = 0;
- }
+ if ((ret = callback(info, PAGE_PT32, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
+ return ret;
+ }
+
+ for (j = 0; j < MAX_PTE32_ENTRIES; j++) {
+ if (tmp_pte[j].present) {
+ addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[j].page_base_addr);
+ addr_t page_va = 0;
+
+ if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest 4KB Page (PA=%p)\n",
+ (void *)page_pa);
+ // We'll let it through for data pages because they may be unmapped or hooked
+ page_va = 0;
+ }
- if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
- return ret;
- }
- }
+ if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
+ return ret;
+ }
+ }
- vaddr += PAGE_SIZE_4KB;
+ vaddr += PAGE_SIZE_4KB;
+ }
+ }
+ } else {
+ vaddr += PAGE_SIZE_4MB;
}
- }
- } else {
- vaddr += PAGE_SIZE_4MB;
}
- }
- return 0;
+ return 0;
}
int v3_walk_guest_pt_32pae(struct guest_info * info, v3_reg_t guest_cr3,
int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
void * private_data) {
- addr_t guest_pdpe_pa = CR3_TO_PDPE32PAE_PA(guest_cr3);
- pdpe32pae_t * guest_pdpe = NULL;
- int i, j, k;
- addr_t vaddr = 0;
- int ret = 0;
-
- if (!callback) {
- PrintError("Call back was not specified\n");
- return -1;
- }
-
- if (guest_pa_to_host_va(info, guest_pdpe_pa, (addr_t *)&guest_pdpe) == -1) {
- PrintError("Could not get virtual address of Guest PDPE32PAE (PA=%p)\n",
- (void *)guest_pdpe_pa);
- return -1;
- }
+ addr_t guest_pdpe_pa = CR3_TO_PDPE32PAE_PA(guest_cr3);
+ pdpe32pae_t * guest_pdpe = NULL;
+ int i, j, k;
+ addr_t vaddr = 0;
+ int ret = 0;
+
+ if (!callback) {
+ PrintError("Call back was not specified\n");
+ return -1;
+ }
-
- if ((ret = callback(info, PAGE_PDP32PAE, vaddr, (addr_t)guest_pdpe, guest_pdpe_pa, private_data)) != 0) {
- return ret;
- }
-
- for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) {
- if (guest_pdpe[i].present) {
- addr_t pde_pa = BASE_TO_PAGE_ADDR(guest_pdpe[i].pd_base_addr);
- pde32pae_t * tmp_pde = NULL;
-
- if (guest_pa_to_host_va(info, pde_pa, (addr_t *)&tmp_pde) == -1) {
- PrintError("Could not get virtual address of Guest PDE32PAE (PA=%p)\n",
- (void *)pde_pa);
+ if (guest_pa_to_host_va(info, guest_pdpe_pa, (addr_t *)&guest_pdpe) == -1) {
+ PrintError("Could not get virtual address of Guest PDPE32PAE (PA=%p)\n",
+ (void *)guest_pdpe_pa);
return -1;
- }
+ }
- if ((ret = callback(info, PAGE_PD32PAE, vaddr, (addr_t)tmp_pde, pde_pa, private_data)) != 0) {
+
+ if ((ret = callback(info, PAGE_PDP32PAE, vaddr, (addr_t)guest_pdpe, guest_pdpe_pa, private_data)) != 0) {
return ret;
- }
+ }
+
+ for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) {
+ if (guest_pdpe[i].present) {
+ addr_t pde_pa = BASE_TO_PAGE_ADDR(guest_pdpe[i].pd_base_addr);
+ pde32pae_t * tmp_pde = NULL;
+
+ if (guest_pa_to_host_va(info, pde_pa, (addr_t *)&tmp_pde) == -1) {
+ PrintError("Could not get virtual address of Guest PDE32PAE (PA=%p)\n",
+ (void *)pde_pa);
+ return -1;
+ }
+
+ if ((ret = callback(info, PAGE_PD32PAE, vaddr, (addr_t)tmp_pde, pde_pa, private_data)) != 0) {
+ return ret;
+ }
- for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) {
- if (tmp_pde[j].present) {
- if (tmp_pde[j].large_page) {
- pde32pae_2MB_t * large_pde = (pde32pae_2MB_t *)&(tmp_pde[j]);
- addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
- addr_t large_page_va = 0;
+ for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) {
+ if (tmp_pde[j].present) {
+ if (tmp_pde[j].large_page) {
+ pde32pae_2MB_t * large_pde = (pde32pae_2MB_t *)&(tmp_pde[j]);
+ addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
+ addr_t large_page_va = 0;
- if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest 2MB Page (PA=%p)\n",
- (void *)large_page_pa);
- // We'll let it through for data pages because they may be unmapped or hooked
- large_page_va = 0;
- }
+ if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest 2MB Page (PA=%p)\n",
+ (void *)large_page_pa);
+ // We'll let it through for data pages because they may be unmapped or hooked
+ large_page_va = 0;
+ }
- if ((ret = callback(info, PAGE_2MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
- return ret;
- }
-
- vaddr += PAGE_SIZE_2MB;
- } else {
- addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[j].pt_base_addr);
- pte32pae_t * tmp_pte = NULL;
+ if ((ret = callback(info, PAGE_2MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
+ return ret;
+ }
+
+ vaddr += PAGE_SIZE_2MB;
+ } else {
+ addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[j].pt_base_addr);
+ pte32pae_t * tmp_pte = NULL;
- if (guest_pa_to_host_va(info, pte_pa, (addr_t *)&tmp_pte) == -1) {
- PrintError("Could not get virtual address of Guest PTE32PAE (PA=%p)\n",
- (void *)pte_pa);
- return -1;
- }
+ if (guest_pa_to_host_va(info, pte_pa, (addr_t *)&tmp_pte) == -1) {
+ PrintError("Could not get virtual address of Guest PTE32PAE (PA=%p)\n",
+ (void *)pte_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PT32PAE, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PT32PAE, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
+ return ret;
+ }
- for (k = 0; k < MAX_PTE32PAE_ENTRIES; k++) {
- if (tmp_pte[k].present) {
- addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[k].page_base_addr);
- addr_t page_va = 0;
+ for (k = 0; k < MAX_PTE32PAE_ENTRIES; k++) {
+ if (tmp_pte[k].present) {
+ addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[k].page_base_addr);
+ addr_t page_va = 0;
- if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest 4KB Page (PA=%p)\n",
- (void *)page_pa);
- // We'll let it through for data pages because they may be unmapped or hooked
- page_va = 0;
- }
+ if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest 4KB Page (PA=%p)\n",
+ (void *)page_pa);
+ // We'll let it through for data pages because they may be unmapped or hooked
+ page_va = 0;
+ }
- if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
- return ret;
- }
- }
+ if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
+ return ret;
+ }
+ }
- vaddr += PAGE_SIZE_4KB;
+ vaddr += PAGE_SIZE_4KB;
+ }
+ }
+ } else {
+ vaddr += PAGE_SIZE_2MB;
+ }
}
- }
} else {
- vaddr += PAGE_SIZE_2MB;
+ vaddr += PAGE_SIZE_2MB * MAX_PDE32PAE_ENTRIES;
}
- }
- } else {
- vaddr += PAGE_SIZE_2MB * MAX_PDE32PAE_ENTRIES;
}
- }
- return 0;
+ return 0;
}
int v3_walk_guest_pt_64(struct guest_info * info, v3_reg_t guest_cr3,
int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
void * private_data) {
- addr_t guest_pml_pa = CR3_TO_PML4E64_PA(guest_cr3);
- pml4e64_t * guest_pml = NULL;
- int i, j, k, m;
- addr_t vaddr = 0;
- int ret = 0;
-
- if (!callback) {
- PrintError("Call back was not specified\n");
- return -1;
- }
+ addr_t guest_pml_pa = CR3_TO_PML4E64_PA(guest_cr3);
+ pml4e64_t * guest_pml = NULL;
+ int i, j, k, m;
+ addr_t vaddr = 0;
+ int ret = 0;
+
+ if (!callback) {
+ PrintError("Call back was not specified\n");
+ return -1;
+ }
- if (guest_pa_to_host_va(info, guest_pml_pa, (addr_t *)&guest_pml) == -1) {
- PrintError("Could not get virtual address of Guest PML464 (PA=%p)\n",
- (void *)guest_pml);
- return -1;
- }
+ if (guest_pa_to_host_va(info, guest_pml_pa, (addr_t *)&guest_pml) == -1) {
+ PrintError("Could not get virtual address of Guest PML464 (PA=%p)\n",
+ (void *)guest_pml);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PML464, vaddr, (addr_t)guest_pml, guest_pml_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PML464, vaddr, (addr_t)guest_pml, guest_pml_pa, private_data)) != 0) {
+ return ret;
+ }
- for (i = 0; i < MAX_PML4E64_ENTRIES; i++) {
- if (guest_pml[i].present) {
- addr_t pdpe_pa = BASE_TO_PAGE_ADDR(guest_pml[i].pdp_base_addr);
- pdpe64_t * tmp_pdpe = NULL;
-
+ for (i = 0; i < MAX_PML4E64_ENTRIES; i++) {
+ if (guest_pml[i].present) {
+ addr_t pdpe_pa = BASE_TO_PAGE_ADDR(guest_pml[i].pdp_base_addr);
+ pdpe64_t * tmp_pdpe = NULL;
- if (guest_pa_to_host_va(info, pdpe_pa, (addr_t *)&tmp_pdpe) == -1) {
- PrintError("Could not get virtual address of Guest PDPE64 (PA=%p)\n",
- (void *)pdpe_pa);
- return -1;
- }
-
- if ((ret = callback(info, PAGE_PDP64, vaddr, (addr_t)tmp_pdpe, pdpe_pa, private_data)) != 0) {
- return ret;
- }
- for (j = 0; j < MAX_PDPE64_ENTRIES; j++) {
- if (tmp_pdpe[j].present) {
- if (tmp_pdpe[j].large_page) {
- pdpe64_1GB_t * large_pdpe = (pdpe64_1GB_t *)&(tmp_pdpe[j]);
- addr_t large_page_pa = BASE_TO_PAGE_ADDR_1GB(large_pdpe->page_base_addr);
- addr_t large_page_va = 0;
-
- if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest 1GB page (PA=%p)\n",
- (void *)large_page_pa);
- // We'll let it through for data pages because they may be unmapped or hooked
- large_page_va = 0;
+ if (guest_pa_to_host_va(info, pdpe_pa, (addr_t *)&tmp_pdpe) == -1) {
+ PrintError("Could not get virtual address of Guest PDPE64 (PA=%p)\n",
+ (void *)pdpe_pa);
+ return -1;
}
-
- if ((ret = callback(info, PAGE_1GB, vaddr, (addr_t)large_page_va, large_page_pa, private_data)) != 0) {
- return ret;
+
+ if ((ret = callback(info, PAGE_PDP64, vaddr, (addr_t)tmp_pdpe, pdpe_pa, private_data)) != 0) {
+ return ret;
}
-
- vaddr += PAGE_SIZE_1GB;
- } else {
- addr_t pde_pa = BASE_TO_PAGE_ADDR(tmp_pdpe[j].pd_base_addr);
- pde64_t * tmp_pde = NULL;
+
+ for (j = 0; j < MAX_PDPE64_ENTRIES; j++) {
+ if (tmp_pdpe[j].present) {
+ if (tmp_pdpe[j].large_page) {
+ pdpe64_1GB_t * large_pdpe = (pdpe64_1GB_t *)&(tmp_pdpe[j]);
+ addr_t large_page_pa = BASE_TO_PAGE_ADDR_1GB(large_pdpe->page_base_addr);
+ addr_t large_page_va = 0;
+
+ if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest 1GB page (PA=%p)\n",
+ (void *)large_page_pa);
+ // We'll let it through for data pages because they may be unmapped or hooked
+ large_page_va = 0;
+ }
+
+ if ((ret = callback(info, PAGE_1GB, vaddr, (addr_t)large_page_va, large_page_pa, private_data)) != 0) {
+ return ret;
+ }
+
+ vaddr += PAGE_SIZE_1GB;
+ } else {
+ addr_t pde_pa = BASE_TO_PAGE_ADDR(tmp_pdpe[j].pd_base_addr);
+ pde64_t * tmp_pde = NULL;
- if (guest_pa_to_host_va(info, pde_pa, (addr_t *)&tmp_pde) == -1) {
- PrintError("Could not get virtual address of Guest PDE64 (PA=%p)\n",
- (void *)pde_pa);
- return -1;
- }
+ if (guest_pa_to_host_va(info, pde_pa, (addr_t *)&tmp_pde) == -1) {
+ PrintError("Could not get virtual address of Guest PDE64 (PA=%p)\n",
+ (void *)pde_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PD64, vaddr, (addr_t)tmp_pde, pde_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PD64, vaddr, (addr_t)tmp_pde, pde_pa, private_data)) != 0) {
+ return ret;
+ }
- for (k = 0; k < MAX_PDE64_ENTRIES; k++) {
- if (tmp_pde[k].present) {
- if (tmp_pde[k].large_page) {
- pde64_2MB_t * large_pde = (pde64_2MB_t *)&(tmp_pde[k]);
- addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
- addr_t large_page_va = 0;
+ for (k = 0; k < MAX_PDE64_ENTRIES; k++) {
+ if (tmp_pde[k].present) {
+ if (tmp_pde[k].large_page) {
+ pde64_2MB_t * large_pde = (pde64_2MB_t *)&(tmp_pde[k]);
+ addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
+ addr_t large_page_va = 0;
- if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest 2MB page (PA=%p)\n",
- (void *)large_page_pa);
- // We'll let it through for data pages because they may be unmapped or hooked
- large_page_va = 0;
- }
+ if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest 2MB page (PA=%p)\n",
+ (void *)large_page_pa);
+ // We'll let it through for data pages because they may be unmapped or hooked
+ large_page_va = 0;
+ }
- if ((ret = callback(info, PAGE_2MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
- return ret;
- }
-
- vaddr += PAGE_SIZE_2MB;
- } else {
- addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[k].pt_base_addr);
- pte64_t * tmp_pte = NULL;
+ if ((ret = callback(info, PAGE_2MB, vaddr, large_page_va, large_page_pa, private_data)) != 0) {
+ return ret;
+ }
+
+ vaddr += PAGE_SIZE_2MB;
+ } else {
+ addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[k].pt_base_addr);
+ pte64_t * tmp_pte = NULL;
- if (guest_pa_to_host_va(info, pte_pa, (addr_t *)&tmp_pte) == -1) {
- PrintError("Could not get virtual address of Guest PTE64 (PA=%p)\n",
- (void *)pte_pa);
- return -1;
- }
+ if (guest_pa_to_host_va(info, pte_pa, (addr_t *)&tmp_pte) == -1) {
+ PrintError("Could not get virtual address of Guest PTE64 (PA=%p)\n",
+ (void *)pte_pa);
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PT64, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PT64, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
+ return ret;
+ }
- for (m = 0; m < MAX_PTE64_ENTRIES; m++) {
- if (tmp_pte[m].present) {
- addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[m].page_base_addr);
- addr_t page_va = 0;
+ for (m = 0; m < MAX_PTE64_ENTRIES; m++) {
+ if (tmp_pte[m].present) {
+ addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[m].page_base_addr);
+ addr_t page_va = 0;
- if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
- PrintDebug("Could not get virtual address of Guest 4KB Page (PA=%p)\n",
- (void *)page_pa);
- // We'll let it through for data pages because they may be unmapped or hooked
- page_va = 0;
- }
+ if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) {
+ PrintDebug("Could not get virtual address of Guest 4KB Page (PA=%p)\n",
+ (void *)page_pa);
+ // We'll let it through for data pages because they may be unmapped or hooked
+ page_va = 0;
+ }
- if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_4KB, vaddr, page_va, page_pa, private_data)) != 0) {
+ return ret;
+ }
+ }
+
+ vaddr += PAGE_SIZE_4KB;
+ }
+ }
+ } else {
+ vaddr += PAGE_SIZE_2MB;
+ }
+ }
}
-
- vaddr += PAGE_SIZE_4KB;
- }
+ } else {
+ vaddr += PAGE_SIZE_1GB;
}
- } else {
- vaddr += PAGE_SIZE_2MB;
- }
}
- }
} else {
- vaddr += PAGE_SIZE_1GB;
+ vaddr += ((ullong_t)PAGE_SIZE_1GB * (ullong_t)MAX_PDPE64_ENTRIES);
}
- }
- } else {
- vaddr += ((ullong_t)PAGE_SIZE_1GB * (ullong_t)MAX_PDPE64_ENTRIES);
}
- }
- return 0;
+ return 0;
}
int v3_walk_host_pt_32(struct guest_info * info, v3_reg_t host_cr3,
int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
void * private_data) {
- pde32_t * host_pde = (pde32_t *)CR3_TO_PDE32_VA(host_cr3);
- addr_t pde_pa = CR3_TO_PDE32_PA(host_cr3);
- int i, j;
- addr_t vaddr = 0;
- int ret = 0;
-
- if (!callback) {
- PrintError("Call back was not specified\n");
- return -1;
- }
+ pde32_t * host_pde = (pde32_t *)CR3_TO_PDE32_VA(host_cr3);
+ addr_t pde_pa = CR3_TO_PDE32_PA(host_cr3);
+ int i, j;
+ addr_t vaddr = 0;
+ int ret = 0;
+
+ if (!callback) {
+ PrintError("Call back was not specified\n");
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PD32, vaddr, (addr_t)host_pde, pde_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PD32, vaddr, (addr_t)host_pde, pde_pa, private_data)) != 0) {
+ return ret;
+ }
- for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
- if (host_pde[i].present) {
- if (host_pde[i].large_page) {
- pde32_4MB_t * large_pde = (pde32_4MB_t *)&(host_pde[i]);
- addr_t large_page_pa = BASE_TO_PAGE_ADDR_4MB(large_pde->page_base_addr);
+ for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
+ if (host_pde[i].present) {
+ if (host_pde[i].large_page) {
+ pde32_4MB_t * large_pde = (pde32_4MB_t *)&(host_pde[i]);
+ addr_t large_page_pa = BASE_TO_PAGE_ADDR_4MB(large_pde->page_base_addr);
- if ((ret = callback(info, PAGE_4MB, vaddr, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_4MB, vaddr, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data)) != 0) {
+ return ret;
+ }
- vaddr += PAGE_SIZE_4MB;
- } else {
- addr_t pte_pa = BASE_TO_PAGE_ADDR(host_pde[i].pt_base_addr);
- pte32_t * tmp_pte = (pte32_t *)V3_VAddr((void *)pte_pa);
+ vaddr += PAGE_SIZE_4MB;
+ } else {
+ addr_t pte_pa = BASE_TO_PAGE_ADDR(host_pde[i].pt_base_addr);
+ pte32_t * tmp_pte = (pte32_t *)V3_VAddr((void *)pte_pa);
- if ((ret = callback(info, PAGE_PT32, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PT32, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
+ return ret;
+ }
- for (j = 0; j < MAX_PTE32_ENTRIES; j++) {
- if (tmp_pte[j].present) {
- addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[j].page_base_addr);
- if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)page_pa), page_pa, private_data)) != 0) {
- return ret;
- }
- }
+ for (j = 0; j < MAX_PTE32_ENTRIES; j++) {
+ if (tmp_pte[j].present) {
+ addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[j].page_base_addr);
+ if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)page_pa), page_pa, private_data)) != 0) {
+ return ret;
+ }
+ }
- vaddr += PAGE_SIZE_4KB;
+ vaddr += PAGE_SIZE_4KB;
+ }
+ }
+ } else {
+ vaddr += PAGE_SIZE_4MB;
}
- }
- } else {
- vaddr += PAGE_SIZE_4MB;
}
- }
- return 0;
+ return 0;
}
int v3_walk_host_pt_32pae(struct guest_info * info, v3_reg_t host_cr3,
int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
void * private_data) {
- pdpe32pae_t * host_pdpe = (pdpe32pae_t *)CR3_TO_PDPE32PAE_VA(host_cr3);
- addr_t pdpe_pa = CR3_TO_PDPE32PAE_PA(host_cr3);
- int i, j, k;
- addr_t vaddr = 0;
- int ret = 0;
-
- if (!callback) {
- PrintError("Callback was not specified\n");
- return -1;
- }
+ pdpe32pae_t * host_pdpe = (pdpe32pae_t *)CR3_TO_PDPE32PAE_VA(host_cr3);
+ addr_t pdpe_pa = CR3_TO_PDPE32PAE_PA(host_cr3);
+ int i, j, k;
+ addr_t vaddr = 0;
+ int ret = 0;
+
+ if (!callback) {
+ PrintError("Callback was not specified\n");
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PDP32PAE, vaddr, (addr_t)host_pdpe, pdpe_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PDP32PAE, vaddr, (addr_t)host_pdpe, pdpe_pa, private_data)) != 0) {
+ return ret;
+ }
- for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) {
- if (host_pdpe[i].present) {
- addr_t pde_pa = BASE_TO_PAGE_ADDR(host_pdpe[i].pd_base_addr);
- pde32pae_t * tmp_pde = (pde32pae_t *)V3_VAddr((void *)pde_pa);
+ for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) {
+ if (host_pdpe[i].present) {
+ addr_t pde_pa = BASE_TO_PAGE_ADDR(host_pdpe[i].pd_base_addr);
+ pde32pae_t * tmp_pde = (pde32pae_t *)V3_VAddr((void *)pde_pa);
- if ((ret = callback(info, PAGE_PD32PAE, vaddr, (addr_t)tmp_pde, pde_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PD32PAE, vaddr, (addr_t)tmp_pde, pde_pa, private_data)) != 0) {
+ return ret;
+ }
- for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) {
- if (tmp_pde[j].present) {
+ for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) {
+ if (tmp_pde[j].present) {
- if (tmp_pde[j].large_page) {
- pde32pae_2MB_t * large_pde = (pde32pae_2MB_t *)&(tmp_pde[j]);
- addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
-
- if ((ret = callback(info, PAGE_2MB, vaddr, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data)) != 0) {
- return ret;
- }
-
- vaddr += PAGE_SIZE_2MB;
- } else {
- addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[j].pt_base_addr);
- pte32pae_t * tmp_pte = (pte32pae_t *)V3_VAddr((void *)pte_pa);
+ if (tmp_pde[j].large_page) {
+ pde32pae_2MB_t * large_pde = (pde32pae_2MB_t *)&(tmp_pde[j]);
+ addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
+
+ if ((ret = callback(info, PAGE_2MB, vaddr, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data)) != 0) {
+ return ret;
+ }
+
+ vaddr += PAGE_SIZE_2MB;
+ } else {
+ addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[j].pt_base_addr);
+ pte32pae_t * tmp_pte = (pte32pae_t *)V3_VAddr((void *)pte_pa);
- if ((ret = callback(info, PAGE_PT32PAE, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_PT32PAE, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
+ return ret;
+ }
- for (k = 0; k < MAX_PTE32PAE_ENTRIES; k++) {
- if (tmp_pte[k].present) {
- addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[k].page_base_addr);
- if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)page_pa), page_pa, private_data)) != 0) {
- return ret;
+ for (k = 0; k < MAX_PTE32PAE_ENTRIES; k++) {
+ if (tmp_pte[k].present) {
+ addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[k].page_base_addr);
+ if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)page_pa), page_pa, private_data)) != 0) {
+ return ret;
+ }
+ }
+
+ vaddr += PAGE_SIZE_4KB;
+ }
+ }
+ } else {
+ vaddr += PAGE_SIZE_2MB;
}
- }
-
- vaddr += PAGE_SIZE_4KB;
}
- }
} else {
- vaddr += PAGE_SIZE_2MB;
+ vaddr += PAGE_SIZE_2MB * MAX_PDE32PAE_ENTRIES;
}
- }
- } else {
- vaddr += PAGE_SIZE_2MB * MAX_PDE32PAE_ENTRIES;
}
- }
- return 0;
+ return 0;
}
int v3_walk_host_pt_64(struct guest_info * info, v3_reg_t host_cr3,
int (*callback)(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data),
void * private_data) {
- pml4e64_t * host_pml = (pml4e64_t *)CR3_TO_PML4E64_VA(host_cr3);
- addr_t pml_pa = CR3_TO_PML4E64_PA(host_cr3);
- int i, j, k, m;
- addr_t vaddr = 0;
- int ret = 0;
-
- if (!callback) {
- PrintError("Callback was not specified\n");
- return -1;
- }
-
- if ((ret = callback(info, PAGE_PML464, vaddr, (addr_t)host_pml, pml_pa, private_data)) != 0) {
- return ret;
- }
-
- for (i = 0; i < MAX_PML4E64_ENTRIES; i++) {
- if (host_pml[i].present) {
- addr_t pdpe_pa = BASE_TO_PAGE_ADDR(host_pml[i].pdp_base_addr);
- pdpe64_t * tmp_pdpe = (pdpe64_t *)V3_VAddr((void *)pdpe_pa);
+ pml4e64_t * host_pml = (pml4e64_t *)CR3_TO_PML4E64_VA(host_cr3);
+ addr_t pml_pa = CR3_TO_PML4E64_PA(host_cr3);
+ int i, j, k, m;
+ addr_t vaddr = 0;
+ int ret = 0;
+
+ if (!callback) {
+ PrintError("Callback was not specified\n");
+ return -1;
+ }
- if ((ret = callback(info, PAGE_PDP64, vaddr, (addr_t)tmp_pdpe, pdpe_pa, private_data)) != 0) {
+ if ((ret = callback(info, PAGE_PML464, vaddr, (addr_t)host_pml, pml_pa, private_data)) != 0) {
return ret;
- }
-
- for (j = 0; j < MAX_PDPE64_ENTRIES; j++) {
- if (tmp_pdpe[j].present) {
- if (tmp_pdpe[j].large_page) {
- pdpe64_1GB_t * large_pdp = (pdpe64_1GB_t *)&(tmp_pdpe[j]);
- addr_t large_page_pa = BASE_TO_PAGE_ADDR_1GB(large_pdp->page_base_addr);
-
- if ((ret = callback(info, PAGE_1GB, vaddr, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data)) != 0) {
- return ret;
- }
+ }
- vaddr += PAGE_SIZE_1GB;
- } else {
- addr_t pde_pa = BASE_TO_PAGE_ADDR(tmp_pdpe[j].pd_base_addr);
- pde64_t * tmp_pde = (pde64_t *)V3_VAddr((void *)pde_pa);
+ for (i = 0; i < MAX_PML4E64_ENTRIES; i++) {
+ if (host_pml[i].present) {
+ addr_t pdpe_pa = BASE_TO_PAGE_ADDR(host_pml[i].pdp_base_addr);
+ pdpe64_t * tmp_pdpe = (pdpe64_t *)V3_VAddr((void *)pdpe_pa);
- if ((ret = callback(info, PAGE_PD64, vaddr, (addr_t)tmp_pde, pde_pa, private_data)) != 0) {
- return ret;
+ if ((ret = callback(info, PAGE_PDP64, vaddr, (addr_t)tmp_pdpe, pdpe_pa, private_data)) != 0) {
+ return ret;
}
- for (k = 0; k < MAX_PDE64_ENTRIES; k++) {
- if (tmp_pde[k].present) {
- if (tmp_pde[k].large_page) {
- pde64_2MB_t * large_pde = (pde64_2MB_t *)&(tmp_pde[k]);
- addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
+ for (j = 0; j < MAX_PDPE64_ENTRIES; j++) {
+ if (tmp_pdpe[j].present) {
+ if (tmp_pdpe[j].large_page) {
+ pdpe64_1GB_t * large_pdp = (pdpe64_1GB_t *)&(tmp_pdpe[j]);
+ addr_t large_page_pa = BASE_TO_PAGE_ADDR_1GB(large_pdp->page_base_addr);
+
+ if ((ret = callback(info, PAGE_1GB, vaddr, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data)) != 0) {
+ return ret;
+ }
+
+ vaddr += PAGE_SIZE_1GB;
+ } else {
+ addr_t pde_pa = BASE_TO_PAGE_ADDR(tmp_pdpe[j].pd_base_addr);
+ pde64_t * tmp_pde = (pde64_t *)V3_VAddr((void *)pde_pa);
+
+ if ((ret = callback(info, PAGE_PD64, vaddr, (addr_t)tmp_pde, pde_pa, private_data)) != 0) {
+ return ret;
+ }
+
+ for (k = 0; k < MAX_PDE64_ENTRIES; k++) {
+ if (tmp_pde[k].present) {
+ if (tmp_pde[k].large_page) {
+ pde64_2MB_t * large_pde = (pde64_2MB_t *)&(tmp_pde[k]);
+ addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
- if ((ret = callback(info, PAGE_2MB, vaddr, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data)) != 0) {
- return ret;
- }
+ if ((ret = callback(info, PAGE_2MB, vaddr, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data)) != 0) {
+ return ret;
+ }
- vaddr += PAGE_SIZE_2MB;
- } else {
- addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[k].pt_base_addr);
- pte64_t * tmp_pte = (pte64_t *)V3_VAddr((void *)pte_pa);
-
- if ((ret = callback(info, PAGE_PT64, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
- return ret;
- }
-
- for (m = 0; m < MAX_PTE64_ENTRIES; m++) {
- if (tmp_pte[m].present) {
- addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[m].page_base_addr);
- if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)page_pa), page_pa, private_data)) != 0) {
- return ret;
- }
+ vaddr += PAGE_SIZE_2MB;
+ } else {
+ addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[k].pt_base_addr);
+ pte64_t * tmp_pte = (pte64_t *)V3_VAddr((void *)pte_pa);
+
+ if ((ret = callback(info, PAGE_PT64, vaddr, (addr_t)tmp_pte, pte_pa, private_data)) != 0) {
+ return ret;
+ }
+
+ for (m = 0; m < MAX_PTE64_ENTRIES; m++) {
+ if (tmp_pte[m].present) {
+ addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[m].page_base_addr);
+ if ((ret = callback(info, PAGE_4KB, vaddr, (addr_t)V3_VAddr((void *)page_pa), page_pa, private_data)) != 0) {
+ return ret;
+ }
+ }
+ vaddr += PAGE_SIZE_4KB;
+ }
+ }
+ } else {
+ vaddr += PAGE_SIZE_2MB;
+ }
+ }
}
- vaddr += PAGE_SIZE_4KB;
- }
+ } else {
+ vaddr += PAGE_SIZE_1GB;
}
- } else {
- vaddr += PAGE_SIZE_2MB;
- }
}
- }
} else {
- vaddr += PAGE_SIZE_1GB;
+ vaddr += (ullong_t)PAGE_SIZE_1GB * (ullong_t)MAX_PDPE64_ENTRIES;
}
- }
- } else {
- vaddr += (ullong_t)PAGE_SIZE_1GB * (ullong_t)MAX_PDPE64_ENTRIES;
}
- }
- return 0;
+ return 0;
}
const uchar_t * v3_page_type_to_str(page_type_t type) {
- switch (type) {
- case PAGE_4KB:
- return PAGE_4KB_STR;
- case PAGE_2MB:
- return PAGE_2MB_STR;
- case PAGE_4MB:
- return PAGE_4MB_STR;
- case PAGE_1GB:
- return PAGE_1GB_STR;
- case PAGE_PT32:
- return PAGE_PT32_STR;
- case PAGE_PD32:
- return PAGE_PD32_STR;
- case PAGE_PDP32PAE:
- return PAGE_PDP32PAE_STR;
- case PAGE_PD32PAE:
- return PAGE_PD32PAE_STR;
- case PAGE_PT32PAE:
- return PAGE_PT32PAE_STR;
- case PAGE_PML464:
- return PAGE_PML464_STR;
- case PAGE_PDP64:
- return PAGE_PDP64_STR;
- case PAGE_PD64:
- return PAGE_PD64_STR;
- case PAGE_PT64:
- return PAGE_PT64_STR;
- default:
- return NULL;
- }
+ switch (type) {
+ case PAGE_4KB:
+ return PAGE_4KB_STR;
+ case PAGE_2MB:
+ return PAGE_2MB_STR;
+ case PAGE_4MB:
+ return PAGE_4MB_STR;
+ case PAGE_1GB:
+ return PAGE_1GB_STR;
+ case PAGE_PT32:
+ return PAGE_PT32_STR;
+ case PAGE_PD32:
+ return PAGE_PD32_STR;
+ case PAGE_PDP32PAE:
+ return PAGE_PDP32PAE_STR;
+ case PAGE_PD32PAE:
+ return PAGE_PD32PAE_STR;
+ case PAGE_PT32PAE:
+ return PAGE_PT32PAE_STR;
+ case PAGE_PML464:
+ return PAGE_PML464_STR;
+ case PAGE_PDP64:
+ return PAGE_PDP64_STR;
+ case PAGE_PD64:
+ return PAGE_PD64_STR;
+ case PAGE_PT64:
+ return PAGE_PT64_STR;
+ default:
+ return NULL;
+ }
}
static void PrintPDE32(addr_t virtual_address, pde32_t * pde)
{
- PrintDebug("PDE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
- (void *)virtual_address,
- (void *)(addr_t) (pde->pt_base_addr << PAGE_POWER),
- pde->present,
- pde->writable,
- pde->user_page,
- pde->write_through,
- pde->cache_disable,
- pde->accessed,
- pde->reserved,
- pde->large_page,
- pde->global_page,
- pde->vmm_info);
+ PrintDebug("PDE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
+ (void *)virtual_address,
+ (void *)(addr_t) (pde->pt_base_addr << PAGE_POWER),
+ pde->present,
+ pde->writable,
+ pde->user_page,
+ pde->write_through,
+ pde->cache_disable,
+ pde->accessed,
+ pde->reserved,
+ pde->large_page,
+ pde->global_page,
+ pde->vmm_info);
}
static void PrintPTE32(addr_t virtual_address, pte32_t * pte)
{
- PrintDebug("PTE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
- (void *)virtual_address,
- (void*)(addr_t)(pte->page_base_addr << PAGE_POWER),
- pte->present,
- pte->writable,
- pte->user_page,
- pte->write_through,
- pte->cache_disable,
- pte->accessed,
- pte->dirty,
- pte->pte_attr,
- pte->global_page,
- pte->vmm_info);
+ PrintDebug("PTE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
+ (void *)virtual_address,
+ (void*)(addr_t)(pte->page_base_addr << PAGE_POWER),
+ pte->present,
+ pte->writable,
+ pte->user_page,
+ pte->write_through,
+ pte->cache_disable,
+ pte->accessed,
+ pte->dirty,
+ pte->pte_attr,
+ pte->global_page,
+ pte->vmm_info);
}
static void PrintPDPE32PAE(addr_t virtual_address, pdpe32pae_t * pdpe)
{
- PrintDebug("PDPE %p -> %p : present=%x, wt=%x, cd=%x, accessed=%x, kernelInfo=%x\n",
- (void *)virtual_address,
- (void *)(addr_t) (pdpe->pd_base_addr << PAGE_POWER),
- pdpe->present,
- pdpe->write_through,
- pdpe->cache_disable,
- pdpe->accessed,
- pdpe->vmm_info);
+ PrintDebug("PDPE %p -> %p : present=%x, wt=%x, cd=%x, accessed=%x, kernelInfo=%x\n",
+ (void *)virtual_address,
+ (void *)(addr_t) (pdpe->pd_base_addr << PAGE_POWER),
+ pdpe->present,
+ pdpe->write_through,
+ pdpe->cache_disable,
+ pdpe->accessed,
+ pdpe->vmm_info);
}
static void PrintPDE32PAE(addr_t virtual_address, pde32pae_t * pde)
{
- PrintDebug("PDE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
- (void *)virtual_address,
- (void *)(addr_t) (pde->pt_base_addr << PAGE_POWER),
- pde->present,
- pde->writable,
- pde->user_page,
- pde->write_through,
- pde->cache_disable,
- pde->accessed,
- pde->large_page,
- pde->global_page,
- pde->vmm_info);
+ PrintDebug("PDE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
+ (void *)virtual_address,
+ (void *)(addr_t) (pde->pt_base_addr << PAGE_POWER),
+ pde->present,
+ pde->writable,
+ pde->user_page,
+ pde->write_through,
+ pde->cache_disable,
+ pde->accessed,
+ pde->large_page,
+ pde->global_page,
+ pde->vmm_info);
}
static void PrintPTE32PAE(addr_t virtual_address, pte32pae_t * pte)
{
- PrintDebug("PTE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
- (void *)virtual_address,
- (void*)(addr_t)(pte->page_base_addr << PAGE_POWER),
- pte->present,
- pte->writable,
- pte->user_page,
- pte->write_through,
- pte->cache_disable,
- pte->accessed,
- pte->dirty,
- pte->pte_attr,
- pte->global_page,
- pte->vmm_info);
+ PrintDebug("PTE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
+ (void *)virtual_address,
+ (void*)(addr_t)(pte->page_base_addr << PAGE_POWER),
+ pte->present,
+ pte->writable,
+ pte->user_page,
+ pte->write_through,
+ pte->cache_disable,
+ pte->accessed,
+ pte->dirty,
+ pte->pte_attr,
+ pte->global_page,
+ pte->vmm_info);
}
static void PrintPML4e64(addr_t virtual_address, pml4e64_t * pml)
{
- PrintDebug("PML4e64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, kernelInfo=%x\n",
- (void *)virtual_address,
- (void *)(addr_t) (BASE_TO_PAGE_ADDR(pml->pdp_base_addr)),
- pml->present,
- pml->writable,
- pml->user_page,
- pml->write_through,
- pml->cache_disable,
- pml->accessed,
- pml->reserved,
- pml->vmm_info);
+ PrintDebug("PML4e64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, kernelInfo=%x\n",
+ (void *)virtual_address,
+ (void *)(addr_t) (BASE_TO_PAGE_ADDR(pml->pdp_base_addr)),
+ pml->present,
+ pml->writable,
+ pml->user_page,
+ pml->write_through,
+ pml->cache_disable,
+ pml->accessed,
+ pml->reserved,
+ pml->vmm_info);
}
static void PrintPDPE64(addr_t virtual_address, pdpe64_t * pdpe)
{
- PrintDebug("PDPE64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage/zero=%x, kernelInfo=%x\n",
- (void *)virtual_address,
- (void *)(addr_t) (BASE_TO_PAGE_ADDR(pdpe->pd_base_addr)),
- pdpe->present,
- pdpe->writable,
- pdpe->user_page,
- pdpe->write_through,
- pdpe->cache_disable,
- pdpe->accessed,
- pdpe->avail,
- pdpe->large_page,
- pdpe->zero,
- pdpe->vmm_info);
+ PrintDebug("PDPE64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage/zero=%x, kernelInfo=%x\n",
+ (void *)virtual_address,
+ (void *)(addr_t) (BASE_TO_PAGE_ADDR(pdpe->pd_base_addr)),
+ pdpe->present,
+ pdpe->writable,
+ pdpe->user_page,
+ pdpe->write_through,
+ pdpe->cache_disable,
+ pdpe->accessed,
+ pdpe->avail,
+ pdpe->large_page,
+ pdpe->zero,
+ pdpe->vmm_info);
}
static void PrintPDE64(addr_t virtual_address, pde64_t * pde)
{
- PrintDebug("PDE64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
- (void *)virtual_address,
- (void *)(addr_t) (BASE_TO_PAGE_ADDR(pde->pt_base_addr)),
- pde->present,
- pde->writable,
- pde->user_page,
- pde->write_through,
- pde->cache_disable,
- pde->accessed,
- pde->avail,
- pde->large_page,
- pde->global_page,
- pde->vmm_info);
+ PrintDebug("PDE64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
+ (void *)virtual_address,
+ (void *)(addr_t) (BASE_TO_PAGE_ADDR(pde->pt_base_addr)),
+ pde->present,
+ pde->writable,
+ pde->user_page,
+ pde->write_through,
+ pde->cache_disable,
+ pde->accessed,
+ pde->avail,
+ pde->large_page,
+ pde->global_page,
+ pde->vmm_info);
}
static void PrintPTE64(addr_t virtual_address, pte64_t * pte)
{
- PrintDebug("PTE64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
- (void *)virtual_address,
- (void*)(addr_t)(BASE_TO_PAGE_ADDR(pte->page_base_addr)),
- pte->present,
- pte->writable,
- pte->user_page,
- pte->write_through,
- pte->cache_disable,
- pte->accessed,
- pte->dirty,
- pte->pte_attr,
- pte->global_page,
- pte->vmm_info);
+ PrintDebug("PTE64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
+ (void *)virtual_address,
+ (void*)(addr_t)(BASE_TO_PAGE_ADDR(pte->page_base_addr)),
+ pte->present,
+ pte->writable,
+ pte->user_page,
+ pte->write_through,
+ pte->cache_disable,
+ pte->accessed,
+ pte->dirty,
+ pte->pte_attr,
+ pte->global_page,
+ pte->vmm_info);
}
static int print_page_walk_cb(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data) {
- int i = 0;
- addr_t tmp_vaddr = 0;
- switch (type) {
-
- /* 64 Bit */
-
- case PAGE_PML464:
- {
- pml4e64_t * pml = (pml4e64_t *)page_ptr;
- PrintDebug("PML4E64 Page\n");
- for (i = 0; i < MAX_PML4E64_ENTRIES; i++) {
- tmp_vaddr = (4096 * MAX_PTE64_ENTRIES);
- tmp_vaddr *= (MAX_PDE64_ENTRIES * MAX_PDPE64_ENTRIES * i); // break apart to avoid int overflow compile errors
- tmp_vaddr += vaddr;
- if (pml[i].present)
- PrintPML4e64(tmp_vaddr, &(pml[i]));
- }
- break;
- }
- case PAGE_PDP64:
- {
- pdpe64_t * pdp = (pdpe64_t *)page_ptr;
- PrintDebug("PDPE64 Page\n");
- for (i = 0; i < MAX_PDPE64_ENTRIES; i++) {
- tmp_vaddr = 4096 * MAX_PTE64_ENTRIES * MAX_PDE64_ENTRIES * i;
- tmp_vaddr += vaddr;
- if (pdp[i].present)
- PrintPDPE64(tmp_vaddr, &(pdp[i]));
- }
- break;
- }
- case PAGE_PD64:
- {
- pde64_t * pd = (pde64_t *)page_ptr;
- PrintDebug("PDE64 Page\n");
- for (i = 0; i < MAX_PDE64_ENTRIES; i++) {
- tmp_vaddr = 4096 * MAX_PTE64_ENTRIES * i;
- tmp_vaddr += vaddr;
- if (pd[i].present)
- PrintPDE64(tmp_vaddr, &(pd[i]));
- }
- break;
- }
- case PAGE_PT64:
- {
- pte64_t * pt = (pte64_t *)page_ptr;
- PrintDebug("PTE64 Page\n");
- for (i = 0; i < MAX_PTE64_ENTRIES; i++) {
- tmp_vaddr = 4096 * i;
- tmp_vaddr += vaddr;
- if (pt[i].present)
- PrintPTE64(tmp_vaddr, &(pt[i]));
- }
- break;
- }
-
- /* 32 BIT PAE */
+ int i = 0;
+ addr_t tmp_vaddr = 0;
+ switch (type) {
+
+ /* 64 Bit */
+
+ case PAGE_PML464:
+ {
+ pml4e64_t * pml = (pml4e64_t *)page_ptr;
+ PrintDebug("PML4E64 Page\n");
+ for (i = 0; i < MAX_PML4E64_ENTRIES; i++) {
+ tmp_vaddr = (4096 * MAX_PTE64_ENTRIES);
+ tmp_vaddr *= (MAX_PDE64_ENTRIES * MAX_PDPE64_ENTRIES * i); // break apart to avoid int overflow compile errors
+ tmp_vaddr += vaddr;
+ if (pml[i].present)
+ PrintPML4e64(tmp_vaddr, &(pml[i]));
+ }
+ break;
+ }
+ case PAGE_PDP64:
+ {
+ pdpe64_t * pdp = (pdpe64_t *)page_ptr;
+ PrintDebug("PDPE64 Page\n");
+ for (i = 0; i < MAX_PDPE64_ENTRIES; i++) {
+ tmp_vaddr = 4096 * MAX_PTE64_ENTRIES * MAX_PDE64_ENTRIES * i;
+ tmp_vaddr += vaddr;
+ if (pdp[i].present)
+ PrintPDPE64(tmp_vaddr, &(pdp[i]));
+ }
+ break;
+ }
+ case PAGE_PD64:
+ {
+ pde64_t * pd = (pde64_t *)page_ptr;
+ PrintDebug("PDE64 Page\n");
+ for (i = 0; i < MAX_PDE64_ENTRIES; i++) {
+ tmp_vaddr = 4096 * MAX_PTE64_ENTRIES * i;
+ tmp_vaddr += vaddr;
+ if (pd[i].present)
+ PrintPDE64(tmp_vaddr, &(pd[i]));
+ }
+ break;
+ }
+ case PAGE_PT64:
+ {
+ pte64_t * pt = (pte64_t *)page_ptr;
+ PrintDebug("PTE64 Page\n");
+ for (i = 0; i < MAX_PTE64_ENTRIES; i++) {
+ tmp_vaddr = 4096 * i;
+ tmp_vaddr += vaddr;
+ if (pt[i].present)
+ PrintPTE64(tmp_vaddr, &(pt[i]));
+ }
+ break;
+ }
+
+ /* 32 BIT PAE */
- case PAGE_PDP32PAE:
- {
- pdpe32pae_t * pdp = (pdpe32pae_t *)page_ptr;
- PrintDebug("PDPE32PAE Page\n");
- for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) {
- tmp_vaddr = 4096 * MAX_PTE32PAE_ENTRIES * MAX_PDE32PAE_ENTRIES * i;
- tmp_vaddr += vaddr;
- if (pdp[i].present)
- PrintPDPE32PAE(tmp_vaddr, &(pdp[i]));
- }
- break;
- }
- case PAGE_PD32PAE:
- {
- pde32pae_t * pd = (pde32pae_t *)page_ptr;
- PrintDebug("PDE32PAE Page\n");
- for (i = 0; i < MAX_PDE32PAE_ENTRIES; i++) {
- tmp_vaddr = 4096 * MAX_PTE32PAE_ENTRIES * i;
- tmp_vaddr += vaddr;
- if (pd[i].present)
- PrintPDE32PAE(tmp_vaddr, &(pd[i]));
- }
- break;
- }
- case PAGE_PT32PAE:
- {
- pte32pae_t * pt = (pte32pae_t *)page_ptr;
- PrintDebug("PTE32PAE Page\n");
- for (i = 0; i < MAX_PTE32PAE_ENTRIES; i++) {
- tmp_vaddr = 4096 * i;
- tmp_vaddr += vaddr;
- if (pt[i].present)
- PrintPTE32PAE(tmp_vaddr, &(pt[i]));
- }
- break;
+ case PAGE_PDP32PAE:
+ {
+ pdpe32pae_t * pdp = (pdpe32pae_t *)page_ptr;
+ PrintDebug("PDPE32PAE Page\n");
+ for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) {
+ tmp_vaddr = 4096 * MAX_PTE32PAE_ENTRIES * MAX_PDE32PAE_ENTRIES * i;
+ tmp_vaddr += vaddr;
+ if (pdp[i].present)
+ PrintPDPE32PAE(tmp_vaddr, &(pdp[i]));
+ }
+ break;
+ }
+ case PAGE_PD32PAE:
+ {
+ pde32pae_t * pd = (pde32pae_t *)page_ptr;
+ PrintDebug("PDE32PAE Page\n");
+ for (i = 0; i < MAX_PDE32PAE_ENTRIES; i++) {
+ tmp_vaddr = 4096 * MAX_PTE32PAE_ENTRIES * i;
+ tmp_vaddr += vaddr;
+ if (pd[i].present)
+ PrintPDE32PAE(tmp_vaddr, &(pd[i]));
+ }
+ break;
+ }
+ case PAGE_PT32PAE:
+ {
+ pte32pae_t * pt = (pte32pae_t *)page_ptr;
+ PrintDebug("PTE32PAE Page\n");
+ for (i = 0; i < MAX_PTE32PAE_ENTRIES; i++) {
+ tmp_vaddr = 4096 * i;
+ tmp_vaddr += vaddr;
+ if (pt[i].present)
+ PrintPTE32PAE(tmp_vaddr, &(pt[i]));
+ }
+ break;
+ }
+
+ /* 32 Bit */
+
+ case PAGE_PD32:
+ {
+ pde32_t * pd = (pde32_t *)page_ptr;
+ PrintDebug("PDE32 Page\n");
+ for (i = 0; i < MAX_PTE32_ENTRIES; i++) {
+ tmp_vaddr = 4096 * MAX_PTE32_ENTRIES * i;
+ tmp_vaddr += vaddr;
+ if (pd[i].present)
+ PrintPDE32(tmp_vaddr, &(pd[i]));
+ }
+ break;
+ }
+ case PAGE_PT32:
+ {
+ pte32_t * pt = (pte32_t *)page_ptr;
+ PrintDebug("PTE32 Page\n");
+ for (i = 0; i < MAX_PTE32_ENTRIES; i++) {
+ tmp_vaddr = 4096 * i;
+ tmp_vaddr += vaddr;
+ if (pt[i].present)
+ PrintPTE32(tmp_vaddr, &(pt[i]));
+ }
+ break;
+ }
+ default:
+ break;
}
- /* 32 Bit */
-
- case PAGE_PD32:
- {
- pde32_t * pd = (pde32_t *)page_ptr;
- PrintDebug("PDE32 Page\n");
- for (i = 0; i < MAX_PTE32_ENTRIES; i++) {
- tmp_vaddr = 4096 * MAX_PTE32_ENTRIES * i;
- tmp_vaddr += vaddr;
- if (pd[i].present)
- PrintPDE32(tmp_vaddr, &(pd[i]));
- }
- break;
- }
- case PAGE_PT32:
- {
- pte32_t * pt = (pte32_t *)page_ptr;
- PrintDebug("PTE32 Page\n");
- for (i = 0; i < MAX_PTE32_ENTRIES; i++) {
- tmp_vaddr = 4096 * i;
- tmp_vaddr += vaddr;
- if (pt[i].present)
- PrintPTE32(tmp_vaddr, &(pt[i]));
- }
- break;
- }
- default:
- break;
- }
-
- return 0;
+ return 0;
}
static int print_page_tree_cb(struct guest_info * info, page_type_t type, addr_t vaddr, addr_t page_ptr, addr_t page_pa, void * private_data) {
- switch (type) {
-
- /* 64 Bit */
-
- case PAGE_PML464:
- {
- pml4e64_t * pml = (pml4e64_t *)page_ptr;
- PrintPML4e64(vaddr, &(pml[PML4E64_INDEX(vaddr)]));
- break;
- }
- case PAGE_PDP64:
- {
- pdpe64_t * pdp = (pdpe64_t *)page_ptr;
- PrintPDPE64(vaddr, &(pdp[PDPE64_INDEX(vaddr)]));
- break;
- }
- case PAGE_PD64:
- {
- pde64_t * pd = (pde64_t *)page_ptr;
- PrintPDE64(vaddr, &(pd[PDE64_INDEX(vaddr)]));
- break;
- }
- case PAGE_PT64:
- {
- pte64_t * pt = (pte64_t *)page_ptr;
- PrintPTE64(vaddr, &(pt[PTE64_INDEX(vaddr)]));
- break;
- }
-
- /* 32 BIT PAE */
+ switch (type) {
+
+ /* 64 Bit */
+
+ case PAGE_PML464:
+ {
+ pml4e64_t * pml = (pml4e64_t *)page_ptr;
+ PrintPML4e64(vaddr, &(pml[PML4E64_INDEX(vaddr)]));
+ break;
+ }
+ case PAGE_PDP64:
+ {
+ pdpe64_t * pdp = (pdpe64_t *)page_ptr;
+ PrintPDPE64(vaddr, &(pdp[PDPE64_INDEX(vaddr)]));
+ break;
+ }
+ case PAGE_PD64:
+ {
+ pde64_t * pd = (pde64_t *)page_ptr;
+ PrintPDE64(vaddr, &(pd[PDE64_INDEX(vaddr)]));
+ break;
+ }
+ case PAGE_PT64:
+ {
+ pte64_t * pt = (pte64_t *)page_ptr;
+ PrintPTE64(vaddr, &(pt[PTE64_INDEX(vaddr)]));
+ break;
+ }
+
+ /* 32 BIT PAE */
- case PAGE_PDP32PAE:
- {
- pdpe32pae_t * pdp = (pdpe32pae_t *)page_ptr;
- PrintPDPE32PAE(vaddr, &(pdp[PDPE32PAE_INDEX(vaddr)]));
- break;
- }
- case PAGE_PD32PAE:
- {
- pde32pae_t * pd = (pde32pae_t *)page_ptr;
- PrintPDE32PAE(vaddr, &(pd[PDE32PAE_INDEX(vaddr)]));
- break;
+ case PAGE_PDP32PAE:
+ {
+ pdpe32pae_t * pdp = (pdpe32pae_t *)page_ptr;
+ PrintPDPE32PAE(vaddr, &(pdp[PDPE32PAE_INDEX(vaddr)]));
+ break;
+ }
+ case PAGE_PD32PAE:
+ {
+ pde32pae_t * pd = (pde32pae_t *)page_ptr;
+ PrintPDE32PAE(vaddr, &(pd[PDE32PAE_INDEX(vaddr)]));
+ break;
+ }
+ case PAGE_PT32PAE:
+ {
+ pte32pae_t * pt = (pte32pae_t *)page_ptr;
+ PrintPTE32PAE(vaddr, &(pt[PTE32PAE_INDEX(vaddr)]));
+ break;
+ }
+
+ /* 32 Bit */
+
+ case PAGE_PD32:
+ {
+ pde32_t * pd = (pde32_t *)page_ptr;
+ PrintPDE32(vaddr, &(pd[PDE32_INDEX(vaddr)]));
+ break;
+ }
+ case PAGE_PT32:
+ {
+ pte32_t * pt = (pte32_t *)page_ptr;
+ PrintPTE32(vaddr, &(pt[PTE32_INDEX(vaddr)]));
+ break;
+ }
+ default:
+ PrintDebug("%s %p->%p \n", v3_page_type_to_str(type), (void *)vaddr, (void *)page_pa);
+ break;
}
- case PAGE_PT32PAE:
- {
- pte32pae_t * pt = (pte32pae_t *)page_ptr;
- PrintPTE32PAE(vaddr, &(pt[PTE32PAE_INDEX(vaddr)]));
- break;
- }
-
- /* 32 Bit */
- case PAGE_PD32:
- {
- pde32_t * pd = (pde32_t *)page_ptr;
- PrintPDE32(vaddr, &(pd[PDE32_INDEX(vaddr)]));
- break;
- }
- case PAGE_PT32:
- {
- pte32_t * pt = (pte32_t *)page_ptr;
- PrintPTE32(vaddr, &(pt[PTE32_INDEX(vaddr)]));
- break;
- }
- default:
- PrintDebug("%s %p->%p \n", v3_page_type_to_str(type), (void *)vaddr, (void *)page_pa);
- break;
- }
-
- return 0;
+ return 0;
}
void PrintPTEntry(struct guest_info * info, page_type_t type, addr_t vaddr, void * entry) {
- print_page_tree_cb(info, type, vaddr, PAGE_ADDR_4KB((addr_t)entry), 0, NULL);
+ print_page_tree_cb(info, type, vaddr, PAGE_ADDR_4KB((addr_t)entry), 0, NULL);
}
void PrintHostPageTables(struct guest_info * info, addr_t cr3) {
- PrintDebug("CR3: %p\n", (void *)cr3);
- switch (info->cpu_mode) {
- case PROTECTED:
- v3_walk_host_pt_32(info, cr3, print_page_walk_cb, NULL);
- break;
- case PROTECTED_PAE:
- v3_walk_host_pt_32pae(info, cr3, print_page_walk_cb, NULL);
- break;
- case LONG:
- case LONG_32_COMPAT:
- case LONG_16_COMPAT:
- v3_walk_host_pt_64(info, cr3, print_page_walk_cb, NULL);
- break;
- default:
- PrintError("Unsupported CPU MODE %s\n", v3_cpu_mode_to_str(info->cpu_mode));
- break;
- }
+ PrintDebug("CR3: %p\n", (void *)cr3);
+ switch (info->cpu_mode) {
+ case PROTECTED:
+ v3_walk_host_pt_32(info, cr3, print_page_walk_cb, NULL);
+ break;
+ case PROTECTED_PAE:
+ v3_walk_host_pt_32pae(info, cr3, print_page_walk_cb, NULL);
+ break;
+ case LONG:
+ case LONG_32_COMPAT:
+ case LONG_16_COMPAT:
+ v3_walk_host_pt_64(info, cr3, print_page_walk_cb, NULL);
+ break;
+ default:
+ PrintError("Unsupported CPU MODE %s\n", v3_cpu_mode_to_str(info->cpu_mode));
+ break;
+ }
}
void PrintGuestPageTables(struct guest_info * info, addr_t cr3) {
- PrintDebug("CR3: %p\n", (void *)cr3);
- switch (info->cpu_mode) {
- case PROTECTED:
- v3_walk_guest_pt_32(info, cr3, print_page_walk_cb, NULL);
- break;
- case PROTECTED_PAE:
- v3_walk_guest_pt_32pae(info, cr3, print_page_walk_cb, NULL);
- break;
- case LONG:
- case LONG_32_COMPAT:
- case LONG_16_COMPAT:
- v3_walk_guest_pt_64(info, cr3, print_page_walk_cb, NULL);
- break;
- default:
- PrintError("Unsupported CPU MODE %s\n", v3_cpu_mode_to_str(info->cpu_mode));
- break;
- }
+ PrintDebug("CR3: %p\n", (void *)cr3);
+ switch (info->cpu_mode) {
+ case PROTECTED:
+ v3_walk_guest_pt_32(info, cr3, print_page_walk_cb, NULL);
+ break;
+ case PROTECTED_PAE:
+ v3_walk_guest_pt_32pae(info, cr3, print_page_walk_cb, NULL);
+ break;
+ case LONG:
+ case LONG_32_COMPAT:
+ case LONG_16_COMPAT:
+ v3_walk_guest_pt_64(info, cr3, print_page_walk_cb, NULL);
+ break;
+ default:
+ PrintError("Unsupported CPU MODE %s\n", v3_cpu_mode_to_str(info->cpu_mode));
+ break;
+ }
}
void PrintHostPageTree(struct guest_info * info, addr_t virtual_addr, addr_t cr3) {
- PrintDebug("CR3: %p\n", (void *)cr3);
- switch (info->cpu_mode) {
- case PROTECTED:
- v3_drill_host_pt_32(info, cr3, virtual_addr, print_page_tree_cb, NULL);
- break;
- case PROTECTED_PAE:
- v3_drill_host_pt_32pae(info, cr3, virtual_addr, print_page_tree_cb, NULL);
- break;
- case LONG:
- case LONG_32_COMPAT:
- case LONG_16_COMPAT:
- v3_drill_host_pt_64(info, cr3, virtual_addr, print_page_tree_cb, NULL);
- break;
- default:
- PrintError("Unsupported CPU MODE %s\n", v3_cpu_mode_to_str(info->cpu_mode));
- break;
- }
+ PrintDebug("CR3: %p\n", (void *)cr3);
+ switch (info->cpu_mode) {
+ case PROTECTED:
+ v3_drill_host_pt_32(info, cr3, virtual_addr, print_page_tree_cb, NULL);
+ break;
+ case PROTECTED_PAE:
+ v3_drill_host_pt_32pae(info, cr3, virtual_addr, print_page_tree_cb, NULL);
+ break;
+ case LONG:
+ case LONG_32_COMPAT:
+ case LONG_16_COMPAT:
+ v3_drill_host_pt_64(info, cr3, virtual_addr, print_page_tree_cb, NULL);
+ break;
+ default:
+ PrintError("Unsupported CPU MODE %s\n", v3_cpu_mode_to_str(info->cpu_mode));
+ break;
+ }
}
void PrintGuestPageTree(struct guest_info * info, addr_t virtual_addr, addr_t cr3) {
- PrintDebug("CR3: %p\n", (void *)cr3);
- switch (info->cpu_mode) {
- case PROTECTED:
- v3_drill_guest_pt_32(info, cr3, virtual_addr, print_page_tree_cb, NULL);
- break;
- case PROTECTED_PAE:
- v3_drill_guest_pt_32pae(info, cr3, virtual_addr, print_page_tree_cb, NULL);
- break;
- case LONG:
- case LONG_32_COMPAT:
- case LONG_16_COMPAT:
- v3_drill_guest_pt_64(info, cr3, virtual_addr, print_page_tree_cb, NULL);
- break;
- default:
- PrintError("Unsupported CPU MODE %s\n", v3_cpu_mode_to_str(info->cpu_mode));
- break;
- }
+ PrintDebug("CR3: %p\n", (void *)cr3);
+ switch (info->cpu_mode) {
+ case PROTECTED:
+ v3_drill_guest_pt_32(info, cr3, virtual_addr, print_page_tree_cb, NULL);
+ break;
+ case PROTECTED_PAE:
+ v3_drill_guest_pt_32pae(info, cr3, virtual_addr, print_page_tree_cb, NULL);
+ break;
+ case LONG:
+ case LONG_32_COMPAT:
+ case LONG_16_COMPAT:
+ v3_drill_guest_pt_64(info, cr3, virtual_addr, print_page_tree_cb, NULL);
+ break;
+ default:
+ PrintError("Unsupported CPU MODE %s\n", v3_cpu_mode_to_str(info->cpu_mode));
+ break;
+ }
}
struct exit_event {
- uint_t exit_code;
- uint_t exit_count;
- uint_t handler_time;
+ uint_t exit_code;
+ uint_t exit_count;
+ uint_t handler_time;
- struct rb_node tree_node;
+ struct rb_node tree_node;
};
void v3_init_profiler(struct guest_info * info) {
- info->profiler.total_exits = 0;
+ info->profiler.total_exits = 0;
- info->profiler.start_time = 0;
- info->profiler.end_time = 0;
- info->profiler.guest_pf_cnt = 0;
+ info->profiler.start_time = 0;
+ info->profiler.end_time = 0;
+ info->profiler.guest_pf_cnt = 0;
- info->profiler.root.rb_node = NULL;
+ info->profiler.root.rb_node = NULL;
}
static inline struct exit_event * __insert_event(struct guest_info * info,
struct exit_event * evt) {
- struct rb_node ** p = &(info->profiler.root.rb_node);
- struct rb_node * parent = NULL;
- struct exit_event * tmp_evt = NULL;
-
- while (*p) {
- parent = *p;
- tmp_evt = rb_entry(parent, struct exit_event, tree_node);
-
- if (evt->exit_code < tmp_evt->exit_code) {
- p = &(*p)->rb_left;
- } else if (evt->exit_code > tmp_evt->exit_code) {
- p = &(*p)->rb_right;
- } else {
- return tmp_evt;
+ struct rb_node ** p = &(info->profiler.root.rb_node);
+ struct rb_node * parent = NULL;
+ struct exit_event * tmp_evt = NULL;
+
+ while (*p) {
+ parent = *p;
+ tmp_evt = rb_entry(parent, struct exit_event, tree_node);
+
+ if (evt->exit_code < tmp_evt->exit_code) {
+ p = &(*p)->rb_left;
+ } else if (evt->exit_code > tmp_evt->exit_code) {
+ p = &(*p)->rb_right;
+ } else {
+ return tmp_evt;
+ }
}
- }
- rb_link_node(&(evt->tree_node), parent, p);
+ rb_link_node(&(evt->tree_node), parent, p);
- return NULL;
+ return NULL;
}
static inline struct exit_event * insert_event(struct guest_info * info,
struct exit_event * evt) {
- struct exit_event * ret;
+ struct exit_event * ret;
- if ((ret = __insert_event(info, evt))) {
- return ret;
- }
+ if ((ret = __insert_event(info, evt))) {
+ return ret;
+ }
- v3_rb_insert_color(&(evt->tree_node), &(info->profiler.root));
+ v3_rb_insert_color(&(evt->tree_node), &(info->profiler.root));
- return NULL;
+ return NULL;
}
static struct exit_event * get_exit(struct guest_info * info, uint_t exit_code) {
- struct rb_node * n = info->profiler.root.rb_node;
- struct exit_event * evt = NULL;
+ struct rb_node * n = info->profiler.root.rb_node;
+ struct exit_event * evt = NULL;
- while (n) {
- evt = rb_entry(n, struct exit_event, tree_node);
+ while (n) {
+ evt = rb_entry(n, struct exit_event, tree_node);
- if (exit_code < evt->exit_code) {
- n = n->rb_left;
- } else if (exit_code > evt->exit_code) {
- n = n->rb_right;
- } else {
- return evt;
+ if (exit_code < evt->exit_code) {
+ n = n->rb_left;
+ } else if (exit_code > evt->exit_code) {
+ n = n->rb_right;
+ } else {
+ return evt;
+ }
}
- }
- return NULL;
+ return NULL;
}
static inline struct exit_event * create_exit(uint_t exit_code) {
- struct exit_event * evt = V3_Malloc(sizeof(struct exit_event));
+ struct exit_event * evt = V3_Malloc(sizeof(struct exit_event));
- evt->exit_code = exit_code;
- evt->exit_count = 0;
- evt->handler_time = 0;
+ evt->exit_code = exit_code;
+ evt->exit_count = 0;
+ evt->handler_time = 0;
- return evt;
+ return evt;
}
void v3_profile_exit(struct guest_info * info, uint_t exit_code) {
- uint_t time = (info->profiler.end_time - info->profiler.start_time);
- struct exit_event * evt = get_exit(info, exit_code);
+ uint_t time = (info->profiler.end_time - info->profiler.start_time);
+ struct exit_event * evt = get_exit(info, exit_code);
- if (evt == NULL) {
- evt = create_exit(exit_code);
- insert_event(info, evt);
- }
+ if (evt == NULL) {
+ evt = create_exit(exit_code);
+ insert_event(info, evt);
+ }
- evt->handler_time = (evt->handler_time * .99) + (time * .01);
+ evt->handler_time = (evt->handler_time * .99) + (time * .01);
- evt->exit_count++;
+ evt->exit_count++;
- info->profiler.total_exits++;
+ info->profiler.total_exits++;
}
void v3_print_profile(struct guest_info * info) {
- struct exit_event * evt = NULL;
- struct rb_node * node = v3_rb_first(&(info->profiler.root));
+ struct exit_event * evt = NULL;
+ struct rb_node * node = v3_rb_first(&(info->profiler.root));
- PrintDebug("GUEST_PF: %u\n", info->profiler.guest_pf_cnt);
-
- do {
- evt = rb_entry(node, struct exit_event, tree_node);
- const char * code_str = vmexit_code_to_str(evt->exit_code);
-
- PrintDebug("%s:%sCnt=%u,%sTime=%u\n",
- code_str,
- (strlen(code_str) > 14) ? "\t" : "\t\t",
- evt->exit_count,
- (evt->exit_count >= 100) ? "\t" : "\t\t",
- evt->handler_time);
+ PrintDebug("GUEST_PF: %u\n", info->profiler.guest_pf_cnt);
+
+ do {
+ evt = rb_entry(node, struct exit_event, tree_node);
+ const char * code_str = vmexit_code_to_str(evt->exit_code);
+
+ PrintDebug("%s:%sCnt=%u,%sTime=%u\n",
+ code_str,
+ (strlen(code_str) > 14) ? "\t" : "\t\t",
+ evt->exit_count,
+ (evt->exit_count >= 100) ? "\t" : "\t\t",
+ evt->handler_time);
- } while ((node = v3_rb_next(node)));
+ } while ((node = v3_rb_next(node)));
}
void v3_init_queue(struct gen_queue * queue) {
- queue->num_entries = 0;
- INIT_LIST_HEAD(&(queue->entries));
+ queue->num_entries = 0;
+ INIT_LIST_HEAD(&(queue->entries));
}
struct gen_queue * v3_create_queue() {
- struct gen_queue * tmp_queue = V3_Malloc(sizeof(struct gen_queue));
- v3_init_queue(tmp_queue);
- return tmp_queue;
+ struct gen_queue * tmp_queue = V3_Malloc(sizeof(struct gen_queue));
+ v3_init_queue(tmp_queue);
+ return tmp_queue;
}
void v3_enqueue(struct gen_queue * queue, addr_t entry) {
- struct queue_entry * q_entry = V3_Malloc(sizeof(struct queue_entry));
+ struct queue_entry * q_entry = V3_Malloc(sizeof(struct queue_entry));
- q_entry->entry = entry;
- list_add_tail(&(q_entry->entry_list), &(queue->entries));
- queue->num_entries++;
+ q_entry->entry = entry;
+ list_add_tail(&(q_entry->entry_list), &(queue->entries));
+ queue->num_entries++;
}
addr_t v3_dequeue(struct gen_queue * queue) {
- addr_t entry_val = 0;
+ addr_t entry_val = 0;
- if (!list_empty(&(queue->entries))) {
- struct list_head * q_entry = queue->entries.next;
- struct queue_entry * tmp_entry = list_entry(q_entry, struct queue_entry, entry_list);
+ if (!list_empty(&(queue->entries))) {
+ struct list_head * q_entry = queue->entries.next;
+ struct queue_entry * tmp_entry = list_entry(q_entry, struct queue_entry, entry_list);
- entry_val = tmp_entry->entry;
- list_del(q_entry);
- V3_Free(tmp_entry);
- }
+ entry_val = tmp_entry->entry;
+ list_del(q_entry);
+ V3_Free(tmp_entry);
+ }
- return entry_val;
+ return entry_val;
}
static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
{
- struct rb_node *right = node->rb_right;
- struct rb_node *parent = rb_parent(node);
+ struct rb_node *right = node->rb_right;
+ struct rb_node *parent = rb_parent(node);
- if ((node->rb_right = right->rb_left))
- rb_set_parent(right->rb_left, node);
- right->rb_left = node;
+ if ((node->rb_right = right->rb_left))
+ rb_set_parent(right->rb_left, node);
+ right->rb_left = node;
- rb_set_parent(right, parent);
+ rb_set_parent(right, parent);
- if (parent)
+ if (parent)
{
- if (node == parent->rb_left)
- parent->rb_left = right;
- else
- parent->rb_right = right;
+ if (node == parent->rb_left)
+ parent->rb_left = right;
+ else
+ parent->rb_right = right;
}
- else
- root->rb_node = right;
- rb_set_parent(node, right);
+ else
+ root->rb_node = right;
+ rb_set_parent(node, right);
}
static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
{
- struct rb_node *left = node->rb_left;
- struct rb_node *parent = rb_parent(node);
+ struct rb_node * left = node->rb_left;
+ struct rb_node * parent = rb_parent(node);
- if ((node->rb_left = left->rb_right))
- rb_set_parent(left->rb_right, node);
- left->rb_right = node;
+ if ((node->rb_left = left->rb_right)) {
+ rb_set_parent(left->rb_right, node);
+ }
- rb_set_parent(left, parent);
+ left->rb_right = node;
- if (parent)
- {
- if (node == parent->rb_right)
- parent->rb_right = left;
- else
- parent->rb_left = left;
+ rb_set_parent(left, parent);
+
+ if (parent) {
+ if (node == parent->rb_right) {
+ parent->rb_right = left;
+ } else {
+ parent->rb_left = left;
}
- else
- root->rb_node = left;
- rb_set_parent(node, left);
+ } else {
+ root->rb_node = left;
+ }
+
+ rb_set_parent(node, left);
}
void v3_rb_insert_color(struct rb_node *node, struct rb_root *root)
{
- struct rb_node *parent, *gparent;
+ struct rb_node *parent, *gparent;
- while ((parent = rb_parent(node)) && rb_is_red(parent))
+ while ((parent = rb_parent(node)) && rb_is_red(parent))
{
- gparent = rb_parent(parent);
+ gparent = rb_parent(parent);
- if (parent == gparent->rb_left)
+ if (parent == gparent->rb_left)
{
- {
- register struct rb_node *uncle = gparent->rb_right;
- if (uncle && rb_is_red(uncle))
- {
- rb_set_black(uncle);
- rb_set_black(parent);
- rb_set_red(gparent);
- node = gparent;
- continue;
- }
- }
+ {
+ register struct rb_node *uncle = gparent->rb_right;
+ if (uncle && rb_is_red(uncle))
+ {
+ rb_set_black(uncle);
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ node = gparent;
+ continue;
+ }
+ }
- if (parent->rb_right == node)
+ if (parent->rb_right == node)
{
- register struct rb_node *tmp;
- __rb_rotate_left(parent, root);
- tmp = parent;
- parent = node;
- node = tmp;
+ register struct rb_node *tmp;
+ __rb_rotate_left(parent, root);
+ tmp = parent;
+ parent = node;
+ node = tmp;
}
- rb_set_black(parent);
- rb_set_red(gparent);
- __rb_rotate_right(gparent, root);
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ __rb_rotate_right(gparent, root);
} else {
+ {
+ register struct rb_node *uncle = gparent->rb_left;
+ if (uncle && rb_is_red(uncle))
{
- register struct rb_node *uncle = gparent->rb_left;
- if (uncle && rb_is_red(uncle))
- {
- rb_set_black(uncle);
- rb_set_black(parent);
- rb_set_red(gparent);
- node = gparent;
- continue;
- }
+ rb_set_black(uncle);
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ node = gparent;
+ continue;
}
+ }
- if (parent->rb_left == node)
- {
- register struct rb_node *tmp;
- __rb_rotate_right(parent, root);
- tmp = parent;
- parent = node;
- node = tmp;
- }
+ if (parent->rb_left == node)
+ {
+ register struct rb_node *tmp;
+ __rb_rotate_right(parent, root);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
- rb_set_black(parent);
- rb_set_red(gparent);
- __rb_rotate_left(gparent, root);
- }
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ __rb_rotate_left(gparent, root);
+ }
}
- rb_set_black(root->rb_node);
+ rb_set_black(root->rb_node);
}
static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
struct rb_root *root)
{
- struct rb_node *other;
+ struct rb_node *other;
- while ((!node || rb_is_black(node)) && node != root->rb_node)
+ while ((!node || rb_is_black(node)) && node != root->rb_node)
{
- if (parent->rb_left == node)
+ if (parent->rb_left == node)
{
- other = parent->rb_right;
- if (rb_is_red(other))
+ other = parent->rb_right;
+ if (rb_is_red(other))
{
- rb_set_black(other);
- rb_set_red(parent);
- __rb_rotate_left(parent, root);
- other = parent->rb_right;
+ rb_set_black(other);
+ rb_set_red(parent);
+ __rb_rotate_left(parent, root);
+ other = parent->rb_right;
}
- if ((!other->rb_left || rb_is_black(other->rb_left)) &&
- (!other->rb_right || rb_is_black(other->rb_right)))
+ if ((!other->rb_left || rb_is_black(other->rb_left)) &&
+ (!other->rb_right || rb_is_black(other->rb_right)))
{
- rb_set_red(other);
- node = parent;
- parent = rb_parent(node);
+ rb_set_red(other);
+ node = parent;
+ parent = rb_parent(node);
}
- else
+ else
{
- if (!other->rb_right || rb_is_black(other->rb_right))
+ if (!other->rb_right || rb_is_black(other->rb_right))
{
- struct rb_node *o_left;
- if ((o_left = other->rb_left))
- rb_set_black(o_left);
- rb_set_red(other);
- __rb_rotate_right(other, root);
- other = parent->rb_right;
+ struct rb_node *o_left;
+ if ((o_left = other->rb_left))
+ rb_set_black(o_left);
+ rb_set_red(other);
+ __rb_rotate_right(other, root);
+ other = parent->rb_right;
}
- rb_set_color(other, rb_color(parent));
- rb_set_black(parent);
- if (other->rb_right)
- rb_set_black(other->rb_right);
- __rb_rotate_left(parent, root);
- node = root->rb_node;
- break;
+ rb_set_color(other, rb_color(parent));
+ rb_set_black(parent);
+ if (other->rb_right)
+ rb_set_black(other->rb_right);
+ __rb_rotate_left(parent, root);
+ node = root->rb_node;
+ break;
}
}
- else
+ else
{
- other = parent->rb_left;
- if (rb_is_red(other))
+ other = parent->rb_left;
+ if (rb_is_red(other))
{
- rb_set_black(other);
- rb_set_red(parent);
- __rb_rotate_right(parent, root);
- other = parent->rb_left;
+ rb_set_black(other);
+ rb_set_red(parent);
+ __rb_rotate_right(parent, root);
+ other = parent->rb_left;
}
- if ((!other->rb_left || rb_is_black(other->rb_left)) &&
- (!other->rb_right || rb_is_black(other->rb_right)))
+ if ((!other->rb_left || rb_is_black(other->rb_left)) &&
+ (!other->rb_right || rb_is_black(other->rb_right)))
{
- rb_set_red(other);
- node = parent;
- parent = rb_parent(node);
+ rb_set_red(other);
+ node = parent;
+ parent = rb_parent(node);
}
- else
+ else
{
- if (!other->rb_left || rb_is_black(other->rb_left))
+ if (!other->rb_left || rb_is_black(other->rb_left))
{
- register struct rb_node *o_right;
- if ((o_right = other->rb_right))
- rb_set_black(o_right);
- rb_set_red(other);
- __rb_rotate_left(other, root);
- other = parent->rb_left;
+ register struct rb_node *o_right;
+ if ((o_right = other->rb_right))
+ rb_set_black(o_right);
+ rb_set_red(other);
+ __rb_rotate_left(other, root);
+ other = parent->rb_left;
}
- rb_set_color(other, rb_color(parent));
- rb_set_black(parent);
- if (other->rb_left)
- rb_set_black(other->rb_left);
- __rb_rotate_right(parent, root);
- node = root->rb_node;
- break;
+ rb_set_color(other, rb_color(parent));
+ rb_set_black(parent);
+ if (other->rb_left)
+ rb_set_black(other->rb_left);
+ __rb_rotate_right(parent, root);
+ node = root->rb_node;
+ break;
}
}
}
- if (node)
- rb_set_black(node);
+ if (node)
+ rb_set_black(node);
}
void v3_rb_erase(struct rb_node *node, struct rb_root *root)
{
- struct rb_node *child, *parent;
- int color;
-
- if (!node->rb_left)
- child = node->rb_right;
- else if (!node->rb_right)
- child = node->rb_left;
- else
+ struct rb_node *child, *parent;
+ int color;
+
+ if (!node->rb_left)
+ child = node->rb_right;
+ else if (!node->rb_right)
+ child = node->rb_left;
+ else
{
- struct rb_node *old = node, *left;
-
- node = node->rb_right;
- while ((left = node->rb_left) != NULL)
- node = left;
- child = node->rb_right;
- parent = rb_parent(node);
- color = rb_color(node);
-
- if (child)
- rb_set_parent(child, parent);
- if (parent == old) {
- parent->rb_right = child;
- parent = node;
- } else
- parent->rb_left = child;
+ struct rb_node *old = node, *left;
+
+ node = node->rb_right;
+ while ((left = node->rb_left) != NULL)
+ node = left;
+ child = node->rb_right;
+ parent = rb_parent(node);
+ color = rb_color(node);
- node->rb_parent_color = old->rb_parent_color;
- node->rb_right = old->rb_right;
- node->rb_left = old->rb_left;
+ if (child)
+ rb_set_parent(child, parent);
+ if (parent == old) {
+ parent->rb_right = child;
+ parent = node;
+ } else
+ parent->rb_left = child;
- if (rb_parent(old))
+ node->rb_parent_color = old->rb_parent_color;
+ node->rb_right = old->rb_right;
+ node->rb_left = old->rb_left;
+
+ if (rb_parent(old))
{
- if (rb_parent(old)->rb_left == old)
- rb_parent(old)->rb_left = node;
- else
- rb_parent(old)->rb_right = node;
+ if (rb_parent(old)->rb_left == old)
+ rb_parent(old)->rb_left = node;
+ else
+ rb_parent(old)->rb_right = node;
} else
- root->rb_node = node;
+ root->rb_node = node;
- rb_set_parent(old->rb_left, node);
- if (old->rb_right)
- rb_set_parent(old->rb_right, node);
- goto color;
+ rb_set_parent(old->rb_left, node);
+ if (old->rb_right)
+ rb_set_parent(old->rb_right, node);
+ goto color;
}
- parent = rb_parent(node);
- color = rb_color(node);
+ parent = rb_parent(node);
+ color = rb_color(node);
- if (child)
- rb_set_parent(child, parent);
- if (parent)
+ if (child)
+ rb_set_parent(child, parent);
+ if (parent)
{
- if (parent->rb_left == node)
- parent->rb_left = child;
- else
- parent->rb_right = child;
+ if (parent->rb_left == node)
+ parent->rb_left = child;
+ else
+ parent->rb_right = child;
}
- else
- root->rb_node = child;
+ else
+ root->rb_node = child;
color:
- if (color == RB_BLACK)
- __rb_erase_color(child, parent, root);
+ if (color == RB_BLACK)
+ __rb_erase_color(child, parent, root);
}
*/
struct rb_node *v3_rb_first(struct rb_root *root)
{
- struct rb_node *n;
-
- n = root->rb_node;
- if (!n)
- return NULL;
- while (n->rb_left)
- n = n->rb_left;
- return n;
+ struct rb_node *n;
+
+ n = root->rb_node;
+ if (!n)
+ return NULL;
+ while (n->rb_left)
+ n = n->rb_left;
+ return n;
}
struct rb_node *v3_rb_last(struct rb_root *root)
{
- struct rb_node *n;
-
- n = root->rb_node;
- if (!n)
- return NULL;
- while (n->rb_right)
- n = n->rb_right;
- return n;
+ struct rb_node *n;
+
+ n = root->rb_node;
+ if (!n)
+ return NULL;
+ while (n->rb_right)
+ n = n->rb_right;
+ return n;
}
struct rb_node *v3_rb_next(struct rb_node *node)
{
- struct rb_node *parent;
-
- /* If we have a right-hand child, go down and then left as far
- as we can. */
- if (node->rb_right) {
- node = node->rb_right;
- while (node->rb_left)
- node=node->rb_left;
- return node;
- }
-
- /* No right-hand children. Everything down and left is
- smaller than us, so any 'next' node must be in the general
- direction of our parent. Go up the tree; any time the
- ancestor is a right-hand child of its parent, keep going
- up. First time it's a left-hand child of its parent, said
- parent is our 'next' node. */
- while ((parent = rb_parent(node)) && node == parent->rb_right)
- node = parent;
-
- return parent;
+ struct rb_node *parent;
+
+ /* If we have a right-hand child, go down and then left as far
+ as we can. */
+ if (node->rb_right) {
+ node = node->rb_right;
+ while (node->rb_left)
+ node=node->rb_left;
+ return node;
+ }
+
+ /* No right-hand children. Everything down and left is
+ smaller than us, so any 'next' node must be in the general
+ direction of our parent. Go up the tree; any time the
+ ancestor is a right-hand child of its parent, keep going
+ up. First time it's a left-hand child of its parent, said
+ parent is our 'next' node. */
+ while ((parent = rb_parent(node)) && node == parent->rb_right)
+ node = parent;
+
+ return parent;
}
struct rb_node *v3_rb_prev(struct rb_node *node)
{
- struct rb_node *parent;
-
- /* If we have a left-hand child, go down and then right as far
- as we can. */
- if (node->rb_left) {
- node = node->rb_left;
- while (node->rb_right)
- node=node->rb_right;
- return node;
- }
-
- /* No left-hand children. Go up till we find an ancestor which
- is a right-hand child of its parent */
- while ((parent = rb_parent(node)) && node == parent->rb_left)
- node = parent;
-
- return parent;
+ struct rb_node *parent;
+
+ /* If we have a left-hand child, go down and then right as far
+ as we can. */
+ if (node->rb_left) {
+ node = node->rb_left;
+ while (node->rb_right)
+ node=node->rb_right;
+ return node;
+ }
+
+ /* No left-hand children. Go up till we find an ancestor which
+ is a right-hand child of its parent */
+ while ((parent = rb_parent(node)) && node == parent->rb_left)
+ node = parent;
+
+ return parent;
}
void v3_rb_replace_node(struct rb_node *victim, struct rb_node *new,
- struct rb_root *root)
+ struct rb_root *root)
{
- struct rb_node *parent = rb_parent(victim);
-
- /* Set the surrounding nodes to point to the replacement */
- if (parent) {
- if (victim == parent->rb_left)
- parent->rb_left = new;
- else
- parent->rb_right = new;
- } else {
- root->rb_node = new;
- }
- if (victim->rb_left)
- rb_set_parent(victim->rb_left, new);
- if (victim->rb_right)
- rb_set_parent(victim->rb_right, new);
+ struct rb_node *parent = rb_parent(victim);
- /* Copy the pointers/colour from the victim to the replacement */
- *new = *victim;
+ /* Set the surrounding nodes to point to the replacement */
+ if (parent) {
+ if (victim == parent->rb_left)
+ parent->rb_left = new;
+ else
+ parent->rb_right = new;
+ } else {
+ root->rb_node = new;
+ }
+ if (victim->rb_left)
+ rb_set_parent(victim->rb_left, new);
+ if (victim->rb_right)
+ rb_set_parent(victim->rb_right, new);
+
+ /* Copy the pointers/colour from the victim to the replacement */
+ *new = *victim;
}
void NO_INST v3_init_ringbuf(struct v3_ringbuf * ring, uint_t size) {
- ring->buf = V3_Malloc(size);
- ring->size = size;
+ ring->buf = V3_Malloc(size);
+ ring->size = size;
- ring->start = 0;
- ring->end = 0;
- ring->current_len = 0;
+ ring->start = 0;
+ ring->end = 0;
+ ring->current_len = 0;
}
NO_INST
struct v3_ringbuf * v3_create_ringbuf(uint_t size) {
- struct v3_ringbuf * ring = (struct v3_ringbuf *)V3_Malloc(sizeof(struct v3_ringbuf));
+ struct v3_ringbuf * ring = (struct v3_ringbuf *)V3_Malloc(sizeof(struct v3_ringbuf));
- v3_init_ringbuf(ring, size);
+ v3_init_ringbuf(ring, size);
- return ring;
+ return ring;
}
NO_INST
void v3_free_ringbuf(struct v3_ringbuf * ring) {
- V3_Free(ring->buf);
- V3_Free(ring);
+ V3_Free(ring->buf);
+ V3_Free(ring);
}
NO_INST
static inline uchar_t * get_read_ptr(struct v3_ringbuf * ring) {
- return (uchar_t *)(ring->buf + ring->start);
+ return (uchar_t *)(ring->buf + ring->start);
}
NO_INST
static inline uchar_t * get_write_ptr(struct v3_ringbuf * ring) {
- return (uchar_t *)(ring->buf + ring->end);
+ return (uchar_t *)(ring->buf + ring->end);
}
NO_INST
static inline int get_read_section_size(struct v3_ringbuf * ring) {
- return ring->size - ring->start;
+ return ring->size - ring->start;
}
NO_INST
static inline int get_write_section_size(struct v3_ringbuf * ring) {
- return ring->size - ring->end;
+ return ring->size - ring->end;
}
NO_INST
static inline int is_read_loop(struct v3_ringbuf * ring, uint_t len) {
- if ((ring->start >= ring->end) && (ring->current_len > 0)) {
- // end is past the end of the buffer
- if (get_read_section_size(ring) < len) {
- return 1;
+ if ((ring->start >= ring->end) && (ring->current_len > 0)) {
+ // end is past the end of the buffer
+ if (get_read_section_size(ring) < len) {
+ return 1;
+ }
}
- }
- return 0;
+ return 0;
}
NO_INST
static inline int is_write_loop(struct v3_ringbuf * ring, uint_t len) {
- if ((ring->end >= ring->start) && (ring->current_len < ring->size)) {
- // end is past the end of the buffer
- if (get_write_section_size(ring) < len) {
- return 1;
+ if ((ring->end >= ring->start) && (ring->current_len < ring->size)) {
+ // end is past the end of the buffer
+ if (get_write_section_size(ring) < len) {
+ return 1;
+ }
}
- }
- return 0;
+ return 0;
}
NO_INST
int v3_ringbuf_avail_space(struct v3_ringbuf * ring) {
- return ring->size - ring->current_len;
+ return ring->size - ring->current_len;
}
- NO_INST
+NO_INST
int v3_ringbuf_data_len(struct v3_ringbuf * ring) {
- return ring->current_len;
+ return ring->current_len;
}
- NO_INST
+NO_INST
int v3_ringbuf_capacity(struct v3_ringbuf * ring) {
- return ring->size;
+ return ring->size;
}
NO_INST
int v3_ringbuf_read(struct v3_ringbuf * ring, uchar_t * dst, uint_t len) {
- int read_len = 0;
- int ring_data_len = ring->current_len;
+ int read_len = 0;
+ int ring_data_len = ring->current_len;
- read_len = (len > ring_data_len) ? ring_data_len : len;
+ read_len = (len > ring_data_len) ? ring_data_len : len;
- if (is_read_loop(ring, read_len)) {
- int section_len = get_read_section_size(ring);
+ if (is_read_loop(ring, read_len)) {
+ int section_len = get_read_section_size(ring);
- memcpy(dst, get_read_ptr(ring), section_len);
- memcpy(dst + section_len, ring->buf, read_len - section_len);
+ memcpy(dst, get_read_ptr(ring), section_len);
+ memcpy(dst + section_len, ring->buf, read_len - section_len);
- ring->start = read_len - section_len;
- } else {
- memcpy(dst, get_read_ptr(ring), read_len);
+ ring->start = read_len - section_len;
+ } else {
+ memcpy(dst, get_read_ptr(ring), read_len);
- ring->start += read_len;
- }
+ ring->start += read_len;
+ }
- ring->current_len -= read_len;
+ ring->current_len -= read_len;
- return read_len;
+ return read_len;
}
- NO_INST
+NO_INST
int v3_ringbuf_peek(struct v3_ringbuf * ring, uchar_t * dst, uint_t len) {
- int read_len = 0;
- int ring_data_len = ring->current_len;
+ int read_len = 0;
+ int ring_data_len = ring->current_len;
- read_len = (len > ring_data_len) ? ring_data_len : len;
+ read_len = (len > ring_data_len) ? ring_data_len : len;
- if (is_read_loop(ring, read_len)) {
- int section_len = get_read_section_size(ring);
+ if (is_read_loop(ring, read_len)) {
+ int section_len = get_read_section_size(ring);
- memcpy(dst, get_read_ptr(ring), section_len);
- memcpy(dst + section_len, ring->buf, read_len - section_len);
- } else {
- memcpy(dst, get_read_ptr(ring), read_len);
- }
+ memcpy(dst, get_read_ptr(ring), section_len);
+ memcpy(dst + section_len, ring->buf, read_len - section_len);
+ } else {
+ memcpy(dst, get_read_ptr(ring), read_len);
+ }
- return read_len;
+ return read_len;
}
NO_INST
int v3_ringbuf_delete(struct v3_ringbuf * ring, uint_t len) {
- int del_len = 0;
- int ring_data_len = ring->current_len;
+ int del_len = 0;
+ int ring_data_len = ring->current_len;
- del_len = (len > ring_data_len) ? ring_data_len : len;
+ del_len = (len > ring_data_len) ? ring_data_len : len;
- if (is_read_loop(ring, del_len)) {
- int section_len = get_read_section_size(ring);
- ring->start = del_len - section_len;
- } else {
- ring->start += del_len;
- }
+ if (is_read_loop(ring, del_len)) {
+ int section_len = get_read_section_size(ring);
+ ring->start = del_len - section_len;
+ } else {
+ ring->start += del_len;
+ }
- ring->current_len -= del_len;
- return del_len;
+ ring->current_len -= del_len;
+ return del_len;
}
NO_INST
int v3_ringbuf_write(struct v3_ringbuf * ring, uchar_t * src, uint_t len) {
- int write_len = 0;
- int ring_avail_space = ring->size - ring->current_len;
+ int write_len = 0;
+ int ring_avail_space = ring->size - ring->current_len;
- write_len = (len > ring_avail_space) ? ring_avail_space : len;
+ write_len = (len > ring_avail_space) ? ring_avail_space : len;
- if (is_write_loop(ring, write_len)) {
- int section_len = get_write_section_size(ring);
+ if (is_write_loop(ring, write_len)) {
+ int section_len = get_write_section_size(ring);
- // PrintDebug("Write loop: write_ptr=%p, src=%p, sec_len=%d\n",
- // (void *)get_write_ptr(ring),(void*)src, section_len);
+ // PrintDebug("Write loop: write_ptr=%p, src=%p, sec_len=%d\n",
+ // (void *)get_write_ptr(ring),(void*)src, section_len);
- memcpy(get_write_ptr(ring), src, section_len);
- ring->end = 0;
+ memcpy(get_write_ptr(ring), src, section_len);
+ ring->end = 0;
- memcpy(get_write_ptr(ring), src + section_len, write_len - section_len);
+ memcpy(get_write_ptr(ring), src + section_len, write_len - section_len);
- ring->end += write_len - section_len;
- } else {
- // PrintDebug("Writing: write_ptr=%p, src=%p, write_len=%d\n",
- // (void *)get_write_ptr(ring),(void*)src, write_len);
+ ring->end += write_len - section_len;
+ } else {
+ // PrintDebug("Writing: write_ptr=%p, src=%p, write_len=%d\n",
+ // (void *)get_write_ptr(ring),(void*)src, write_len);
- memcpy(get_write_ptr(ring), src, write_len);
+ memcpy(get_write_ptr(ring), src, write_len);
- ring->end += write_len;
- }
+ ring->end += write_len;
+ }
- ring->current_len += write_len;
+ ring->current_len += write_len;
- return write_len;
+ return write_len;
}
NO_INST
void v3_print_ringbuf(struct v3_ringbuf * ring) {
- int ctr = 0;
+ int ctr = 0;
- for (ctr = 0; ctr < ring->current_len; ctr++) {
- int index = (ctr + ring->start) % ring->size;
+ for (ctr = 0; ctr < ring->current_len; ctr++) {
+ int index = (ctr + ring->start) % ring->size;
- PrintDebug("Entry %d (index=%d): %c\n", ctr, index, ring->buf[index]);
- }
+ PrintDebug("Entry %d (index=%d): %c\n", ctr, index, ring->buf[index]);
+ }
}
struct shadow_page_data {
- v3_reg_t cr3;
- addr_t page_pa;
+ v3_reg_t cr3;
+ addr_t page_pa;
- struct list_head page_list_node;
+ struct list_head page_list_node;
};
static uint_t pte_hash_fn(addr_t key) {
- return hash_long(key, 32);
+ return hash_long(key, 32);
}
static int pte_equals(addr_t key1, addr_t key2) {
- return (key1 == key2);
+ return (key1 == key2);
}
static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info);
int v3_init_shadow_page_state(struct guest_info * info) {
- struct shadow_page_state * state = &(info->shdw_pg_state);
+ struct shadow_page_state * state = &(info->shdw_pg_state);
- state->guest_cr3 = 0;
- state->guest_cr0 = 0;
+ state->guest_cr3 = 0;
+ state->guest_cr0 = 0;
- INIT_LIST_HEAD(&(state->page_list));
+ INIT_LIST_HEAD(&(state->page_list));
- state->cached_ptes = NULL;
- state->cached_cr3 = 0;
+ state->cached_ptes = NULL;
+ state->cached_cr3 = 0;
- return 0;
+ return 0;
}
// creates new shadow page tables
// updates the shadow CR3 register to point to the new pts
int v3_activate_shadow_pt(struct guest_info * info) {
- switch (v3_get_cpu_mode(info)) {
-
- case PROTECTED:
- return activate_shadow_pt_32(info);
- case PROTECTED_PAE:
- return activate_shadow_pt_32pae(info);
- case LONG:
- case LONG_32_COMPAT:
- case LONG_16_COMPAT:
- return activate_shadow_pt_64(info);
- default:
- PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info)));
- return -1;
- }
-
- return 0;
+ switch (v3_get_cpu_mode(info)) {
+
+ case PROTECTED:
+ return activate_shadow_pt_32(info);
+ case PROTECTED_PAE:
+ return activate_shadow_pt_32pae(info);
+ case LONG:
+ case LONG_32_COMPAT:
+ case LONG_16_COMPAT:
+ return activate_shadow_pt_64(info);
+ default:
+ PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info)));
+ return -1;
+ }
+
+ return 0;
}
int v3_activate_passthrough_pt(struct guest_info * info) {
- // For now... But we need to change this....
- // As soon as shadow paging becomes active the passthrough tables are hosed
- // So this will cause chaos if it is called at that time
+ // For now... But we need to change this....
+ // As soon as shadow paging becomes active the passthrough tables are hosed
+ // So this will cause chaos if it is called at that time
- info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
- //PrintError("Activate Passthrough Page tables not implemented\n");
- return 0;
+ info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
+ //PrintError("Activate Passthrough Page tables not implemented\n");
+ return 0;
}
int v3_handle_shadow_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
- if (v3_get_mem_mode(info) == PHYSICAL_MEM) {
- // If paging is not turned on we need to handle the special cases
- return v3_handle_passthrough_pagefault(info, fault_addr, error_code);
- } else if (v3_get_mem_mode(info) == VIRTUAL_MEM) {
-
- switch (v3_get_cpu_mode(info)) {
- case PROTECTED:
- return handle_shadow_pagefault_32(info, fault_addr, error_code);
- break;
- case PROTECTED_PAE:
- return handle_shadow_pagefault_32pae(info, fault_addr, error_code);
- case LONG:
- case LONG_32_COMPAT:
- case LONG_16_COMPAT:
- return handle_shadow_pagefault_64(info, fault_addr, error_code);
- break;
- default:
- PrintError("Unhandled CPU Mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info)));
- return -1;
+ if (v3_get_mem_mode(info) == PHYSICAL_MEM) {
+ // If paging is not turned on we need to handle the special cases
+ return v3_handle_passthrough_pagefault(info, fault_addr, error_code);
+ } else if (v3_get_mem_mode(info) == VIRTUAL_MEM) {
+
+ switch (v3_get_cpu_mode(info)) {
+ case PROTECTED:
+ return handle_shadow_pagefault_32(info, fault_addr, error_code);
+ break;
+ case PROTECTED_PAE:
+ return handle_shadow_pagefault_32pae(info, fault_addr, error_code);
+ case LONG:
+ case LONG_32_COMPAT:
+ case LONG_16_COMPAT:
+ return handle_shadow_pagefault_64(info, fault_addr, error_code);
+ break;
+ default:
+ PrintError("Unhandled CPU Mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info)));
+ return -1;
+ }
+ } else {
+ PrintError("Invalid Memory mode\n");
+ return -1;
}
- } else {
- PrintError("Invalid Memory mode\n");
- return -1;
- }
}
int v3_handle_shadow_invlpg(struct guest_info * info) {
- uchar_t instr[15];
- struct x86_instr dec_instr;
- int ret = 0;
- addr_t vaddr = 0;
-
- if (v3_get_mem_mode(info) != VIRTUAL_MEM) {
- // Paging must be turned on...
- // should handle with some sort of fault I think
- PrintError("ERROR: INVLPG called in non paged mode\n");
- return -1;
- }
-
- if (v3_get_mem_mode(info) == 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 into buffer\n");
- return -1;
- }
-
- if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
- PrintError("Decoding Error\n");
- return -1;
- }
+ uchar_t instr[15];
+ struct x86_instr dec_instr;
+ int ret = 0;
+ addr_t vaddr = 0;
+
+ if (v3_get_mem_mode(info) != VIRTUAL_MEM) {
+ // Paging must be turned on...
+ // should handle with some sort of fault I think
+ PrintError("ERROR: INVLPG called in non paged mode\n");
+ return -1;
+ }
+
+ if (v3_get_mem_mode(info) == 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 into buffer\n");
+ return -1;
+ }
+
+ if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
+ PrintError("Decoding Error\n");
+ return -1;
+ }
- if ((dec_instr.op_type != V3_OP_INVLPG) ||
- (dec_instr.num_operands != 1) ||
- (dec_instr.dst_operand.type != MEM_OPERAND)) {
- PrintError("Decoder Error: Not a valid INVLPG instruction...\n");
- return -1;
- }
-
- vaddr = dec_instr.dst_operand.operand;
-
- info->rip += dec_instr.instr_length;
-
- switch (v3_get_cpu_mode(info)) {
- case PROTECTED:
- return handle_shadow_invlpg_32(info, vaddr);
- case PROTECTED_PAE:
- return handle_shadow_invlpg_32pae(info, vaddr);
- case LONG:
- case LONG_32_COMPAT:
- case LONG_16_COMPAT:
- return handle_shadow_invlpg_64(info, vaddr);
- default:
- PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info)));
- return -1;
- }
+ if ((dec_instr.op_type != V3_OP_INVLPG) ||
+ (dec_instr.num_operands != 1) ||
+ (dec_instr.dst_operand.type != MEM_OPERAND)) {
+ PrintError("Decoder Error: Not a valid INVLPG instruction...\n");
+ return -1;
+ }
+
+ vaddr = dec_instr.dst_operand.operand;
+
+ info->rip += dec_instr.instr_length;
+
+ switch (v3_get_cpu_mode(info)) {
+ case PROTECTED:
+ return handle_shadow_invlpg_32(info, vaddr);
+ case PROTECTED_PAE:
+ return handle_shadow_invlpg_32pae(info, vaddr);
+ case LONG:
+ case LONG_32_COMPAT:
+ case LONG_16_COMPAT:
+ return handle_shadow_invlpg_64(info, vaddr);
+ default:
+ PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info)));
+ return -1;
+ }
}
static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info) {
- struct shadow_page_state * state = &(info->shdw_pg_state);
- v3_reg_t cur_cr3 = info->ctrl_regs.cr3;
- struct shadow_page_data * page_tail = NULL;
- addr_t shdw_page = 0;
+ struct shadow_page_state * state = &(info->shdw_pg_state);
+ v3_reg_t cur_cr3 = info->ctrl_regs.cr3;
+ struct shadow_page_data * page_tail = NULL;
+ addr_t shdw_page = 0;
- if (!list_empty(&(state->page_list))) {
- page_tail = list_tail_entry(&(state->page_list), struct shadow_page_data, page_list_node);
+ if (!list_empty(&(state->page_list))) {
+ page_tail = list_tail_entry(&(state->page_list), struct shadow_page_data, page_list_node);
- if (page_tail->cr3 != cur_cr3) {
- PrintDebug("Reusing old shadow Page: %p (cur_CR3=%p)(page_cr3=%p) \n",
- (void *)(addr_t)page_tail->page_pa,
- (void *)(addr_t)cur_cr3,
- (void *)(addr_t)(page_tail->cr3));
+ if (page_tail->cr3 != cur_cr3) {
+ PrintDebug("Reusing old shadow Page: %p (cur_CR3=%p)(page_cr3=%p) \n",
+ (void *)(addr_t)page_tail->page_pa,
+ (void *)(addr_t)cur_cr3,
+ (void *)(addr_t)(page_tail->cr3));
- list_move(&(page_tail->page_list_node), &(state->page_list));
+ list_move(&(page_tail->page_list_node), &(state->page_list));
- memset(V3_VAddr((void *)(page_tail->page_pa)), 0, PAGE_SIZE_4KB);
+ memset(V3_VAddr((void *)(page_tail->page_pa)), 0, PAGE_SIZE_4KB);
- return page_tail;
+ return page_tail;
+ }
}
- }
- // else
+ // else
- page_tail = (struct shadow_page_data *)V3_Malloc(sizeof(struct shadow_page_data));
- page_tail->page_pa = (addr_t)V3_AllocPages(1);
+ page_tail = (struct shadow_page_data *)V3_Malloc(sizeof(struct shadow_page_data));
+ page_tail->page_pa = (addr_t)V3_AllocPages(1);
- PrintDebug("Allocating new shadow Page: %p (cur_cr3=%p)\n",
- (void *)(addr_t)page_tail->page_pa,
- (void *)(addr_t)cur_cr3);
+ PrintDebug("Allocating new shadow Page: %p (cur_cr3=%p)\n",
+ (void *)(addr_t)page_tail->page_pa,
+ (void *)(addr_t)cur_cr3);
- page_tail->cr3 = cur_cr3;
- list_add(&(page_tail->page_list_node), &(state->page_list));
+ page_tail->cr3 = cur_cr3;
+ list_add(&(page_tail->page_list_node), &(state->page_list));
- shdw_page = (addr_t)V3_VAddr((void *)(page_tail->page_pa));
- memset((void *)shdw_page, 0, PAGE_SIZE_4KB);
+ shdw_page = (addr_t)V3_VAddr((void *)(page_tail->page_pa));
+ memset((void *)shdw_page, 0, PAGE_SIZE_4KB);
- return page_tail;
+ return page_tail;
}
static void inject_guest_pf(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
- if (info->enable_profiler) {
- info->profiler.guest_pf_cnt++;
- }
+ if (info->enable_profiler) {
+ info->profiler.guest_pf_cnt++;
+ }
- info->ctrl_regs.cr2 = fault_addr;
- v3_raise_exception_with_error(info, PF_EXCEPTION, *(uint_t *)&error_code);
+ info->ctrl_regs.cr2 = fault_addr;
+ v3_raise_exception_with_error(info, PF_EXCEPTION, *(uint_t *)&error_code);
}
static int is_guest_pf(pt_access_status_t guest_access, pt_access_status_t shadow_access) {
- /* basically the reasoning is that there can be multiple reasons for a page fault:
- If there is a permissions failure for a page present in the guest _BUT_
- the reason for the fault was that the page is not present in the shadow,
- _THEN_ we have to map the shadow page in and reexecute, this will generate
- a permissions fault which is _THEN_ valid to send to the guest
- _UNLESS_ both the guest and shadow have marked the page as not present
-
- whew...
- */
- if (guest_access != PT_ACCESS_OK) {
- // Guest Access Error
-
- if ((shadow_access != PT_ACCESS_NOT_PRESENT) &&
- (guest_access != PT_ACCESS_NOT_PRESENT)) {
- // aka (guest permission error)
- return 1;
+ /* basically the reasoning is that there can be multiple reasons for a page fault:
+ If there is a permissions failure for a page present in the guest _BUT_
+ the reason for the fault was that the page is not present in the shadow,
+ _THEN_ we have to map the shadow page in and reexecute, this will generate
+ a permissions fault which is _THEN_ valid to send to the guest
+ _UNLESS_ both the guest and shadow have marked the page as not present
+
+ whew...
+ */
+ if (guest_access != PT_ACCESS_OK) {
+ // Guest Access Error
+
+ if ((shadow_access != PT_ACCESS_NOT_PRESENT) &&
+ (guest_access != PT_ACCESS_NOT_PRESENT)) {
+ // aka (guest permission error)
+ return 1;
+ }
+
+ if ((shadow_access == PT_ACCESS_NOT_PRESENT) &&
+ (guest_access == PT_ACCESS_NOT_PRESENT)) {
+ // Page tables completely blank, handle guest first
+ return 1;
+ }
+
+ // Otherwise we'll handle the guest fault later...?
}
- if ((shadow_access == PT_ACCESS_NOT_PRESENT) &&
- (guest_access == PT_ACCESS_NOT_PRESENT)) {
- // Page tables completely blank, handle guest first
- return 1;
- }
-
- // Otherwise we'll handle the guest fault later...?
- }
-
- return 0;
+ return 0;
}
static int cache_page_tables_32(struct guest_info * info, addr_t pde) {
- struct shadow_page_state * state = &(info->shdw_pg_state);
- addr_t pde_host_addr;
- pde32_t * tmp_pde;
- struct hashtable * pte_cache = NULL;
- int i = 0;
-
- if (pde == state->cached_cr3) {
- return 1;
- }
+ struct shadow_page_state * state = &(info->shdw_pg_state);
+ addr_t pde_host_addr;
+ pde32_t * tmp_pde;
+ struct hashtable * pte_cache = NULL;
+ int i = 0;
+
+ if (pde == state->cached_cr3) {
+ return 1;
+ }
- if (state->cached_ptes != NULL) {
- hashtable_destroy(state->cached_ptes, 0, 0);
- state->cached_ptes = NULL;
- }
+ if (state->cached_ptes != NULL) {
+ hashtable_destroy(state->cached_ptes, 0, 0);
+ state->cached_ptes = NULL;
+ }
- state->cached_cr3 = pde;
+ state->cached_cr3 = pde;
- pte_cache = create_hashtable(0, &pte_hash_fn, &pte_equals);
- state->cached_ptes = pte_cache;
+ pte_cache = create_hashtable(0, &pte_hash_fn, &pte_equals);
+ state->cached_ptes = pte_cache;
- if (guest_pa_to_host_va(info, pde, &pde_host_addr) == -1) {
- PrintError("Could not lookup host address of guest PDE\n");
- return -1;
- }
+ if (guest_pa_to_host_va(info, pde, &pde_host_addr) == -1) {
+ PrintError("Could not lookup host address of guest PDE\n");
+ return -1;
+ }
- tmp_pde = (pde32_t *)pde_host_addr;
+ tmp_pde = (pde32_t *)pde_host_addr;
- add_pte_map(pte_cache, pde, pde_host_addr);
+ add_pte_map(pte_cache, pde, pde_host_addr);
- for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
- if ((tmp_pde[i].present) && (tmp_pde[i].large_page == 0)) {
- addr_t pte_host_addr;
+ for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
+ if ((tmp_pde[i].present) && (tmp_pde[i].large_page == 0)) {
+ addr_t pte_host_addr;
- if (guest_pa_to_host_va(info, (addr_t)(BASE_TO_PAGE_ADDR(tmp_pde[i].pt_base_addr)), &pte_host_addr) == -1) {
- PrintError("Could not lookup host address of guest PDE\n");
- return -1;
- }
+ if (guest_pa_to_host_va(info, (addr_t)(BASE_TO_PAGE_ADDR(tmp_pde[i].pt_base_addr)), &pte_host_addr) == -1) {
+ PrintError("Could not lookup host address of guest PDE\n");
+ return -1;
+ }
- add_pte_map(pte_cache, (addr_t)(BASE_TO_PAGE_ADDR(tmp_pde[i].pt_base_addr)), pte_host_addr);
+ add_pte_map(pte_cache, (addr_t)(BASE_TO_PAGE_ADDR(tmp_pde[i].pt_base_addr)), pte_host_addr);
+ }
}
- }
- return 0;
+ return 0;
}
// We assume that shdw_pg_state.guest_cr3 is pointing to the page tables we want to activate
// We also assume that the CPU mode has not changed during this page table transition
static inline int activate_shadow_pt_32(struct guest_info * info) {
- struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
- struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
- int cached = 0;
+ struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
+ struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
+ int cached = 0;
- // Check if shadow page tables are in the cache
- cached = cache_page_tables_32(info, CR3_TO_PDE32_PA(*(addr_t *)guest_cr3));
+ // Check if shadow page tables are in the cache
+ cached = cache_page_tables_32(info, CR3_TO_PDE32_PA(*(addr_t *)guest_cr3));
- if (cached == -1) {
- PrintError("CR3 Cache failed\n");
- return -1;
- } else if (cached == 0) {
- struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
+ if (cached == -1) {
+ PrintError("CR3 Cache failed\n");
+ return -1;
+ } else if (cached == 0) {
+ struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
- shdw_page->cr3 = shdw_page->page_pa;
+ shdw_page->cr3 = shdw_page->page_pa;
- shadow_cr3->pdt_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
- PrintDebug( "Created new shadow page table %p\n", (void *)BASE_TO_PAGE_ADDR(shadow_cr3->pdt_base_addr));
- } else {
- PrintDebug("Reusing cached shadow Page table\n");
- }
+ shadow_cr3->pdt_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
+ PrintDebug( "Created new shadow page table %p\n", (void *)BASE_TO_PAGE_ADDR(shadow_cr3->pdt_base_addr));
+ } else {
+ PrintDebug("Reusing cached shadow Page table\n");
+ }
- shadow_cr3->pwt = guest_cr3->pwt;
- shadow_cr3->pcd = guest_cr3->pcd;
+ shadow_cr3->pwt = guest_cr3->pwt;
+ shadow_cr3->pcd = guest_cr3->pcd;
- return 0;
+ return 0;
}
/*
* *
*/
static int handle_large_pagefault_32(struct guest_info * info,
- addr_t fault_addr, pf_error_t error_code,
+ addr_t fault_addr, pf_error_t error_code,
pte32_t * shadow_pt, pde32_4MB_t * large_guest_pde);
static int handle_shadow_pte32_fault(struct guest_info * info,
static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
- pde32_t * guest_pd = NULL;
- pde32_t * shadow_pd = CR3_TO_PDE32_VA(info->ctrl_regs.cr3);
- addr_t guest_cr3 = CR3_TO_PDE32_PA(info->shdw_pg_state.guest_cr3);
- pt_access_status_t guest_pde_access;
- pt_access_status_t shadow_pde_access;
- pde32_t * guest_pde = NULL;
- pde32_t * shadow_pde = (pde32_t *)&(shadow_pd[PDE32_INDEX(fault_addr)]);
-
- PrintDebug("Shadow page fault handler: %p\n", (void*) fault_addr );
-
- if (guest_pa_to_host_va(info, guest_cr3, (addr_t*)&guest_pd) == -1) {
- PrintError("Invalid Guest PDE Address: 0x%p\n", (void *)guest_cr3);
- return -1;
- }
+ pde32_t * guest_pd = NULL;
+ pde32_t * shadow_pd = CR3_TO_PDE32_VA(info->ctrl_regs.cr3);
+ addr_t guest_cr3 = CR3_TO_PDE32_PA(info->shdw_pg_state.guest_cr3);
+ pt_access_status_t guest_pde_access;
+ pt_access_status_t shadow_pde_access;
+ pde32_t * guest_pde = NULL;
+ pde32_t * shadow_pde = (pde32_t *)&(shadow_pd[PDE32_INDEX(fault_addr)]);
+
+ PrintDebug("Shadow page fault handler: %p\n", (void*) fault_addr );
+
+ if (guest_pa_to_host_va(info, guest_cr3, (addr_t*)&guest_pd) == -1) {
+ PrintError("Invalid Guest PDE Address: 0x%p\n", (void *)guest_cr3);
+ return -1;
+ }
- guest_pde = (pde32_t *)&(guest_pd[PDE32_INDEX(fault_addr)]);
+ guest_pde = (pde32_t *)&(guest_pd[PDE32_INDEX(fault_addr)]);
- // Check the guest page permissions
- guest_pde_access = v3_can_access_pde32(guest_pd, fault_addr, error_code);
+ // Check the guest page permissions
+ guest_pde_access = v3_can_access_pde32(guest_pd, fault_addr, error_code);
- // Check the shadow page permissions
- shadow_pde_access = v3_can_access_pde32(shadow_pd, fault_addr, error_code);
+ // Check the shadow page permissions
+ shadow_pde_access = v3_can_access_pde32(shadow_pd, fault_addr, error_code);
- /* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pde_access, shadow_pde_access) == 1) {
- PrintDebug("Injecting PDE pf to guest: (guest access error=%d) (pf error code=%d)\n",
- *(uint_t *)&guest_pde_access, *(uint_t *)&error_code);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
- }
+ /* Was the page fault caused by the Guest's page tables? */
+ if (is_guest_pf(guest_pde_access, shadow_pde_access) == 1) {
+ PrintDebug("Injecting PDE pf to guest: (guest access error=%d) (pf error code=%d)\n",
+ *(uint_t *)&guest_pde_access, *(uint_t *)&error_code);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
+ }
- if (shadow_pde_access == PT_ACCESS_NOT_PRESENT)
- {
- struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
- pte32_t * shadow_pt = (pte32_t *)V3_VAddr((void *)shdw_page->page_pa);
-
- shadow_pde->present = 1;
- shadow_pde->user_page = guest_pde->user_page;
- // shadow_pde->large_page = guest_pde->large_page;
- shadow_pde->large_page = 0;
+ if (shadow_pde_access == PT_ACCESS_NOT_PRESENT)
+ {
+ struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
+ pte32_t * shadow_pt = (pte32_t *)V3_VAddr((void *)shdw_page->page_pa);
+
+ shadow_pde->present = 1;
+ shadow_pde->user_page = guest_pde->user_page;
+ // shadow_pde->large_page = guest_pde->large_page;
+ shadow_pde->large_page = 0;
- // VMM Specific options
- shadow_pde->write_through = 0;
- shadow_pde->cache_disable = 0;
- shadow_pde->global_page = 0;
- //
+ // VMM Specific options
+ shadow_pde->write_through = 0;
+ shadow_pde->cache_disable = 0;
+ shadow_pde->global_page = 0;
+ //
- guest_pde->accessed = 1;
+ guest_pde->accessed = 1;
- shadow_pde->pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(shadow_pt));
+ shadow_pde->pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(shadow_pt));
- if (guest_pde->large_page == 0) {
- pte32_t * guest_pt = NULL;
- shadow_pde->writable = guest_pde->writable;
-
- if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr), (addr_t*)&guest_pt) == -1) {
- // Machine check the guest
- PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr));
- v3_raise_exception(info, MC_EXCEPTION);
- return 0;
- }
-
- if (handle_shadow_pte32_fault(info, fault_addr, error_code, shadow_pt, guest_pt) == -1) {
- PrintError("Error handling Page fault caused by PTE\n");
- return -1;
- }
- } else {
- // ?? What if guest pde is dirty a this point?
- ((pde32_4MB_t *)guest_pde)->dirty = 0;
- shadow_pde->writable = 0;
-
- if (handle_large_pagefault_32(info, fault_addr, error_code, shadow_pt, (pde32_4MB_t *)guest_pde) == -1) {
- PrintError("Error handling large pagefault\n");
- return -1;
- }
-
- }
- }
- else if (shadow_pde_access == PT_ACCESS_OK)
- {
- //
- // PTE fault
- //
- pte32_t * shadow_pt = (pte32_t *)V3_VAddr( (void*)(addr_t) BASE_TO_PAGE_ADDR(shadow_pde->pt_base_addr) );
-
- if (guest_pde->large_page == 0) {
- pte32_t * guest_pt = NULL;
-
- if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr), (addr_t*)&guest_pt) == -1) {
- // Machine check the guest
- PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr));
- v3_raise_exception(info, MC_EXCEPTION);
- return 0;
+ if (guest_pde->large_page == 0) {
+ pte32_t * guest_pt = NULL;
+ shadow_pde->writable = guest_pde->writable;
+
+ if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr), (addr_t*)&guest_pt) == -1) {
+ // Machine check the guest
+ PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr));
+ v3_raise_exception(info, MC_EXCEPTION);
+ return 0;
+ }
+
+ if (handle_shadow_pte32_fault(info, fault_addr, error_code, shadow_pt, guest_pt) == -1) {
+ PrintError("Error handling Page fault caused by PTE\n");
+ return -1;
+ }
+ } else {
+ // ?? What if guest pde is dirty a this point?
+ ((pde32_4MB_t *)guest_pde)->dirty = 0;
+ shadow_pde->writable = 0;
+
+ if (handle_large_pagefault_32(info, fault_addr, error_code, shadow_pt, (pde32_4MB_t *)guest_pde) == -1) {
+ PrintError("Error handling large pagefault\n");
+ return -1;
+ }
+
+ }
}
+ else if (shadow_pde_access == PT_ACCESS_OK)
+ {
+ //
+ // PTE fault
+ //
+ pte32_t * shadow_pt = (pte32_t *)V3_VAddr( (void*)(addr_t) BASE_TO_PAGE_ADDR(shadow_pde->pt_base_addr) );
+
+ if (guest_pde->large_page == 0) {
+ pte32_t * guest_pt = NULL;
+
+ if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr), (addr_t*)&guest_pt) == -1) {
+ // Machine check the guest
+ PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr));
+ v3_raise_exception(info, MC_EXCEPTION);
+ return 0;
+ }
- if (handle_shadow_pte32_fault(info, fault_addr, error_code, shadow_pt, guest_pt) == -1) {
- PrintError("Error handling Page fault caused by PTE\n");
- return -1;
- }
- } else if (guest_pde->large_page == 1) {
- if (handle_large_pagefault_32(info, fault_addr, error_code, shadow_pt, (pde32_4MB_t *)guest_pde) == -1) {
- PrintError("Error handling large pagefault\n");
- return -1;
+ if (handle_shadow_pte32_fault(info, fault_addr, error_code, shadow_pt, guest_pt) == -1) {
+ PrintError("Error handling Page fault caused by PTE\n");
+ return -1;
+ }
+ } else if (guest_pde->large_page == 1) {
+ if (handle_large_pagefault_32(info, fault_addr, error_code, shadow_pt, (pde32_4MB_t *)guest_pde) == -1) {
+ PrintError("Error handling large pagefault\n");
+ return -1;
+ }
+ }
}
- }
- }
- else if ((shadow_pde_access == PT_ACCESS_WRITE_ERROR) &&
- (guest_pde->large_page == 1))
- {
- //
- // Page Directory Entry marked read-only
- // Its a large page and we need to update the dirty bit in the guest
- //
-
- PrintDebug("Large page write error... Setting dirty bit and returning\n");
- ((pde32_4MB_t *)guest_pde)->dirty = 1;
- shadow_pde->writable = guest_pde->writable;
- return 0;
+ else if ((shadow_pde_access == PT_ACCESS_WRITE_ERROR) &&
+ (guest_pde->large_page == 1))
+ {
+ //
+ // Page Directory Entry marked read-only
+ // Its a large page and we need to update the dirty bit in the guest
+ //
+
+ PrintDebug("Large page write error... Setting dirty bit and returning\n");
+ ((pde32_4MB_t *)guest_pde)->dirty = 1;
+ shadow_pde->writable = guest_pde->writable;
+ return 0;
- }
- else if (shadow_pde_access == PT_ACCESS_USER_ERROR)
- {
- //
- // Page Directory Entry marked non-user
- //
- PrintDebug("Shadow Paging User access error (shadow_pde_access=0x%x, guest_pde_access=0x%x)\n",
- shadow_pde_access, guest_pde_access);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
- }
- else
- {
- // inject page fault in guest
- inject_guest_pf(info, fault_addr, error_code);
- PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pde_access);
- PrintDebug("Manual Says to inject page fault into guest\n");
+ }
+ else if (shadow_pde_access == PT_ACCESS_USER_ERROR)
+ {
+ //
+ // Page Directory Entry marked non-user
+ //
+ PrintDebug("Shadow Paging User access error (shadow_pde_access=0x%x, guest_pde_access=0x%x)\n",
+ shadow_pde_access, guest_pde_access);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
+ }
+ else
+ {
+ // inject page fault in guest
+ inject_guest_pf(info, fault_addr, error_code);
+ PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pde_access);
+ PrintDebug("Manual Says to inject page fault into guest\n");
#ifdef DEBUG_SHADOW_PAGING
- PrintDebug("Guest PDE: (access=%d)\n\t", guest_pde_access);
- PrintPTEntry(info, PAGE_PD32, fault_addr, guest_pde);
- PrintDebug("Shadow PDE: (access=%d)\n\t", shadow_pde_access);
- PrintPTEntry(info, PAGE_PD32, fault_addr, shadow_pde);
+ PrintDebug("Guest PDE: (access=%d)\n\t", guest_pde_access);
+ PrintPTEntry(info, PAGE_PD32, fault_addr, guest_pde);
+ PrintDebug("Shadow PDE: (access=%d)\n\t", shadow_pde_access);
+ PrintPTEntry(info, PAGE_PD32, fault_addr, shadow_pde);
#endif
- return 0;
- }
+ return 0;
+ }
- PrintDebug("Returning end of PDE function (rip=%p)\n", (void *)(addr_t)(info->rip));
- return 0;
+ PrintDebug("Returning end of PDE function (rip=%p)\n", (void *)(addr_t)(info->rip));
+ return 0;
}
* only special case shadow checks remain
*/
static int handle_large_pagefault_32(struct guest_info * info,
- addr_t fault_addr, pf_error_t error_code,
- pte32_t * shadow_pt, pde32_4MB_t * large_guest_pde)
+ addr_t fault_addr, pf_error_t error_code,
+ pte32_t * shadow_pt, pde32_4MB_t * large_guest_pde)
{
- pt_access_status_t shadow_pte_access = v3_can_access_pte32(shadow_pt, fault_addr, error_code);
- pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]);
- addr_t guest_fault_pa = BASE_TO_PAGE_ADDR_4MB(large_guest_pde->page_base_addr) + PAGE_OFFSET_4MB(fault_addr);
- struct shadow_page_state * state = &(info->shdw_pg_state);
+ pt_access_status_t shadow_pte_access = v3_can_access_pte32(shadow_pt, fault_addr, error_code);
+ pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]);
+ addr_t guest_fault_pa = BASE_TO_PAGE_ADDR_4MB(large_guest_pde->page_base_addr) + PAGE_OFFSET_4MB(fault_addr);
+ struct shadow_page_state * state = &(info->shdw_pg_state);
- struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_fault_pa);
+ struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_fault_pa);
- if ((shdw_reg == NULL) ||
- (shdw_reg->host_type == SHDW_REGION_INVALID)) {
- // Inject a machine check in the guest
- PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_fault_pa);
- v3_raise_exception(info, MC_EXCEPTION);
- return -1;
- }
-
- if (shadow_pte_access == PT_ACCESS_OK) {
- // Inconsistent state...
- // Guest Re-Entry will flush tables and everything should now workd
- PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
- return 0;
- }
+ if ((shdw_reg == NULL) ||
+ (shdw_reg->host_type == SHDW_REGION_INVALID)) {
+ // Inject a machine check in the guest
+ PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_fault_pa);
+ v3_raise_exception(info, MC_EXCEPTION);
+ return -1;
+ }
+
+ if (shadow_pte_access == PT_ACCESS_OK) {
+ // Inconsistent state...
+ // Guest Re-Entry will flush tables and everything should now workd
+ PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
+ return 0;
+ }
- if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
- // Get the guest physical address of the fault
-
- if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
- (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
- addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_fault_pa);
-
- shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
-
- shadow_pte->present = 1;
-
- /* We are assuming that the PDE entry has precedence
- * so the Shadow PDE will mirror the guest PDE settings,
- * and we don't have to worry about them here
- * Allow everything
- */
- shadow_pte->user_page = 1;
-
- if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) {
- // Check if the entry is a page table...
- PrintDebug("Marking page as Guest Page Table (large page)\n");
- shadow_pte->writable = 0;
- } else if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
- shadow_pte->writable = 0;
- } else {
- shadow_pte->writable = 1;
- }
-
- //set according to VMM policy
- shadow_pte->write_through = 0;
- shadow_pte->cache_disable = 0;
- shadow_pte->global_page = 0;
- //
+ if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
+ // Get the guest physical address of the fault
+
+ if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
+ (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
+ addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_fault_pa);
+
+ shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
+
+ shadow_pte->present = 1;
+
+ /* We are assuming that the PDE entry has precedence
+ * so the Shadow PDE will mirror the guest PDE settings,
+ * and we don't have to worry about them here
+ * Allow everything
+ */
+ shadow_pte->user_page = 1;
+
+ if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) {
+ // Check if the entry is a page table...
+ PrintDebug("Marking page as Guest Page Table (large page)\n");
+ shadow_pte->writable = 0;
+ } else if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
+ shadow_pte->writable = 0;
+ } else {
+ shadow_pte->writable = 1;
+ }
+
+ //set according to VMM policy
+ shadow_pte->write_through = 0;
+ shadow_pte->cache_disable = 0;
+ shadow_pte->global_page = 0;
+ //
- } else {
- // Handle hooked pages as well as other special pages
- // if (handle_special_page_fault(info, fault_addr, guest_fault_pa, error_code) == -1) {
+ } else {
+ // Handle hooked pages as well as other special pages
+ // if (handle_special_page_fault(info, fault_addr, guest_fault_pa, error_code) == -1) {
- if (v3_handle_mem_full_hook(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
- PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
- return -1;
- }
- }
- } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
+ if (v3_handle_mem_full_hook(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
+ PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
+ return -1;
+ }
+ }
+ } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
- if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
+ if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
- if (v3_handle_mem_wr_hook(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
- PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
- return -1;
- }
- }
+ if (v3_handle_mem_wr_hook(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
+ PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
+ return -1;
+ }
+ }
- if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) {
- struct shadow_page_state * state = &(info->shdw_pg_state);
- PrintDebug("Write operation on Guest PAge Table Page (large page)\n");
- state->cached_cr3 = 0;
- shadow_pte->writable = 1;
- }
+ if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) {
+ struct shadow_page_state * state = &(info->shdw_pg_state);
+ PrintDebug("Write operation on Guest PAge Table Page (large page)\n");
+ state->cached_cr3 = 0;
+ shadow_pte->writable = 1;
+ }
- } else {
- PrintError("Error in large page fault handler...\n");
- PrintError("This case should have been handled at the top level handler\n");
- return -1;
- }
+ } else {
+ PrintError("Error in large page fault handler...\n");
+ PrintError("This case should have been handled at the top level handler\n");
+ return -1;
+ }
- PrintDebug("Returning from large page fault handler\n");
- return 0;
+ PrintDebug("Returning from large page fault handler\n");
+ return 0;
}
pte32_t * shadow_pt,
pte32_t * guest_pt) {
- pt_access_status_t guest_pte_access;
- pt_access_status_t shadow_pte_access;
- pte32_t * guest_pte = (pte32_t *)&(guest_pt[PTE32_INDEX(fault_addr)]);;
- pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]);
- addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) + PAGE_OFFSET(fault_addr);
- struct shadow_page_state * state = &(info->shdw_pg_state);
-
- struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_pa);
-
- if ((shdw_reg == NULL) ||
- (shdw_reg->host_type == SHDW_REGION_INVALID)) {
- // Inject a machine check in the guest
- PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_pa);
- v3_raise_exception(info, MC_EXCEPTION);
- return 0;
- }
+ pt_access_status_t guest_pte_access;
+ pt_access_status_t shadow_pte_access;
+ pte32_t * guest_pte = (pte32_t *)&(guest_pt[PTE32_INDEX(fault_addr)]);;
+ pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]);
+ addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) + PAGE_OFFSET(fault_addr);
+ struct shadow_page_state * state = &(info->shdw_pg_state);
+
+ struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_pa);
+
+ if ((shdw_reg == NULL) ||
+ (shdw_reg->host_type == SHDW_REGION_INVALID)) {
+ // Inject a machine check in the guest
+ PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_pa);
+ v3_raise_exception(info, MC_EXCEPTION);
+ return 0;
+ }
- // Check the guest page permissions
- guest_pte_access = v3_can_access_pte32(guest_pt, fault_addr, error_code);
+ // Check the guest page permissions
+ guest_pte_access = v3_can_access_pte32(guest_pt, fault_addr, error_code);
- // Check the shadow page permissions
- shadow_pte_access = v3_can_access_pte32(shadow_pt, fault_addr, error_code);
+ // Check the shadow page permissions
+ shadow_pte_access = v3_can_access_pte32(shadow_pt, fault_addr, error_code);
#ifdef DEBUG_SHADOW_PAGING
- PrintDebug("Guest PTE: (access=%d)\n\t", guest_pte_access);
- PrintPTEntry(info, PAGE_PT32, fault_addr, guest_pte);
- PrintDebug("Shadow PTE: (access=%d)\n\t", shadow_pte_access);
- PrintPTEntry(info, PAGE_PT32, fault_addr, shadow_pte);
+ PrintDebug("Guest PTE: (access=%d)\n\t", guest_pte_access);
+ PrintPTEntry(info, PAGE_PT32, fault_addr, guest_pte);
+ PrintDebug("Shadow PTE: (access=%d)\n\t", shadow_pte_access);
+ PrintPTEntry(info, PAGE_PT32, fault_addr, shadow_pte);
#endif
- /* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pte_access, shadow_pte_access) == 1) {
- PrintDebug("Access error injecting pf to guest (guest access error=%d) (pf error code=%d)\n",
- guest_pte_access, *(uint_t*)&error_code);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
- }
+ /* Was the page fault caused by the Guest's page tables? */
+ if (is_guest_pf(guest_pte_access, shadow_pte_access) == 1) {
+ PrintDebug("Access error injecting pf to guest (guest access error=%d) (pf error code=%d)\n",
+ guest_pte_access, *(uint_t*)&error_code);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
+ }
- if (shadow_pte_access == PT_ACCESS_OK) {
- // Inconsistent state...
- // Guest Re-Entry will flush page tables and everything should now work
- PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
- return 0;
- }
+ if (shadow_pte_access == PT_ACCESS_OK) {
+ // Inconsistent state...
+ // Guest Re-Entry will flush page tables and everything should now work
+ PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
+ return 0;
+ }
- if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
- // Page Table Entry Not Present
- PrintDebug("guest_pa =%p\n", (void *)guest_pa);
+ if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
+ // Page Table Entry Not Present
+ PrintDebug("guest_pa =%p\n", (void *)guest_pa);
- if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
- (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
- addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
+ if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
+ (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
+ addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
- shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
+ shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
- shadow_pte->present = guest_pte->present;
- shadow_pte->user_page = guest_pte->user_page;
+ shadow_pte->present = guest_pte->present;
+ shadow_pte->user_page = guest_pte->user_page;
- //set according to VMM policy
- shadow_pte->write_through = 0;
- shadow_pte->cache_disable = 0;
- shadow_pte->global_page = 0;
- //
+ //set according to VMM policy
+ shadow_pte->write_through = 0;
+ shadow_pte->cache_disable = 0;
+ shadow_pte->global_page = 0;
+ //
- guest_pte->accessed = 1;
+ guest_pte->accessed = 1;
- if (guest_pte->dirty == 1) {
- shadow_pte->writable = guest_pte->writable;
- } else if ((guest_pte->dirty == 0) && (error_code.write == 1)) {
- shadow_pte->writable = guest_pte->writable;
- guest_pte->dirty = 1;
- } else if ((guest_pte->dirty == 0) && (error_code.write == 0)) {
- shadow_pte->writable = 0;
- }
-
- // dirty flag has been set, check if its in the cache
- if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) {
- if (error_code.write == 1) {
- state->cached_cr3 = 0;
- shadow_pte->writable = guest_pte->writable;
+ if (guest_pte->dirty == 1) {
+ shadow_pte->writable = guest_pte->writable;
+ } else if ((guest_pte->dirty == 0) && (error_code.write == 1)) {
+ shadow_pte->writable = guest_pte->writable;
+ guest_pte->dirty = 1;
+ } else if ((guest_pte->dirty == 0) && (error_code.write == 0)) {
+ shadow_pte->writable = 0;
+ }
+
+ // dirty flag has been set, check if its in the cache
+ if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) {
+ if (error_code.write == 1) {
+ state->cached_cr3 = 0;
+ shadow_pte->writable = guest_pte->writable;
+ } else {
+ shadow_pte->writable = 0;
+ }
+ }
+
+ // Write hooks trump all, and are set Read Only
+ if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
+ shadow_pte->writable = 0;
+ }
+
} else {
- shadow_pte->writable = 0;
+ // Page fault handled by hook functions
+
+ if (v3_handle_mem_full_hook(info, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
+ PrintError("Special Page fault handler returned error for address: %p\n", (void *)fault_addr);
+ return -1;
+ }
}
- }
+ } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
+ guest_pte->dirty = 1;
- // Write hooks trump all, and are set Read Only
- if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
- shadow_pte->writable = 0;
- }
+ if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
+ if (v3_handle_mem_wr_hook(info, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
+ PrintError("Special Page fault handler returned error for address: %p\n", (void *)fault_addr);
+ return -1;
+ }
+ } else {
+ PrintDebug("Shadow PTE Write Error\n");
+ shadow_pte->writable = guest_pte->writable;
+ }
- } else {
- // Page fault handled by hook functions
+ if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) {
+ struct shadow_page_state * state = &(info->shdw_pg_state);
+ PrintDebug("Write operation on Guest PAge Table Page\n");
+ state->cached_cr3 = 0;
+ }
- if (v3_handle_mem_full_hook(info, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
- PrintError("Special Page fault handler returned error for address: %p\n", (void *)fault_addr);
- return -1;
- }
- }
- } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
- guest_pte->dirty = 1;
+ return 0;
- if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
- if (v3_handle_mem_wr_hook(info, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
- PrintError("Special Page fault handler returned error for address: %p\n", (void *)fault_addr);
- return -1;
- }
} else {
- PrintDebug("Shadow PTE Write Error\n");
- shadow_pte->writable = guest_pte->writable;
- }
-
- if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) {
- struct shadow_page_state * state = &(info->shdw_pg_state);
- PrintDebug("Write operation on Guest PAge Table Page\n");
- state->cached_cr3 = 0;
+ // Inject page fault into the guest
+ inject_guest_pf(info, fault_addr, error_code);
+ PrintError("PTE Page fault fell through... Not sure if this should ever happen\n");
+ PrintError("Manual Says to inject page fault into guest\n");
+ return -1;
}
+ PrintDebug("Returning end of function\n");
return 0;
-
- } else {
- // Inject page fault into the guest
- inject_guest_pf(info, fault_addr, error_code);
- PrintError("PTE Page fault fell through... Not sure if this should ever happen\n");
- PrintError("Manual Says to inject page fault into guest\n");
- return -1;
- }
-
- PrintDebug("Returning end of function\n");
- return 0;
}
/* If we start to optimize we should look up the guest pages in the cache... */
static inline int handle_shadow_invlpg_32(struct guest_info * info, addr_t vaddr) {
- pde32_t * shadow_pd = (pde32_t *)CR3_TO_PDE32_VA(info->ctrl_regs.cr3);
- pde32_t * shadow_pde = (pde32_t *)&shadow_pd[PDE32_INDEX(vaddr)];
+ pde32_t * shadow_pd = (pde32_t *)CR3_TO_PDE32_VA(info->ctrl_regs.cr3);
+ pde32_t * shadow_pde = (pde32_t *)&shadow_pd[PDE32_INDEX(vaddr)];
- addr_t guest_cr3 = CR3_TO_PDE32_PA(info->shdw_pg_state.guest_cr3);
- pde32_t * guest_pd = NULL;
- pde32_t * guest_pde;
+ addr_t guest_cr3 = CR3_TO_PDE32_PA(info->shdw_pg_state.guest_cr3);
+ pde32_t * guest_pd = NULL;
+ pde32_t * guest_pde;
- if (guest_pa_to_host_va(info, guest_cr3, (addr_t*)&guest_pd) == -1) {
- PrintError("Invalid Guest PDE Address: 0x%p\n", (void *)guest_cr3);
- return -1;
- }
+ if (guest_pa_to_host_va(info, guest_cr3, (addr_t*)&guest_pd) == -1) {
+ PrintError("Invalid Guest PDE Address: 0x%p\n", (void *)guest_cr3);
+ return -1;
+ }
- guest_pde = (pde32_t *)&(guest_pd[PDE32_INDEX(vaddr)]);
+ guest_pde = (pde32_t *)&(guest_pd[PDE32_INDEX(vaddr)]);
- if (guest_pde->large_page == 1) {
- shadow_pde->present = 0;
- PrintDebug("Invalidating Large Page\n");
- } else if (shadow_pde->present == 1) {
- pte32_t * shadow_pt = (pte32_t *)(addr_t)BASE_TO_PAGE_ADDR_4KB(shadow_pde->pt_base_addr);
- pte32_t * shadow_pte = (pte32_t *) V3_VAddr( (void*) &shadow_pt[PTE32_INDEX(vaddr)] );
+ if (guest_pde->large_page == 1) {
+ shadow_pde->present = 0;
+ PrintDebug("Invalidating Large Page\n");
+ } else if (shadow_pde->present == 1) {
+ pte32_t * shadow_pt = (pte32_t *)(addr_t)BASE_TO_PAGE_ADDR_4KB(shadow_pde->pt_base_addr);
+ pte32_t * shadow_pte = (pte32_t *) V3_VAddr( (void*) &shadow_pt[PTE32_INDEX(vaddr)] );
- PrintDebug("Setting not present\n");
+ PrintDebug("Setting not present\n");
- shadow_pte->present = 0;
- }
- return 0;
+ shadow_pte->present = 0;
+ }
+ return 0;
}
static inline int activate_shadow_pt_32pae(struct guest_info * info) {
- PrintError("Activating 32 bit PAE page tables not implemented\n");
- return -1;
+ PrintError("Activating 32 bit PAE page tables not implemented\n");
+ return -1;
}
*/
static inline int handle_shadow_pagefault_32pae(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
- PrintError("32 bit PAE shadow paging not implemented\n");
- return -1;
+ PrintError("32 bit PAE shadow paging not implemented\n");
+ return -1;
}
static inline int handle_shadow_invlpg_32pae(struct guest_info * info, addr_t vaddr) {
- PrintError("32 bit PAE shadow paging not implemented\n");
- return -1;
+ PrintError("32 bit PAE shadow paging not implemented\n");
+ return -1;
}
static inline int activate_shadow_pt_64(struct guest_info * info) {
- struct cr3_64 * shadow_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3);
- struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->shdw_pg_state.guest_cr3);
- struct shadow_page_data * shadow_pt = create_new_shadow_pt(info);
- addr_t shadow_pt_addr = shadow_pt->page_pa;
+ struct cr3_64 * shadow_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3);
+ struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->shdw_pg_state.guest_cr3);
+ struct shadow_page_data * shadow_pt = create_new_shadow_pt(info);
+ addr_t shadow_pt_addr = shadow_pt->page_pa;
- // Because this is a new CR3 load the allocated page is the new CR3 value
- shadow_pt->cr3 = shadow_pt->page_pa;
+ // Because this is a new CR3 load the allocated page is the new CR3 value
+ shadow_pt->cr3 = shadow_pt->page_pa;
- PrintDebug("Top level Shadow page pa=%p\n", (void *)shadow_pt_addr);
+ PrintDebug("Top level Shadow page pa=%p\n", (void *)shadow_pt_addr);
- shadow_cr3->pml4t_base_addr = PAGE_BASE_ADDR_4KB(shadow_pt_addr);
- PrintDebug("Creating new 64 bit shadow page table %p\n", (void *)BASE_TO_PAGE_ADDR(shadow_cr3->pml4t_base_addr));
+ shadow_cr3->pml4t_base_addr = PAGE_BASE_ADDR_4KB(shadow_pt_addr);
+ PrintDebug("Creating new 64 bit shadow page table %p\n", (void *)BASE_TO_PAGE_ADDR(shadow_cr3->pml4t_base_addr));
- shadow_cr3->pwt = guest_cr3->pwt;
- shadow_cr3->pcd = guest_cr3->pcd;
+ shadow_cr3->pwt = guest_cr3->pwt;
+ shadow_cr3->pcd = guest_cr3->pcd;
- return 0;
+ return 0;
}
static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
- pml4e64_t * guest_pml = NULL;
- pml4e64_t * shadow_pml = CR3_TO_PML4E64_VA(info->ctrl_regs.cr3);
- addr_t guest_cr3 = CR3_TO_PML4E64_PA(info->shdw_pg_state.guest_cr3);
- pt_access_status_t guest_pml4e_access;
- pt_access_status_t shadow_pml4e_access;
- pml4e64_t * guest_pml4e = NULL;
- pml4e64_t * shadow_pml4e = (pml4e64_t *)&(shadow_pml[PML4E64_INDEX(fault_addr)]);
-
- PrintDebug("64 bit Shadow page fault handler: %p\n", (void *)fault_addr);
- PrintDebug("Handling PML fault\n");
-
- if (guest_pa_to_host_va(info, guest_cr3, (addr_t*)&guest_pml) == -1) {
- PrintError("Invalid Guest PML4E Address: 0x%p\n", (void *)guest_cr3);
- return -1;
- }
+ pml4e64_t * guest_pml = NULL;
+ pml4e64_t * shadow_pml = CR3_TO_PML4E64_VA(info->ctrl_regs.cr3);
+ addr_t guest_cr3 = CR3_TO_PML4E64_PA(info->shdw_pg_state.guest_cr3);
+ pt_access_status_t guest_pml4e_access;
+ pt_access_status_t shadow_pml4e_access;
+ pml4e64_t * guest_pml4e = NULL;
+ pml4e64_t * shadow_pml4e = (pml4e64_t *)&(shadow_pml[PML4E64_INDEX(fault_addr)]);
+
+ PrintDebug("64 bit Shadow page fault handler: %p\n", (void *)fault_addr);
+ PrintDebug("Handling PML fault\n");
+
+ if (guest_pa_to_host_va(info, guest_cr3, (addr_t*)&guest_pml) == -1) {
+ PrintError("Invalid Guest PML4E Address: 0x%p\n", (void *)guest_cr3);
+ return -1;
+ }
- guest_pml4e = (pml4e64_t *)&(guest_pml[PML4E64_INDEX(fault_addr)]);
+ guest_pml4e = (pml4e64_t *)&(guest_pml[PML4E64_INDEX(fault_addr)]);
- PrintDebug("Checking Guest %p\n", (void *)guest_pml);
- // Check the guest page permissions
- guest_pml4e_access = v3_can_access_pml4e64(guest_pml, fault_addr, error_code);
+ PrintDebug("Checking Guest %p\n", (void *)guest_pml);
+ // Check the guest page permissions
+ guest_pml4e_access = v3_can_access_pml4e64(guest_pml, fault_addr, error_code);
- PrintDebug("Checking shadow %p\n", (void *)shadow_pml);
- // Check the shadow page permissions
- shadow_pml4e_access = v3_can_access_pml4e64(shadow_pml, fault_addr, error_code);
+ PrintDebug("Checking shadow %p\n", (void *)shadow_pml);
+ // Check the shadow page permissions
+ shadow_pml4e_access = v3_can_access_pml4e64(shadow_pml, fault_addr, error_code);
- /* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pml4e_access, shadow_pml4e_access) == 1) {
- PrintDebug("Injecting PML4E pf to guest: (guest access error=%d) (pf error code=%d)\n",
- *(uint_t *)&guest_pml4e_access, *(uint_t *)&error_code);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
- }
-
- if (shadow_pml4e_access == PT_ACCESS_USER_ERROR) {
- //
- // PML4 Entry marked non-user
- //
- PrintDebug("Shadow Paging User access error (shadow_pml4e_access=0x%x, guest_pml4e_access=0x%x)\n",
- shadow_pml4e_access, guest_pml4e_access);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
- } else if ((shadow_pml4e_access != PT_ACCESS_NOT_PRESENT) &&
- (shadow_pml4e_access != PT_ACCESS_OK)) {
- // inject page fault in guest
- inject_guest_pf(info, fault_addr, error_code);
- PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pml4e_access);
- PrintDebug("Manual Says to inject page fault into guest\n");
- return 0;
- }
+ /* Was the page fault caused by the Guest's page tables? */
+ if (is_guest_pf(guest_pml4e_access, shadow_pml4e_access) == 1) {
+ PrintDebug("Injecting PML4E pf to guest: (guest access error=%d) (pf error code=%d)\n",
+ *(uint_t *)&guest_pml4e_access, *(uint_t *)&error_code);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
+ }
+
+ if (shadow_pml4e_access == PT_ACCESS_USER_ERROR) {
+ //
+ // PML4 Entry marked non-user
+ //
+ PrintDebug("Shadow Paging User access error (shadow_pml4e_access=0x%x, guest_pml4e_access=0x%x)\n",
+ shadow_pml4e_access, guest_pml4e_access);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
+ } else if ((shadow_pml4e_access != PT_ACCESS_NOT_PRESENT) &&
+ (shadow_pml4e_access != PT_ACCESS_OK)) {
+ // inject page fault in guest
+ inject_guest_pf(info, fault_addr, error_code);
+ PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pml4e_access);
+ PrintDebug("Manual Says to inject page fault into guest\n");
+ return 0;
+ }
- pdpe64_t * shadow_pdp = NULL;
- pdpe64_t * guest_pdp = NULL;
+ pdpe64_t * shadow_pdp = NULL;
+ pdpe64_t * guest_pdp = NULL;
- // Get the next shadow page level, allocate if not present
+ // Get the next shadow page level, allocate if not present
- if (shadow_pml4e_access == PT_ACCESS_NOT_PRESENT) {
- struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
- shadow_pdp = (pdpe64_t *)V3_VAddr((void *)shdw_page->page_pa);
+ if (shadow_pml4e_access == PT_ACCESS_NOT_PRESENT) {
+ struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
+ shadow_pdp = (pdpe64_t *)V3_VAddr((void *)shdw_page->page_pa);
- shadow_pml4e->present = 1;
- shadow_pml4e->user_page = guest_pml4e->user_page;
- shadow_pml4e->writable = guest_pml4e->writable;
+ shadow_pml4e->present = 1;
+ shadow_pml4e->user_page = guest_pml4e->user_page;
+ shadow_pml4e->writable = guest_pml4e->writable;
- // VMM Specific options
- shadow_pml4e->write_through = 0;
- shadow_pml4e->cache_disable = 0;
- //
+ // VMM Specific options
+ shadow_pml4e->write_through = 0;
+ shadow_pml4e->cache_disable = 0;
+ //
- guest_pml4e->accessed = 1;
+ guest_pml4e->accessed = 1;
- shadow_pml4e->pdp_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
- } else {
- shadow_pdp = (pdpe64_t *)V3_VAddr((void *)(addr_t)BASE_TO_PAGE_ADDR(shadow_pml4e->pdp_base_addr));
- }
+ shadow_pml4e->pdp_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
+ } else {
+ shadow_pdp = (pdpe64_t *)V3_VAddr((void *)(addr_t)BASE_TO_PAGE_ADDR(shadow_pml4e->pdp_base_addr));
+ }
- // Continue processing at the next level
+ // Continue processing at the next level
- if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pml4e->pdp_base_addr), (addr_t *)&guest_pdp) == -1) {
- // Machine check the guest
- PrintDebug("Invalid Guest PDP Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pml4e->pdp_base_addr));
- v3_raise_exception(info, MC_EXCEPTION);
- return 0;
- }
+ if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pml4e->pdp_base_addr), (addr_t *)&guest_pdp) == -1) {
+ // Machine check the guest
+ PrintDebug("Invalid Guest PDP Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pml4e->pdp_base_addr));
+ v3_raise_exception(info, MC_EXCEPTION);
+ return 0;
+ }
- if (handle_pdpe_shadow_pagefault_64(info, fault_addr, error_code, shadow_pdp, guest_pdp) == -1) {
- PrintError("Error handling Page fault caused by PDPE\n");
- return -1;
- }
+ if (handle_pdpe_shadow_pagefault_64(info, fault_addr, error_code, shadow_pdp, guest_pdp) == -1) {
+ PrintError("Error handling Page fault caused by PDPE\n");
+ return -1;
+ }
- return 0;
+ return 0;
}
// For now we are not going to handle 1 Gigabyte pages
static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
pdpe64_t * shadow_pdp, pdpe64_t * guest_pdp) {
- pt_access_status_t guest_pdpe_access;
- pt_access_status_t shadow_pdpe_access;
- pdpe64_t * guest_pdpe = (pdpe64_t *)&(guest_pdp[PDPE64_INDEX(fault_addr)]);
- pdpe64_t * shadow_pdpe = (pdpe64_t *)&(shadow_pdp[PDPE64_INDEX(fault_addr)]);
+ pt_access_status_t guest_pdpe_access;
+ pt_access_status_t shadow_pdpe_access;
+ pdpe64_t * guest_pdpe = (pdpe64_t *)&(guest_pdp[PDPE64_INDEX(fault_addr)]);
+ pdpe64_t * shadow_pdpe = (pdpe64_t *)&(shadow_pdp[PDPE64_INDEX(fault_addr)]);
- PrintDebug("Handling PDP fault\n");
+ PrintDebug("Handling PDP fault\n");
- if (fault_addr==0) {
- PrintDebug("Guest Page Tree for guest virtual address zero fault\n");
- PrintGuestPageTree(info,fault_addr,(addr_t)(info->shdw_pg_state.guest_cr3));
- PrintDebug("Host Page Tree for guest virtual address zero fault\n");
- PrintHostPageTree(info,fault_addr,(addr_t)(info->ctrl_regs.cr3));
- }
+ if (fault_addr==0) {
+ PrintDebug("Guest Page Tree for guest virtual address zero fault\n");
+ PrintGuestPageTree(info,fault_addr,(addr_t)(info->shdw_pg_state.guest_cr3));
+ PrintDebug("Host Page Tree for guest virtual address zero fault\n");
+ PrintHostPageTree(info,fault_addr,(addr_t)(info->ctrl_regs.cr3));
+ }
- // Check the guest page permissions
- guest_pdpe_access = v3_can_access_pdpe64(guest_pdp, fault_addr, error_code);
+ // Check the guest page permissions
+ guest_pdpe_access = v3_can_access_pdpe64(guest_pdp, fault_addr, error_code);
- // Check the shadow page permissions
- shadow_pdpe_access = v3_can_access_pdpe64(shadow_pdp, fault_addr, error_code);
+ // Check the shadow page permissions
+ shadow_pdpe_access = v3_can_access_pdpe64(shadow_pdp, fault_addr, error_code);
- /* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pdpe_access, shadow_pdpe_access) == 1) {
- PrintDebug("Injecting PDPE pf to guest: (guest access error=%d) (pf error code=%d)\n",
- *(uint_t *)&guest_pdpe_access, *(uint_t *)&error_code);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
- }
-
- if (shadow_pdpe_access == PT_ACCESS_USER_ERROR) {
- //
- // PML4 Entry marked non-user
- //
- PrintDebug("Shadow Paging User access error (shadow_pdpe_access=0x%x, guest_pdpe_access=0x%x)\n",
- shadow_pdpe_access, guest_pdpe_access);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
- } else if ((shadow_pdpe_access != PT_ACCESS_NOT_PRESENT) &&
- (shadow_pdpe_access != PT_ACCESS_OK)) {
- // inject page fault in guest
- inject_guest_pf(info, fault_addr, error_code);
- PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pdpe_access);
- PrintDebug("Manual Says to inject page fault into guest\n");
- return 0;
- }
+ /* Was the page fault caused by the Guest's page tables? */
+ if (is_guest_pf(guest_pdpe_access, shadow_pdpe_access) == 1) {
+ PrintDebug("Injecting PDPE pf to guest: (guest access error=%d) (pf error code=%d)\n",
+ *(uint_t *)&guest_pdpe_access, *(uint_t *)&error_code);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
+ }
+
+ if (shadow_pdpe_access == PT_ACCESS_USER_ERROR) {
+ //
+ // PML4 Entry marked non-user
+ //
+ PrintDebug("Shadow Paging User access error (shadow_pdpe_access=0x%x, guest_pdpe_access=0x%x)\n",
+ shadow_pdpe_access, guest_pdpe_access);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
+ } else if ((shadow_pdpe_access != PT_ACCESS_NOT_PRESENT) &&
+ (shadow_pdpe_access != PT_ACCESS_OK)) {
+ // inject page fault in guest
+ inject_guest_pf(info, fault_addr, error_code);
+ PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pdpe_access);
+ PrintDebug("Manual Says to inject page fault into guest\n");
+ return 0;
+ }
- pde64_t * shadow_pd = NULL;
- pde64_t * guest_pd = NULL;
+ pde64_t * shadow_pd = NULL;
+ pde64_t * guest_pd = NULL;
- // Get the next shadow page level, allocate if not present
+ // Get the next shadow page level, allocate if not present
- if (shadow_pdpe_access == PT_ACCESS_NOT_PRESENT) {
- struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
- shadow_pd = (pde64_t *)V3_VAddr((void *)shdw_page->page_pa);
+ if (shadow_pdpe_access == PT_ACCESS_NOT_PRESENT) {
+ struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
+ shadow_pd = (pde64_t *)V3_VAddr((void *)shdw_page->page_pa);
- shadow_pdpe->present = 1;
- shadow_pdpe->user_page = guest_pdpe->user_page;
- shadow_pdpe->writable = guest_pdpe->writable;
+ shadow_pdpe->present = 1;
+ shadow_pdpe->user_page = guest_pdpe->user_page;
+ shadow_pdpe->writable = guest_pdpe->writable;
- // VMM Specific options
- shadow_pdpe->write_through = 0;
- shadow_pdpe->cache_disable = 0;
- //
+ // VMM Specific options
+ shadow_pdpe->write_through = 0;
+ shadow_pdpe->cache_disable = 0;
+ //
- guest_pdpe->accessed = 1;
+ guest_pdpe->accessed = 1;
- shadow_pdpe->pd_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
- } else {
- shadow_pd = (pde64_t *)V3_VAddr((void *)(addr_t)BASE_TO_PAGE_ADDR(shadow_pdpe->pd_base_addr));
- }
+ shadow_pdpe->pd_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
+ } else {
+ shadow_pd = (pde64_t *)V3_VAddr((void *)(addr_t)BASE_TO_PAGE_ADDR(shadow_pdpe->pd_base_addr));
+ }
- // Continue processing at the next level
+ // Continue processing at the next level
- if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pdpe->pd_base_addr), (addr_t *)&guest_pd) == -1) {
- // Machine check the guest
- PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pdpe->pd_base_addr));
- v3_raise_exception(info, MC_EXCEPTION);
- return 0;
- }
+ if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pdpe->pd_base_addr), (addr_t *)&guest_pd) == -1) {
+ // Machine check the guest
+ PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pdpe->pd_base_addr));
+ v3_raise_exception(info, MC_EXCEPTION);
+ return 0;
+ }
- if (handle_pde_shadow_pagefault_64(info, fault_addr, error_code, shadow_pd, guest_pd) == -1) {
- PrintError("Error handling Page fault caused by PDE\n");
- return -1;
- }
+ if (handle_pde_shadow_pagefault_64(info, fault_addr, error_code, shadow_pd, guest_pd) == -1) {
+ PrintError("Error handling Page fault caused by PDE\n");
+ return -1;
+ }
- return 0;
+ return 0;
}
static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
pde64_t * shadow_pd, pde64_t * guest_pd) {
- pt_access_status_t guest_pde_access;
- pt_access_status_t shadow_pde_access;
- pde64_t * guest_pde = (pde64_t *)&(guest_pd[PDE64_INDEX(fault_addr)]);
- pde64_t * shadow_pde = (pde64_t *)&(shadow_pd[PDE64_INDEX(fault_addr)]);
+ pt_access_status_t guest_pde_access;
+ pt_access_status_t shadow_pde_access;
+ pde64_t * guest_pde = (pde64_t *)&(guest_pd[PDE64_INDEX(fault_addr)]);
+ pde64_t * shadow_pde = (pde64_t *)&(shadow_pd[PDE64_INDEX(fault_addr)]);
- PrintDebug("Handling PDE fault\n");
+ PrintDebug("Handling PDE fault\n");
- // Check the guest page permissions
- guest_pde_access = v3_can_access_pde64(guest_pd, fault_addr, error_code);
+ // Check the guest page permissions
+ guest_pde_access = v3_can_access_pde64(guest_pd, fault_addr, error_code);
- // Check the shadow page permissions
- shadow_pde_access = v3_can_access_pde64(shadow_pd, fault_addr, error_code);
+ // Check the shadow page permissions
+ shadow_pde_access = v3_can_access_pde64(shadow_pd, fault_addr, error_code);
- /* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pde_access, shadow_pde_access) == 1) {
- PrintDebug("Injecting PDE pf to guest: (guest access error=%d) (pf error code=%d)\n",
- *(uint_t *)&guest_pde_access, *(uint_t *)&error_code);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
- }
-
- if (shadow_pde_access == PT_ACCESS_USER_ERROR) {
- //
- // PDE Entry marked non-user
- //
- PrintDebug("Shadow Paging User access error (shadow_pdpe_access=0x%x, guest_pdpe_access=0x%x)\n",
- shadow_pde_access, guest_pde_access);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
+ /* Was the page fault caused by the Guest's page tables? */
+ if (is_guest_pf(guest_pde_access, shadow_pde_access) == 1) {
+ PrintDebug("Injecting PDE pf to guest: (guest access error=%d) (pf error code=%d)\n",
+ *(uint_t *)&guest_pde_access, *(uint_t *)&error_code);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
+ }
- } else if ((shadow_pde_access == PT_ACCESS_WRITE_ERROR) &&
- (guest_pde->large_page == 1)) {
+ if (shadow_pde_access == PT_ACCESS_USER_ERROR) {
+ //
+ // PDE Entry marked non-user
+ //
+ PrintDebug("Shadow Paging User access error (shadow_pdpe_access=0x%x, guest_pdpe_access=0x%x)\n",
+ shadow_pde_access, guest_pde_access);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
- ((pde64_2MB_t *)guest_pde)->dirty = 1;
- shadow_pde->writable = guest_pde->writable;
+ } else if ((shadow_pde_access == PT_ACCESS_WRITE_ERROR) &&
+ (guest_pde->large_page == 1)) {
- //PrintDebug("Returning due to large page Write Error\n");
- //PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
+ ((pde64_2MB_t *)guest_pde)->dirty = 1;
+ shadow_pde->writable = guest_pde->writable;
- return 0;
- } else if ((shadow_pde_access != PT_ACCESS_NOT_PRESENT) &&
- (shadow_pde_access != PT_ACCESS_OK)) {
- // inject page fault in guest
- inject_guest_pf(info, fault_addr, error_code);
- PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pde_access);
- PrintDebug("Manual Says to inject page fault into guest\n");
- return 0;
- }
+ //PrintDebug("Returning due to large page Write Error\n");
+ //PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
+
+ return 0;
+ } else if ((shadow_pde_access != PT_ACCESS_NOT_PRESENT) &&
+ (shadow_pde_access != PT_ACCESS_OK)) {
+ // inject page fault in guest
+ inject_guest_pf(info, fault_addr, error_code);
+ PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pde_access);
+ PrintDebug("Manual Says to inject page fault into guest\n");
+ return 0;
+ }
- pte64_t * shadow_pt = NULL;
- pte64_t * guest_pt = NULL;
+ pte64_t * shadow_pt = NULL;
+ pte64_t * guest_pt = NULL;
- // Get the next shadow page level, allocate if not present
+ // Get the next shadow page level, allocate if not present
- if (shadow_pde_access == PT_ACCESS_NOT_PRESENT) {
- struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
- shadow_pt = (pte64_t *)V3_VAddr((void *)shdw_page->page_pa);
+ if (shadow_pde_access == PT_ACCESS_NOT_PRESENT) {
+ struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
+ shadow_pt = (pte64_t *)V3_VAddr((void *)shdw_page->page_pa);
- PrintDebug("Creating new shadow PT: %p\n", shadow_pt);
+ PrintDebug("Creating new shadow PT: %p\n", shadow_pt);
- shadow_pde->present = 1;
- shadow_pde->user_page = guest_pde->user_page;
+ shadow_pde->present = 1;
+ shadow_pde->user_page = guest_pde->user_page;
- if (guest_pde->large_page == 0) {
- shadow_pde->writable = guest_pde->writable;
- } else {
- // This large page flag is temporary until we can get a working cache....
- ((pde64_2MB_t *)guest_pde)->vmm_info = V3_LARGE_PG;
+ if (guest_pde->large_page == 0) {
+ shadow_pde->writable = guest_pde->writable;
+ } else {
+ // This large page flag is temporary until we can get a working cache....
+ ((pde64_2MB_t *)guest_pde)->vmm_info = V3_LARGE_PG;
- if (error_code.write) {
- shadow_pde->writable = guest_pde->writable;
- ((pde64_2MB_t *)guest_pde)->dirty = 1;
- } else {
- shadow_pde->writable = 0;
- ((pde64_2MB_t *)guest_pde)->dirty = 0;
- }
- }
+ if (error_code.write) {
+ shadow_pde->writable = guest_pde->writable;
+ ((pde64_2MB_t *)guest_pde)->dirty = 1;
+ } else {
+ shadow_pde->writable = 0;
+ ((pde64_2MB_t *)guest_pde)->dirty = 0;
+ }
+ }
- // VMM Specific options
- shadow_pde->write_through = 0;
- shadow_pde->cache_disable = 0;
- shadow_pde->global_page = 0;
- //
+ // VMM Specific options
+ shadow_pde->write_through = 0;
+ shadow_pde->cache_disable = 0;
+ shadow_pde->global_page = 0;
+ //
- guest_pde->accessed = 1;
+ guest_pde->accessed = 1;
- shadow_pde->pt_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
- } else {
- shadow_pt = (pte64_t *)V3_VAddr((void *)BASE_TO_PAGE_ADDR(shadow_pde->pt_base_addr));
- }
-
- // Continue processing at the next level
- if (guest_pde->large_page == 0) {
- if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr), (addr_t *)&guest_pt) == -1) {
- // Machine check the guest
- PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr));
- v3_raise_exception(info, MC_EXCEPTION);
- return 0;
+ shadow_pde->pt_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
+ } else {
+ shadow_pt = (pte64_t *)V3_VAddr((void *)BASE_TO_PAGE_ADDR(shadow_pde->pt_base_addr));
}
+
+ // Continue processing at the next level
+ if (guest_pde->large_page == 0) {
+ if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr), (addr_t *)&guest_pt) == -1) {
+ // Machine check the guest
+ PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr));
+ v3_raise_exception(info, MC_EXCEPTION);
+ return 0;
+ }
- if (handle_pte_shadow_pagefault_64(info, fault_addr, error_code, shadow_pt, guest_pt) == -1) {
- PrintError("Error handling Page fault caused by PDE\n");
- return -1;
+ if (handle_pte_shadow_pagefault_64(info, fault_addr, error_code, shadow_pt, guest_pt) == -1) {
+ PrintError("Error handling Page fault caused by PDE\n");
+ return -1;
+ }
+ } else {
+ if (handle_2MB_shadow_pagefault_64(info, fault_addr, error_code, shadow_pt, (pde64_2MB_t *)guest_pde) == -1) {
+ PrintError("Error handling large pagefault\n");
+ return -1;
+ }
}
- } else {
- if (handle_2MB_shadow_pagefault_64(info, fault_addr, error_code, shadow_pt, (pde64_2MB_t *)guest_pde) == -1) {
- PrintError("Error handling large pagefault\n");
- return -1;
- }
- }
- return 0;
+ return 0;
}
static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
pte64_t * shadow_pt, pte64_t * guest_pt) {
- pt_access_status_t guest_pte_access;
- pt_access_status_t shadow_pte_access;
- pte64_t * guest_pte = (pte64_t *)&(guest_pt[PTE64_INDEX(fault_addr)]);;
- pte64_t * shadow_pte = (pte64_t *)&(shadow_pt[PTE64_INDEX(fault_addr)]);
- addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) + PAGE_OFFSET(fault_addr);
- // struct shadow_page_state * state = &(info->shdw_pg_state);
+ pt_access_status_t guest_pte_access;
+ pt_access_status_t shadow_pte_access;
+ pte64_t * guest_pte = (pte64_t *)&(guest_pt[PTE64_INDEX(fault_addr)]);;
+ pte64_t * shadow_pte = (pte64_t *)&(shadow_pt[PTE64_INDEX(fault_addr)]);
+ addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) + PAGE_OFFSET(fault_addr);
+ // struct shadow_page_state * state = &(info->shdw_pg_state);
- PrintDebug("Handling PTE fault\n");
+ PrintDebug("Handling PTE fault\n");
- struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_pa);
+ struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_pa);
- if ((shdw_reg == NULL) ||
- (shdw_reg->host_type == SHDW_REGION_INVALID)) {
- // Inject a machine check in the guest
- PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_pa);
- v3_raise_exception(info, MC_EXCEPTION);
- return 0;
- }
+ if ((shdw_reg == NULL) ||
+ (shdw_reg->host_type == SHDW_REGION_INVALID)) {
+ // Inject a machine check in the guest
+ PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_pa);
+ v3_raise_exception(info, MC_EXCEPTION);
+ return 0;
+ }
- // Check the guest page permissions
- guest_pte_access = v3_can_access_pte64(guest_pt, fault_addr, error_code);
+ // Check the guest page permissions
+ guest_pte_access = v3_can_access_pte64(guest_pt, fault_addr, error_code);
- // Check the shadow page permissions
- shadow_pte_access = v3_can_access_pte64(shadow_pt, fault_addr, error_code);
+ // Check the shadow page permissions
+ shadow_pte_access = v3_can_access_pte64(shadow_pt, fault_addr, error_code);
- /* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pte_access, shadow_pte_access) == 1) {
- PrintDebug("Access error injecting pf to guest (guest access error=%d) (pf error code=%d)\n",
- guest_pte_access, *(uint_t*)&error_code);
- inject_guest_pf(info, fault_addr, error_code);
- return 0;
- }
+ /* Was the page fault caused by the Guest's page tables? */
+ if (is_guest_pf(guest_pte_access, shadow_pte_access) == 1) {
+ PrintDebug("Access error injecting pf to guest (guest access error=%d) (pf error code=%d)\n",
+ guest_pte_access, *(uint_t*)&error_code);
+ inject_guest_pf(info, fault_addr, error_code);
+ return 0;
+ }
- if (shadow_pte_access == PT_ACCESS_OK) {
- // Inconsistent state...
- // Guest Re-Entry will flush page tables and everything should now work
- PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
- return 0;
- }
+ if (shadow_pte_access == PT_ACCESS_OK) {
+ // Inconsistent state...
+ // Guest Re-Entry will flush page tables and everything should now work
+ PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
+ return 0;
+ }
- if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
- // Page Table Entry Not Present
- PrintDebug("guest_pa =%p\n", (void *)guest_pa);
+ if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
+ // Page Table Entry Not Present
+ PrintDebug("guest_pa =%p\n", (void *)guest_pa);
- if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
- (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
- addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
+ if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
+ (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
+ addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
- shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
+ shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
- shadow_pte->present = guest_pte->present;
- shadow_pte->user_page = guest_pte->user_page;
+ shadow_pte->present = guest_pte->present;
+ shadow_pte->user_page = guest_pte->user_page;
- //set according to VMM policy
- shadow_pte->write_through = 0;
- shadow_pte->cache_disable = 0;
- shadow_pte->global_page = 0;
- //
+ //set according to VMM policy
+ shadow_pte->write_through = 0;
+ shadow_pte->cache_disable = 0;
+ shadow_pte->global_page = 0;
+ //
- guest_pte->accessed = 1;
+ guest_pte->accessed = 1;
- if (guest_pte->dirty == 1) {
- shadow_pte->writable = guest_pte->writable;
- } else if ((guest_pte->dirty == 0) && (error_code.write == 1)) {
- shadow_pte->writable = guest_pte->writable;
+ if (guest_pte->dirty == 1) {
+ shadow_pte->writable = guest_pte->writable;
+ } else if ((guest_pte->dirty == 0) && (error_code.write == 1)) {
+ shadow_pte->writable = guest_pte->writable;
+ guest_pte->dirty = 1;
+ } else if ((guest_pte->dirty == 0) && (error_code.write == 0)) {
+ shadow_pte->writable = 0;
+ }
+
+ // dirty flag has been set, check if its in the cache
+ /* if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) { */
+ /* if (error_code.write == 1) { */
+ /* state->cached_cr3 = 0; */
+ /* shadow_pte->writable = guest_pte->writable; */
+ /* } else { */
+ /* shadow_pte->writable = 0; */
+ /* } */
+ /* } */
+
+ // Write hooks trump all, and are set Read Only
+ if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
+ shadow_pte->writable = 0;
+ }
+
+ } else {
+ // Page fault handled by hook functions
+
+ if (v3_handle_mem_full_hook(info, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
+ PrintError("Special Page fault handler returned error for address: %p\n", (void *)fault_addr);
+ return -1;
+ }
+ }
+ } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
guest_pte->dirty = 1;
- } else if ((guest_pte->dirty == 0) && (error_code.write == 0)) {
- shadow_pte->writable = 0;
- }
-
- // dirty flag has been set, check if its in the cache
-/* if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) { */
-/* if (error_code.write == 1) { */
-/* state->cached_cr3 = 0; */
-/* shadow_pte->writable = guest_pte->writable; */
-/* } else { */
-/* shadow_pte->writable = 0; */
-/* } */
-/* } */
-
- // Write hooks trump all, and are set Read Only
- if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
- shadow_pte->writable = 0;
- }
- } else {
- // Page fault handled by hook functions
+ if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
+ if (v3_handle_mem_wr_hook(info, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
+ PrintError("Special Page fault handler returned error for address: %p\n", (void *)fault_addr);
+ return -1;
+ }
+ } else {
+ PrintDebug("Shadow PTE Write Error\n");
+ shadow_pte->writable = guest_pte->writable;
+ }
- if (v3_handle_mem_full_hook(info, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
- PrintError("Special Page fault handler returned error for address: %p\n", (void *)fault_addr);
- return -1;
- }
- }
- } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
- guest_pte->dirty = 1;
+ /* if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) { */
+ /* struct shadow_page_state * state = &(info->shdw_pg_state); */
+ /* PrintDebug("Write operation on Guest PAge Table Page\n"); */
+ /* state->cached_cr3 = 0; */
+ /* } */
+
+ return 0;
- if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
- if (v3_handle_mem_wr_hook(info, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
- PrintError("Special Page fault handler returned error for address: %p\n", (void *)fault_addr);
- return -1;
- }
} else {
- PrintDebug("Shadow PTE Write Error\n");
- shadow_pte->writable = guest_pte->writable;
+ // Inject page fault into the guest
+ inject_guest_pf(info, fault_addr, error_code);
+ PrintError("PTE Page fault fell through... Not sure if this should ever happen\n");
+ PrintError("Manual Says to inject page fault into guest\n");
+ return -1;
}
-/* if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) { */
-/* struct shadow_page_state * state = &(info->shdw_pg_state); */
-/* PrintDebug("Write operation on Guest PAge Table Page\n"); */
-/* state->cached_cr3 = 0; */
-/* } */
-
return 0;
-
- } else {
- // Inject page fault into the guest
- inject_guest_pf(info, fault_addr, error_code);
- PrintError("PTE Page fault fell through... Not sure if this should ever happen\n");
- PrintError("Manual Says to inject page fault into guest\n");
- return -1;
- }
-
- return 0;
}
addr_t fault_addr, pf_error_t error_code,
pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde)
{
- pt_access_status_t shadow_pte_access = v3_can_access_pte64(shadow_pt, fault_addr, error_code);
- pte64_t * shadow_pte = (pte64_t *)&(shadow_pt[PTE64_INDEX(fault_addr)]);
- addr_t guest_fault_pa = BASE_TO_PAGE_ADDR_2MB(large_guest_pde->page_base_addr) + PAGE_OFFSET_2MB(fault_addr);
- // struct shadow_page_state * state = &(info->shdw_pg_state);
+ pt_access_status_t shadow_pte_access = v3_can_access_pte64(shadow_pt, fault_addr, error_code);
+ pte64_t * shadow_pte = (pte64_t *)&(shadow_pt[PTE64_INDEX(fault_addr)]);
+ addr_t guest_fault_pa = BASE_TO_PAGE_ADDR_2MB(large_guest_pde->page_base_addr) + PAGE_OFFSET_2MB(fault_addr);
+ // struct shadow_page_state * state = &(info->shdw_pg_state);
- PrintDebug("Handling 2MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code);
- PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde);
+ PrintDebug("Handling 2MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code);
+ PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde);
- struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_fault_pa);
+ struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_fault_pa);
- if ((shdw_reg == NULL) ||
- (shdw_reg->host_type == SHDW_REGION_INVALID)) {
- // Inject a machine check in the guest
- PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_fault_pa);
- v3_raise_exception(info, MC_EXCEPTION);
- return -1;
- }
+ if ((shdw_reg == NULL) ||
+ (shdw_reg->host_type == SHDW_REGION_INVALID)) {
+ // Inject a machine check in the guest
+ PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_fault_pa);
+ v3_raise_exception(info, MC_EXCEPTION);
+ return -1;
+ }
- if (shadow_pte_access == PT_ACCESS_OK) {
- // Inconsistent state...
- // Guest Re-Entry will flush tables and everything should now workd
- PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
- //PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
- return 0;
- }
+ if (shadow_pte_access == PT_ACCESS_OK) {
+ // Inconsistent state...
+ // Guest Re-Entry will flush tables and everything should now workd
+ PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
+ //PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
+ return 0;
+ }
- if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
- // Get the guest physical address of the fault
+ if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
+ // Get the guest physical address of the fault
- if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
- (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
- addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_fault_pa);
+ if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
+ (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
+ addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_fault_pa);
- PrintDebug("Shadow PA=%p, ShadowPTE=%p\n", (void *)shadow_pa, (void *)shadow_pte);
+ PrintDebug("Shadow PA=%p, ShadowPTE=%p\n", (void *)shadow_pa, (void *)shadow_pte);
- shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
- PrintDebug("Test1\n");
+ shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
+ PrintDebug("Test1\n");
- shadow_pte->present = 1;
+ shadow_pte->present = 1;
- /* We are assuming that the PDE entry has precedence
- * so the Shadow PDE will mirror the guest PDE settings,
- * and we don't have to worry about them here
- * Allow everything
- */
- shadow_pte->user_page = 1;
+ /* We are assuming that the PDE entry has precedence
+ * so the Shadow PDE will mirror the guest PDE settings,
+ * and we don't have to worry about them here
+ * Allow everything
+ */
+ shadow_pte->user_page = 1;
-/* if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) { */
-/* // Check if the entry is a page table... */
-/* PrintDebug("Marking page as Guest Page Table (large page)\n"); */
-/* shadow_pte->writable = 0; */
-/* } else */ if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
- shadow_pte->writable = 0;
- } else {
- shadow_pte->writable = 1;
- }
+ /* if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) { */
+ /* // Check if the entry is a page table... */
+ /* PrintDebug("Marking page as Guest Page Table (large page)\n"); */
+ /* shadow_pte->writable = 0; */
+ /* } else */ if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
+ shadow_pte->writable = 0;
+ } else {
+ shadow_pte->writable = 1;
+ }
- //set according to VMM policy
- shadow_pte->write_through = 0;
- shadow_pte->cache_disable = 0;
- shadow_pte->global_page = 0;
- //
+ //set according to VMM policy
+ shadow_pte->write_through = 0;
+ shadow_pte->cache_disable = 0;
+ shadow_pte->global_page = 0;
+ //
- } else {
- // Handle hooked pages as well as other special pages
- // if (handle_special_page_fault(info, fault_addr, guest_fault_pa, error_code) == -1) {
+ } else {
+ // Handle hooked pages as well as other special pages
+ // if (handle_special_page_fault(info, fault_addr, guest_fault_pa, error_code) == -1) {
- if (v3_handle_mem_full_hook(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
- PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
- return -1;
- }
- }
- } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
+ if (v3_handle_mem_full_hook(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
+ PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
+ return -1;
+ }
+ }
+ } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
- if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
+ if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
- if (v3_handle_mem_wr_hook(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
- PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
- return -1;
- }
- }
+ if (v3_handle_mem_wr_hook(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
+ PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
+ return -1;
+ }
+ }
-/* if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) { */
-/* struct shadow_page_state * state = &(info->shdw_pg_state); */
-/* PrintDebug("Write operation on Guest PAge Table Page (large page)\n"); */
-/* state->cached_cr3 = 0; */
-/* shadow_pte->writable = 1; */
-/* } */
+ /* if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) { */
+ /* struct shadow_page_state * state = &(info->shdw_pg_state); */
+ /* PrintDebug("Write operation on Guest PAge Table Page (large page)\n"); */
+ /* state->cached_cr3 = 0; */
+ /* shadow_pte->writable = 1; */
+ /* } */
- } else {
- PrintError("Error in large page fault handler...\n");
- PrintError("This case should have been handled at the top level handler\n");
- return -1;
- }
+ } else {
+ PrintError("Error in large page fault handler...\n");
+ PrintError("This case should have been handled at the top level handler\n");
+ return -1;
+ }
- // PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
- PrintDebug("Returning from large page fault handler\n");
- return 0;
+ // PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
+ PrintDebug("Returning from large page fault handler\n");
+ return 0;
}
addr_t vaddr, addr_t page_ptr, addr_t page_pa,
void * private_data) {
- switch (type) {
- case PAGE_PML464:
- {
- pml4e64_t * pml = (pml4e64_t *)page_ptr;
-
- if (pml[PML4E64_INDEX(vaddr)].present == 0) {
- return 1;
- }
- return 0;
- }
- case PAGE_PDP64:
- {
- pdpe64_t * pdp = (pdpe64_t *)page_ptr;
- pdpe64_t * pdpe = &(pdp[PDPE64_INDEX(vaddr)]);
-
- if (pdpe->present == 0) {
- return 1;
- }
+ switch (type) {
+ case PAGE_PML464:
+ {
+ pml4e64_t * pml = (pml4e64_t *)page_ptr;
+
+ if (pml[PML4E64_INDEX(vaddr)].present == 0) {
+ return 1;
+ }
+ return 0;
+ }
+ case PAGE_PDP64:
+ {
+ pdpe64_t * pdp = (pdpe64_t *)page_ptr;
+ pdpe64_t * pdpe = &(pdp[PDPE64_INDEX(vaddr)]);
+
+ if (pdpe->present == 0) {
+ return 1;
+ }
- if (pdpe->vmm_info == V3_LARGE_PG) {
- PrintError("1 Gigabyte pages not supported\n");
- return -1;
-
- pdpe->present = 0;
- return 1;
- }
-
- return 0;
- }
- case PAGE_PD64:
- {
- pde64_t * pd = (pde64_t *)page_ptr;
- pde64_t * pde = &(pd[PDE64_INDEX(vaddr)]);
-
- if (pde->present == 0) {
- return 1;
- }
+ if (pdpe->vmm_info == V3_LARGE_PG) {
+ PrintError("1 Gigabyte pages not supported\n");
+ return -1;
+
+ pdpe->present = 0;
+ return 1;
+ }
+
+ return 0;
+ }
+ case PAGE_PD64:
+ {
+ pde64_t * pd = (pde64_t *)page_ptr;
+ pde64_t * pde = &(pd[PDE64_INDEX(vaddr)]);
+
+ if (pde->present == 0) {
+ return 1;
+ }
- if (pde->vmm_info == V3_LARGE_PG) {
- pde->present = 0;
- return 1;
- }
+ if (pde->vmm_info == V3_LARGE_PG) {
+ pde->present = 0;
+ return 1;
+ }
- return 0;
- }
- case PAGE_PT64:
- {
- pte64_t * pt = (pte64_t *)page_ptr;
+ return 0;
+ }
+ case PAGE_PT64:
+ {
+ pte64_t * pt = (pte64_t *)page_ptr;
- pt[PTE64_INDEX(vaddr)].present = 0;
+ pt[PTE64_INDEX(vaddr)].present = 0;
- return 1;
- }
- default:
- PrintError("Invalid Page Type\n");
- return -1;
+ return 1;
+ }
+ default:
+ PrintError("Invalid Page Type\n");
+ return -1;
- }
+ }
- // should not get here
- PrintError("Should not get here....\n");
- return -1;
+ // should not get here
+ PrintError("Should not get here....\n");
+ return -1;
}
static inline int handle_shadow_invlpg_64(struct guest_info * info, addr_t vaddr) {
- PrintDebug("INVLPG64 - %p\n",(void*)vaddr);
+ PrintDebug("INVLPG64 - %p\n",(void*)vaddr);
- int ret = v3_drill_host_pt_64(info, info->ctrl_regs.cr3, vaddr, invalidation_cb_64, NULL);
- if (ret == -1) {
- PrintError("Page table drill returned error.... \n");
- PrintHostPageTree(info, vaddr, info->ctrl_regs.cr3);
- }
+ int ret = v3_drill_host_pt_64(info, info->ctrl_regs.cr3, vaddr, invalidation_cb_64, NULL);
+ if (ret == -1) {
+ PrintError("Page table drill returned error.... \n");
+ PrintHostPageTree(info, vaddr, info->ctrl_regs.cr3);
+ }
- return (ret == -1) ? -1 : 0;
+ return (ret == -1) ? -1 : 0;
}
struct v3_socket_hooks * sock_hooks = 0;
void V3_Init_Sockets(struct v3_socket_hooks * hooks) {
- PrintInfo("Initializing Socket Interface\n");
- sock_hooks = hooks;
+ PrintInfo("Initializing Socket Interface\n");
+ sock_hooks = hooks;
- PrintDebug("V3 sockets inited\n");
+ PrintDebug("V3 sockets inited\n");
- return;
+ return;
}
static float e = 0.00000001;
double v3_ceil(double x) {
- if ((double)(x - (int)x) == 0) {
- return (int)x;
- }
- return (int)(x + e) + 1;
+ if ((double)(x - (int)x) == 0) {
+ return (int)x;
+ }
+ return (int)(x + e) + 1;
}
t1 = s1;
while (*s1) s1++;
while (i < limit) {
- if(*s2 == '\0') break;
- *s1++ = *s2++;
+ if(*s2 == '\0') break;
+ *s1++ = *s2++;
}
*s1 = '\0';
return t1;
int ret = 0;
while (*buf >= '0' && *buf <= '9') {
- ret *= 10;
- ret += *buf - '0';
- buf++;
+ ret *= 10;
+ ret += *buf - '0';
+ buf++;
}
return ret;
void v3_init_time(struct guest_info * info) {
- struct vm_time * time_state = &(info->time_state);
+ struct vm_time * time_state = &(info->time_state);
- time_state->cpu_freq = V3_CPU_KHZ();
+ time_state->cpu_freq = V3_CPU_KHZ();
- time_state->guest_tsc = 0;
- time_state->cached_host_tsc = 0;
- // time_state->pending_cycles = 0;
+ time_state->guest_tsc = 0;
+ time_state->cached_host_tsc = 0;
+ // time_state->pending_cycles = 0;
- INIT_LIST_HEAD(&(time_state->timers));
- time_state->num_timers = 0;
+ INIT_LIST_HEAD(&(time_state->timers));
+ time_state->num_timers = 0;
}
int v3_add_timer(struct guest_info * info, struct vm_timer_ops * ops, void * private_data) {
- struct vm_timer * timer = NULL;
- timer = (struct vm_timer *)V3_Malloc(sizeof(struct vm_timer));
- V3_ASSERT(timer != NULL);
+ struct vm_timer * timer = NULL;
+ timer = (struct vm_timer *)V3_Malloc(sizeof(struct vm_timer));
+ V3_ASSERT(timer != NULL);
- timer->ops = ops;
- timer->private_data = private_data;
+ timer->ops = ops;
+ timer->private_data = private_data;
- list_add(&(timer->timer_link), &(info->time_state.timers));
- info->time_state.num_timers++;
+ list_add(&(timer->timer_link), &(info->time_state.timers));
+ info->time_state.num_timers++;
- return 0;
+ return 0;
}
int v3_remove_timer(struct guest_info * info, struct vm_timer * timer) {
- list_del(&(timer->timer_link));
- info->time_state.num_timers--;
+ list_del(&(timer->timer_link));
+ info->time_state.num_timers--;
- V3_Free(timer);
- return 0;
+ V3_Free(timer);
+ return 0;
}
void v3_update_time(struct guest_info * info, ullong_t cycles) {
- struct vm_timer * tmp_timer;
+ struct vm_timer * tmp_timer;
- info->time_state.guest_tsc += cycles;
+ info->time_state.guest_tsc += cycles;
- list_for_each_entry(tmp_timer, &(info->time_state.timers), timer_link) {
- tmp_timer->ops->update_time(cycles, info->time_state.cpu_freq, tmp_timer->private_data);
- }
+ list_for_each_entry(tmp_timer, &(info->time_state.timers), timer_link) {
+ tmp_timer->ops->update_time(cycles, info->time_state.cpu_freq, tmp_timer->private_data);
+ }
- //info->time_state.pending_cycles = 0;
+ //info->time_state.pending_cycles = 0;
}
void PrintTraceHex(unsigned char x) {
- unsigned char z;
+ unsigned char z;
- z = (x >> 4) & 0xf;
- PrintTrace("%x", z);
- z = x & 0xf;
- PrintTrace("%x", z);
+ z = (x >> 4) & 0xf;
+ PrintTrace("%x", z);
+ z = x & 0xf;
+ PrintTrace("%x", z);
}
void PrintTraceLL(ullong_t num) {
- unsigned char * z = (unsigned char *)#
- int i;
+ unsigned char * z = (unsigned char *)#
+ int i;
- for (i = 7; i >= 0; i--) {
- PrintTraceHex(*(z + i));
- }
+ for (i = 7; i >= 0; i--) {
+ PrintTraceHex(*(z + i));
+ }
}
void PrintTraceMemDump(uchar_t * start, int n) {
- int i, j;
+ int i, j;
- for (i = 0; i < n; i += 16) {
- PrintTrace("%p", (void *)(start + i));
- for (j = i; (j < (i + 16)) && (j < n); j += 2) {
- PrintTrace(" ");
- PrintTraceHex(*(uchar_t *)(start + j));
- if ((j + 1) < n) {
- PrintTraceHex(*((uchar_t *)(start + j + 1)));
- }
- }
- PrintTrace(" ");
- for (j = i; (j < (i + 16)) && (j < n); j++) {
- PrintTrace("%c", ((start[j] >= 32) && (start[j] <= 126)) ? start[j] : '.');
+ for (i = 0; i < n; i += 16) {
+ PrintTrace("%p", (void *)(start + i));
+ for (j = i; (j < (i + 16)) && (j < n); j += 2) {
+ PrintTrace(" ");
+ PrintTraceHex(*(uchar_t *)(start + j));
+ if ((j + 1) < n) {
+ PrintTraceHex(*((uchar_t *)(start + j + 1)));
+ }
+ }
+ PrintTrace(" ");
+ for (j = i; (j < (i + 16)) && (j < n); j++) {
+ PrintTrace("%c", ((start[j] >= 32) && (start[j] <= 126)) ? start[j] : '.');
+ }
+ PrintTrace("\n");
}
- PrintTrace("\n");
- }
}
#define MASK(val, length) ({ \
- ullong_t mask = 0x0LL; \
- switch (length) { \
- case 1: \
- mask = mask_1; \
- break; \
- case 2: \
- mask = mask_2; \
- break; \
- case 4: \
- mask = mask_4; \
- break; \
- case 8: \
- mask = mask_8; \
- break; \
- } \
- val & mask;}) \
-
+ ullong_t mask = 0x0LL; \
+ switch (length) { \
+ case 1: \
+ mask = mask_1; \
+ break; \
+ case 2: \
+ mask = mask_2; \
+ break; \
+ case 4: \
+ mask = mask_4; \
+ break; \
+ case 8: \
+ mask = mask_8; \
+ break; \
+ } \
+ val & mask; \
+ })
+
struct memory_operand {
- uint_t segment_size;
- addr_t segment;
- uint_t base_size;
- addr_t base;
- uint_t index_size;
- addr_t index;
- addr_t scale;
- uint_t displacement_size;
- ullong_t displacement;
+ uint_t segment_size;
+ addr_t segment;
+ uint_t base_size;
+ addr_t base;
+ uint_t index_size;
+ addr_t index;
+ addr_t scale;
+ uint_t displacement_size;
+ ullong_t displacement;
};
static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
- switch (info->cpu_mode) {
- case REAL:
- if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
- xed_state_init(state,
- XED_MACHINE_MODE_LEGACY_16,
- XED_ADDRESS_WIDTH_16b,
- XED_ADDRESS_WIDTH_16b);
- }
- break;
- case PROTECTED:
- case PROTECTED_PAE:
- if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
- xed_state_init(state,
- XED_MACHINE_MODE_LEGACY_32,
- XED_ADDRESS_WIDTH_32b,
- XED_ADDRESS_WIDTH_32b);
- }
- break;
- case LONG_32_COMPAT:
- if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
- xed_state_init(state,
- XED_MACHINE_MODE_LONG_COMPAT_32,
- XED_ADDRESS_WIDTH_32b,
- XED_ADDRESS_WIDTH_32b);
- }
- break;
- case LONG:
- if (state->mmode != XED_MACHINE_MODE_LONG_64) {
- PrintDebug("Setting decoder to long mode\n");
- // state->mmode = XED_MACHINE_MODE_LONG_64;
- //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
- xed_state_init(state,
- XED_MACHINE_MODE_LONG_64,
- XED_ADDRESS_WIDTH_64b,
- XED_ADDRESS_WIDTH_64b);
+ switch (info->cpu_mode) {
+ case REAL:
+ if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
+ xed_state_init(state,
+ XED_MACHINE_MODE_LEGACY_16,
+ XED_ADDRESS_WIDTH_16b,
+ XED_ADDRESS_WIDTH_16b);
+ }
+ break;
+ case PROTECTED:
+ case PROTECTED_PAE:
+ if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
+ xed_state_init(state,
+ XED_MACHINE_MODE_LEGACY_32,
+ XED_ADDRESS_WIDTH_32b,
+ XED_ADDRESS_WIDTH_32b);
+ }
+ break;
+ case LONG_32_COMPAT:
+ if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
+ xed_state_init(state,
+ XED_MACHINE_MODE_LONG_COMPAT_32,
+ XED_ADDRESS_WIDTH_32b,
+ XED_ADDRESS_WIDTH_32b);
+ }
+ break;
+ case LONG:
+ if (state->mmode != XED_MACHINE_MODE_LONG_64) {
+ PrintDebug("Setting decoder to long mode\n");
+ // state->mmode = XED_MACHINE_MODE_LONG_64;
+ //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
+ xed_state_init(state,
+ XED_MACHINE_MODE_LONG_64,
+ XED_ADDRESS_WIDTH_64b,
+ XED_ADDRESS_WIDTH_64b);
+ }
+ break;
+ default:
+ PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
+ return -1;
}
- break;
- default:
- PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
- return -1;
- }
- return 0;
+ return 0;
}
static int is_flags_reg(xed_reg_enum_t xed_reg) {
- switch (xed_reg) {
- case XED_REG_FLAGS:
- case XED_REG_EFLAGS:
- case XED_REG_RFLAGS:
- return 1;
- default:
- return 0;
- }
+ switch (xed_reg) {
+ case XED_REG_FLAGS:
+ case XED_REG_EFLAGS:
+ case XED_REG_RFLAGS:
+ return 1;
+ default:
+ return 0;
+ }
}
int v3_init_decoder(struct guest_info * info) {
- // Global library initialization, only do it once
- if (tables_inited == 0) {
- xed_tables_init();
- tables_inited = 1;
- }
-
- xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
- xed_state_zero(decoder_state);
- xed_state_init(decoder_state,
- XED_MACHINE_MODE_LEGACY_32,
- XED_ADDRESS_WIDTH_32b,
- XED_ADDRESS_WIDTH_32b);
-
- info->decoder_state = decoder_state;
-
- return 0;
+ // Global library initialization, only do it once
+ if (tables_inited == 0) {
+ xed_tables_init();
+ tables_inited = 1;
+ }
+
+ xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
+ xed_state_zero(decoder_state);
+ xed_state_init(decoder_state,
+ XED_MACHINE_MODE_LEGACY_32,
+ XED_ADDRESS_WIDTH_32b,
+ XED_ADDRESS_WIDTH_32b);
+
+ info->decoder_state = decoder_state;
+
+ return 0;
}
int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
- xed_decoded_inst_t xed_instr;
- xed_error_enum_t xed_error;
+ xed_decoded_inst_t xed_instr;
+ xed_error_enum_t xed_error;
- if (set_decoder_mode(info, info->decoder_state) == -1) {
- PrintError("Could not set decoder mode\n");
- return -1;
- }
+ if (set_decoder_mode(info, info->decoder_state) == -1) {
+ PrintError("Could not set decoder mode\n");
+ return -1;
+ }
- xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
+ xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
- xed_error = xed_decode(&xed_instr,
- REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
- XED_MAX_INSTRUCTION_BYTES);
+ xed_error = xed_decode(&xed_instr,
+ REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
+ XED_MAX_INSTRUCTION_BYTES);
- if (xed_error != XED_ERROR_NONE) {
- PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
- return -1;
- }
+ if (xed_error != XED_ERROR_NONE) {
+ PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
+ return -1;
+ }
- instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
+ instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
- if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
- PrintError("Tried to decode memory operation with no memory operands\n");
- return -1;
- }
+ if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
+ PrintError("Tried to decode memory operation with no memory operands\n");
+ return -1;
+ }
- instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
+ instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
- xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
- if (cat == XED_CATEGORY_STRINGOP) {
- instr_info->str_op = 1;
- } else {
- instr_info->str_op = 0;
- }
+ xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
+ if (cat == XED_CATEGORY_STRINGOP) {
+ instr_info->str_op = 1;
+ } else {
+ instr_info->str_op = 0;
+ }
- xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
- if (xed_operand_values_has_real_rep(operands)) {
- instr_info->has_rep = 1;
- } else {
- instr_info->has_rep = 0;
- }
+ xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
+ if (xed_operand_values_has_real_rep(operands)) {
+ instr_info->has_rep = 1;
+ } else {
+ instr_info->has_rep = 0;
+ }
- return 0;
+ return 0;
}
xed_decoded_inst_t * xed_instr, const xed_inst_t * xi,
struct x86_instr * instr) {
- PrintDebug("String operation\n");
+ PrintDebug("String operation\n");
- if (instr->op_type == V3_OP_MOVS) {
- instr->num_operands = 2;
+ if (instr->op_type == V3_OP_MOVS) {
+ instr->num_operands = 2;
- if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
- PrintError("Could not get Destination memory operand\n");
- return -1;
- }
+ if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
+ PrintError("Could not get Destination memory operand\n");
+ return -1;
+ }
- if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
- PrintError("Could not get Source memory operand\n");
- return -1;
- }
+ if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
+ PrintError("Could not get Source memory operand\n");
+ return -1;
+ }
- if (instr->prefixes.rep == 1) {
- addr_t reg_addr = 0;
- uint_t reg_length = 0;
+ if (instr->prefixes.rep == 1) {
+ addr_t reg_addr = 0;
+ uint_t reg_length = 0;
- xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), ®_addr, ®_length);
- instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
- } else {
- instr->str_op_length = 1;
- }
+ xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), ®_addr, ®_length);
+ instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
+ } else {
+ instr->str_op_length = 1;
+ }
- } else if (instr->op_type == V3_OP_STOS) {
- instr->num_operands = 2;
+ } else if (instr->op_type == V3_OP_STOS) {
+ instr->num_operands = 2;
- if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
- PrintError("Could not get Destination memory operand\n");
- return -1;
- }
+ if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
+ PrintError("Could not get Destination memory operand\n");
+ return -1;
+ }
- // STOS reads from rax
- xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0),
- &(instr->src_operand.operand),
- &(instr->src_operand.size));
- instr->src_operand.type = REG_OPERAND;
+ // STOS reads from rax
+ xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0),
+ &(instr->src_operand.operand),
+ &(instr->src_operand.size));
+ instr->src_operand.type = REG_OPERAND;
- if (instr->prefixes.rep == 1) {
- addr_t reg_addr = 0;
- uint_t reg_length = 0;
+ if (instr->prefixes.rep == 1) {
+ addr_t reg_addr = 0;
+ uint_t reg_length = 0;
+
+ xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), ®_addr, ®_length);
+ instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
+ } else {
+ instr->str_op_length = 1;
+ }
- xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), ®_addr, ®_length);
- instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
} else {
- instr->str_op_length = 1;
+ PrintError("Unhandled String OP\n");
+ return -1;
}
- } else {
- PrintError("Unhandled String OP\n");
- return -1;
- }
-
- return 0;
+ return 0;
}
int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
- xed_decoded_inst_t xed_instr;
- xed_error_enum_t xed_error;
+ xed_decoded_inst_t xed_instr;
+ xed_error_enum_t xed_error;
- v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
+ v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
- if (set_decoder_mode(info, info->decoder_state) == -1) {
- PrintError("Could not set decoder mode\n");
- return -1;
- }
+ if (set_decoder_mode(info, info->decoder_state) == -1) {
+ PrintError("Could not set decoder mode\n");
+ return -1;
+ }
- xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
+ xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
- xed_error = xed_decode(&xed_instr,
- REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
- XED_MAX_INSTRUCTION_BYTES);
+ xed_error = xed_decode(&xed_instr,
+ REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
+ XED_MAX_INSTRUCTION_BYTES);
- if (xed_error != XED_ERROR_NONE) {
- PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
- return -1;
- }
+ if (xed_error != XED_ERROR_NONE) {
+ PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
+ return -1;
+ }
- const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
+ const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
- instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
+ instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
- xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
+ xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
#ifdef DEBUG_XED
- xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
+ xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
- PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
+ PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
#endif
- if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
- PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
- return -1;
- }
-
-
- // We special case the string operations...
- if (xed_decoded_inst_get_category(&xed_instr) == XED_CATEGORY_STRINGOP) {
- instr->is_str_op = 1;
- return decode_string_op(info, &xed_instr, xi, instr);
- } else {
- instr->is_str_op = 0;
- instr->str_op_length = 0;
- }
-
-
- instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
-
- if (instr->num_operands > 3) {
- PrintDebug("Special Case Not Handled\n");
- return -1;
- // special case
- } else if (instr->num_operands == 3) {
- const xed_operand_t * op = xed_inst_operand(xi, 2);
- xed_operand_enum_t op_enum = xed_operand_name(op);
-
- if ((!xed_operand_is_register(op_enum)) ||
- (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
- // special case
- PrintError("Special Case not handled\n");
- return -1;
+ if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
+ PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
+ return -1;
}
- }
-
-
-
- //PrintDebug("Number of operands: %d\n", instr->num_operands);
- //PrintDebug("INSTR length: %d\n", instr->instr_length);
- // set first operand
- if (instr->num_operands >= 1) {
- const xed_operand_t * op = xed_inst_operand(xi, 0);
- xed_operand_enum_t op_enum = xed_operand_name(op);
- struct x86_operand * v3_op = NULL;
-
- /*
- if (xed_operand_written(op)) {
- v3_op = &(instr->dst_operand);
- } else {
- v3_op = &(instr->src_operand);
- }
- */
+ // We special case the string operations...
+ if (xed_decoded_inst_get_category(&xed_instr) == XED_CATEGORY_STRINGOP) {
+ instr->is_str_op = 1;
+ return decode_string_op(info, &xed_instr, xi, instr);
+ } else {
+ instr->is_str_op = 0;
+ instr->str_op_length = 0;
+ }
- v3_op = &(instr->dst_operand);
- if (xed_operand_is_register(op_enum)) {
- xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
- int v3_reg_type = xed_reg_to_v3_reg(info,
- xed_reg,
- &(v3_op->operand),
- &(v3_op->size));
+ instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
- if (v3_reg_type == -1) {
- PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
- v3_op->type = INVALID_OPERAND;
+ if (instr->num_operands > 3) {
+ PrintDebug("Special Case Not Handled\n");
return -1;
- } else if (v3_reg_type == SEGMENT_REGISTER) {
- struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
- v3_op->operand = (addr_t)&(seg_reg->selector);
- }
-
- v3_op->type = REG_OPERAND;
- } else {
-
- switch (op_enum) {
-
- case XED_OPERAND_MEM0:
- {
- PrintDebug("Memory operand (1)\n");
- if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
- PrintError("Could not get first memory operand\n");
+ // special case
+ } else if (instr->num_operands == 3) {
+ const xed_operand_t * op = xed_inst_operand(xi, 2);
+ xed_operand_enum_t op_enum = xed_operand_name(op);
+
+ if ((!xed_operand_is_register(op_enum)) ||
+ (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
+ // special case
+ PrintError("Special Case not handled\n");
return -1;
- }
}
- break;
+ }
- case XED_OPERAND_MEM1:
- case XED_OPERAND_IMM1:
- // illegal
- PrintError("Illegal Operand Order\n");
- return -1;
- case XED_OPERAND_IMM0:
- case XED_OPERAND_AGEN:
- case XED_OPERAND_PTR:
- case XED_OPERAND_RELBR:
- default:
- PrintError("Unhandled Operand Type\n");
- return -1;
+ //PrintDebug("Number of operands: %d\n", instr->num_operands);
+ //PrintDebug("INSTR length: %d\n", instr->instr_length);
+
+ // set first operand
+ if (instr->num_operands >= 1) {
+ const xed_operand_t * op = xed_inst_operand(xi, 0);
+ xed_operand_enum_t op_enum = xed_operand_name(op);
+ struct x86_operand * v3_op = NULL;
- }
+ /*
+ if (xed_operand_written(op)) {
+ v3_op = &(instr->dst_operand);
+ } else {
+ v3_op = &(instr->src_operand);
+ }
+ */
+
+ v3_op = &(instr->dst_operand);
+
+ if (xed_operand_is_register(op_enum)) {
+ xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
+ int v3_reg_type = xed_reg_to_v3_reg(info,
+ xed_reg,
+ &(v3_op->operand),
+ &(v3_op->size));
+
+ if (v3_reg_type == -1) {
+ PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
+ v3_op->type = INVALID_OPERAND;
+ return -1;
+ } else if (v3_reg_type == SEGMENT_REGISTER) {
+ struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
+ v3_op->operand = (addr_t)&(seg_reg->selector);
+ }
+
+ v3_op->type = REG_OPERAND;
+ } else {
+
+ switch (op_enum) {
+
+ case XED_OPERAND_MEM0:
+ {
+ PrintDebug("Memory operand (1)\n");
+ if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
+ PrintError("Could not get first memory operand\n");
+ return -1;
+ }
+ }
+ break;
+
+ case XED_OPERAND_MEM1:
+ case XED_OPERAND_IMM1:
+ // illegal
+ PrintError("Illegal Operand Order\n");
+ return -1;
+
+
+ case XED_OPERAND_IMM0:
+ case XED_OPERAND_AGEN:
+ case XED_OPERAND_PTR:
+ case XED_OPERAND_RELBR:
+ default:
+ PrintError("Unhandled Operand Type\n");
+ return -1;
+
+
+ }
+ }
}
- }
- // set second operand
- if (instr->num_operands >= 2) {
- const xed_operand_t * op = xed_inst_operand(xi, 1);
- // xed_operand_type_enum_t op_type = xed_operand_type(op);
- xed_operand_enum_t op_enum = xed_operand_name(op);
+ // set second operand
+ if (instr->num_operands >= 2) {
+ const xed_operand_t * op = xed_inst_operand(xi, 1);
+ // xed_operand_type_enum_t op_type = xed_operand_type(op);
+ xed_operand_enum_t op_enum = xed_operand_name(op);
- struct x86_operand * v3_op;
-
- /*
- if (xed_operand_written(op)) {
- v3_op = &(instr->dst_operand);
- } else {
- v3_op = &(instr->src_operand);
- }
- */
- v3_op = &(instr->src_operand);
-
- if (xed_operand_is_register(op_enum)) {
- xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
- int v3_reg_type = xed_reg_to_v3_reg(info,
- xed_reg,
- &(v3_op->operand),
- &(v3_op->size));
- if (v3_reg_type == -1) {
- PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
- v3_op->type = INVALID_OPERAND;
- return -1;
- } else if (v3_reg_type == SEGMENT_REGISTER) {
- struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
- v3_op->operand = (addr_t)&(seg_reg->selector);
- }
+ struct x86_operand * v3_op;
- v3_op->type = REG_OPERAND;
+ /*
+ if (xed_operand_written(op)) {
+ v3_op = &(instr->dst_operand);
+ } else {
+ v3_op = &(instr->src_operand);
+ }
+ */
+ v3_op = &(instr->src_operand);
+
+ if (xed_operand_is_register(op_enum)) {
+ xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
+ int v3_reg_type = xed_reg_to_v3_reg(info,
+ xed_reg,
+ &(v3_op->operand),
+ &(v3_op->size));
+ if (v3_reg_type == -1) {
+ PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
+ v3_op->type = INVALID_OPERAND;
+ return -1;
+ } else if (v3_reg_type == SEGMENT_REGISTER) {
+ struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
+ v3_op->operand = (addr_t)&(seg_reg->selector);
+ }
+
+ v3_op->type = REG_OPERAND;
- } else {
+ } else {
- switch (op_enum) {
+ switch (op_enum) {
- case XED_OPERAND_MEM0:
- {
- PrintDebug("Memory operand (2)\n");
- if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
- PrintError("Could not get first memory operand\n");
- return -1;
- }
- }
- break;
+ case XED_OPERAND_MEM0:
+ {
+ PrintDebug("Memory operand (2)\n");
+ if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
+ PrintError("Could not get first memory operand\n");
+ return -1;
+ }
+ }
+ break;
- case XED_OPERAND_IMM0:
- {
- instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
+ case XED_OPERAND_IMM0:
+ {
+ instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
- if (instr->src_operand.size > 4) {
- PrintError("Unhandled 64 bit immediates\n");
- return -1;
- }
- instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
+ if (instr->src_operand.size > 4) {
+ PrintError("Unhandled 64 bit immediates\n");
+ return -1;
+ }
+ instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
- instr->src_operand.type = IMM_OPERAND;
+ instr->src_operand.type = IMM_OPERAND;
- }
- break;
+ }
+ break;
- case XED_OPERAND_MEM1:
- case XED_OPERAND_IMM1:
- // illegal
- PrintError("Illegal Operand Order\n");
- return -1;
+ case XED_OPERAND_MEM1:
+ case XED_OPERAND_IMM1:
+ // illegal
+ PrintError("Illegal Operand Order\n");
+ return -1;
- case XED_OPERAND_AGEN:
- case XED_OPERAND_PTR:
- case XED_OPERAND_RELBR:
- default:
- PrintError("Unhandled Operand Type\n");
- return -1;
- }
+ case XED_OPERAND_AGEN:
+ case XED_OPERAND_PTR:
+ case XED_OPERAND_RELBR:
+ default:
+ PrintError("Unhandled Operand Type\n");
+ return -1;
+ }
+ }
+
}
- }
+ // set third operand
+ if (instr->num_operands >= 3) {
+ const xed_operand_t * op = xed_inst_operand(xi, 2);
+ xed_operand_type_enum_t op_type = xed_operand_type(op);
+ xed_operand_enum_t op_enum = xed_operand_name(op);
- // set third operand
- if (instr->num_operands >= 3) {
- const xed_operand_t * op = xed_inst_operand(xi, 2);
- xed_operand_type_enum_t op_type = xed_operand_type(op);
- xed_operand_enum_t op_enum = xed_operand_name(op);
+ if (xed_operand_is_register(op_enum)) {
+ xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
+ int v3_reg_type = xed_reg_to_v3_reg(info,
+ xed_reg,
+ &(instr->third_operand.operand),
+ &(instr->third_operand.size));
- if (xed_operand_is_register(op_enum)) {
- xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
- int v3_reg_type = xed_reg_to_v3_reg(info,
- xed_reg,
- &(instr->third_operand.operand),
- &(instr->third_operand.size));
+ if (v3_reg_type == -1) {
+ PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
+ instr->third_operand.type = INVALID_OPERAND;
+ return -1;
+ } else if (v3_reg_type == SEGMENT_REGISTER) {
+ struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
+ instr->third_operand.operand = (addr_t)&(seg_reg->selector);
+ }
- if (v3_reg_type == -1) {
- PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
- instr->third_operand.type = INVALID_OPERAND;
- return -1;
- } else if (v3_reg_type == SEGMENT_REGISTER) {
- struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
- instr->third_operand.operand = (addr_t)&(seg_reg->selector);
- }
+ instr->third_operand.type = REG_OPERAND;
- instr->third_operand.type = REG_OPERAND;
-
- } else {
- PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
- return -1;
- }
+ } else {
+ PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
+ return -1;
+ }
- }
+ }
int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
- return -1;
+ return -1;
}
static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
- struct memory_operand mem_op;
-
- addr_t seg;
- addr_t base;
- addr_t scale;
- addr_t index;
- ullong_t displacement;
- int addr_width = v3_get_addr_width(info);;
- // struct v3_segment * seg_reg;
-
- PrintDebug("Xen mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
- PrintDebug("Address width: %s\n",
- xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
- PrintDebug("Stack Address width: %s\n",
- xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
+ struct memory_operand mem_op;
+
+ addr_t seg;
+ addr_t base;
+ addr_t scale;
+ addr_t index;
+ ullong_t displacement;
+ int addr_width = v3_get_addr_width(info);;
+ // struct v3_segment * seg_reg;
+
+ PrintDebug("Xen mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
+ PrintDebug("Address width: %s\n",
+ xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
+ PrintDebug("Stack Address width: %s\n",
+ xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
- memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
+ memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
- xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
- if (xed_seg != XED_REG_INVALID) {
- struct v3_segment *tmp_segment;
- if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
- PrintError("Unhandled Segment Register\n");
- return -1;
+ xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
+ if (xed_seg != XED_REG_INVALID) {
+ struct v3_segment *tmp_segment;
+ if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
+ PrintError("Unhandled Segment Register\n");
+ return -1;
+ }
+ mem_op.segment = tmp_segment->base;
}
- mem_op.segment = tmp_segment->base;
- }
-
- xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
- if (xed_base != XED_REG_INVALID) {
- addr_t base_reg;
- if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
- PrintError("Unhandled Base register\n");
- return -1;
+
+ xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
+ if (xed_base != XED_REG_INVALID) {
+ addr_t base_reg;
+ if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
+ PrintError("Unhandled Base register\n");
+ return -1;
+ }
+ mem_op.base = *(addr_t *)base_reg;
}
- mem_op.base = *(addr_t *)base_reg;
- }
- xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
- if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
- addr_t index_reg;
+ xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
+ if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
+ addr_t index_reg;
- if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
- PrintError("Unhandled Index Register\n");
- return -1;
- }
+ if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
+ PrintError("Unhandled Index Register\n");
+ return -1;
+ }
- mem_op.index= *(addr_t *)index_reg;
+ mem_op.index= *(addr_t *)index_reg;
- xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
- if (xed_scale != 0) {
- mem_op.scale = xed_scale;
+ xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
+ if (xed_scale != 0) {
+ mem_op.scale = xed_scale;
+ }
}
- }
- xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
- if (disp_bits) {
- xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
+ xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
+ if (disp_bits) {
+ xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
- mem_op.displacement_size = disp_bits;
- mem_op.displacement = xed_disp;
- }
+ mem_op.displacement_size = disp_bits;
+ mem_op.displacement = xed_disp;
+ }
- operand->type = MEM_OPERAND;
- operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
+ operand->type = MEM_OPERAND;
+ operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
- PrintDebug("Struct: Seg=%p (size=%d), base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n",
- (void *)mem_op.segment, mem_op.segment_size, (void*)mem_op.base, (void *)mem_op.index,
- (void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
+ PrintDebug("Struct: Seg=%p (size=%d), base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n",
+ (void *)mem_op.segment, mem_op.segment_size, (void*)mem_op.base, (void *)mem_op.index,
+ (void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
- PrintDebug("operand size: %d\n", operand->size);
+ PrintDebug("operand size: %d\n", operand->size);
- seg = MASK(mem_op.segment, mem_op.segment_size);
- base = MASK(mem_op.base, mem_op.base_size);
- index = MASK(mem_op.index, mem_op.index_size);
- scale = mem_op.scale;
+ seg = MASK(mem_op.segment, mem_op.segment_size);
+ base = MASK(mem_op.base, mem_op.base_size);
+ index = MASK(mem_op.index, mem_op.index_size);
+ scale = mem_op.scale;
- // 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);
- }
+ // 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);
+ PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n",
+ (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
- operand->operand = MASK((seg + base + (scale * index) + displacement), addr_width);
+ operand->operand = MASK((seg + base + (scale * index) + displacement), addr_width);
- return 0;
+ return 0;
}
static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len) {
- PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
+ PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
- switch (xed_reg) {
- case XED_REG_INVALID:
- *v3_reg = 0;
- *reg_len = 0;
- return -1;
+ switch (xed_reg) {
+ case XED_REG_INVALID:
+ *v3_reg = 0;
+ *reg_len = 0;
+ return -1;
- /*
- * GPRs
- */
- case XED_REG_RAX:
- *v3_reg = (addr_t)&(info->vm_regs.rax);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_EAX:
- *v3_reg = (addr_t)&(info->vm_regs.rax);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_AX:
- *v3_reg = (addr_t)&(info->vm_regs.rax);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_AH:
- *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
- *reg_len = 1;
- return GPR_REGISTER;
- case XED_REG_AL:
- *v3_reg = (addr_t)&(info->vm_regs.rax);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_RCX:
- *v3_reg = (addr_t)&(info->vm_regs.rcx);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_ECX:
- *v3_reg = (addr_t)&(info->vm_regs.rcx);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_CX:
- *v3_reg = (addr_t)&(info->vm_regs.rcx);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_CH:
- *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
- *reg_len = 1;
- return GPR_REGISTER;
- case XED_REG_CL:
- *v3_reg = (addr_t)&(info->vm_regs.rcx);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_RDX:
- *v3_reg = (addr_t)&(info->vm_regs.rdx);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_EDX:
- *v3_reg = (addr_t)&(info->vm_regs.rdx);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_DX:
- *v3_reg = (addr_t)&(info->vm_regs.rdx);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_DH:
- *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
- *reg_len = 1;
- return GPR_REGISTER;
- case XED_REG_DL:
- *v3_reg = (addr_t)&(info->vm_regs.rdx);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_RBX:
- *v3_reg = (addr_t)&(info->vm_regs.rbx);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_EBX:
- *v3_reg = (addr_t)&(info->vm_regs.rbx);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_BX:
- *v3_reg = (addr_t)&(info->vm_regs.rbx);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_BH:
- *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
- *reg_len = 1;
- return GPR_REGISTER;
- case XED_REG_BL:
- *v3_reg = (addr_t)&(info->vm_regs.rbx);
- *reg_len = 1;
- return GPR_REGISTER;
-
-
- case XED_REG_RSP:
- *v3_reg = (addr_t)&(info->vm_regs.rsp);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_ESP:
- *v3_reg = (addr_t)&(info->vm_regs.rsp);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_SP:
- *v3_reg = (addr_t)&(info->vm_regs.rsp);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_SPL:
- *v3_reg = (addr_t)&(info->vm_regs.rsp);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_RBP:
- *v3_reg = (addr_t)&(info->vm_regs.rbp);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_EBP:
- *v3_reg = (addr_t)&(info->vm_regs.rbp);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_BP:
- *v3_reg = (addr_t)&(info->vm_regs.rbp);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_BPL:
- *v3_reg = (addr_t)&(info->vm_regs.rbp);
- *reg_len = 1;
- return GPR_REGISTER;
-
-
-
- case XED_REG_RSI:
- *v3_reg = (addr_t)&(info->vm_regs.rsi);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_ESI:
- *v3_reg = (addr_t)&(info->vm_regs.rsi);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_SI:
- *v3_reg = (addr_t)&(info->vm_regs.rsi);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_SIL:
- *v3_reg = (addr_t)&(info->vm_regs.rsi);
- *reg_len = 1;
- return GPR_REGISTER;
-
-
- case XED_REG_RDI:
- *v3_reg = (addr_t)&(info->vm_regs.rdi);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_EDI:
- *v3_reg = (addr_t)&(info->vm_regs.rdi);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_DI:
- *v3_reg = (addr_t)&(info->vm_regs.rdi);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_DIL:
- *v3_reg = (addr_t)&(info->vm_regs.rdi);
- *reg_len = 1;
- return GPR_REGISTER;
-
-
-
-
-
- case XED_REG_R8:
- *v3_reg = (addr_t)&(info->vm_regs.r8);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_R8D:
- *v3_reg = (addr_t)&(info->vm_regs.r8);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_R8W:
- *v3_reg = (addr_t)&(info->vm_regs.r8);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_R8B:
- *v3_reg = (addr_t)&(info->vm_regs.r8);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_R9:
- *v3_reg = (addr_t)&(info->vm_regs.r9);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_R9D:
- *v3_reg = (addr_t)&(info->vm_regs.r9);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_R9W:
- *v3_reg = (addr_t)&(info->vm_regs.r9);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_R9B:
- *v3_reg = (addr_t)&(info->vm_regs.r9);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_R10:
- *v3_reg = (addr_t)&(info->vm_regs.r10);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_R10D:
- *v3_reg = (addr_t)&(info->vm_regs.r10);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_R10W:
- *v3_reg = (addr_t)&(info->vm_regs.r10);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_R10B:
- *v3_reg = (addr_t)&(info->vm_regs.r10);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_R11:
- *v3_reg = (addr_t)&(info->vm_regs.r11);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_R11D:
- *v3_reg = (addr_t)&(info->vm_regs.r11);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_R11W:
- *v3_reg = (addr_t)&(info->vm_regs.r11);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_R11B:
- *v3_reg = (addr_t)&(info->vm_regs.r11);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_R12:
- *v3_reg = (addr_t)&(info->vm_regs.r12);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_R12D:
- *v3_reg = (addr_t)&(info->vm_regs.r12);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_R12W:
- *v3_reg = (addr_t)&(info->vm_regs.r12);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_R12B:
- *v3_reg = (addr_t)&(info->vm_regs.r12);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_R13:
- *v3_reg = (addr_t)&(info->vm_regs.r13);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_R13D:
- *v3_reg = (addr_t)&(info->vm_regs.r13);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_R13W:
- *v3_reg = (addr_t)&(info->vm_regs.r13);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_R13B:
- *v3_reg = (addr_t)&(info->vm_regs.r13);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_R14:
- *v3_reg = (addr_t)&(info->vm_regs.r14);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_R14D:
- *v3_reg = (addr_t)&(info->vm_regs.r14);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_R14W:
- *v3_reg = (addr_t)&(info->vm_regs.r14);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_R14B:
- *v3_reg = (addr_t)&(info->vm_regs.r14);
- *reg_len = 1;
- return GPR_REGISTER;
-
- case XED_REG_R15:
- *v3_reg = (addr_t)&(info->vm_regs.r15);
- *reg_len = 8;
- return GPR_REGISTER;
- case XED_REG_R15D:
- *v3_reg = (addr_t)&(info->vm_regs.r15);
- *reg_len = 4;
- return GPR_REGISTER;
- case XED_REG_R15W:
- *v3_reg = (addr_t)&(info->vm_regs.r15);
- *reg_len = 2;
- return GPR_REGISTER;
- case XED_REG_R15B:
- *v3_reg = (addr_t)&(info->vm_regs.r15);
- *reg_len = 1;
- return GPR_REGISTER;
-
-
- /*
- * CTRL REGS
- */
- case XED_REG_RIP:
- *v3_reg = (addr_t)&(info->rip);
- *reg_len = 8;
- return CTRL_REGISTER;
- case XED_REG_EIP:
- *v3_reg = (addr_t)&(info->rip);
- *reg_len = 4;
- return CTRL_REGISTER;
- case XED_REG_IP:
- *v3_reg = (addr_t)&(info->rip);
- *reg_len = 2;
- return CTRL_REGISTER;
-
- case XED_REG_FLAGS:
- *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
- *reg_len = 2;
- return CTRL_REGISTER;
- case XED_REG_EFLAGS:
- *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
- *reg_len = 4;
- return CTRL_REGISTER;
- case XED_REG_RFLAGS:
- *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
- *reg_len = 8;
- return CTRL_REGISTER;
-
- case XED_REG_CR0:
- *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
- *reg_len = 4;
- return CTRL_REGISTER;
- case XED_REG_CR2:
- *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
- *reg_len = 4;
- return CTRL_REGISTER;
- case XED_REG_CR3:
- *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
- *reg_len = 4;
- return CTRL_REGISTER;
- case XED_REG_CR4:
- *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
- *reg_len = 4;
- return CTRL_REGISTER;
- case XED_REG_CR8:
- *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
- *reg_len = 4;
- return CTRL_REGISTER;
-
- case XED_REG_CR1:
- case XED_REG_CR5:
- case XED_REG_CR6:
- case XED_REG_CR7:
- case XED_REG_CR9:
- case XED_REG_CR10:
- case XED_REG_CR11:
- case XED_REG_CR12:
- case XED_REG_CR13:
- case XED_REG_CR14:
- case XED_REG_CR15:
- return -1;
+ /*
+ * GPRs
+ */
+ case XED_REG_RAX:
+ *v3_reg = (addr_t)&(info->vm_regs.rax);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_EAX:
+ *v3_reg = (addr_t)&(info->vm_regs.rax);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_AX:
+ *v3_reg = (addr_t)&(info->vm_regs.rax);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_AH:
+ *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
+ *reg_len = 1;
+ return GPR_REGISTER;
+ case XED_REG_AL:
+ *v3_reg = (addr_t)&(info->vm_regs.rax);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_RCX:
+ *v3_reg = (addr_t)&(info->vm_regs.rcx);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_ECX:
+ *v3_reg = (addr_t)&(info->vm_regs.rcx);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_CX:
+ *v3_reg = (addr_t)&(info->vm_regs.rcx);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_CH:
+ *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
+ *reg_len = 1;
+ return GPR_REGISTER;
+ case XED_REG_CL:
+ *v3_reg = (addr_t)&(info->vm_regs.rcx);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_RDX:
+ *v3_reg = (addr_t)&(info->vm_regs.rdx);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_EDX:
+ *v3_reg = (addr_t)&(info->vm_regs.rdx);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_DX:
+ *v3_reg = (addr_t)&(info->vm_regs.rdx);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_DH:
+ *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
+ *reg_len = 1;
+ return GPR_REGISTER;
+ case XED_REG_DL:
+ *v3_reg = (addr_t)&(info->vm_regs.rdx);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_RBX:
+ *v3_reg = (addr_t)&(info->vm_regs.rbx);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_EBX:
+ *v3_reg = (addr_t)&(info->vm_regs.rbx);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_BX:
+ *v3_reg = (addr_t)&(info->vm_regs.rbx);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_BH:
+ *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
+ *reg_len = 1;
+ return GPR_REGISTER;
+ case XED_REG_BL:
+ *v3_reg = (addr_t)&(info->vm_regs.rbx);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+
+ case XED_REG_RSP:
+ *v3_reg = (addr_t)&(info->vm_regs.rsp);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_ESP:
+ *v3_reg = (addr_t)&(info->vm_regs.rsp);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_SP:
+ *v3_reg = (addr_t)&(info->vm_regs.rsp);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_SPL:
+ *v3_reg = (addr_t)&(info->vm_regs.rsp);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_RBP:
+ *v3_reg = (addr_t)&(info->vm_regs.rbp);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_EBP:
+ *v3_reg = (addr_t)&(info->vm_regs.rbp);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_BP:
+ *v3_reg = (addr_t)&(info->vm_regs.rbp);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_BPL:
+ *v3_reg = (addr_t)&(info->vm_regs.rbp);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+
+
+ case XED_REG_RSI:
+ *v3_reg = (addr_t)&(info->vm_regs.rsi);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_ESI:
+ *v3_reg = (addr_t)&(info->vm_regs.rsi);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_SI:
+ *v3_reg = (addr_t)&(info->vm_regs.rsi);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_SIL:
+ *v3_reg = (addr_t)&(info->vm_regs.rsi);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+
+ case XED_REG_RDI:
+ *v3_reg = (addr_t)&(info->vm_regs.rdi);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_EDI:
+ *v3_reg = (addr_t)&(info->vm_regs.rdi);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_DI:
+ *v3_reg = (addr_t)&(info->vm_regs.rdi);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_DIL:
+ *v3_reg = (addr_t)&(info->vm_regs.rdi);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+
+
+
+
+ case XED_REG_R8:
+ *v3_reg = (addr_t)&(info->vm_regs.r8);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R8D:
+ *v3_reg = (addr_t)&(info->vm_regs.r8);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R8W:
+ *v3_reg = (addr_t)&(info->vm_regs.r8);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R8B:
+ *v3_reg = (addr_t)&(info->vm_regs.r8);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R9:
+ *v3_reg = (addr_t)&(info->vm_regs.r9);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R9D:
+ *v3_reg = (addr_t)&(info->vm_regs.r9);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R9W:
+ *v3_reg = (addr_t)&(info->vm_regs.r9);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R9B:
+ *v3_reg = (addr_t)&(info->vm_regs.r9);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R10:
+ *v3_reg = (addr_t)&(info->vm_regs.r10);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R10D:
+ *v3_reg = (addr_t)&(info->vm_regs.r10);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R10W:
+ *v3_reg = (addr_t)&(info->vm_regs.r10);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R10B:
+ *v3_reg = (addr_t)&(info->vm_regs.r10);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R11:
+ *v3_reg = (addr_t)&(info->vm_regs.r11);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R11D:
+ *v3_reg = (addr_t)&(info->vm_regs.r11);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R11W:
+ *v3_reg = (addr_t)&(info->vm_regs.r11);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R11B:
+ *v3_reg = (addr_t)&(info->vm_regs.r11);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R12:
+ *v3_reg = (addr_t)&(info->vm_regs.r12);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R12D:
+ *v3_reg = (addr_t)&(info->vm_regs.r12);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R12W:
+ *v3_reg = (addr_t)&(info->vm_regs.r12);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R12B:
+ *v3_reg = (addr_t)&(info->vm_regs.r12);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R13:
+ *v3_reg = (addr_t)&(info->vm_regs.r13);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R13D:
+ *v3_reg = (addr_t)&(info->vm_regs.r13);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R13W:
+ *v3_reg = (addr_t)&(info->vm_regs.r13);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R13B:
+ *v3_reg = (addr_t)&(info->vm_regs.r13);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R14:
+ *v3_reg = (addr_t)&(info->vm_regs.r14);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R14D:
+ *v3_reg = (addr_t)&(info->vm_regs.r14);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R14W:
+ *v3_reg = (addr_t)&(info->vm_regs.r14);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R14B:
+ *v3_reg = (addr_t)&(info->vm_regs.r14);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R15:
+ *v3_reg = (addr_t)&(info->vm_regs.r15);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R15D:
+ *v3_reg = (addr_t)&(info->vm_regs.r15);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R15W:
+ *v3_reg = (addr_t)&(info->vm_regs.r15);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R15B:
+ *v3_reg = (addr_t)&(info->vm_regs.r15);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+
+ /*
+ * CTRL REGS
+ */
+ case XED_REG_RIP:
+ *v3_reg = (addr_t)&(info->rip);
+ *reg_len = 8;
+ return CTRL_REGISTER;
+ case XED_REG_EIP:
+ *v3_reg = (addr_t)&(info->rip);
+ *reg_len = 4;
+ return CTRL_REGISTER;
+ case XED_REG_IP:
+ *v3_reg = (addr_t)&(info->rip);
+ *reg_len = 2;
+ return CTRL_REGISTER;
+
+ case XED_REG_FLAGS:
+ *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
+ *reg_len = 2;
+ return CTRL_REGISTER;
+ case XED_REG_EFLAGS:
+ *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
+ *reg_len = 4;
+ return CTRL_REGISTER;
+ case XED_REG_RFLAGS:
+ *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
+ *reg_len = 8;
+ return CTRL_REGISTER;
+
+ case XED_REG_CR0:
+ *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
+ *reg_len = 4;
+ return CTRL_REGISTER;
+ case XED_REG_CR2:
+ *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
+ *reg_len = 4;
+ return CTRL_REGISTER;
+ case XED_REG_CR3:
+ *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
+ *reg_len = 4;
+ return CTRL_REGISTER;
+ case XED_REG_CR4:
+ *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
+ *reg_len = 4;
+ return CTRL_REGISTER;
+ case XED_REG_CR8:
+ *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
+ *reg_len = 4;
+ return CTRL_REGISTER;
+
+ case XED_REG_CR1:
+ case XED_REG_CR5:
+ case XED_REG_CR6:
+ case XED_REG_CR7:
+ case XED_REG_CR9:
+ case XED_REG_CR10:
+ case XED_REG_CR11:
+ case XED_REG_CR12:
+ case XED_REG_CR13:
+ case XED_REG_CR14:
+ case XED_REG_CR15:
+ return -1;
- /*
- * SEGMENT REGS
- */
- case XED_REG_CS:
- *v3_reg = (addr_t)&(info->segments.cs);
- *reg_len = 8;
- return SEGMENT_REGISTER;
- case XED_REG_DS:
- *v3_reg = (addr_t)&(info->segments.ds);
- *reg_len = 8;
- return SEGMENT_REGISTER;
- case XED_REG_ES:
- *v3_reg = (addr_t)&(info->segments.es);
- *reg_len = 8;
- return SEGMENT_REGISTER;
- case XED_REG_SS:
- *v3_reg = (addr_t)&(info->segments.ss);
- *reg_len = 8;
- return SEGMENT_REGISTER;
- case XED_REG_FS:
- *v3_reg = (addr_t)&(info->segments.fs);
- *reg_len = 8;
- return SEGMENT_REGISTER;
- case XED_REG_GS:
- *v3_reg = (addr_t)&(info->segments.gs);
- *reg_len = 8;
- return SEGMENT_REGISTER;
-
-
- case XED_REG_GDTR:
- case XED_REG_LDTR:
- case XED_REG_IDTR:
- case XED_REG_TR:
- PrintError("Segment selector operand... Don't know how to handle this...\n");
- return -1;
+ /*
+ * SEGMENT REGS
+ */
+ case XED_REG_CS:
+ *v3_reg = (addr_t)&(info->segments.cs);
+ *reg_len = 8;
+ return SEGMENT_REGISTER;
+ case XED_REG_DS:
+ *v3_reg = (addr_t)&(info->segments.ds);
+ *reg_len = 8;
+ return SEGMENT_REGISTER;
+ case XED_REG_ES:
+ *v3_reg = (addr_t)&(info->segments.es);
+ *reg_len = 8;
+ return SEGMENT_REGISTER;
+ case XED_REG_SS:
+ *v3_reg = (addr_t)&(info->segments.ss);
+ *reg_len = 8;
+ return SEGMENT_REGISTER;
+ case XED_REG_FS:
+ *v3_reg = (addr_t)&(info->segments.fs);
+ *reg_len = 8;
+ return SEGMENT_REGISTER;
+ case XED_REG_GS:
+ *v3_reg = (addr_t)&(info->segments.gs);
+ *reg_len = 8;
+ return SEGMENT_REGISTER;
+
+
+ case XED_REG_GDTR:
+ case XED_REG_LDTR:
+ case XED_REG_IDTR:
+ case XED_REG_TR:
+ PrintError("Segment selector operand... Don't know how to handle this...\n");
+ return -1;
- /*
- * DEBUG REGS
- */
- case XED_REG_DR0:
- case XED_REG_DR1:
- case XED_REG_DR2:
- case XED_REG_DR3:
- case XED_REG_DR4:
- case XED_REG_DR5:
- case XED_REG_DR6:
- case XED_REG_DR7:
- case XED_REG_DR8:
- case XED_REG_DR9:
- case XED_REG_DR10:
- case XED_REG_DR11:
- case XED_REG_DR12:
- case XED_REG_DR13:
- case XED_REG_DR14:
- case XED_REG_DR15:
- return -1;
+ /*
+ * DEBUG REGS
+ */
+ case XED_REG_DR0:
+ case XED_REG_DR1:
+ case XED_REG_DR2:
+ case XED_REG_DR3:
+ case XED_REG_DR4:
+ case XED_REG_DR5:
+ case XED_REG_DR6:
+ case XED_REG_DR7:
+ case XED_REG_DR8:
+ case XED_REG_DR9:
+ case XED_REG_DR10:
+ case XED_REG_DR11:
+ case XED_REG_DR12:
+ case XED_REG_DR13:
+ case XED_REG_DR14:
+ case XED_REG_DR15:
+ return -1;
- case XED_REG_XMM0:
- case XED_REG_XMM1:
- case XED_REG_XMM2:
- case XED_REG_XMM3:
- case XED_REG_XMM4:
- case XED_REG_XMM5:
- case XED_REG_XMM6:
- case XED_REG_XMM7:
- case XED_REG_XMM8:
- case XED_REG_XMM9:
- case XED_REG_XMM10:
- case XED_REG_XMM11:
- case XED_REG_XMM12:
- case XED_REG_XMM13:
- case XED_REG_XMM14:
- case XED_REG_XMM15:
-
- case XED_REG_MMX0:
- case XED_REG_MMX1:
- case XED_REG_MMX2:
- case XED_REG_MMX3:
- case XED_REG_MMX4:
- case XED_REG_MMX5:
- case XED_REG_MMX6:
- case XED_REG_MMX7:
-
- case XED_REG_ST0:
- case XED_REG_ST1:
- case XED_REG_ST2:
- case XED_REG_ST3:
- case XED_REG_ST4:
- case XED_REG_ST5:
- case XED_REG_ST6:
- case XED_REG_ST7:
-
- case XED_REG_ONE:
- case XED_REG_STACKPUSH:
- case XED_REG_STACKPOP:
+ case XED_REG_XMM0:
+ case XED_REG_XMM1:
+ case XED_REG_XMM2:
+ case XED_REG_XMM3:
+ case XED_REG_XMM4:
+ case XED_REG_XMM5:
+ case XED_REG_XMM6:
+ case XED_REG_XMM7:
+ case XED_REG_XMM8:
+ case XED_REG_XMM9:
+ case XED_REG_XMM10:
+ case XED_REG_XMM11:
+ case XED_REG_XMM12:
+ case XED_REG_XMM13:
+ case XED_REG_XMM14:
+ case XED_REG_XMM15:
+
+ case XED_REG_MMX0:
+ case XED_REG_MMX1:
+ case XED_REG_MMX2:
+ case XED_REG_MMX3:
+ case XED_REG_MMX4:
+ case XED_REG_MMX5:
+ case XED_REG_MMX6:
+ case XED_REG_MMX7:
+
+ case XED_REG_ST0:
+ case XED_REG_ST1:
+ case XED_REG_ST2:
+ case XED_REG_ST3:
+ case XED_REG_ST4:
+ case XED_REG_ST5:
+ case XED_REG_ST6:
+ case XED_REG_ST7:
+
+ case XED_REG_ONE:
+ case XED_REG_STACKPUSH:
+ case XED_REG_STACKPOP:
- case XED_REG_TSC:
- case XED_REG_TSCAUX:
- case XED_REG_MSRS:
-
- case XED_REG_X87CONTROL:
- case XED_REG_X87STATUS:
- case XED_REG_X87TOP:
- case XED_REG_X87TAG:
- case XED_REG_X87PUSH:
- case XED_REG_X87POP:
- case XED_REG_X87POP2:
-
- case XED_REG_MXCSR:
-
- case XED_REG_TMP0:
- case XED_REG_TMP1:
- case XED_REG_TMP2:
- case XED_REG_TMP3:
- case XED_REG_TMP4:
- case XED_REG_TMP5:
- case XED_REG_TMP6:
- case XED_REG_TMP7:
- case XED_REG_TMP8:
- case XED_REG_TMP9:
- case XED_REG_TMP10:
- case XED_REG_TMP11:
- case XED_REG_TMP12:
- case XED_REG_TMP13:
- case XED_REG_TMP14:
- case XED_REG_TMP15:
-
- case XED_REG_LAST:
-
- case XED_REG_ERROR:
- // error??
- return -1;
+ case XED_REG_TSC:
+ case XED_REG_TSCAUX:
+ case XED_REG_MSRS:
+
+ case XED_REG_X87CONTROL:
+ case XED_REG_X87STATUS:
+ case XED_REG_X87TOP:
+ case XED_REG_X87TAG:
+ case XED_REG_X87PUSH:
+ case XED_REG_X87POP:
+ case XED_REG_X87POP2:
+
+ case XED_REG_MXCSR:
+
+ case XED_REG_TMP0:
+ case XED_REG_TMP1:
+ case XED_REG_TMP2:
+ case XED_REG_TMP3:
+ case XED_REG_TMP4:
+ case XED_REG_TMP5:
+ case XED_REG_TMP6:
+ case XED_REG_TMP7:
+ case XED_REG_TMP8:
+ case XED_REG_TMP9:
+ case XED_REG_TMP10:
+ case XED_REG_TMP11:
+ case XED_REG_TMP12:
+ case XED_REG_TMP13:
+ case XED_REG_TMP14:
+ case XED_REG_TMP15:
+
+ case XED_REG_LAST:
+
+ case XED_REG_ERROR:
+ // error??
+ return -1;
- }
+ }
- return 0;
+ return 0;
}
static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
- switch (iform) {
-
- /* Control Instructions */
-
- case XED_IFORM_MOV_CR_GPR64_CR:
- case XED_IFORM_MOV_CR_GPR32_CR:
- return V3_OP_MOVCR2;
-
- case XED_IFORM_MOV_CR_CR_GPR64:
- case XED_IFORM_MOV_CR_CR_GPR32:
- return V3_OP_MOV2CR;
-
- case XED_IFORM_SMSW_GPRv:
- return V3_OP_SMSW;
-
- case XED_IFORM_LMSW_GPR16:
- return V3_OP_LMSW;
-
- case XED_IFORM_CLTS:
- return V3_OP_CLTS;
-
- case XED_IFORM_INVLPG_MEMb:
- return V3_OP_INVLPG;
-
-
- /* Data Instructions */
-
- // Write
- case XED_IFORM_ADC_MEMv_GPRv:
- case XED_IFORM_ADC_MEMv_IMM:
- case XED_IFORM_ADC_MEMb_GPR8:
- case XED_IFORM_ADC_MEMb_IMM:
- // Read
- case XED_IFORM_ADC_GPRv_MEMv:
- case XED_IFORM_ADC_GPR8_MEMb:
- return V3_OP_ADC;
-
- // Write
- case XED_IFORM_ADD_MEMv_GPRv:
- case XED_IFORM_ADD_MEMb_IMM:
- case XED_IFORM_ADD_MEMb_GPR8:
- case XED_IFORM_ADD_MEMv_IMM:
- // Read
- case XED_IFORM_ADD_GPRv_MEMv:
- case XED_IFORM_ADD_GPR8_MEMb:
- return V3_OP_ADD;
-
- // Write
- case XED_IFORM_AND_MEMv_IMM:
- case XED_IFORM_AND_MEMb_GPR8:
- case XED_IFORM_AND_MEMv_GPRv:
- case XED_IFORM_AND_MEMb_IMM:
- // Read
- case XED_IFORM_AND_GPR8_MEMb:
- case XED_IFORM_AND_GPRv_MEMv:
- return V3_OP_AND;
-
- // Write
- case XED_IFORM_SUB_MEMv_IMM:
- case XED_IFORM_SUB_MEMb_GPR8:
- case XED_IFORM_SUB_MEMb_IMM:
- case XED_IFORM_SUB_MEMv_GPRv:
- // Read
- case XED_IFORM_SUB_GPR8_MEMb:
- case XED_IFORM_SUB_GPRv_MEMv:
- return V3_OP_SUB;
-
- // Write
- case XED_IFORM_MOV_MEMv_GPRv:
- case XED_IFORM_MOV_MEMb_GPR8:
- case XED_IFORM_MOV_MEMb_AL:
- case XED_IFORM_MOV_MEMv_IMM:
- case XED_IFORM_MOV_MEMb_IMM:
- // Read
- case XED_IFORM_MOV_GPRv_MEMv:
- case XED_IFORM_MOV_GPR8_MEMb:
- case XED_IFORM_MOV_AL_MEMb:
- return V3_OP_MOV;
-
-
- // Read
- case XED_IFORM_MOVZX_GPRv_MEMb:
- case XED_IFORM_MOVZX_GPRv_MEMw:
- return V3_OP_MOVZX;
-
- // Read
- case XED_IFORM_MOVSX_GPRv_MEMb:
- case XED_IFORM_MOVSX_GPRv_MEMw:
- return V3_OP_MOVSX;
-
-
-
- case XED_IFORM_DEC_MEMv:
- case XED_IFORM_DEC_MEMb:
- return V3_OP_DEC;
-
- case XED_IFORM_INC_MEMb:
- case XED_IFORM_INC_MEMv:
- return V3_OP_INC;
-
- // Write
- case XED_IFORM_OR_MEMv_IMM:
- case XED_IFORM_OR_MEMb_IMM:
- case XED_IFORM_OR_MEMv_GPRv:
- case XED_IFORM_OR_MEMb_GPR8:
- // Read
- case XED_IFORM_OR_GPRv_MEMv:
- case XED_IFORM_OR_GPR8_MEMb:
- return V3_OP_OR;
-
- // Write
- case XED_IFORM_XOR_MEMv_GPRv:
- case XED_IFORM_XOR_MEMb_IMM:
- case XED_IFORM_XOR_MEMb_GPR8:
- case XED_IFORM_XOR_MEMv_IMM:
- // Read
- case XED_IFORM_XOR_GPRv_MEMv:
- case XED_IFORM_XOR_GPR8_MEMb:
- return V3_OP_XOR;
-
- case XED_IFORM_NEG_MEMb:
- case XED_IFORM_NEG_MEMv:
- return V3_OP_NEG;
-
- case XED_IFORM_NOT_MEMv:
- case XED_IFORM_NOT_MEMb:
- return V3_OP_NOT;
-
- case XED_IFORM_XCHG_MEMv_GPRv:
- case XED_IFORM_XCHG_MEMb_GPR8:
- return V3_OP_XCHG;
-
- case XED_IFORM_SETB_MEMb:
- return V3_OP_SETB;
-
- case XED_IFORM_SETBE_MEMb:
- return V3_OP_SETBE;
-
- case XED_IFORM_SETL_MEMb:
- return V3_OP_SETL;
-
- case XED_IFORM_SETLE_MEMb:
- return V3_OP_SETLE;
-
- case XED_IFORM_SETNB_MEMb:
- return V3_OP_SETNB;
-
- case XED_IFORM_SETNBE_MEMb:
- return V3_OP_SETNBE;
-
- case XED_IFORM_SETNL_MEMb:
- return V3_OP_SETNL;
-
- case XED_IFORM_SETNLE_MEMb:
- return V3_OP_SETNLE;
-
- case XED_IFORM_SETNO_MEMb:
- return V3_OP_SETNO;
+ switch (iform) {
+
+ /* Control Instructions */
+
+ case XED_IFORM_MOV_CR_GPR64_CR:
+ case XED_IFORM_MOV_CR_GPR32_CR:
+ return V3_OP_MOVCR2;
+
+ case XED_IFORM_MOV_CR_CR_GPR64:
+ case XED_IFORM_MOV_CR_CR_GPR32:
+ return V3_OP_MOV2CR;
+
+ case XED_IFORM_SMSW_GPRv:
+ return V3_OP_SMSW;
+
+ case XED_IFORM_LMSW_GPR16:
+ return V3_OP_LMSW;
+
+ case XED_IFORM_CLTS:
+ return V3_OP_CLTS;
+
+ case XED_IFORM_INVLPG_MEMb:
+ return V3_OP_INVLPG;
+
+
+ /* Data Instructions */
+
+ // Write
+ case XED_IFORM_ADC_MEMv_GPRv:
+ case XED_IFORM_ADC_MEMv_IMM:
+ case XED_IFORM_ADC_MEMb_GPR8:
+ case XED_IFORM_ADC_MEMb_IMM:
+ // Read
+ case XED_IFORM_ADC_GPRv_MEMv:
+ case XED_IFORM_ADC_GPR8_MEMb:
+ return V3_OP_ADC;
+
+ // Write
+ case XED_IFORM_ADD_MEMv_GPRv:
+ case XED_IFORM_ADD_MEMb_IMM:
+ case XED_IFORM_ADD_MEMb_GPR8:
+ case XED_IFORM_ADD_MEMv_IMM:
+ // Read
+ case XED_IFORM_ADD_GPRv_MEMv:
+ case XED_IFORM_ADD_GPR8_MEMb:
+ return V3_OP_ADD;
+
+ // Write
+ case XED_IFORM_AND_MEMv_IMM:
+ case XED_IFORM_AND_MEMb_GPR8:
+ case XED_IFORM_AND_MEMv_GPRv:
+ case XED_IFORM_AND_MEMb_IMM:
+ // Read
+ case XED_IFORM_AND_GPR8_MEMb:
+ case XED_IFORM_AND_GPRv_MEMv:
+ return V3_OP_AND;
+
+ // Write
+ case XED_IFORM_SUB_MEMv_IMM:
+ case XED_IFORM_SUB_MEMb_GPR8:
+ case XED_IFORM_SUB_MEMb_IMM:
+ case XED_IFORM_SUB_MEMv_GPRv:
+ // Read
+ case XED_IFORM_SUB_GPR8_MEMb:
+ case XED_IFORM_SUB_GPRv_MEMv:
+ return V3_OP_SUB;
+
+ // Write
+ case XED_IFORM_MOV_MEMv_GPRv:
+ case XED_IFORM_MOV_MEMb_GPR8:
+ case XED_IFORM_MOV_MEMb_AL:
+ case XED_IFORM_MOV_MEMv_IMM:
+ case XED_IFORM_MOV_MEMb_IMM:
+ // Read
+ case XED_IFORM_MOV_GPRv_MEMv:
+ case XED_IFORM_MOV_GPR8_MEMb:
+ case XED_IFORM_MOV_AL_MEMb:
+ return V3_OP_MOV;
+
+
+ // Read
+ case XED_IFORM_MOVZX_GPRv_MEMb:
+ case XED_IFORM_MOVZX_GPRv_MEMw:
+ return V3_OP_MOVZX;
+
+ // Read
+ case XED_IFORM_MOVSX_GPRv_MEMb:
+ case XED_IFORM_MOVSX_GPRv_MEMw:
+ return V3_OP_MOVSX;
+
+
+
+ case XED_IFORM_DEC_MEMv:
+ case XED_IFORM_DEC_MEMb:
+ return V3_OP_DEC;
+
+ case XED_IFORM_INC_MEMb:
+ case XED_IFORM_INC_MEMv:
+ return V3_OP_INC;
+
+ // Write
+ case XED_IFORM_OR_MEMv_IMM:
+ case XED_IFORM_OR_MEMb_IMM:
+ case XED_IFORM_OR_MEMv_GPRv:
+ case XED_IFORM_OR_MEMb_GPR8:
+ // Read
+ case XED_IFORM_OR_GPRv_MEMv:
+ case XED_IFORM_OR_GPR8_MEMb:
+ return V3_OP_OR;
+
+ // Write
+ case XED_IFORM_XOR_MEMv_GPRv:
+ case XED_IFORM_XOR_MEMb_IMM:
+ case XED_IFORM_XOR_MEMb_GPR8:
+ case XED_IFORM_XOR_MEMv_IMM:
+ // Read
+ case XED_IFORM_XOR_GPRv_MEMv:
+ case XED_IFORM_XOR_GPR8_MEMb:
+ return V3_OP_XOR;
+
+ case XED_IFORM_NEG_MEMb:
+ case XED_IFORM_NEG_MEMv:
+ return V3_OP_NEG;
+
+ case XED_IFORM_NOT_MEMv:
+ case XED_IFORM_NOT_MEMb:
+ return V3_OP_NOT;
+
+ case XED_IFORM_XCHG_MEMv_GPRv:
+ case XED_IFORM_XCHG_MEMb_GPR8:
+ return V3_OP_XCHG;
+
+ case XED_IFORM_SETB_MEMb:
+ return V3_OP_SETB;
+
+ case XED_IFORM_SETBE_MEMb:
+ return V3_OP_SETBE;
+
+ case XED_IFORM_SETL_MEMb:
+ return V3_OP_SETL;
+
+ case XED_IFORM_SETLE_MEMb:
+ return V3_OP_SETLE;
+
+ case XED_IFORM_SETNB_MEMb:
+ return V3_OP_SETNB;
+
+ case XED_IFORM_SETNBE_MEMb:
+ return V3_OP_SETNBE;
+
+ case XED_IFORM_SETNL_MEMb:
+ return V3_OP_SETNL;
+
+ case XED_IFORM_SETNLE_MEMb:
+ return V3_OP_SETNLE;
+
+ case XED_IFORM_SETNO_MEMb:
+ return V3_OP_SETNO;
- case XED_IFORM_SETNP_MEMb:
- return V3_OP_SETNP;
+ case XED_IFORM_SETNP_MEMb:
+ return V3_OP_SETNP;
- case XED_IFORM_SETNS_MEMb:
- return V3_OP_SETNS;
+ case XED_IFORM_SETNS_MEMb:
+ return V3_OP_SETNS;
- case XED_IFORM_SETNZ_MEMb:
- return V3_OP_SETNZ;
+ case XED_IFORM_SETNZ_MEMb:
+ return V3_OP_SETNZ;
- case XED_IFORM_SETO_MEMb:
- return V3_OP_SETO;
+ case XED_IFORM_SETO_MEMb:
+ return V3_OP_SETO;
- case XED_IFORM_SETP_MEMb:
- return V3_OP_SETP;
+ case XED_IFORM_SETP_MEMb:
+ return V3_OP_SETP;
- case XED_IFORM_SETS_MEMb:
- return V3_OP_SETS;
+ case XED_IFORM_SETS_MEMb:
+ return V3_OP_SETS;
- case XED_IFORM_SETZ_MEMb:
- return V3_OP_SETZ;
+ case XED_IFORM_SETZ_MEMb:
+ return V3_OP_SETZ;
- case XED_IFORM_MOVSB:
- case XED_IFORM_MOVSW:
- case XED_IFORM_MOVSD:
- case XED_IFORM_MOVSQ:
- return V3_OP_MOVS;
+ case XED_IFORM_MOVSB:
+ case XED_IFORM_MOVSW:
+ case XED_IFORM_MOVSD:
+ case XED_IFORM_MOVSQ:
+ return V3_OP_MOVS;
- case XED_IFORM_STOSB:
- case XED_IFORM_STOSW:
- case XED_IFORM_STOSD:
- case XED_IFORM_STOSQ:
- return V3_OP_STOS;
+ case XED_IFORM_STOSB:
+ case XED_IFORM_STOSW:
+ case XED_IFORM_STOSD:
+ case XED_IFORM_STOSQ:
+ return V3_OP_STOS;
- default:
- return V3_INVALID_OP;
- }
+ default:
+ return V3_INVALID_OP;
+ }
}