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] Track high-water-mark of p2m map

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Track high-water-mark of p2m map
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 16 Nov 2006 09:00:39 +0000
Delivery-date: Thu, 16 Nov 2006 01:00:24 -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>
# Node ID 11a93cc59159a1b8f7ee459534f3a7377bdfe375
# Parent  6e22ba7217201f3c3d7219d824f7aa80cd431c36
[XEN] Track high-water-mark of p2m map
and so avoid some unnecessary __copy_from_user faults.
Also tidy the p2m functions generally.
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
---
 xen/arch/x86/mm/shadow/common.c |   22 ++++++++-------
 xen/arch/x86/mm/shadow/types.h  |    4 --
 xen/include/asm-x86/domain.h    |    2 +
 xen/include/asm-x86/hvm/io.h    |    3 --
 xen/include/asm-x86/mm.h        |   28 -------------------
 xen/include/asm-x86/shadow.h    |   57 +++++++++++++++++++++++++++++++++++-----
 6 files changed, 65 insertions(+), 51 deletions(-)

diff -r 6e22ba721720 -r 11a93cc59159 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Wed Nov 15 09:44:12 2006 +0000
+++ b/xen/arch/x86/mm/shadow/common.c   Wed Nov 15 14:36:10 2006 +0000
@@ -1047,6 +1047,10 @@ shadow_set_p2m_entry(struct domain *d, u
     else
         *p2m_entry = l1e_empty();
 
+    /* Track the highest gfn for which we have ever had a valid mapping */
+    if ( valid_mfn(mfn) && (gfn > d->arch.max_mapped_pfn) ) 
+        d->arch.max_mapped_pfn = gfn;
+
     /* The P2M can be shadowed: keep the shadows synced */
     if ( d->vcpu[0] != NULL )
         (void)__shadow_validate_guest_entry(
@@ -1142,12 +1146,9 @@ sh_gfn_to_mfn_foreign(struct domain *d, 
     mfn = pagetable_get_mfn(d->arch.phys_table);
 
 
-#if CONFIG_PAGING_LEVELS > 2
-    if ( gpfn >= (RO_MPT_VIRT_END-RO_MPT_VIRT_START) / sizeof(l1_pgentry_t) ) 
-        /* This pfn is higher than the p2m map can hold */
+    if ( gpfn > d->arch.max_mapped_pfn ) 
+        /* This pfn is higher than the highest the p2m map currently holds */
         return _mfn(INVALID_MFN);
-#endif
-
 
 #if CONFIG_PAGING_LEVELS >= 4
     { 
@@ -3333,13 +3334,14 @@ void shadow_audit_p2m(struct domain *d)
             set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
         }
 
-        if ( test_linear )
-        {
-            lp2mfn = get_mfn_from_gpfn(gfn);
-            if ( lp2mfn != mfn_x(p2mfn) )
+        if ( test_linear && (gfn <= d->arch.max_mapped_pfn) )
+        {
+            lp2mfn = gfn_to_mfn_current(gfn);
+            if ( mfn_x(lp2mfn) != mfn_x(p2mfn) )
             {
                 SHADOW_PRINTK("linear mismatch gfn %#lx -> mfn %#lx "
-                               "(!= mfn %#lx)\n", gfn, lp2mfn, p2mfn);
+                              "(!= mfn %#lx)\n", gfn, 
+                              mfn_x(lp2mfn), mfn_x(p2mfn));
             }
         }
 
diff -r 6e22ba721720 -r 11a93cc59159 xen/arch/x86/mm/shadow/types.h
--- a/xen/arch/x86/mm/shadow/types.h    Wed Nov 15 09:44:12 2006 +0000
+++ b/xen/arch/x86/mm/shadow/types.h    Wed Nov 15 14:36:10 2006 +0000
@@ -416,9 +416,7 @@ vcpu_gfn_to_mfn(struct vcpu *v, gfn_t gf
 {
     if ( !shadow_vcpu_mode_translate(v) )
         return _mfn(gfn_x(gfn));
-    if ( likely(current->domain == v->domain) )
-        return _mfn(get_mfn_from_gpfn(gfn_x(gfn)));
-    return sh_gfn_to_mfn_foreign(v->domain, gfn_x(gfn));
+    return sh_gfn_to_mfn(v->domain, gfn_x(gfn));
 }
 
 static inline gfn_t
diff -r 6e22ba721720 -r 11a93cc59159 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Wed Nov 15 09:44:12 2006 +0000
+++ b/xen/include/asm-x86/domain.h      Wed Nov 15 14:36:10 2006 +0000
@@ -111,6 +111,8 @@ struct arch_domain
 
     /* Shadow translated domain: P2M mapping */
     pagetable_t phys_table;
+    /* Highest guest frame that's ever been mapped in the p2m */
+    unsigned long max_mapped_pfn;
 
 } __cacheline_aligned;
 
diff -r 6e22ba721720 -r 11a93cc59159 xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h      Wed Nov 15 09:44:12 2006 +0000
+++ b/xen/include/asm-x86/hvm/io.h      Wed Nov 15 14:36:10 2006 +0000
@@ -151,8 +151,5 @@ extern int cpu_get_interrupt(struct vcpu
 extern int cpu_get_interrupt(struct vcpu *v, int *type);
 extern int cpu_has_pending_irq(struct vcpu *v);
 
-// XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO 
frame.
-#define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT)))
-
 #endif /* __ASM_X86_HVM_IO_H__ */
 
diff -r 6e22ba721720 -r 11a93cc59159 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Wed Nov 15 09:44:12 2006 +0000
+++ b/xen/include/asm-x86/mm.h  Wed Nov 15 14:36:10 2006 +0000
@@ -304,37 +304,9 @@ int check_descriptor(struct desc_struct 
 
 #define gmfn_to_mfn(_d, gpfn)  mfn_x(sh_gfn_to_mfn(_d, gpfn))
 
-
-/*
- * The phys_to_machine_mapping is the reversed mapping of MPT for full
- * virtualization.  It is only used by shadow_mode_translate()==true
- * guests, so we steal the address space that would have normally
- * been used by the read-only MPT map.
- */
-#define phys_to_machine_mapping ((l1_pgentry_t *)RO_MPT_VIRT_START)
 #define INVALID_MFN             (~0UL)
 #define VALID_MFN(_mfn)         (!((_mfn) & (1U<<31)))
 
-static inline unsigned long get_mfn_from_gpfn(unsigned long pfn)
-{
-    l1_pgentry_t l1e = l1e_empty();
-    int ret;
-
-#if CONFIG_PAGING_LEVELS > 2
-    if ( pfn >= (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof(l1_pgentry_t) ) 
-        /* This pfn is higher than the p2m map can hold */
-        return INVALID_MFN;
-#endif
-
-    ret = __copy_from_user(&l1e,
-                               &phys_to_machine_mapping[pfn],
-                               sizeof(l1e));
-
-    if ( (ret == 0) && (l1e_get_flags(l1e) & _PAGE_PRESENT) )
-        return l1e_get_pfn(l1e);
-
-    return INVALID_MFN;
-}
 
 #ifdef MEMORY_GUARD
 void memguard_init(void);
diff -r 6e22ba721720 -r 11a93cc59159 xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Wed Nov 15 09:44:12 2006 +0000
+++ b/xen/include/asm-x86/shadow.h      Wed Nov 15 14:36:10 2006 +0000
@@ -663,12 +663,40 @@ struct shadow_walk_cache {
 
 
 /**************************************************************************/
-/* Guest physmap (p2m) support */
+/* Guest physmap (p2m) support 
+ *
+ * The phys_to_machine_mapping is the reversed mapping of MPT for full
+ * virtualization.  It is only used by shadow_mode_translate()==true
+ * guests, so we steal the address space that would have normally
+ * been used by the read-only MPT map.
+ */
+
+#define phys_to_machine_mapping ((l1_pgentry_t *)RO_MPT_VIRT_START)
+
+/* Read the current domain's P2M table. */
+static inline mfn_t sh_gfn_to_mfn_current(unsigned long gfn)
+{
+    l1_pgentry_t l1e = l1e_empty();
+    int ret;
+
+    if ( gfn > current->domain->arch.max_mapped_pfn )
+        return _mfn(INVALID_MFN);
+
+    /* Don't read off the end of the p2m table */
+    ASSERT(gfn < (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof(l1_pgentry_t));
+
+    ret = __copy_from_user(&l1e,
+                           &phys_to_machine_mapping[gfn],
+                           sizeof(l1e));
+
+    if ( (ret == 0) && (l1e_get_flags(l1e) & _PAGE_PRESENT) )
+        return _mfn(l1e_get_pfn(l1e));
+
+    return _mfn(INVALID_MFN);
+}
 
 /* Walk another domain's P2M table, mapping pages as we go */
-extern mfn_t
-sh_gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
-
+extern mfn_t sh_gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
 
 /* General conversion function from gfn to mfn */
 static inline mfn_t
@@ -676,12 +704,19 @@ sh_gfn_to_mfn(struct domain *d, unsigned
 {
     if ( !shadow_mode_translate(d) )
         return _mfn(gfn);
-    else if ( likely(current->domain == d) )
-        return _mfn(get_mfn_from_gpfn(gfn));
-    else
+    if ( likely(current->domain == d) )
+        return sh_gfn_to_mfn_current(gfn);
+    else 
         return sh_gfn_to_mfn_foreign(d, gfn);
 }
 
+/* Compatibility function for HVM code */
+static inline unsigned long get_mfn_from_gpfn(unsigned long pfn)
+{
+    return mfn_x(sh_gfn_to_mfn_current(pfn));
+}
+
+/* General conversion function from mfn to gfn */
 static inline unsigned long
 sh_mfn_to_gfn(struct domain *d, mfn_t mfn)
 {
@@ -689,6 +724,14 @@ sh_mfn_to_gfn(struct domain *d, mfn_t mf
         return get_gpfn_from_mfn(mfn_x(mfn));
     else
         return mfn_x(mfn);
+}
+
+/* Is this guest address an mmio one? (i.e. not defined in p2m map) */
+static inline int
+mmio_space(paddr_t gpa)
+{
+    unsigned long gfn = gpa >> PAGE_SHIFT;    
+    return !VALID_MFN(mfn_x(sh_gfn_to_mfn_current(gfn)));
 }
 
 static inline l1_pgentry_t

_______________________________________________
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] Track high-water-mark of p2m map, Xen patchbot-unstable <=