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

[Xen-changelog] Added unshadowing of L2s that contain entries which are both



ChangeSet 1.1236.32.9, 2005/03/16 01:17:37+00:00, mafetter@xxxxxxxxxxxxxxxx

        Added unshadowing of L2s that contain entries which are both
        not present and non-zero.  This is a hack, but ought to work OK
        for linux domains.
        
        Signed-off-by: michael.fetterman@xxxxxxxxxxxx



 arch/x86/shadow.c        |   24 +++++++++++++++++++-----
 include/asm-x86/shadow.h |    9 +++++----
 include/xen/perfc_defn.h |    1 +
 3 files changed, 25 insertions(+), 9 deletions(-)


diff -Nru a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     2005-04-05 12:10:22 -04:00
+++ b/xen/arch/x86/shadow.c     2005-04-05 12:10:22 -04:00
@@ -299,8 +299,6 @@
 static void inline
 free_shadow_l2_table(struct domain *d, unsigned long smfn)
 {
-    printk("free_shadow_l2_table(smfn=%p)\n", smfn);
-
     unsigned long *pl2e = map_domain_mem(smfn << PAGE_SHIFT);
     int i, external = shadow_mode_external(d);
 
@@ -1666,6 +1664,7 @@
     unsigned long smfn;
     unsigned long *guest, *shadow, *snapshot;
     int need_flush = 0, external = shadow_mode_external(d);
+    int unshadow;
 
     ASSERT(spin_is_locked(&d->arch.shadow_lock));
 
@@ -1686,6 +1685,7 @@
         guest    = map_domain_mem(entry->gmfn         << PAGE_SHIFT);
         snapshot = map_domain_mem(entry->snapshot_mfn << PAGE_SHIFT);
         shadow   = map_domain_mem(smfn                << PAGE_SHIFT);
+        unshadow = 0;
 
         switch ( stype ) {
         case PGT_l1_shadow:
@@ -1719,6 +1719,16 @@
                     //
                     // snapshot[i] = new_pde;
                 }
+
+                // XXX - This hack works for linux guests.
+                //       Need a better solution long term.
+                if ( !(new_pde & _PAGE_PRESENT) && unlikely(new_pde != 0) &&
+                     (frame_table[smfn].u.inuse.type_info & PGT_pinned) &&
+                     !unshadow )
+                {
+                    perfc_incrc(unshadow_l2_count);
+                    unshadow = 1;
+                }
             }
             break;
         default:
@@ -1729,6 +1739,9 @@
         unmap_domain_mem(shadow);
         unmap_domain_mem(snapshot);
         unmap_domain_mem(guest);
+
+        if ( unlikely(unshadow) )
+            shadow_unpin(smfn);
     }
 
     return need_flush;
@@ -1919,7 +1932,7 @@
     struct domain *d = ed->domain;
     unsigned long gmfn = pagetable_val(ed->arch.guest_table) >> PAGE_SHIFT;
     unsigned long gpfn = __mfn_to_gpfn(d, gmfn);
-    unsigned long smfn, hl2mfn;
+    unsigned long smfn, hl2mfn, old_smfn;
 
     int max_mode = ( shadow_mode_external(d) ? SHM_external
                      : shadow_mode_translate(d) ? SHM_translate
@@ -1946,9 +1959,10 @@
         smfn = shadow_l2_table(d, gpfn, gmfn);
     if ( !get_shadow_ref(smfn) )
         BUG();
-    if ( pagetable_val(ed->arch.shadow_table) )
-        put_shadow_ref(pagetable_val(ed->arch.shadow_table) >> PAGE_SHIFT);
+    old_smfn = pagetable_val(ed->arch.shadow_table) >> PAGE_SHIFT;
     ed->arch.shadow_table = mk_pagetable(smfn << PAGE_SHIFT);
+    if ( old_smfn )
+        put_shadow_ref(old_smfn);
 
     SH_VVLOG("0: __update_pagetables(gmfn=%p, smfn=%p)", gmfn, smfn);
 
diff -Nru a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      2005-04-05 12:10:22 -04:00
+++ b/xen/include/asm-x86/shadow.h      2005-04-05 12:10:22 -04:00
@@ -651,7 +651,7 @@
 static int inline
 validate_pde_change(
     struct domain *d,
-    unsigned long new_pde,
+    unsigned long new_gpde,
     unsigned long *shadow_pde_p)
 {
     unsigned long old_spde, new_spde;
@@ -659,11 +659,12 @@
     perfc_incrc(validate_pde_calls);
 
     old_spde = *shadow_pde_p;
-    l2pde_propagate_from_guest(d, &new_pde, &new_spde);
+    l2pde_propagate_from_guest(d, &new_gpde, &new_spde);
 
-    // XXX Shouldn't we supposed to propagate the new_pde to the guest?
+    // XXX Shouldn't we propagate the new_gpde to the guest?
+    // And then mark the guest's L2 page as dirty?
 
-    // only do the ref counting if something important changed.
+    // Only do the ref counting if something important changed.
     //
     if ( ((old_spde | new_spde) & _PAGE_PRESENT) &&
          ((old_spde ^ new_spde) & (PAGE_MASK | _PAGE_PRESENT)) )
diff -Nru a/xen/include/xen/perfc_defn.h b/xen/include/xen/perfc_defn.h
--- a/xen/include/xen/perfc_defn.h      2005-04-05 12:10:22 -04:00
+++ b/xen/include/xen/perfc_defn.h      2005-04-05 12:10:22 -04:00
@@ -30,6 +30,7 @@
 PERFCOUNTER_CPU( shadow_set_l1e_unlinked,  "shadow_set_l1e found unlinked l1" )
 PERFCOUNTER_CPU( shadow_set_l1e_fail,      "shadow_set_l1e failed (no sl1)" )
 PERFCOUNTER_CPU( shadow_invlpg_faults,     "shadow_invlpg's get_user faulted")
+PERFCOUNTER_CPU( unshadow_l2_count,        "unpinned L2 count")
 
 
 /* STATUS counters do not reset when 'P' is hit */

_______________________________________________
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®.