WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] This fixes the following scenerio:

# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID fa99d895bb187dc2b995d054fb93d000bf249a71
# Parent  1df8b53bdd37dd91e8354a784f790af93f6c57af
This fixes the following scenerio:
1) gmfn X is L2 table, and a shadow for it is set.
2) A write to page X, and the same page would be L1 table
also.(Something like the linear page table) But the shadow for L1 table
is not set.

The code path will be shadow_fault -> l1pte_write_fault. Because X is L2
table, so shadow_mark_va_out_of_sync is called , this function will
allocate a OO entry for this table, and set the writable_pl1e to -1.
Also it alloc a L1 shadow for X through shadow_map_l1_into_current_l2.
When allocating, free_out_of_sync_state will be called to free all OO
entry. However, since the OO entry allocated on
shadow_mark_va_out_of_sync has the writable_pl1e to -1, this OO entry
will never be released.

Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx>

diff -r 1df8b53bdd37 -r fa99d895bb18 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Wed Nov 16 10:39:38 2005
+++ b/xen/arch/x86/shadow.c     Wed Nov 16 10:41:14 2005
@@ -873,7 +873,7 @@
 }
 
 static struct out_of_sync_entry *
-mark_mfn_out_of_sync(struct vcpu *v, unsigned long gpfn,
+__mark_mfn_out_of_sync(struct vcpu *v, unsigned long gpfn,
                              unsigned long mfn)
 {
     struct domain *d = v->domain;
@@ -909,7 +909,6 @@
     entry->v = v;
     entry->gpfn = gpfn;
     entry->gmfn = mfn;
-    entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn);
     entry->writable_pl1e = -1;
 
 #if 0 // this code has not been updated for 32pae & 64 bit modes
@@ -923,20 +922,34 @@
     //
     get_page(page, d);
 
+    return entry;
+}
+
+static struct out_of_sync_entry *
+mark_mfn_out_of_sync(struct vcpu *v, unsigned long gpfn,
+                             unsigned long mfn)
+{
+    struct out_of_sync_entry *entry =
+        __mark_mfn_out_of_sync(v, gpfn, mfn);
+    struct domain *d = v->domain;
+
+    entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn);
     // Add to the out-of-sync list
     //
     entry->next = d->arch.out_of_sync;
     d->arch.out_of_sync = entry;
 
     return entry;
+
 }
 
 static void shadow_mark_va_out_of_sync(
     struct vcpu *v, unsigned long gpfn, unsigned long mfn, unsigned long va)
 {
     struct out_of_sync_entry *entry =
-        shadow_mark_mfn_out_of_sync(v, gpfn, mfn);
+        __mark_mfn_out_of_sync(v, gpfn, mfn);
     l2_pgentry_t sl2e;
+    struct domain *d = v->domain;
 
 #if CONFIG_PAGING_LEVELS >= 4
     {
@@ -971,6 +984,7 @@
     }
     ASSERT(l2e_get_flags(sl2e) & _PAGE_PRESENT);
 
+    entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn);
     // NB: this is stored as a machine address.
     entry->writable_pl1e =
         l2e_get_paddr(sl2e) | (sizeof(l1_pgentry_t) * l1_table_offset(va));
@@ -982,6 +996,11 @@
     //
     if ( !get_shadow_ref(l2e_get_pfn(sl2e)) )
         BUG();
+
+    // Add to the out-of-sync list
+    //
+    entry->next = d->arch.out_of_sync;
+    d->arch.out_of_sync = entry;
 
     FSH_LOG("mark_out_of_sync(va=%lx -> writable_pl1e=%lx)",
             va, entry->writable_pl1e);
diff -r 1df8b53bdd37 -r fa99d895bb18 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Wed Nov 16 10:39:38 2005
+++ b/xen/arch/x86/shadow32.c   Wed Nov 16 10:41:14 2005
@@ -1826,7 +1826,7 @@
 }
 
 struct out_of_sync_entry *
-shadow_mark_mfn_out_of_sync(struct vcpu *v, unsigned long gpfn,
+__shadow_mark_mfn_out_of_sync(struct vcpu *v, unsigned long gpfn,
                              unsigned long mfn)
 {
     struct domain *d = v->domain;
@@ -1862,7 +1862,6 @@
     entry->v = v;
     entry->gpfn = gpfn;
     entry->gmfn = mfn;
-    entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn);
     entry->writable_pl1e = -1;
 
 #if SHADOW_DEBUG
@@ -1874,6 +1873,18 @@
     //
     get_page(page, d);
 
+    return entry;
+}
+
+struct out_of_sync_entry *
+shadow_mark_mfn_out_of_sync(struct vcpu *v, unsigned long gpfn,
+                             unsigned long mfn)
+{
+    struct out_of_sync_entry *entry =
+      __shadow_mark_mfn_out_of_sync(v, gpfn, mfn);
+    struct domain *d = v->domain;
+
+    entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn);
     // Add to the out-of-sync list
     //
     entry->next = d->arch.out_of_sync;
@@ -1886,8 +1897,9 @@
     struct vcpu *v, unsigned long gpfn, unsigned long mfn, unsigned long va)
 {
     struct out_of_sync_entry *entry =
-        shadow_mark_mfn_out_of_sync(v, gpfn, mfn);
+        __shadow_mark_mfn_out_of_sync(v, gpfn, mfn);
     l2_pgentry_t sl2e;
+    struct domain *d = v->domain;
 
     // We need the address of shadow PTE that maps @va.
     // It might not exist yet.  Make sure it's there.
@@ -1902,6 +1914,7 @@
     }
     ASSERT(l2e_get_flags(sl2e) & _PAGE_PRESENT);
 
+    entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn);
     // NB: this is stored as a machine address.
     entry->writable_pl1e =
         l2e_get_paddr(sl2e) | (sizeof(l1_pgentry_t) * l1_table_offset(va));
@@ -1913,6 +1926,11 @@
     //
     if ( !get_shadow_ref(l2e_get_pfn(sl2e)) )
         BUG();
+
+    // Add to the out-of-sync list
+    //
+    entry->next = d->arch.out_of_sync;
+    d->arch.out_of_sync = entry;
 
     FSH_LOG("mark_out_of_sync(va=%lx -> writable_pl1e=%lx)",
             va, entry->writable_pl1e);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] This fixes the following scenerio:, Xen patchbot -unstable <=