pde32_t * v3_create_direct_passthrough_pts(struct guest_info * guest_info);
-int v3_handle_shadow_pagefault_physical_mode(struct guest_info * info, addr_t fault_addr, pf_error_t error_code);
+int v3_handle_passthrough_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code);
#endif // ! __V3VEE__
#include <palacios/vmm_msr.h>
#define BASE_ADDR_MSR 0x0000001B
+#define DEFAULT_BASE_ADDR 0xfee00000
+struct apic_base_addr_reg {
+ uchar_t rsvd;
+ uint_t bsc : 1;
+ uint_t rsvd2 : 2;
+ uint_t apic_enable : 1;
+ ullong_t base_addr : 40;
+ uint_t rsvd3 : 12;
+} __attribute__((packed));
+
struct apic_state {
+ addr_t base_addr;
+
v3_msr_t base_addr_reg;
+
+
};
-static int read_base_addr(uint_t msr, v3_msr_t * dst, void * priv_data) {
+static int read_apic_msr(uint_t msr, v3_msr_t * dst, void * priv_data) {
struct vm_device * dev = (struct vm_device *)priv_data;
struct apic_state * apic = (struct apic_state *)dev->private_data;
PrintDebug("READING APIC BASE ADDR: HI=%x LO=%x\n", apic->base_addr_reg.hi, apic->base_addr_reg.lo);
}
-static int write_base_addr(uint_t msr, v3_msr_t src, void * priv_data) {
+static int write_apic_msr(uint_t msr, v3_msr_t src, void * priv_data) {
// struct vm_device * dev = (struct vm_device *)priv_data;
// struct apic_state * apic = (struct apic_state *)dev->private_data;
}
+static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+ PrintDebug("Read from apic address space\n");
+ return -1;
+}
+
+
+static int apic_write(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+ PrintDebug("Write to apic address space\n");
+ return -1;
+}
+
+
static int apic_deinit(struct vm_device * dev) {
struct guest_info * info = dev->vm;
static int apic_init(struct vm_device * dev) {
struct guest_info * info = dev->vm;
+ struct apic_state * apic = (struct apic_state *)(dev->private_data);
+
+ apic->base_addr = DEFAULT_BASE_ADDR;
+
+ v3_hook_msr(info, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev);
- v3_hook_msr(info, BASE_ADDR_MSR, read_base_addr, write_base_addr, dev);
+ v3_hook_full_mem(info, DEFAULT_BASE_ADDR, DEFAULT_BASE_ADDR + PAGE_SIZE_4KB, apic_read, apic_write, dev);
return 0;
}
#include <palacios/vmm_direct_paging.h>
-
-// Inline handler functions for each cpu mode
-#include "vmm_direct_paging_32.h"
-
#include <palacios/vmm_paging.h>
#include <palacios/vmm.h>
#include <palacios/vm_guest_mem.h>
#include <palacios/vm_guest.h>
+
+
+// Inline handler functions for each cpu mode
+#include "vmm_direct_paging_32.h"
+
pde32_t * v3_create_direct_passthrough_pts(struct guest_info * info) {
v3_vm_cpu_mode_t mode = v3_get_cpu_mode(info);
switch(mode) {
case REAL:
case PROTECTED:
- return v3_create_direct_passthrough_pts_32(info);
+ return create_direct_passthrough_pts_32(info);
case PROTECTED_PAE:
break;
case LONG:
return NULL;
}
-int v3_handle_shadow_pagefault_physical_mode(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
+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 v3_handle_shadow_pagefault_physical_mode_32(info, fault_addr, error_code);
+ return handle_passthrough_pagefault_32(info, fault_addr, error_code);
case PROTECTED_PAE:
break;
case LONG:
}
-static inline pde32_t * v3_create_direct_passthrough_pts_32(struct guest_info * info) {
+static inline pde32_t * create_direct_passthrough_pts_32(struct guest_info * info) {
return create_pde32();
}
-static inline int v3_handle_shadow_pagefault_physical_mode_32(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
+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);
int pde_index = PDE32_INDEX(fault_addr);
int pte_index = PTE32_INDEX(fault_addr);
- if(pde[pde_index].present != 1) {
+
+ if (pde[pde_index].present != 1) {
+
PrintError("Creating new page table for PTE index: %d\n", pde_index);
+
pte32_t * pte = create_pte32();
addr_t host_addr;
+
if(guest_pa_to_host_pa(info, fault_addr, &host_addr) == -1) return -1;
+
struct v3_shadow_region * region = v3_get_shadow_region(info, PAGE_BASE_ADDR(host_addr));
+
+ pte[pte_index].present = 1;
+ pte[pte_index].writable = 1;
+ pte[pte_index].user_page = 1;
+ pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+
+ 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));
+
+ if (region->host_type == SHDW_REGION_WRITE_HOOK) {
+ pte[pte_index].writable = 0;
+ }
+
+ PrintError("Fault Addr: 0x%p\nHost Addr: 0x%p\n", (void*)fault_addr, (void*)host_addr);
+
+ } else {
+ pte32_t * pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
+
+ if (pte[pte_index].present != 1) {
+ addr_t host_addr;
+
+ if (guest_pa_to_host_pa(info, fault_addr, &host_addr) == -1) return -1;
+
+ struct v3_shadow_region * region = v3_get_shadow_region(info, PAGE_BASE_ADDR(host_addr));
+
pte[pte_index].present = 1;
pte[pte_index].writable = 1;
pte[pte_index].user_page = 1;
pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
-
- 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));
- if(region->host_type == SHDW_REGION_WRITE_HOOK) {
+
+ if (region->host_type == SHDW_REGION_WRITE_HOOK) {
pte[pte_index].writable = 0;
}
- PrintError("Fault Addr: 0x%p\nHost Addr: 0x%p\n", (void*)fault_addr, (void*)host_addr);
- }
- else {
- pte32_t * pte = (void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr);
- if(pte[pte_index].present != 1) {
- addr_t host_addr;
- if(guest_pa_to_host_pa(info, fault_addr, &host_addr) == -1) return -1;
- struct v3_shadow_region * region = v3_get_shadow_region(info, PAGE_BASE_ADDR(host_addr));
- pte[pte_index].present = 1;
- pte[pte_index].writable = 1;
- pte[pte_index].user_page = 1;
- pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
- if(region->host_type == SHDW_REGION_WRITE_HOOK) {
- pte[pte_index].writable = 0;
- }
- }
}
- return 0;
+ }
+ return 0;
}
if (dec_instr->dst_operand.size == 1) {
- movs8((addr_t *)dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+ 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));
+ 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));
+ movs32((addr_t*)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
} else {
PrintError("Invalid operand length\n");
return -1;
}
+ PrintDebug("Calling Write function\n");
if (write_fn(write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
PrintError("Did not fully read hooked data\n");
int op_len = 0;
PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
- PrintDebug("GVA=%p\n", (void *)write_gva);
+ 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);
if (v3_get_mem_mode(info) == PHYSICAL_MEM) {
// If paging is not turned on we need to handle the special cases
- return v3_handle_shadow_pagefault_physical_mode(info, fault_addr, error_code);
+ 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)) {
break;
case PROTECTED:
case PROTECTED_PAE:
- case LONG_32_COMPAT:
if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
xed_state_init(state,
XED_MACHINE_MODE_LEGACY_32,
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) {
- state->mmode = XED_MACHINE_MODE_LONG_64;
+ 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:
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;
ullong_t displacement;
// 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));
base = MASK(mem_op.base, mem_op.base_size);
index = MASK(mem_op.index, mem_op.index_size);
scale = mem_op.scale;
- displacement = MASK(mem_op.displacement, mem_op.displacement_size);
+ // displacement = MASK(mem_op.displacement, mem_op.displacement_size);
+ displacement = mem_op.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);
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) {
- // PrintError("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: