break;
case PROTECTED_PAE:
case LONG:
- // currently not handled
- return -1;
- break;
default:
+ PrintDebug("Unhandled CPU Mode\n");
return -1;
}
} else {
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;
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;
}
// Page Directory Entry marked non-user
//
- PrintDebug("Shadow Paging User access error\n");
- return -1;
+ PrintDebug("Shadow Paging User access error (shadow_pde_access=0x%x, guest_pde_access=0x%x - injecting into guest\n", shadow_pde_access, guest_pde_access);
+ info->ctrl_regs.cr2 = fault_addr;
+ raise_exception_with_error(info, PF_EXCEPTION, *(uint_t *)&error_code);
+ return 0;
+
} else if (shadow_pde_access == PT_ACCESS_OK) {
pte32_t * shadow_pt = (pte32_t *)PDE32_T_ADDR((*shadow_pde));
pte32_t * guest_pt = NULL;
// this probably shouldn't ever happen
PrintDebug("Unknown Error occurred\n");
PrintDebug("Manual Says to inject page fault into guest\n");
- return -1;
+
+
+ return 0;
+
}
//PrintDebugPageTables(shadow_pd);
// 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;