Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


ugg
[palacios.git] / palacios / src / palacios / vmm_shadow_paging.c
index eeb4fda..abb190b 100644 (file)
@@ -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;
   }
@@ -274,8 +279,11 @@ int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_er
     // 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;
@@ -306,7 +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;
+
+
+    return 0;
+
   }
 
   //PrintDebugPageTables(shadow_pd);
@@ -337,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;