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.


cleaned up 32 bit shadow paging implementation
Jack Lange [Tue, 3 Feb 2009 22:38:21 +0000 (16:38 -0600)]
palacios/include/palacios/vmm_paging.h
palacios/src/palacios/vmm_shadow_paging_32.h

index 7535a3e..69989c4 100644 (file)
@@ -190,7 +190,6 @@ typedef enum {PAGE_4KB, PAGE_2MB, PAGE_4MB, PAGE_1GB,
 
 /* Page Table Flag Values */
 #define PT32_HOOK 0x1
-#define PT32_GUEST_PT 0x2
 
 
 
index 6acd920..28e718e 100644 (file)
@@ -263,6 +263,7 @@ static int handle_large_pagefault_32(struct guest_info * info,
   pt_access_status_t shadow_pte_access = v3_can_access_pte32(shadow_pt, fault_addr, error_code);
   pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]);
   addr_t guest_fault_pa = BASE_TO_PAGE_ADDR_4MB(large_guest_pde->page_base_addr) + PAGE_OFFSET_4MB(fault_addr);  
+  struct shadow_page_state * state = &(info->shdw_pg_state);
 
   struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info, guest_fault_pa);
 
@@ -288,7 +289,6 @@ static int handle_large_pagefault_32(struct guest_info * info,
 
     if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) || 
        (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
-      struct shadow_page_state * state = &(info->shdw_pg_state);
       addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_fault_pa);
 
       shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
@@ -305,7 +305,6 @@ static int handle_large_pagefault_32(struct guest_info * info,
       if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) {
        // Check if the entry is a page table...
        PrintDebug("Marking page as Guest Page Table (large page)\n");
-       shadow_pte->vmm_info = PT32_GUEST_PT;
        shadow_pte->writable = 0;
       } else if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
        shadow_pte->writable = 0;
@@ -336,7 +335,10 @@ static int handle_large_pagefault_32(struct guest_info * info,
        PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
        return -1;
       }
-    } else if (shadow_pte->vmm_info == PT32_GUEST_PT) {
+    }
+
+
+    if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_fault_pa)) != NULL) {
       struct shadow_page_state * state = &(info->shdw_pg_state);
       PrintDebug("Write operation on Guest PAge Table Page (large page)\n");
       state->cached_cr3 = 0;
@@ -370,6 +372,7 @@ static int handle_shadow_pte32_fault(struct guest_info * info,
   pte32_t * guest_pte = (pte32_t *)&(guest_pt[PTE32_INDEX(fault_addr)]);;
   pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]);
   addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) +  PAGE_OFFSET(fault_addr);
+  struct shadow_page_state * state = &(info->shdw_pg_state);
 
   struct v3_shadow_region * shdw_reg =  v3_get_shadow_region(info, guest_pa);
 
@@ -417,7 +420,6 @@ static int handle_shadow_pte32_fault(struct guest_info * info,
 
     if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
        (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
-      struct shadow_page_state * state = &(info->shdw_pg_state);
       addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
       
       shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
@@ -433,28 +435,27 @@ static int handle_shadow_pte32_fault(struct guest_info * info,
       
       guest_pte->accessed = 1;
       
-      if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) {
-       // Check if the entry is a page table...
-       PrintDebug("Marking page as Guest Page Table %d\n", shadow_pte->writable);
-       shadow_pte->vmm_info = PT32_GUEST_PT;
-      }
-
-      if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
-       shadow_pte->writable = 0;
-      } else if (guest_pte->dirty == 1) {
+      if (guest_pte->dirty == 1) {
        shadow_pte->writable = guest_pte->writable;
       } else if ((guest_pte->dirty == 0) && (error_code.write == 1)) {
        shadow_pte->writable = guest_pte->writable;
        guest_pte->dirty = 1;
-       
-       if (shadow_pte->vmm_info == PT32_GUEST_PT) {
-         // Well that was quick...
-         struct shadow_page_state * state = &(info->shdw_pg_state);
-         PrintDebug("Immediate Write operation on Guest PAge Table Page\n");
+      } else if ((guest_pte->dirty == 0) && (error_code.write == 0)) {
+       shadow_pte->writable = 0;
+      }
+
+      // dirty flag has been set, check if its in the cache
+      if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) {
+       if (error_code.write == 1) {
          state->cached_cr3 = 0;
+         shadow_pte->writable = guest_pte->writable;
+       } else {
+         shadow_pte->writable = 0;
        }
+      }
 
-      } else if ((guest_pte->dirty == 0) && (error_code.write == 0)) {  // was =
+      // Write hooks trump all, and are set Read Only
+      if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
        shadow_pte->writable = 0;
       }
 
@@ -479,7 +480,7 @@ static int handle_shadow_pte32_fault(struct guest_info * info,
       shadow_pte->writable = guest_pte->writable;
     }
 
-    if (shadow_pte->vmm_info == PT32_GUEST_PT) {
+    if (find_pte_map(state->cached_ptes, PAGE_ADDR(guest_pa)) != NULL) {
       struct shadow_page_state * state = &(info->shdw_pg_state);
       PrintDebug("Write operation on Guest PAge Table Page\n");
       state->cached_cr3 = 0;