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] x86: PV support for hugepages

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: PV support for hugepages
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 05 Nov 2008 07:01:04 -0800
Delivery-date: Wed, 05 Nov 2008 07:04:25 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/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 Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1225882641 0
# Node ID 5fd51e1e9c798f18a06a43c4cb83df93ac0698dd
# Parent  1e437b5b418a1c47c96f8c65442bc63ab35f671c
x86: PV support for hugepages

Hugepage support must be enabled via the hypervisor command line
option "allowhugepage". There is currently no support in the tools for
saving/restoring/migrating guests who use hugepages.

Signed-off-by: Dave McCracken <dave.mccracken@xxxxxxxxxx>
---
 xen/arch/x86/mm.c                 |   89 ++++++++++++++++++++++++++++++++------
 xen/arch/x86/traps.c              |   10 ++--
 xen/include/asm-x86/mm.h          |    1 
 xen/include/asm-x86/x86_32/page.h |    2 
 xen/include/asm-x86/x86_64/page.h |    2 
 5 files changed, 86 insertions(+), 18 deletions(-)

diff -r 1e437b5b418a -r 5fd51e1e9c79 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Nov 05 10:26:19 2008 +0000
+++ b/xen/arch/x86/mm.c Wed Nov 05 10:57:21 2008 +0000
@@ -160,6 +160,9 @@ unsigned long total_pages;
 
 #define PAGE_CACHE_ATTRS (_PAGE_PAT|_PAGE_PCD|_PAGE_PWT)
 
+int opt_allow_hugepage;
+boolean_param("allowhugepage", opt_allow_hugepage);
+
 #define l1_disallow_mask(d)                                     \
     ((d != dom_io) &&                                           \
      (rangeset_is_empty((d)->iomem_caps) &&                     \
@@ -584,6 +587,28 @@ static int get_page_and_type_from_pagenr
         put_page(page);
 
     return rc;
+}
+
+static int get_data_page(
+    struct page_info *page, struct domain *d, int writeable)
+{
+    int rc;
+
+    if ( writeable )
+        rc = get_page_and_type(page, d, PGT_writable_page);
+    else
+        rc = get_page(page, d);
+
+    return rc;
+}
+
+static void put_data_page(
+    struct page_info *page, int writeable)
+{
+    if ( writeable )
+        put_page_and_type(page);
+    else
+        put_page(page);
 }
 
 /*
@@ -700,10 +725,9 @@ get_page_from_l1e(
      * contribute to writeable mapping refcounts.  (This allows the
      * qemu-dm helper process in dom0 to map the domain's memory without
      * messing up the count of "real" writable mappings.) */
-    okay = (((l1f & _PAGE_RW) && 
-             !(unlikely(paging_mode_external(d) && (d != curr->domain))))
-            ? get_page_and_type(page, d, PGT_writable_page)
-            : get_page(page, d));
+    okay = get_data_page(
+        page, d,
+        (l1f & _PAGE_RW) && !(paging_mode_external(d) && (d != curr->domain)));
     if ( !okay )
     {
         MEM_LOG("Error getting mfn %lx (pfn %lx) from L1 entry %" PRIpte
@@ -751,6 +775,7 @@ get_page_from_l2e(
 get_page_from_l2e(
     l2_pgentry_t l2e, unsigned long pfn, struct domain *d)
 {
+    unsigned long mfn = l2e_get_pfn(l2e);
     int rc;
 
     if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
@@ -762,10 +787,37 @@ get_page_from_l2e(
         return -EINVAL;
     }
 
-    rc = get_page_and_type_from_pagenr(
-        l2e_get_pfn(l2e), PGT_l1_page_table, d, 0, 0);
-    if ( unlikely(rc == -EINVAL) && get_l2_linear_pagetable(l2e, pfn, d) )
-        rc = 0;
+    if ( !(l2e_get_flags(l2e) & _PAGE_PSE) )
+    {
+        rc = get_page_and_type_from_pagenr(mfn, PGT_l1_page_table, d, 0, 0);
+        if ( unlikely(rc == -EINVAL) && get_l2_linear_pagetable(l2e, pfn, d) )
+            rc = 0;
+    }
+    else if ( !opt_allow_hugepage || (mfn & (L1_PAGETABLE_ENTRIES-1)) )
+    {
+        rc = -EINVAL;
+    }
+    else
+    {
+        unsigned long m = mfn;
+        int writeable = !!(l2e_get_flags(l2e) & _PAGE_RW);
+  
+        do {
+            rc = get_data_page(mfn_to_page(m), d, writeable);
+            if ( unlikely(!rc) )
+            {
+                while ( m-- > mfn )
+                    put_data_page(mfn_to_page(m), writeable);
+                return -EINVAL;
+            }
+        } while ( m++ < (mfn + (L1_PAGETABLE_ENTRIES-1)) );
+
+#ifdef __x86_64__
+        map_pages_to_xen(
+            (unsigned long)mfn_to_virt(mfn), mfn, L1_PAGETABLE_ENTRIES,
+            PAGE_HYPERVISOR | l2e_get_flags(l2e));
+#endif
+    }
 
     return rc;
 }
@@ -954,13 +1006,24 @@ void put_page_from_l1e(l1_pgentry_t l1e,
  */
 static int put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn)
 {
-    if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) && 
-         (l2e_get_pfn(l2e) != pfn) )
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) || (l2e_get_pfn(l2e) == pfn) )
+        return 1;
+
+    if ( l2e_get_flags(l2e) & _PAGE_PSE )
+    {
+        unsigned long mfn = l2e_get_pfn(l2e), m = mfn;
+        int writeable = l2e_get_flags(l2e) & _PAGE_RW;
+        ASSERT(opt_allow_hugepage && !(mfn & (L1_PAGETABLE_ENTRIES-1)));
+        do {
+            put_data_page(mfn_to_page(m), writeable);
+        } while ( m++ < (mfn + (L1_PAGETABLE_ENTRIES-1)) );
+    }
+    else
     {
         put_page_and_type(l2e_get_page(l2e));
-        return 0;
-    }
-    return 1;
+    }
+
+    return 0;
 }
 
 static int __put_page_type(struct page_info *, int preemptible);
