X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_shadow_paging.c;h=abb190b5f522ba6dc3d86d21a4ff6429961f253d;hb=526ffdd06c1afb982d0d9831b99f337b6a094960;hp=c25a3cb5df26f31021f6872ba434d3d6eedf9446;hpb=08a79dd2e3c75109539bdce50c049303b1fb0912;p=palacios.releases.git diff --git a/palacios/src/palacios/vmm_shadow_paging.c b/palacios/src/palacios/vmm_shadow_paging.c index c25a3cb..abb190b 100644 --- a/palacios/src/palacios/vmm_shadow_paging.c +++ b/palacios/src/palacios/vmm_shadow_paging.c @@ -30,10 +30,8 @@ int handle_shadow_pagefault(struct guest_info * info, addr_t fault_addr, pf_erro break; case PROTECTED_PAE: case LONG: - // currently not handled - return -1; - break; default: + PrintDebug("Unhandled CPU Mode\n"); return -1; } } else { @@ -116,12 +114,17 @@ int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_er the reason for the fault was that the page is not present in the shadow, _THEN_ we have to map the shadow page in and reexecute, this will generate a permissions fault which is _THEN_ valid to send to the guest + _UNLESS_ both the guest and shadow have marked the page as not present whew... */ if ((guest_pde_access != PT_ACCESS_OK) && - ( (shadow_pde_access != PT_ENTRY_NOT_PRESENT) && - (guest_pde_access != PT_ENTRY_NOT_PRESENT))) { // aka (guest permission error) + ( + ( (shadow_pde_access != PT_ENTRY_NOT_PRESENT) && + (guest_pde_access != PT_ENTRY_NOT_PRESENT)) // aka (guest permission error) + || + ( (shadow_pde_access == PT_ENTRY_NOT_PRESENT) && + (guest_pde_access == PT_ENTRY_NOT_PRESENT)))) { // inject page fault to the guest (Guest PDE fault) info->ctrl_regs.cr2 = fault_addr; @@ -131,12 +134,14 @@ int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_er PrintDebug("Injecting PDE pf to guest: (guest access error=%d) (pf error code=%d)\n", guest_pde_access, error_code); return 0; - PrintDebug("Guest CR3=%x\n", guest_cr3); - PrintDebug("Guest PD\n"); - PrintPD32(guest_pd); - PrintDebug("Shadow PD\n"); - PrintPD32(shadow_pd); - + + /* + PrintDebug("Guest CR3=%x\n", guest_cr3); + PrintDebug("Guest PD\n"); + PrintPD32(guest_pd); + PrintDebug("Shadow PD\n"); + PrintPD32(shadow_pd); + */ return -1; } @@ -309,8 +314,10 @@ int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_er // this probably shouldn't ever happen PrintDebug("Unknown Error occurred\n"); PrintDebug("Manual Says to inject page fault into guest\n"); - //return -1; Huh? It's a successful handling of the fault... + + return 0; + } //PrintDebugPageTables(shadow_pd); @@ -341,18 +348,28 @@ int handle_shadow_pte32_fault(struct guest_info * info, // Check the shadow page permissions shadow_pte_access = can_access_pte32(shadow_pt, fault_addr, error_code); + + PrintDebug("Guest PTE: (access=%d)\n\t", guest_pte_access); + PrintPTE32(fault_addr, guest_pte); + PrintDebug("Shadow PTE: (access=%d)\n\t", shadow_pte_access); + PrintPTE32(fault_addr, shadow_pte); /* This should be redone, but basically the reasoning is that there can be multiple reasons for a page fault: If there is a permissions failure for a page present in the guest _BUT_ the reason for the fault was that the page is not present in the shadow, _THEN_ we have to map the shadow page in and reexecute, this will generate a permissions fault which is _THEN_ valid to send to the guest + _UNLESS_ both the guest and shadow have marked the page as not present whew... */ if ((guest_pte_access != PT_ACCESS_OK) && - ((shadow_pte_access != PT_ENTRY_NOT_PRESENT) && - (guest_pte_access != PT_ENTRY_NOT_PRESENT))) { // aka (guest permission error) + ( + ((shadow_pte_access != PT_ENTRY_NOT_PRESENT) && + (guest_pte_access != PT_ENTRY_NOT_PRESENT)) // aka (guest permission error) + || + ((shadow_pte_access == PT_ENTRY_NOT_PRESENT) && + (guest_pte_access == PT_ENTRY_NOT_PRESENT)))) { // Inject page fault into the guest info->ctrl_regs.cr2 = fault_addr;