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.


Cleanup and sanity-checking of endianness, dead code, unchecked returns (Coverity...
[palacios.git] / palacios / src / palacios / mmu / vmm_shdw_pg_tlb_64.h
index 76d22f9..0a8bc6d 100644 (file)
@@ -17,6 +17,9 @@
  * 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);
@@ -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
@@ -745,9 +778,6 @@ static int invalidation_cb_64(struct guest_info * info, page_type_t type,
                if (pdpe->vmm_info == V3_LARGE_PG) {
                    PrintError(info->vm_info, info, "1 Gigabyte pages not supported\n");
                    return -1;
-
-                   pdpe->present = 0;
-                   return 1;
                }
 
                return 0;