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: