From: Jack Lange Date: Tue, 3 Mar 2009 23:31:56 +0000 (-0600) Subject: reformatting of the source files X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=266af4b5b19da7bee8e7445288c7c1cb3ee194c7 reformatting of the source files --- diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index 674be35..fed5fae 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -18,9 +18,6 @@ */ - - - #include #include @@ -52,11 +49,11 @@ extern int v3_svm_launch(vmcb_t * vmcb, struct v3_gprs * vm_regs); 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; } @@ -64,302 +61,298 @@ static vmcb_t * Allocate_VMCB() { #include 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 @@ -370,118 +363,119 @@ static int start_svm_guest(struct guest_info *info) { #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; } @@ -491,154 +485,107 @@ static int start_svm_guest(struct guest_info *info) { /* 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; } diff --git a/palacios/src/palacios/svm_halt.c b/palacios/src/palacios/svm_halt.c index 5316edc..54e8a3d 100644 --- a/palacios/src/palacios/svm_halt.c +++ b/palacios/src/palacios/svm_halt.c @@ -40,36 +40,34 @@ 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; } diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index 5c85a56..b89d28c 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -37,453 +37,405 @@ 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; } @@ -634,293 +586,293 @@ static const char VMEXIT_INVALID_VMCB_STR[] = "VMEXIT_INVALID_VMCB"; 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; } diff --git a/palacios/src/palacios/svm_io.c b/palacios/src/palacios/svm_io.c index e43deb0..99f83a7 100644 --- a/palacios/src/palacios/svm_io.c +++ b/palacios/src/palacios/svm_io.c @@ -34,39 +34,39 @@ // 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; } @@ -77,176 +77,175 @@ int v3_handle_svm_io_in(struct guest_info * info) { * 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; } @@ -255,136 +254,134 @@ int v3_handle_svm_io_out(struct guest_info * info) { */ 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; } diff --git a/palacios/src/palacios/svm_msr.c b/palacios/src/palacios/svm_msr.c index bd16fb2..ee14a14 100644 --- a/palacios/src/palacios/svm_msr.c +++ b/palacios/src/palacios/svm_msr.c @@ -37,105 +37,105 @@ 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; } diff --git a/palacios/src/palacios/svm_pause.c b/palacios/src/palacios/svm_pause.c index c922ee3..b2197a4 100644 --- a/palacios/src/palacios/svm_pause.c +++ b/palacios/src/palacios/svm_pause.c @@ -24,12 +24,9 @@ #include -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; } diff --git a/palacios/src/palacios/svm_wbinvd.c b/palacios/src/palacios/svm_wbinvd.c index 9fe3dc3..c8c11e6 100644 --- a/palacios/src/palacios/svm_wbinvd.c +++ b/palacios/src/palacios/svm_wbinvd.c @@ -30,13 +30,13 @@ 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; } diff --git a/palacios/src/palacios/vm_dev.c b/palacios/src/palacios/vm_dev.c index 6257a98..ac034ca 100644 --- a/palacios/src/palacios/vm_dev.c +++ b/palacios/src/palacios/vm_dev.c @@ -25,40 +25,40 @@ 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); } diff --git a/palacios/src/palacios/vm_guest.c b/palacios/src/palacios/vm_guest.c index 5406e7a..87a1ae6 100644 --- a/palacios/src/palacios/vm_guest.c +++ b/palacios/src/palacios/vm_guest.c @@ -27,64 +27,64 @@ 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; + } } @@ -96,130 +96,130 @@ static const uchar_t LONG_32_COMPAT_STR[] = "32bit Compat"; 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]); + } } diff --git a/palacios/src/palacios/vm_guest_mem.c b/palacios/src/palacios/vm_guest_mem.c index b8db954..b17dd76 100644 --- a/palacios/src/palacios/vm_guest_mem.c +++ b/palacios/src/palacios/vm_guest_mem.c @@ -29,56 +29,56 @@ extern struct v3_os_hooks * os_hooks; /**********************************/ 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; } @@ -87,10 +87,10 @@ int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t // 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; } @@ -103,94 +103,94 @@ int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * /* !! 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; } @@ -201,9 +201,9 @@ int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * 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; } @@ -213,103 +213,103 @@ int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t 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; } @@ -321,32 +321,32 @@ int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * * 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; } @@ -358,33 +358,33 @@ int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int co * 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; } @@ -394,26 +394,26 @@ int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int co * 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; } diff --git a/palacios/src/palacios/vmcb.c b/palacios/src/palacios/vmcb.c index 7e3317f..379be02 100644 --- a/palacios/src/palacios/vmcb.c +++ b/palacios/src/palacios/vmcb.c @@ -24,391 +24,385 @@ 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); } diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 77c654e..7343cd5 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -32,37 +32,37 @@ struct v3_os_hooks * os_hooks = NULL; 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"); + } } diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index 32e3862..f5ca663 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -59,74 +59,74 @@ static struct vm_device * configure_generic(struct guest_info * info, struct v3 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; } @@ -135,110 +135,110 @@ int v3_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) * 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; } @@ -264,14 +264,14 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ 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); } @@ -288,13 +288,13 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ 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); @@ -311,130 +311,129 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ 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; } diff --git a/palacios/src/palacios/vmm_debug.c b/palacios/src/palacios/vmm_debug.c index 9865dd1..51f1c0f 100644 --- a/palacios/src/palacios/vmm_debug.c +++ b/palacios/src/palacios/vmm_debug.c @@ -21,39 +21,37 @@ #include -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"); + } } diff --git a/palacios/src/palacios/vmm_decoder.c b/palacios/src/palacios/vmm_decoder.c index 54c77c4..4b88e67 100644 --- a/palacios/src/palacios/vmm_decoder.c +++ b/palacios/src/palacios/vmm_decoder.c @@ -22,90 +22,90 @@ 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++; + } } - } } diff --git a/palacios/src/palacios/vmm_dev_mgr.c b/palacios/src/palacios/vmm_dev_mgr.c index e872ce7..61850bf 100644 --- a/palacios/src/palacios/vmm_dev_mgr.c +++ b/palacios/src/palacios/vmm_dev_mgr.c @@ -32,62 +32,62 @@ 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; } @@ -96,14 +96,14 @@ int v3_unattach_device(struct vm_device * dev) { /* 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; } @@ -115,55 +115,55 @@ int v3_dev_hook_io(struct vm_device *dev, 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); } @@ -190,30 +190,30 @@ static int dev_mgr_hook_mem(struct guest_info *vm, 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; } @@ -221,23 +221,23 @@ static int dev_mgr_hook_mem(struct guest_info *vm, 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 @@ -245,44 +245,26 @@ static int dev_mgr_unhook_mem(struct vm_device *dev, - - - - - - - - - - - - - - - - - - #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) { @@ -290,17 +272,17 @@ 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 diff --git a/palacios/src/palacios/vmm_direct_paging.c b/palacios/src/palacios/vmm_direct_paging.c index df873bc..3bbbbf9 100644 --- a/palacios/src/palacios/vmm_direct_paging.c +++ b/palacios/src/palacios/vmm_direct_paging.c @@ -25,11 +25,11 @@ #include 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 @@ -38,25 +38,25 @@ static addr_t create_generic_pt_page() { 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; } diff --git a/palacios/src/palacios/vmm_direct_paging_32.h b/palacios/src/palacios/vmm_direct_paging_32.h index abe55fe..4df18a9 100644 --- a/palacios/src/palacios/vmm_direct_paging_32.h +++ b/palacios/src/palacios/vmm_direct_paging_32.h @@ -32,72 +32,71 @@ 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; } diff --git a/palacios/src/palacios/vmm_direct_paging_32pae.h b/palacios/src/palacios/vmm_direct_paging_32pae.h index ff526ed..033c69d 100644 --- a/palacios/src/palacios/vmm_direct_paging_32pae.h +++ b/palacios/src/palacios/vmm_direct_paging_32pae.h @@ -31,86 +31,86 @@ 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; } diff --git a/palacios/src/palacios/vmm_emulator.c b/palacios/src/palacios/vmm_emulator.c index 6b1925e..e6adab1 100644 --- a/palacios/src/palacios/vmm_emulator.c +++ b/palacios/src/palacios/vmm_emulator.c @@ -39,103 +39,103 @@ static int emulate_string_write_op(struct guest_info * info, struct x86_instr * 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; } @@ -143,62 +143,62 @@ static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * de 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; } @@ -208,159 +208,159 @@ static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec 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; } @@ -368,85 +368,85 @@ int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gp 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; } @@ -456,270 +456,270 @@ int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gp 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; } diff --git a/palacios/src/palacios/vmm_hashtable.c b/palacios/src/palacios/vmm_hashtable.c index fa9aba3..fe74dc7 100644 --- a/palacios/src/palacios/vmm_hashtable.c +++ b/palacios/src/palacios/vmm_hashtable.c @@ -44,10 +44,10 @@ 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 { @@ -67,15 +67,15 @@ 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; } @@ -94,47 +94,47 @@ uint_t do_hash(struct hashtable * htable, addr_t key) { #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; } @@ -142,7 +142,7 @@ ulong_t hash_buffer(uchar_t * msg, uint_t length) { /*****************************************************************************/ /* 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 */ @@ -159,32 +159,32 @@ static inline uint_t indexFor(uint_t table_length, uint_t hash_value) { 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]); @@ -201,28 +201,28 @@ struct hashtable * create_hashtable(uint_t min_size, /* 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*/ } @@ -252,7 +252,7 @@ static int hashtable_expand(struct hashtable * htable) { /* 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)]; @@ -266,53 +266,53 @@ static int hashtable_expand(struct hashtable * htable) { 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; @@ -334,19 +334,19 @@ int hashtable_insert(struct hashtable * htable, addr_t key, addr_t value) { 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); @@ -380,12 +380,12 @@ int hashtable_change(struct hashtable * htable, addr_t key, addr_t value, int fr /* 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; } @@ -409,8 +409,8 @@ int hashtable_inc(struct hashtable * htable, addr_t key, addr_t value) { /* 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; } @@ -433,8 +433,8 @@ int hashtable_dec(struct hashtable * htable, addr_t key, addr_t value) { /* 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; } @@ -447,115 +447,115 @@ int hashtable_dec(struct hashtable * htable, addr_t key, addr_t value) { /*****************************************************************************/ /* 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); } @@ -566,89 +566,89 @@ void hashtable_destroy(struct hashtable * htable, int free_values, int free_keys 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; } @@ -659,68 +659,68 @@ int hashtable_iterator_advance(struct hashtable_iter * iter) { * 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; } @@ -768,4 +768,4 @@ int hashtable_iterator_search(struct hashtable_iter * iter, * 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. -*/ + */ diff --git a/palacios/src/palacios/vmm_host_events.c b/palacios/src/palacios/vmm_host_events.c index b9d122a..58ac6ea 100644 --- a/palacios/src/palacios/vmm_host_events.c +++ b/palacios/src/palacios/vmm_host_events.c @@ -22,13 +22,13 @@ 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; } @@ -37,74 +37,74 @@ int v3_hook_host_event(struct guest_info * info, 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; } diff --git a/palacios/src/palacios/vmm_hypercall.c b/palacios/src/palacios/vmm_hypercall.c index 3c570a3..f3169a7 100644 --- a/palacios/src/palacios/vmm_hypercall.c +++ b/palacios/src/palacios/vmm_hypercall.c @@ -22,75 +22,75 @@ 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; } @@ -98,30 +98,30 @@ int v3_register_hypercall(struct guest_info * info, uint_t hypercall_id, 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); } diff --git a/palacios/src/palacios/vmm_instrument.c b/palacios/src/palacios/vmm_instrument.c index a207455..f7478f7 100644 --- a/palacios/src/palacios/vmm_instrument.c +++ b/palacios/src/palacios/vmm_instrument.c @@ -32,10 +32,10 @@ static ullong_t last = 0; 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)); @@ -46,89 +46,89 @@ void __cyg_profile_func_enter(void * this, void * callsite) __attribute__((__n 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); + } } diff --git a/palacios/src/palacios/vmm_intr.c b/palacios/src/palacios/vmm_intr.c index 7ffd1a8..ac6b6ce 100644 --- a/palacios/src/palacios/vmm_intr.c +++ b/palacios/src/palacios/vmm_intr.c @@ -32,30 +32,30 @@ 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)); } @@ -63,8 +63,8 @@ void v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops 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]; } @@ -73,29 +73,29 @@ int v3_hook_irq(struct guest_info * info, 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; + } } @@ -103,24 +103,24 @@ int v3_hook_irq(struct guest_info * info, 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; + } } @@ -128,16 +128,16 @@ int v3_hook_passthrough_irq(struct guest_info * info, uint_t irq) 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); } @@ -148,129 +148,129 @@ int v3_deliver_irq(struct guest_info * info, struct v3_interrupt * intr) { 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; } @@ -279,23 +279,23 @@ intr_type_t v3_get_intr_type(struct guest_info * info) { 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; } diff --git a/palacios/src/palacios/vmm_mem.c b/palacios/src/palacios/vmm_mem.c index 0537006..38eb602 100644 --- a/palacios/src/palacios/vmm_mem.c +++ b/palacios/src/palacios/vmm_mem.c @@ -35,25 +35,25 @@ struct v3_shadow_region * insert_shadow_region(struct guest_info * info, 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); + } } @@ -64,22 +64,22 @@ int v3_add_shadow_mem( struct guest_info * info, 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; } @@ -89,23 +89,23 @@ int v3_hook_write_mem(struct guest_info * info, addr_t guest_addr_start, addr_t 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, @@ -113,22 +113,22 @@ int v3_hook_full_mem(struct guest_info * info, addr_t guest_addr_start, addr_t g 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; } @@ -137,41 +137,41 @@ int v3_hook_full_mem(struct guest_info * info, addr_t guest_addr_start, addr_t g 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; } @@ -185,125 +185,125 @@ int handle_special_page_fault(struct guest_info * info, 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))); } @@ -315,15 +315,15 @@ static const uchar_t SHDW_REGION_ALLOCATED_STR[] = "SHDW_REGION_ALLOCATED"; 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; + } } diff --git a/palacios/src/palacios/vmm_msr.c b/palacios/src/palacios/vmm_msr.c index 434fc9d..105bfe6 100644 --- a/palacios/src/palacios/vmm_msr.c +++ b/palacios/src/palacios/vmm_msr.c @@ -24,10 +24,10 @@ 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; } @@ -36,54 +36,54 @@ int v3_hook_msr(struct guest_info * info, uint_t msr, 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); + } } diff --git a/palacios/src/palacios/vmm_paging.c b/palacios/src/palacios/vmm_paging.c index b492d5b..dc7aa97 100644 --- a/palacios/src/palacios/vmm_paging.c +++ b/palacios/src/palacios/vmm_paging.c @@ -54,215 +54,215 @@ static pt_entry_type_t pte64_lookup(pte64_t * pt, addr_t addr, addr_t * entry); 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); } @@ -274,138 +274,138 @@ int v3_find_guest_pt_64_page(struct guest_info * info, v3_reg_t guest_cr3, page_ 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); } @@ -414,59 +414,59 @@ int v3_check_guest_pt_32(struct guest_info * info, v3_reg_t guest_cr3, addr_t va 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); } @@ -484,21 +484,21 @@ page_type_t v3_get_host_data_page_type_64(struct guest_info * info, v3_reg_t cr3 **/ 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; + } } @@ -506,17 +506,17 @@ static pt_entry_type_t pde32_lookup(pde32_t * pd, addr_t addr, addr_t * entry) { /* 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; + } } @@ -528,45 +528,45 @@ static pt_entry_type_t pte32_lookup(pte32_t * pt, addr_t addr, addr_t * entry) { * **/ 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; + } } @@ -577,77 +577,77 @@ static pt_entry_type_t pte32pae_lookup(pte32pae_t * pt, addr_t addr, addr_t * en * **/ 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; } @@ -656,13 +656,13 @@ static pt_access_status_t can_access_pt_entry(gen_pt_t * pt, pf_error_t access_t * 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); } @@ -670,41 +670,41 @@ pt_access_status_t inline v3_can_access_pte32(pte32_t * pte, addr_t addr, pf_err * 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); } @@ -712,463 +712,42 @@ pt_access_status_t inline v3_can_access_pte64(pte64_t * pte, addr_t addr, pf_err - - - - -/* 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; } @@ -1176,125 +755,125 @@ int v3_drill_host_pt_32(struct guest_info * info, v3_reg_t host_cr3, addr_t vadd 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; } @@ -1306,318 +885,318 @@ int v3_drill_host_pt_64(struct guest_info * info, v3_reg_t host_cr3, addr_t vadd 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; } @@ -1626,190 +1205,190 @@ int v3_drill_guest_pt_64(struct guest_info * info, v3_reg_t guest_cr3, addr_t va 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; } @@ -1818,199 +1397,199 @@ int v3_walk_guest_pt_32pae(struct guest_info * info, v3_reg_t guest_cr3, 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; } @@ -2020,162 +1599,162 @@ int v3_walk_host_pt_32(struct guest_info * info, v3_reg_t host_cr3, 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; } @@ -2196,34 +1775,34 @@ static const uchar_t PAGE_PT64_STR[] = "64 Bit PT"; 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; + } } diff --git a/palacios/src/palacios/vmm_paging_debug.h b/palacios/src/palacios/vmm_paging_debug.h index caaa549..f39ff4d 100644 --- a/palacios/src/palacios/vmm_paging_debug.h +++ b/palacios/src/palacios/vmm_paging_debug.h @@ -28,37 +28,37 @@ 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); } @@ -70,48 +70,48 @@ static void PrintPTE32(addr_t virtual_address, pte32_t * pte) 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); } @@ -123,71 +123,71 @@ static void PrintPTE32PAE(addr_t virtual_address, pte32pae_t * pte) 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); } @@ -198,132 +198,132 @@ static void PrintPTE64(addr_t virtual_address, pte64_t * pte) 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; } @@ -331,164 +331,164 @@ static int print_page_walk_cb(struct guest_info * info, page_type_t type, addr_t 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; + } } diff --git a/palacios/src/palacios/vmm_profiler.c b/palacios/src/palacios/vmm_profiler.c index 46a9e5e..f7bc878 100644 --- a/palacios/src/palacios/vmm_profiler.c +++ b/palacios/src/palacios/vmm_profiler.c @@ -24,129 +24,129 @@ 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))); } diff --git a/palacios/src/palacios/vmm_queue.c b/palacios/src/palacios/vmm_queue.c index e47b4bb..f0ed9a8 100644 --- a/palacios/src/palacios/vmm_queue.c +++ b/palacios/src/palacios/vmm_queue.c @@ -22,37 +22,37 @@ 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; } diff --git a/palacios/src/palacios/vmm_rbtree.c b/palacios/src/palacios/vmm_rbtree.c index 520e227..3b15bcf 100644 --- a/palacios/src/palacios/vmm_rbtree.c +++ b/palacios/src/palacios/vmm_rbtree.c @@ -25,267 +25,270 @@ 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); } @@ -294,98 +297,98 @@ void v3_rb_erase(struct rb_node *node, struct rb_root *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; } diff --git a/palacios/src/palacios/vmm_ringbuffer.c b/palacios/src/palacios/vmm_ringbuffer.c index 5df142b..af24280 100644 --- a/palacios/src/palacios/vmm_ringbuffer.c +++ b/palacios/src/palacios/vmm_ringbuffer.c @@ -24,194 +24,194 @@ 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]); + } } diff --git a/palacios/src/palacios/vmm_shadow_paging.c b/palacios/src/palacios/vmm_shadow_paging.c index 015bb84..8074c16 100644 --- a/palacios/src/palacios/vmm_shadow_paging.c +++ b/palacios/src/palacios/vmm_shadow_paging.c @@ -42,10 +42,10 @@ 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; }; @@ -56,11 +56,11 @@ DEFINE_HASHTABLE_SEARCH(find_pte_map, addr_t, addr_t); 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); @@ -75,17 +75,17 @@ static int is_guest_pf(pt_access_status_t guest_access, pt_access_status_t shado 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; } @@ -94,206 +94,206 @@ int v3_init_shadow_page_state(struct guest_info * info) { // 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; } diff --git a/palacios/src/palacios/vmm_shadow_paging_32.h b/palacios/src/palacios/vmm_shadow_paging_32.h index 50045e9..4e22011 100644 --- a/palacios/src/palacios/vmm_shadow_paging_32.h +++ b/palacios/src/palacios/vmm_shadow_paging_32.h @@ -19,50 +19,50 @@ 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; } @@ -71,31 +71,31 @@ static int cache_page_tables_32(struct guest_info * info, addr_t pde) { // 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; } /* @@ -106,7 +106,7 @@ static inline int activate_shadow_pt_32(struct guest_info * info) { * * */ 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, @@ -117,157 +117,157 @@ 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; } @@ -276,102 +276,102 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa * 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; } @@ -386,168 +386,168 @@ static int handle_shadow_pte32_fault(struct guest_info * info, 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; } diff --git a/palacios/src/palacios/vmm_shadow_paging_32pae.h b/palacios/src/palacios/vmm_shadow_paging_32pae.h index ce12b27..d6ef1c7 100644 --- a/palacios/src/palacios/vmm_shadow_paging_32pae.h +++ b/palacios/src/palacios/vmm_shadow_paging_32pae.h @@ -19,8 +19,8 @@ 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; } @@ -37,14 +37,14 @@ static inline int activate_shadow_pt_32pae(struct guest_info * info) { */ 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; } diff --git a/palacios/src/palacios/vmm_shadow_paging_64.h b/palacios/src/palacios/vmm_shadow_paging_64.h index a33d0ca..f0dcd31 100644 --- a/palacios/src/palacios/vmm_shadow_paging_64.h +++ b/palacios/src/palacios/vmm_shadow_paging_64.h @@ -19,24 +19,24 @@ 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; } @@ -66,99 +66,99 @@ static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t faul 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; } @@ -166,344 +166,344 @@ static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fa // 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; } @@ -512,109 +512,109 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info, 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; } @@ -624,79 +624,79 @@ static int invalidation_cb_64(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_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; } diff --git a/palacios/src/palacios/vmm_socket.c b/palacios/src/palacios/vmm_socket.c index acad8f3..0e61f83 100644 --- a/palacios/src/palacios/vmm_socket.c +++ b/palacios/src/palacios/vmm_socket.c @@ -27,12 +27,12 @@ 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; } diff --git a/palacios/src/palacios/vmm_string.c b/palacios/src/palacios/vmm_string.c index 7107782..77cee82 100644 --- a/palacios/src/palacios/vmm_string.c +++ b/palacios/src/palacios/vmm_string.c @@ -64,10 +64,10 @@ 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; } @@ -206,8 +206,8 @@ char *strncat(char *s1, const char *s2, size_t limit) t1 = s1; while (*s1) s1++; while (i < limit) { - if(*s2 == '\0') break; - *s1++ = *s2++; + if(*s2 == '\0') break; + *s1++ = *s2++; } *s1 = '\0'; return t1; @@ -270,9 +270,9 @@ int atoi(const char *buf) int ret = 0; while (*buf >= '0' && *buf <= '9') { - ret *= 10; - ret += *buf - '0'; - buf++; + ret *= 10; + ret += *buf - '0'; + buf++; } return ret; diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index 82a50eb..86eaa02 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -22,54 +22,54 @@ 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; } diff --git a/palacios/src/palacios/vmm_util.c b/palacios/src/palacios/vmm_util.c index 029f9fd..5d51666 100644 --- a/palacios/src/palacios/vmm_util.c +++ b/palacios/src/palacios/vmm_util.c @@ -26,42 +26,42 @@ extern struct v3_os_hooks * os_hooks; 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"); - } } diff --git a/palacios/src/palacios/vmm_xed.c b/palacios/src/palacios/vmm_xed.c index 1aef74a..35693fe 100644 --- a/palacios/src/palacios/vmm_xed.c +++ b/palacios/src/palacios/vmm_xed.c @@ -63,33 +63,34 @@ static const ullong_t mask_8 = 0xffffffffffffffffLL; #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; }; @@ -101,132 +102,132 @@ static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, a 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; } @@ -234,324 +235,324 @@ static int decode_string_op(struct guest_info * info, 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; + } - } + } @@ -561,7 +562,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) { - return -1; + return -1; } @@ -569,826 +570,826 @@ int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_b 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; + } }