Fix writable pagetables when a flush happens in a different
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 13 Jan 2006 15:27:45 +0000 (16:27 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 13 Jan 2006 15:27:45 +0000 (16:27 +0100)
domain, which is temporarily made to run on the wrong
pagetables.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/mm.c

index 1b4afa2fa28c6bfa82f6363f973a43237efd0caa..79da37d3ea070d14c634544527d85f189b29683f 100644 (file)
@@ -3023,12 +3023,25 @@ void ptwr_flush(struct domain *d, const int which)
      * STEP 2. Validate any modified PTEs.
      */
 
-    pl1e = map_domain_page(l1e_get_pfn(pte));
-    modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
-    unmap_domain_page(pl1e);
-    perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
-    ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified);
-    d->arch.ptwr[which].prev_nr_updates = modified;
+    if ( likely(d == current->domain) )
+    {
+        pl1e = map_domain_page(l1e_get_pfn(pte));
+        modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
+        unmap_domain_page(pl1e);
+        perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
+        ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified);
+        d->arch.ptwr[which].prev_nr_updates = modified;
+    }
+    else
+    {
+        /*
+         * Must make a temporary global mapping, since we are running in the
+         * wrong address space, so no access to our own mapcache.
+         */
+        pl1e = map_domain_page_global(l1e_get_pfn(pte));
+        modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
+        unmap_domain_page_global(pl1e);
+    }
 
     /*
      * STEP 3. Reattach the L1 p.t. page into the current address space.