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

[Xen-changelog] [linux-2.6.18-xen] Imported patch pmd-shared.patch from xen-unstable.hg 15200:bd3d6b4c52ec



# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Date 1180947924 -3600
# Node ID 5ce6cd5ee596d51861829eba00bd723cf15f8ef5
# Parent  e1c18245a2f5a840b68e9a0344080deba1e92934
Imported patch pmd-shared.patch from xen-unstable.hg 15200:bd3d6b4c52ec
---
 arch/i386/mm/pageattr.c                |    2 -
 arch/i386/mm/pgtable.c                 |   51 +++++++++++++++++++++++++++++----
 include/asm-i386/pgtable-2level-defs.h |    2 +
 include/asm-i386/pgtable-3level-defs.h |    2 +
 4 files changed, 50 insertions(+), 7 deletions(-)

diff -r e1c18245a2f5 -r 5ce6cd5ee596 arch/i386/mm/pageattr.c
--- a/arch/i386/mm/pageattr.c   Mon Jun 04 10:05:24 2007 +0100
+++ b/arch/i386/mm/pageattr.c   Mon Jun 04 10:05:24 2007 +0100
@@ -84,7 +84,7 @@ static void set_pmd_pte(pte_t *kpte, uns
        unsigned long flags;
 
        set_pte_atomic(kpte, pte);      /* change init_mm */
-       if (PTRS_PER_PMD > 1)
+       if (HAVE_SHARED_KERNEL_PMD)
                return;
 
        spin_lock_irqsave(&pgd_lock, flags);
diff -r e1c18245a2f5 -r 5ce6cd5ee596 arch/i386/mm/pgtable.c
--- a/arch/i386/mm/pgtable.c    Mon Jun 04 10:05:24 2007 +0100
+++ b/arch/i386/mm/pgtable.c    Mon Jun 04 10:05:24 2007 +0100
@@ -214,9 +214,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
                spin_lock_irqsave(&pgd_lock, flags);
        }
 
-       clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
-                       swapper_pg_dir + USER_PTRS_PER_PGD,
-                       KERNEL_PGD_PTRS);
+       if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
+               clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
+                               swapper_pg_dir + USER_PTRS_PER_PGD,
+                               KERNEL_PGD_PTRS);
        if (PTRS_PER_PMD > 1)
                return;
 
@@ -248,6 +249,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
                        goto out_oom;
                set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
        }
+
+       if (!HAVE_SHARED_KERNEL_PMD) {
+               unsigned long flags;
+
+               for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
+                       pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
+                       if (!pmd)
+                               goto out_oom;
+                       set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
+               }
+
+               spin_lock_irqsave(&pgd_lock, flags);
+               for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
+                       unsigned long v = (unsigned long)i << PGDIR_SHIFT;
+                       pgd_t *kpgd = pgd_offset_k(v);
+                       pud_t *kpud = pud_offset(kpgd, v);
+                       pmd_t *kpmd = pmd_offset(kpud, v);
+                       pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
+                       memcpy(pmd, kpmd, PAGE_SIZE);
+               }
+               pgd_list_add(pgd);
+               spin_unlock_irqrestore(&pgd_lock, flags);
+       }
+
        return pgd;
 
 out_oom:
@@ -262,9 +287,23 @@ void pgd_free(pgd_t *pgd)
        int i;
 
        /* in the PAE case user pgd entries are overwritten before usage */
-       if (PTRS_PER_PMD > 1)
-               for (i = 0; i < USER_PTRS_PER_PGD; ++i)
-                       kmem_cache_free(pmd_cache, (void 
*)__va(pgd_val(pgd[i])-1));
+       if (PTRS_PER_PMD > 1) {
+               for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
+                       pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
+                       kmem_cache_free(pmd_cache, pmd);
+               }
+               if (!HAVE_SHARED_KERNEL_PMD) {
+                       unsigned long flags;
+                       spin_lock_irqsave(&pgd_lock, flags);
+                       pgd_list_del(pgd);
+                       spin_unlock_irqrestore(&pgd_lock, flags);
+                       for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
+                               pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
+                               memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
+                               kmem_cache_free(pmd_cache, pmd);
+                       }
+               }
+       }
        /* in the non-PAE case, free_pgtables() clears user pgd entries */
        kmem_cache_free(pgd_cache, pgd);
 }
diff -r e1c18245a2f5 -r 5ce6cd5ee596 include/asm-i386/pgtable-2level-defs.h
--- a/include/asm-i386/pgtable-2level-defs.h    Mon Jun 04 10:05:24 2007 +0100
+++ b/include/asm-i386/pgtable-2level-defs.h    Mon Jun 04 10:05:24 2007 +0100
@@ -1,5 +1,7 @@
 #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
 #define _I386_PGTABLE_2LEVEL_DEFS_H
+
+#define HAVE_SHARED_KERNEL_PMD 0
 
 /*
  * traditional i386 two-level paging structure:
diff -r e1c18245a2f5 -r 5ce6cd5ee596 include/asm-i386/pgtable-3level-defs.h
--- a/include/asm-i386/pgtable-3level-defs.h    Mon Jun 04 10:05:24 2007 +0100
+++ b/include/asm-i386/pgtable-3level-defs.h    Mon Jun 04 10:05:24 2007 +0100
@@ -1,5 +1,7 @@
 #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
 #define _I386_PGTABLE_3LEVEL_DEFS_H
+
+#define HAVE_SHARED_KERNEL_PMD 1
 
 /*
  * PGDIR_SHIFT determines what a top-level page table entry can map

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