bitkeeper revision 1.1159.260.1 (420e07e16YlSevQI9RYNGLwarPr2gQ)
authormafetter@fleming.research <mafetter@fleming.research>
Sat, 12 Feb 2005 13:42:57 +0000 (13:42 +0000)
committermafetter@fleming.research <mafetter@fleming.research>
Sat, 12 Feb 2005 13:42:57 +0000 (13:42 +0000)
Bug fix for shadow code.

When update_va_mapping() updates a entry, the corresponding shadow
entry may not be reachable via the shadow_linear_pg_table, even though
it is currently shadowed, as the corresponding spde has not necessarily
been faulted into place yet.

xen/arch/x86/memory.c
xen/include/xen/perfc_defn.h

index 631e5c50c94a6879d53a37d7267fd0cbf3fa6a96..3961b37a897db2f99c36cd02d07e9c9d596d5a9c 100644 (file)
@@ -1573,10 +1573,26 @@ int do_update_va_mapping(unsigned long page_nr,
             &shadow_linear_pg_table[page_nr])))) )
         {
             /*
-             * Since L2's are guranteed RW, failure indicates the page was not 
-             * shadowed, so ignore.
+             * Since L2's are guranteed RW, failure indicates either that the
+             * page was not shadowed, or that the L2 entry has not yet been
+             * updated to reflect the shadow.
              */
-            perfc_incrc(shadow_update_va_fail);
+            unsigned l2_idx = page_nr >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT);
+            l2_pgentry_t gpde = linear_l2_table[l2_idx];
+            unsigned long gpfn = l2_pgentry_val(gpde) >> PAGE_SHIFT;
+
+            if (get_shadow_status(&d->mm, gpfn))
+            {
+                unsigned long *gl1e = map_domain_mem(gpfn << PAGE_SHIFT);
+                unsigned l1_idx = page_nr & (ENTRIES_PER_L1_PAGETABLE - 1);
+                gl1e[l1_idx] = sval;
+                unmap_domain_mem(gl1e);
+                put_shadow_status(&d->mm);
+
+                perfc_incrc(shadow_update_va_fail1);
+            }
+            else
+                perfc_incrc(shadow_update_va_fail2);
         }
 
         /*
index f6868d78b988f8292bbcbafa74c04b6b2f9b64c0..d5dc9436fffa6d57387eeeffc7d1a02053b326f3 100644 (file)
@@ -25,7 +25,8 @@ PERFCOUNTER_CPU( shadow_l2_table_count, "shadow_l2_table count" )
 PERFCOUNTER_CPU( shadow_l1_table_count, "shadow_l1_table count" )
 PERFCOUNTER_CPU( unshadow_table_count, "unshadow_table count" )
 PERFCOUNTER_CPU( shadow_fixup_count, "shadow_fixup count" )
-PERFCOUNTER_CPU( shadow_update_va_fail, "shadow_update_va_fail" )
+PERFCOUNTER_CPU( shadow_update_va_fail1, "shadow_update_va_fail1" )
+PERFCOUNTER_CPU( shadow_update_va_fail2, "shadow_update_va_fail2" )
 
 /* STATUS counters do not reset when 'P' is hit */
 PERFSTATUS( shadow_l2_pages, "current # shadow L2 pages" )