[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Allow a guest to switch pagetables 'atomically'. That is, the new pagetables



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 5adaa690872746d66f8f4c0fdacc81a9117723cb
# Parent  38d9f4cbbc1e4f26bc7d7a839db4852d6db48193
Allow a guest to switch pagetables 'atomically'. That is, the new pagetables
do not need to be read-only in the old pagetables, and the old pagetables do
not need to be read-only in the new pagetables.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 38d9f4cbbc1e -r 5adaa6908727 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Feb 27 15:29:03 2006
+++ b/xen/arch/x86/mm.c Mon Feb 27 16:18:58 2006
@@ -1570,42 +1570,68 @@
     unsigned long old_base_mfn;
 
     if ( shadow_mode_refcounts(d) )
+    {
         okay = get_page_from_pagenr(mfn, d);
+        if ( unlikely(!okay) )
+        {
+            MEM_LOG("Error while installing new baseptr %lx", mfn);
+            return 0;
+        }
+    }
     else
+    {
         okay = get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d);
-
-    if ( likely(okay) )
-    {
-        invalidate_shadow_ldt(v);
-
-        old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-        v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
-        update_pagetables(v); /* update shadow_table and monitor_table */
-
-        write_ptbase(v);
-
+        if ( unlikely(!okay) )
+        {
+            /* Switch to idle pagetable: this VCPU has no active p.t. now. */
+            old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
+            v->arch.guest_table = mk_pagetable(0);
+            update_pagetables(v);
+            write_cr3(__pa(idle_pg_table));
+            if ( old_base_mfn != 0 )
+                put_page_and_type(mfn_to_page(old_base_mfn));
+
+            /* Retry the validation with no active p.t. for this VCPU. */
+            okay = get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d);
+            if ( !okay )
+            {
+                /* Failure here is unrecoverable: the VCPU has no pagetable! */
+                MEM_LOG("Fatal error while installing new baseptr %lx", mfn);
+                domain_crash(d);
+                percpu_info[v->processor].deferred_ops = 0;
+                return 0;
+            }
+        }
+    }
+
+    invalidate_shadow_ldt(v);
+
+    old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
+    v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
+    update_pagetables(v); /* update shadow_table and monitor_table */
+
+    write_ptbase(v);
+
+    if ( likely(old_base_mfn != 0) )
+    {
         if ( shadow_mode_refcounts(d) )
             put_page(mfn_to_page(old_base_mfn));
         else
             put_page_and_type(mfn_to_page(old_base_mfn));
-
-        /* CR3 also holds a ref to its shadow... */
-        if ( shadow_mode_enabled(d) )
-        {
-            if ( v->arch.monitor_shadow_ref )
-                put_shadow_ref(v->arch.monitor_shadow_ref);
-            v->arch.monitor_shadow_ref =
-                pagetable_get_pfn(v->arch.monitor_table);
-            ASSERT(!page_get_owner(mfn_to_page(v->arch.monitor_shadow_ref)));
-            get_shadow_ref(v->arch.monitor_shadow_ref);
-        }
-    }
-    else
-    {
-        MEM_LOG("Error while installing new baseptr %lx", mfn);
-    }
-
-    return okay;
+    }
+
+    /* CR3 also holds a ref to its shadow... */
+    if ( shadow_mode_enabled(d) )
+    {
+        if ( v->arch.monitor_shadow_ref )
+            put_shadow_ref(v->arch.monitor_shadow_ref);
+        v->arch.monitor_shadow_ref =
+            pagetable_get_pfn(v->arch.monitor_table);
+        ASSERT(!page_get_owner(mfn_to_page(v->arch.monitor_shadow_ref)));
+        get_shadow_ref(v->arch.monitor_shadow_ref);
+    }
+
+    return 1;
 }
 
 static void process_deferred_ops(unsigned int cpu)
@@ -1625,7 +1651,7 @@
         else
             local_flush_tlb();
     }
-        
+
     if ( deferred_ops & DOP_RELOAD_LDT )
         (void)map_ldt_shadow_page(0);
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.