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

[Xen-devel] [PATCH RFC 14/44] x86/mm: Added safety checks that pagetables aren't shared



Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/mm.c        | 19 ++++++++++++++++++-
 xen/arch/x86/setup.c     |  1 +
 xen/include/asm-x86/mm.h |  6 +++++-
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 375565f..d6f88ca 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -505,18 +505,35 @@ void do_write_ptbase(struct vcpu *v, bool tlb_maintenance)
     unsigned long new_cr3;
     unsigned int cpu = smp_processor_id();
     unsigned long *this_curr_ptbase = &per_cpu(curr_ptbase, cpu);
+    struct page_info *new_pg;
 
     /* Check that %cr3 isn't being shuffled under our feet. */
     ASSERT(*this_curr_ptbase == read_cr3());
 
     new_cr3 = pt_maybe_shadow(v);
+    new_pg = maddr_to_page(new_cr3);
+
+    /* Check that new_cr3 isn't in use by a different pcpu. */
+    if ( new_cr3 != *this_curr_ptbase )
+        BUG_ON(test_and_set_bit(_PGC_inuse_pgtable, &new_pg->count_info));
+    else
+        /* Same cr3.  Check that it is still marked as in use. */
+        ASSERT(test_bit(_PGC_inuse_pgtable, &new_pg->count_info));
 
     if ( tlb_maintenance )
         write_cr3(new_cr3);
     else
         asm volatile ( "mov %0, %%cr3" :: "r" (new_cr3) : "memory" );
 
-    *this_curr_ptbase = new_cr3;
+    /* Mark the old cr3 as no longer in use. */
+    if ( new_cr3 != *this_curr_ptbase )
+    {
+        struct page_info *old_pg = maddr_to_page(*this_curr_ptbase);
+
+        BUG_ON(!test_and_clear_bit(_PGC_inuse_pgtable, &old_pg->count_info));
+
+        *this_curr_ptbase = new_cr3;
+    }
 }
 
 /*
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 7a05a7c..ffa7ea4 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -246,6 +246,7 @@ void early_switch_to_idle(void)
     set_current(v);
     per_cpu(curr_vcpu, cpu) = v;
 
+    __set_bit(_PGC_inuse_pgtable, &maddr_to_page(v->arch.cr3)->count_info);
     asm volatile ( "mov %[npge], %%cr4;"
                    "mov %[cr3], %%cr3;"
                    "mov %[pge], %%cr4;"
diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
index ceb7dd4..64044c6 100644
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -258,8 +258,12 @@ struct page_info
 #define PGC_state_free    PG_mask(3, 9)
 #define page_state_is(pg, st) (((pg)->count_info&PGC_state) == PGC_state_##st)
 
+/* Page is a root pagetable, with a pcpus %cr3 pointing at it. */
+#define _PGC_inuse_pgtable PG_shift(10)
+#define PGC_inuse_pgtable  PG_mask(1, 10)
+
  /* Count of references to this frame. */
-#define PGC_count_width   PG_shift(9)
+#define PGC_count_width   PG_shift(10)
 #define PGC_count_mask    ((1UL<<PGC_count_width)-1)
 
 /*
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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