diff -r 1e437b5b418a -r 5fd51e1e9c79 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Nov 05 10:26:19 2008 +0000
+++ b/xen/arch/x86/traps.c      Wed Nov 05 10:57:21 2008 +0000
@@ -723,7 +723,8 @@ static void pv_cpuid(struct cpu_user_reg
     {
         /* Modify Feature Information. */
         __clear_bit(X86_FEATURE_VME, &d);
-        __clear_bit(X86_FEATURE_PSE, &d);
+        if ( !opt_allow_hugepage )
+            __clear_bit(X86_FEATURE_PSE, &d);
         __clear_bit(X86_FEATURE_PGE, &d);
         __clear_bit(X86_FEATURE_MCE, &d);
         __clear_bit(X86_FEATURE_MCA, &d);
@@ -2003,9 +2004,12 @@ static int emulate_privileged_op(struct 
         case 4: /* Read CR4 */
             /*
              * Guests can read CR4 to see what features Xen has enabled. We
-             * therefore lie about PGE & PSE as they are unavailable to guests.
+             * therefore lie about PGE as it is unavailable to guests.
+             * Also disallow PSE if hugepages are not enabled.
              */
-            *reg = read_cr4() & ~(X86_CR4_PGE|X86_CR4_PSE);
+            *reg = read_cr4() & ~X86_CR4_PGE;
+            if ( !opt_allow_hugepage )
+                *reg &= ~X86_CR4_PSE;
             break;
 
         default:
diff -r 1e437b5b418a -r 5fd51e1e9c79 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Wed Nov 05 10:26:19 2008 +0000
+++ b/xen/include/asm-x86/mm.h  Wed Nov 05 10:57:21 2008 +0000
@@ -263,6 +263,7 @@ pae_copy_root(struct vcpu *v, l3_pgentry
 
 int check_descriptor(const struct domain *, struct desc_struct *d);
 
+extern int opt_allow_hugepage;
 
 /******************************************************************************
  * With shadow pagetables, the different kinds of address start 
diff -r 1e437b5b418a -r 5fd51e1e9c79 xen/include/asm-x86/x86_32/page.h
--- a/xen/include/asm-x86/x86_32/page.h Wed Nov 05 10:26:19 2008 +0000
+++ b/xen/include/asm-x86/x86_32/page.h Wed Nov 05 10:57:21 2008 +0000
@@ -112,7 +112,7 @@ extern unsigned int PAGE_HYPERVISOR_NOCA
 #define BASE_DISALLOW_MASK (0xFFFFF198U & ~_PAGE_NX)
 
 #define L1_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_GNTTAB)
-#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK)
+#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK & ~_PAGE_PSE)
 #define L3_DISALLOW_MASK 0xFFFFF1FEU /* must-be-zero */
 
 #endif /* __X86_32_PAGE_H__ */
diff -r 1e437b5b418a -r 5fd51e1e9c79 xen/include/asm-x86/x86_64/page.h
--- a/xen/include/asm-x86/x86_64/page.h Wed Nov 05 10:26:19 2008 +0000
+++ b/xen/include/asm-x86/x86_64/page.h Wed Nov 05 10:57:21 2008 +0000
@@ -115,7 +115,7 @@ typedef l4_pgentry_t root_pgentry_t;
 #define BASE_DISALLOW_MASK (0xFF800198U & ~_PAGE_NX)
 
 #define L1_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_GNTTAB)
-#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK)
+#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK & ~_PAGE_PSE)
 #define L3_DISALLOW_MASK (BASE_DISALLOW_MASK)
 #define L4_DISALLOW_MASK (BASE_DISALLOW_MASK)
 

_______________________________________________
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] x86: PV support for hugepages, Xen patchbot-unstable <=