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;
}