return 0;
     }
     
+    
+
     // Guest Is in Paged mode
     switch (guest_info->cpu_mode) {
     case PROTECTED:
        pde32_t * pde = 0;
        addr_t guest_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.guest_cr3);
 
+
        if (guest_pa_to_host_va(guest_info, guest_pde, (addr_t *)&pde) == -1) {
          PrintDebug("In GVA->GPA: Invalid GPA(%x)->HVA PDE32 lookup\n", guest_pde);
          return -1;
     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) {
+
+
+    /* JRL FIXME:
+     * This should be somewhere else....
+     */
+    addr_t tmp_addr;
+      
+    addr_t shadow_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.shadow_cr3);
+    
+    // Check the Shadow Page Tables first (Virtual TLB)
+    if (pt32_lookup((pde32_t *)shadow_pde, cursor, &tmp_addr) == 0) {
+      host_addr = tmp_addr;
+
+      if (host_pa_to_host_va(tmp_addr, &host_addr) != 0) {
+       return bytes_read;
+      }
+    } else {
+    
+      // No entry in the VTLB, do a guest page table walk
+   
+      if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
+       PrintDebug("Invalid GVA(%x)->HVA lookup\n", cursor);
+       return bytes_read;
+      }
+    }
+    /* JRL: END GRUESOME HACK */
+
+
+    /*
+      if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
       PrintDebug("Invalid GVA(%x)->HVA lookup\n", cursor);
       return bytes_read;
-    }
+      }
+    */
+    
 
     memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
     
 
     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);
 
        /* Delete the current Page Tables */
        delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
 
+       PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n", 
+                  info->shdw_pg_state.shadow_cr3, info->shdw_pg_state.guest_cr3);
+
 
        *guest_cr3 = *new_cr3;
 
+
+
        // Something like this
        shadow_pt =  create_new_shadow_pt32(info);
        //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
 
-
        /* Copy Various flags */
        *shadow_cr3 = *new_cr3;
+
+
        
        shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
 
+       PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n", 
+                  info->shdw_pg_state.shadow_cr3, info->shdw_pg_state.guest_cr3);
+
+
        if (info->mem_mode == VIRTUAL_MEM) {
          // If we aren't in paged mode then we have to preserve the identity mapped CR3
          info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
 
 int raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code) {
   struct vm_intr * intr_state = &(info->intr_state);
 
-  if (intr_state->excp_pending) {
+  if (intr_state->excp_pending == 0) {
     intr_state->excp_pending = 1;
     intr_state->excp_num = excp;
     intr_state->excp_error_code = error_code;
 int intr_pending(struct guest_info * info) {
   struct vm_intr * intr_state = &(info->intr_state);
 
-  if (intr_state->excp_pending) {
+  if (intr_state->excp_pending == 1) {
     return 1;
-  } else if (intr_state->controller->intr_pending(intr_state->controller_state)) {
+  } else if (intr_state->controller->intr_pending(intr_state->controller_state) == 1) {
     return 1;
   }
 
 uint_t get_intr_number(struct guest_info * info) {
   struct vm_intr * intr_state = &(info->intr_state);
 
-  if (intr_state->excp_pending) {
+  if (intr_state->excp_pending == 1) {
     return intr_state->excp_num;
   } else if (intr_state->controller->intr_pending(intr_state->controller_state)) {
     return intr_state->controller->get_intr_number(intr_state->controller_state);
 
 
 
 
+int pt32_lookup(pde32_t * pd, addr_t vaddr, addr_t * paddr) {
+  addr_t pde_entry;
+  pde32_entry_type_t pde_entry_type;
+
+  if (pd == 0) {
+    return -1;
+  }
+
+  pde_entry_type = pde32_lookup(pd, vaddr, &pde_entry);
+
+  if (pde_entry_type == PDE32_ENTRY_PTE32) {
+    return pte32_lookup((pte32_t *)pde_entry, vaddr, paddr);
+  } else if (pde_entry_type == PDE32_ENTRY_LARGE_PAGE) {
+    *paddr = pde_entry;
+    return 0;
+  }
+
+  return -1;
+}
+
 
 
 /* We can't do a full lookup because we don't know what context the page tables are in...
 
     info->ctrl_regs.cr2 = fault_addr;
     raise_exception_with_error(info, PF_EXCEPTION, *(uint_t *)&error_code);
 
+    PrintDebug("Injecting PDE pf to guest\n");
     return 0;
   }
 
        * Check the Intel manual because we are ignoring Large Page issues here
        * Also be wary of hooked pages
        */
+
+      PrintDebug("Large PAge!!!\n");
+      return -1;
+
     }
 
   } else if (shadow_pde_access == PT_WRITE_ERROR) {
   }
 
   //PrintDebugPageTables(shadow_pde);
-
+  PrintDebug("Returning end of PDE function\n");
   return 0;
 }
 
     info->ctrl_regs.cr2 = fault_addr;
     raise_exception_with_error(info, PF_EXCEPTION, *(uint_t *)&error_code);
     
+    PrintDebug("Access error injecting pf to guest\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;
   } else if (shadow_pte_access == PT_ENTRY_NOT_PRESENT) {
     addr_t shadow_pa;
     guest_pte_entry->dirty = 1;
     shadow_pte_entry->writable = guest_pte_entry->writable;
 
+    PrintDebug("Shadow PTE Write Error\n");
+
     return 0;
   } else {
     // Inject page fault into the guest        
     return -1;
   }
 
+  PrintDebug("Returning end of function\n");
   return 0;
 }