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] [xen-unstable] [XEN] Snapshot PAE l3es when they are sha

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Snapshot PAE l3es when they are shadowed.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 14 Feb 2007 10:15:09 -0800
Delivery-date: Wed, 14 Feb 2007 10:15:13 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1171464378 0
# Node ID a00b8d3800a82a993344c9546ddc1f00a9c514be
# Parent  cbbd748c4b58f66367b750a2fbba4da5b71fd94c
[XEN] Snapshot PAE l3es when they are shadowed.
We don't update the shadows so we mustn't look at the guest l3es
or we'll be confused by them if they change.
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/svm/svm.c            |    2 
 xen/arch/x86/mm.c                     |    3 
 xen/arch/x86/mm/shadow/multi.c        |  115 ++++++++++++++++------------------
 xen/arch/x86/mm/shadow/page-guest32.h |    5 -
 xen/arch/x86/mm/shadow/types.h        |    2 
 xen/include/asm-x86/domain.h          |    8 +-
 xen/include/asm-x86/page.h            |    3 
 7 files changed, 63 insertions(+), 75 deletions(-)

diff -r cbbd748c4b58 -r a00b8d3800a8 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Feb 14 14:44:07 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Wed Feb 14 14:46:18 2007 +0000
@@ -2679,7 +2679,7 @@ void walk_shadow_and_guest_pt(unsigned l
     shadow_sync_va(v, gva);
 
     gpte.l1 = 0;
-    __copy_from_user(&gpte, &linear_pg_table[ l1_linear_offset(gva) ],
+    __copy_from_user(&gpte, &__linear_l1_table[ l1_linear_offset(gva) ],
                      sizeof(gpte) );
     printk( "G-PTE = %x, flags=%x\n", gpte.l1, l1e_get_flags(gpte) );
 
diff -r cbbd748c4b58 -r a00b8d3800a8 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Feb 14 14:44:07 2007 +0000
+++ b/xen/arch/x86/mm.c Wed Feb 14 14:46:18 2007 +0000
@@ -374,9 +374,6 @@ void write_ptbase(struct vcpu *v)
 /* Should be called after CR3 is updated.
  * Updates vcpu->arch.cr3 and, for HVM guests, vcpu->arch.hvm_vcpu.cpu_cr3.
  * 
- * Also updates other state derived from CR3 (vcpu->arch.guest_vtable,
- * shadow_vtable, etc).
- *
  * Uses values found in vcpu->arch.(guest_table and guest_table_user), and
  * for HVM guests, arch.monitor_table and hvm's guest CR3.
  *
diff -r cbbd748c4b58 -r a00b8d3800a8 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Wed Feb 14 14:44:07 2007 +0000
+++ b/xen/arch/x86/mm/shadow/multi.c    Wed Feb 14 14:46:18 2007 +0000
@@ -237,7 +237,8 @@ guest_walk_tables(struct vcpu *v, unsign
 #if GUEST_PAGING_LEVELS >= 4 /* 64-bit only... */
     /* Get l4e from the top level table */
     gw->l4mfn = pagetable_get_mfn(v->arch.guest_table);
-    gw->l4e = (guest_l4e_t *)v->arch.guest_vtable + guest_l4_table_offset(va);
+    gw->l4e = (guest_l4e_t *)v->arch.paging.shadow.guest_vtable 
+        + guest_l4_table_offset(va);
     /* Walk down to the l3e */
     if ( !(guest_l4e_get_flags(*gw->l4e) & _PAGE_PRESENT) ) return 0;
     gw->l3mfn = vcpu_gfn_to_mfn(v, guest_l4e_get_gfn(*gw->l4e));
@@ -248,9 +249,8 @@ guest_walk_tables(struct vcpu *v, unsign
     gw->l3e = ((guest_l3e_t *)sh_map_domain_page(gw->l3mfn))
         + guest_l3_table_offset(va);
 #else /* PAE only... */
-    /* Get l3e from the top level table */
-    gw->l3mfn = pagetable_get_mfn(v->arch.guest_table);
-    gw->l3e = (guest_l3e_t *)v->arch.guest_vtable + guest_l3_table_offset(va);
+    /* Get l3e from the cache of the guest's top level table */
+    gw->l3e = (guest_l3e_t 
*)&v->arch.paging.shadow.gl3e[guest_l3_table_offset(va)];
 #endif /* PAE or 64... */
     /* Walk down to the l2e */
     if ( !(guest_l3e_get_flags(*gw->l3e) & _PAGE_PRESENT) ) return 0;
@@ -264,7 +264,8 @@ guest_walk_tables(struct vcpu *v, unsign
 #else /* 32-bit only... */
     /* Get l2e from the top level table */
     gw->l2mfn = pagetable_get_mfn(v->arch.guest_table);
-    gw->l2e = (guest_l2e_t *)v->arch.guest_vtable + guest_l2_table_offset(va);
+    gw->l2e = (guest_l2e_t *)v->arch.paging.shadow.guest_vtable 
+        + guest_l2_table_offset(va);
 #endif /* All levels... */
     
     if ( !(guest_l2e_get_flags(*gw->l2e) & _PAGE_PRESENT) ) return 0;
@@ -357,8 +358,8 @@ static inline void print_gw(walk_t *gw)
     SHADOW_PRINTK("   l4e=%p\n", gw->l4e);
     if ( gw->l4e )
         SHADOW_PRINTK("   *l4e=%" SH_PRI_gpte "\n", gw->l4e->l4);
+    SHADOW_PRINTK("   l3mfn=%" PRI_mfn "\n", mfn_x(gw->l3mfn));
 #endif /* PAE or 64... */
-    SHADOW_PRINTK("   l3mfn=%" PRI_mfn "\n", mfn_x(gw->l3mfn));
     SHADOW_PRINTK("   l3e=%p\n", gw->l3e);
     if ( gw->l3e )
         SHADOW_PRINTK("   *l3e=%" SH_PRI_gpte "\n", gw->l3e->l3);
@@ -3169,8 +3170,7 @@ sh_update_linear_entries(struct vcpu *v)
 #else /* GUEST_PAGING_LEVELS == 3 */
         
         shadow_l3e = (shadow_l3e_t *)&v->arch.paging.shadow.l3table;
-        /* Always safe to use guest_vtable, because it's globally mapped */
-        guest_l3e = v->arch.guest_vtable;
+        guest_l3e = (guest_l3e_t *)&v->arch.paging.shadow.gl3e;
 
 #endif /* GUEST_PAGING_LEVELS */
         
@@ -3268,38 +3268,36 @@ sh_update_linear_entries(struct vcpu *v)
 }
 
 
-/* Removes vcpu->arch.guest_vtable and vcpu->arch.shadow_table[].
+/* Removes vcpu->arch.paging.shadow.guest_vtable and vcpu->arch.shadow_table[].
  * Does all appropriate management/bookkeeping/refcounting/etc...
  */
 static void
 sh_detach_old_tables(struct vcpu *v)
 {
-    struct domain *d = v->domain;
     mfn_t smfn;
     int i = 0;
 
     ////
-    //// vcpu->arch.guest_vtable
+    //// vcpu->arch.paging.shadow.guest_vtable
     ////
-    if ( v->arch.guest_vtable )
-    {
-#if GUEST_PAGING_LEVELS == 4
+
+#if GUEST_PAGING_LEVELS == 3
+    /* PAE guests don't have a mapping of the guest top-level table */
+    ASSERT(v->arch.paging.shadow.guest_vtable == NULL);
+#else
+    if ( v->arch.paging.shadow.guest_vtable )
+    {
+        struct domain *d = v->domain;
         if ( shadow_mode_external(d) || shadow_mode_translate(d) )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-#elif GUEST_PAGING_LEVELS == 3
-        if ( 1 || shadow_mode_external(d) || shadow_mode_translate(d) )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-#elif GUEST_PAGING_LEVELS == 2
-        if ( shadow_mode_external(d) || shadow_mode_translate(d) )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-#endif
-        v->arch.guest_vtable = NULL;
-    }
+            sh_unmap_domain_page_global(v->arch.paging.shadow.guest_vtable);
+        v->arch.paging.shadow.guest_vtable = NULL;
+    }
+#endif
+
 
     ////
     //// vcpu->arch.shadow_table[]
     ////
-
 
 #if GUEST_PAGING_LEVELS == 3
     /* PAE guests have four shadow_table entries */
@@ -3398,7 +3396,9 @@ sh_update_cr3(struct vcpu *v, int do_loc
     struct domain *d = v->domain;
     mfn_t gmfn;
 #if GUEST_PAGING_LEVELS == 3
+    guest_l3e_t *gl3e;
     u32 guest_idx=0;
+    int i;
 #endif
 
     /* Don't do anything on an uninitialised vcpu */
@@ -3457,55 +3457,54 @@ sh_update_cr3(struct vcpu *v, int do_loc
 
 
     ////
-    //// vcpu->arch.guest_vtable
+    //// vcpu->arch.paging.shadow.guest_vtable
     ////
 #if GUEST_PAGING_LEVELS == 4
     if ( shadow_mode_external(d) || shadow_mode_translate(d) )
     {
-        if ( v->arch.guest_vtable )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
+        if ( v->arch.paging.shadow.guest_vtable )
+            sh_unmap_domain_page_global(v->arch.paging.shadow.guest_vtable);
+        v->arch.paging.shadow.guest_vtable = sh_map_domain_page_global(gmfn);
     }
     else
-        v->arch.guest_vtable = __linear_l4_table;
+        v->arch.paging.shadow.guest_vtable = __linear_l4_table;
 #elif GUEST_PAGING_LEVELS == 3
-    if ( v->arch.guest_vtable )
-        sh_unmap_domain_page_global(v->arch.guest_vtable);
-    if ( shadow_mode_external(d) )
-    {
-        if ( paging_vcpu_mode_translate(v) ) 
-            /* Paging enabled: find where in the page the l3 table is */
-            guest_idx = guest_index((void *)hvm_get_guest_ctrl_reg(v, 3));
-        else
-            /* Paging disabled: l3 is at the start of a page (in the p2m) */ 
-            guest_idx = 0; 
-
-        // Ignore the low 2 bits of guest_idx -- they are really just
-        // cache control.
-        guest_idx &= ~3;
-
-        // XXX - why does this need a global map?
-        v->arch.guest_vtable =
-            (guest_l3e_t *)sh_map_domain_page_global(gmfn) + guest_idx;
-    }
+     /* On PAE guests we don't use a mapping of the guest's own top-level
+      * table.  We cache the current state of that table and shadow that,
+      * until the next CR3 write makes us refresh our cache. */
+     ASSERT(v->arch.paging.shadow.guest_vtable == NULL);
+ 
+     if ( shadow_mode_external(d) && paging_vcpu_mode_translate(v) ) 
+         /* Paging enabled: find where in the page the l3 table is */
+         guest_idx = guest_index((void *)hvm_get_guest_ctrl_reg(v, 3));
     else
-        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
+        /* Paging disabled or PV: l3 is at the start of a page */ 
+        guest_idx = 0; 
+     
+     // Ignore the low 2 bits of guest_idx -- they are really just
+     // cache control.
+     guest_idx &= ~3;
+     
+     gl3e = ((guest_l3e_t *)sh_map_domain_page(gmfn)) + guest_idx;
+     for ( i = 0; i < 4 ; i++ )
+         v->arch.paging.shadow.gl3e[i] = gl3e[i];
+     sh_unmap_domain_page(gl3e);
 #elif GUEST_PAGING_LEVELS == 2
     if ( shadow_mode_external(d) || shadow_mode_translate(d) )
     {
-        if ( v->arch.guest_vtable )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
+        if ( v->arch.paging.shadow.guest_vtable )
+            sh_unmap_domain_page_global(v->arch.paging.shadow.guest_vtable);
+        v->arch.paging.shadow.guest_vtable = sh_map_domain_page_global(gmfn);
     }
     else
-        v->arch.guest_vtable = __linear_l2_table;
+        v->arch.paging.shadow.guest_vtable = __linear_l2_table;
 #else
 #error this should never happen
 #endif
 
 #if 0
-    printk("%s %s %d gmfn=%05lx guest_vtable=%p\n",
-           __func__, __FILE__, __LINE__, gmfn, v->arch.guest_vtable);
+    printk("%s %s %d gmfn=%05lx shadow.guest_vtable=%p\n",
+           __func__, __FILE__, __LINE__, gmfn, 
v->arch.paging.shadow.guest_vtable);
 #endif
 
     ////
@@ -3523,10 +3522,10 @@ sh_update_cr3(struct vcpu *v, int do_loc
     /* PAE guests have four shadow_table entries, based on the 
      * current values of the guest's four l3es. */
     {
-        int i, flush = 0;
+        int flush = 0;
         gfn_t gl2gfn;
         mfn_t gl2mfn;
-        guest_l3e_t *gl3e = (guest_l3e_t*)v->arch.guest_vtable;
+        guest_l3e_t *gl3e = (guest_l3e_t*)&v->arch.paging.shadow.gl3e;
         /* First, make all four entries read-only. */
         for ( i = 0; i < 4; i++ )
         {
diff -r cbbd748c4b58 -r a00b8d3800a8 xen/arch/x86/mm/shadow/page-guest32.h
--- a/xen/arch/x86/mm/shadow/page-guest32.h     Wed Feb 14 14:44:07 2007 +0000
+++ b/xen/arch/x86/mm/shadow/page-guest32.h     Wed Feb 14 14:46:18 2007 +0000
@@ -87,11 +87,6 @@ static inline l2_pgentry_32_t l2e_from_p
 #define l2_table_offset_32(a)         \
     (((a) >> L2_PAGETABLE_SHIFT_32) & (L2_PAGETABLE_ENTRIES_32 - 1))
 
-#define linear_l1_table_32                                                 \
-    ((l1_pgentry_32_t *)(LINEAR_PT_VIRT_START))
-
-#define linear_pg_table_32 linear_l1_table_32
-
 #endif /* __X86_PAGE_GUEST_H__ */
 
 /*
diff -r cbbd748c4b58 -r a00b8d3800a8 xen/arch/x86/mm/shadow/types.h
--- a/xen/arch/x86/mm/shadow/types.h    Wed Feb 14 14:44:07 2007 +0000
+++ b/xen/arch/x86/mm/shadow/types.h    Wed Feb 14 14:46:18 2007 +0000
@@ -447,10 +447,8 @@ struct shadow_walk_t
     guest_l2e_t *l2e;           /* Pointer to guest's level 2 entry */
     guest_l1e_t *l1e;           /* Pointer to guest's level 1 entry */
     guest_l1e_t eff_l1e;        /* Effective level 1 entry */
-#if GUEST_PAGING_LEVELS >= 3
 #if GUEST_PAGING_LEVELS >= 4
     mfn_t l4mfn;                /* MFN that the level 4 entry is in */
-#endif
     mfn_t l3mfn;                /* MFN that the level 3 entry is in */
 #endif
     mfn_t l2mfn;                /* MFN that the level 2 entry is in */
diff -r cbbd748c4b58 -r a00b8d3800a8 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Wed Feb 14 14:44:07 2007 +0000
+++ b/xen/include/asm-x86/domain.h      Wed Feb 14 14:46:18 2007 +0000
@@ -92,7 +92,11 @@ struct shadow_vcpu {
 #if CONFIG_PAGING_LEVELS >= 3
     /* PAE guests: per-vcpu shadow top-level table */
     l3_pgentry_t l3table[4] __attribute__((__aligned__(32)));
-#endif
+    /* PAE guests: per-vcpu cache of the top-level *guest* entries */
+    l3_pgentry_t gl3e[4] __attribute__((__aligned__(32)));
+#endif
+    /* Non-PAE guests: pointer to guest top-level pagetable */
+    void *guest_vtable;
     /* Last MFN that we emulated a write to. */
     unsigned long last_emulated_mfn;
     /* MFN of the last shadow that we shot a writeable mapping in */
@@ -242,8 +246,6 @@ struct arch_vcpu
     pagetable_t monitor_table;          /* (MFN) hypervisor PT (for HVM) */
     unsigned long cr3;                     /* (MA) value to install in HW CR3 
*/
 
-    void *guest_vtable;                 /* virtual addr of pagetable */
-
     /* Current LDT details. */
     unsigned long shadow_ldt_mapcnt;
 
diff -r cbbd748c4b58 -r a00b8d3800a8 xen/include/asm-x86/page.h
--- a/xen/include/asm-x86/page.h        Wed Feb 14 14:44:07 2007 +0000
+++ b/xen/include/asm-x86/page.h        Wed Feb 14 14:46:18 2007 +0000
@@ -278,9 +278,6 @@ typedef struct { u64 pfn; } pagetable_t;
 #define __linear_l4_table \
  ((l4_pgentry_t *)(__linear_l3_table + l3_linear_offset(LINEAR_PT_VIRT_START)))
 
-#define linear_l1_table __linear_l1_table
-#define linear_pg_table linear_l1_table
-#define linear_l2_table(v) ((l2_pgentry_t *)(v)->arch.guest_vtable)
 
 #ifndef __ASSEMBLY__
 #if CONFIG_PAGING_LEVELS == 3

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [XEN] Snapshot PAE l3es when they are shadowed., Xen patchbot-unstable <=