* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
+#ifdef V3_CONFIG_TM_FUNC
+#include <extensions/trans_mem.h>
+#endif
static inline int activate_shadow_pt_64(struct guest_info * info) {
struct cr3_64 * shadow_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3);
guest_pde->accessed = 1;
shadow_pde->pt_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
- } else {
+ } else { // when PT_ACCESS_OK is true
+ if ((info->use_large_pages == 1) && (guest_pde->large_page == 1) ) {
+ addr_t guest_pa = BASE_TO_PAGE_ADDR_4MB(((pde32_4MB_t *)guest_pde)->page_base_addr);
+ uint32_t page_size = v3_get_max_page_size(info, guest_pa, LONG);
+ if (page_size == PAGE_SIZE_2MB) {
+ if (shadow_pde_access == PT_ACCESS_OK) {
+ // Inconsistent state...
+ // Guest Re-Entry will flush tables and everything should now workd
+ PrintDebug(info->vm_info, info, "Inconsistent state PDE... Guest re-entry should flush tlb\n");
+ //PrintDebug(info->vm_info, info, "Bug here: shadow_pde_access is %d page_size is %d\n",
+ // (uint_t)shadow_pde_access,(uint_t)page_size);
+ return 0;
+ }
+ }
+ }
shadow_pt = (pte64_t *)V3_VAddr((void *)BASE_TO_PAGE_ADDR(shadow_pde->pt_base_addr));
}
return 0;
}
-
if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
// Page Table Entry Not Present
PrintDebug(info->vm_info, info, "guest_pa =%p\n", (void *)guest_pa);
+#ifdef V3_CONFIG_TM_FUNC
+ addr_t page_to_use;
+ if (v3_tm_handle_pf_64(info, error_code, fault_addr, &page_to_use) == -1) {
+ return -1;
+ }
+#endif
+
if ((shdw_reg->flags.alloced == 1) ||
(shdw_reg->flags.read == 1)) {
addr_t shadow_pa = 0;
return -1;
}
+#ifdef V3_CONFIG_TM_FUNC
+ v3_tm_handle_usr_tlb_miss(info, error_code, page_to_use, &shadow_pa);
+#endif
+
shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
shadow_pte->present = guest_pte->present;
shadow_pte->writable = 0;
}
+#ifdef V3_CONFIG_TM_FUNC
+ v3_tm_handle_read_fault(info, error_code, shadow_pte);
+#endif
} else {
// Pass to unhandled call back
if (shdw_reg->unhandled(info, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
return 0;
}
+ /* Note that this handler is currently invoked only when PT_ACCESS_OK is PT_NOT_PRESENT. */
if (shadow_pde_access == PT_ACCESS_OK) {
// Inconsistent state...
// Guest Re-Entry will flush tables and everything should now workd
PrintDebug(info->vm_info, info, "Inconsistent state... Guest re-entry should flush tlb\n");
+ PrintError(info->vm_info, info, "Hmm... did not expect call to this handler with PT_ACCESS_OK to happen...\n");
//PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
return 0;
}
+
if (shadow_pde_access == PT_ACCESS_NOT_PRESENT) {
// Get the guest physical address of the fault