X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fmmu%2Fvmm_shdw_pg_tlb_64.h;h=334c675118807fa5198574cf28e39de4d60e91c3;hb=894733a198529cfaf93f4f4b68b255906154ab56;hp=76d22f93b085160b14efa832995c6868c7f1ad01;hpb=acaadd79c597c8d5180fbfbec79c01fef3dff003;p=palacios.git diff --git a/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_64.h b/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_64.h index 76d22f9..334c675 100644 --- a/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_64.h +++ b/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_64.h @@ -17,6 +17,9 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ +#ifdef V3_CONFIG_TM_FUNC +#include +#endif static inline int activate_shadow_pt_64(struct guest_info * info) { struct cr3_64 * shadow_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3); @@ -387,7 +390,21 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault 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)); } @@ -465,11 +482,17 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault 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; @@ -479,6 +502,10 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault 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; @@ -507,6 +534,9 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault 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) { @@ -567,14 +597,17 @@ static int handle_2MB_shadow_pagefault_pde_64(struct guest_info * info, 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