[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] This adds a patch for the vanilla kernel, to be pushed upstream some
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 0d415d73f8f208a2053ceb104fd332ee3a81639b # Parent de2e58cdec3779c9160dfdc937938496da63b497 This adds a patch for the vanilla kernel, to be pushed upstream some day. It adds a #define which is 1 or 0 depending on whether the pmd for the kernel address space is shared or not. Xen can't use a shared pmd due to linear mappings in the Xen private area. Also includes patches for modified files in the sparse tree. Signed-off-by: Gerd Knorr <kraxel@xxxxxxx> Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r de2e58cdec37 -r 0d415d73f8f2 linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h Mon Jul 11 15:43:12 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h Mon Jul 11 15:46:46 2005 @@ -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 de2e58cdec37 -r 0d415d73f8f2 linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Mon Jul 11 15:43:12 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Mon Jul 11 15:46:46 2005 @@ -274,14 +274,14 @@ { unsigned long flags; - if (PTRS_PER_PMD == 1) + if (!HAVE_SHARED_KERNEL_PMD) spin_lock_irqsave(&pgd_lock, flags); memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - if (PTRS_PER_PMD > 1) + if (HAVE_SHARED_KERNEL_PMD) return; pgd_list_add(pgd); @@ -289,12 +289,11 @@ memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); } -/* never called when PTRS_PER_PMD > 1 */ void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused) { unsigned long flags; /* can be called from interrupt context */ - if (PTRS_PER_PMD > 1) + if (HAVE_SHARED_KERNEL_PMD) return; spin_lock_irqsave(&pgd_lock, flags); @@ -304,12 +303,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm) { - int i; + int i = 0; pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL); if (PTRS_PER_PMD == 1 || !pgd) return pgd; + if (!HAVE_SHARED_KERNEL_PMD) { + /* alloc and copy kernel pmd */ + unsigned long flags; + pgd_t *copy_pgd = pgd_offset_k(PAGE_OFFSET); + pud_t *copy_pud = pud_offset(copy_pgd, PAGE_OFFSET); + pmd_t *copy_pmd = pmd_offset(copy_pud, PAGE_OFFSET); + pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); + if (0 == pmd) + goto out_oom; + + spin_lock_irqsave(&pgd_lock, flags); + memcpy(pmd, copy_pmd, PAGE_SIZE); + spin_unlock_irqrestore(&pgd_lock, flags); + make_page_readonly(pmd); + set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd))); + } + + /* alloc user pmds */ for (i = 0; i < USER_PTRS_PER_PGD; ++i) { pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); if (!pmd) @@ -339,9 +356,17 @@ } /* 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) { + pmd_t *pmd = (void *)__va(pgd_val(pgd[USER_PTRS_PER_PGD])-1); + make_page_writable(pmd); + 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 de2e58cdec37 -r 0d415d73f8f2 patches/linux-2.6.12/pmd-shared.patch --- /dev/null Mon Jul 11 15:43:12 2005 +++ b/patches/linux-2.6.12/pmd-shared.patch Mon Jul 11 15:46:46 2005 @@ -0,0 +1,134 @@ +diff -urNpP linux-2.6.12/arch/i386/mm/init.c linux-2.6.12.new/arch/i386/mm/init.c +--- linux-2.6.12/arch/i386/mm/init.c 2005-06-17 20:48:29.000000000 +0100 ++++ linux-2.6.12.new/arch/i386/mm/init.c 2005-07-11 16:28:09.778165582 +0100 +@@ -634,7 +634,7 @@ void __init pgtable_cache_init(void) + PTRS_PER_PGD*sizeof(pgd_t), + 0, + pgd_ctor, +- PTRS_PER_PMD == 1 ? pgd_dtor : NULL); ++ pgd_dtor); + if (!pgd_cache) + panic("pgtable_cache_init(): Cannot create pgd cache"); + } +diff -urNpP linux-2.6.12/arch/i386/mm/pageattr.c linux-2.6.12.new/arch/i386/mm/pageattr.c +--- linux-2.6.12/arch/i386/mm/pageattr.c 2005-06-17 20:48:29.000000000 +0100 ++++ linux-2.6.12.new/arch/i386/mm/pageattr.c 2005-07-11 16:28:09.775165494 +0100 +@@ -75,7 +75,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 -urNpP linux-2.6.12/arch/i386/mm/pgtable.c linux-2.6.12.new/arch/i386/mm/pgtable.c +--- linux-2.6.12/arch/i386/mm/pgtable.c 2005-06-17 20:48:29.000000000 +0100 ++++ linux-2.6.12.new/arch/i386/mm/pgtable.c 2005-07-11 16:32:01.478023726 +0100 +@@ -199,14 +199,14 @@ void pgd_ctor(void *pgd, kmem_cache_t *c + { + unsigned long flags; + +- if (PTRS_PER_PMD == 1) ++ if (!HAVE_SHARED_KERNEL_PMD) + spin_lock_irqsave(&pgd_lock, flags); + + memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + +- if (PTRS_PER_PMD > 1) ++ if (HAVE_SHARED_KERNEL_PMD) + return; + + pgd_list_add(pgd); +@@ -214,11 +214,13 @@ void pgd_ctor(void *pgd, kmem_cache_t *c + memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); + } + +-/* never called when PTRS_PER_PMD > 1 */ + void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused) + { + unsigned long flags; /* can be called from interrupt context */ + ++ if (HAVE_SHARED_KERNEL_PMD) ++ return; ++ + spin_lock_irqsave(&pgd_lock, flags); + pgd_list_del(pgd); + spin_unlock_irqrestore(&pgd_lock, flags); +@@ -226,12 +228,29 @@ void pgd_dtor(void *pgd, kmem_cache_t *c + + pgd_t *pgd_alloc(struct mm_struct *mm) + { +- int i; ++ int i = 0; + pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL); + + if (PTRS_PER_PMD == 1 || !pgd) + return pgd; + ++ if (!HAVE_SHARED_KERNEL_PMD) { ++ /* alloc and copy kernel pmd */ ++ unsigned long flags; ++ pgd_t *copy_pgd = pgd_offset_k(PAGE_OFFSET); ++ pud_t *copy_pud = pud_offset(copy_pgd, PAGE_OFFSET); ++ pmd_t *copy_pmd = pmd_offset(copy_pud, PAGE_OFFSET); ++ pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); ++ if (0 == pmd) ++ goto out_oom; ++ ++ spin_lock_irqsave(&pgd_lock, flags); ++ memcpy(pmd, copy_pmd, PAGE_SIZE); ++ spin_unlock_irqrestore(&pgd_lock, flags); ++ set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd))); ++ } ++ ++ /* alloc user pmds */ + for (i = 0; i < USER_PTRS_PER_PGD; ++i) { + pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); + if (!pmd) +@@ -252,9 +271,16 @@ 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) { ++ pmd_t *pmd = (void *)__va(pgd_val(pgd[USER_PTRS_PER_PGD])-1); ++ kmem_cache_free(pmd_cache, pmd); ++ } ++ } + /* in the non-PAE case, free_pgtables() clears user pgd entries */ + kmem_cache_free(pgd_cache, pgd); + } +diff -urNpP linux-2.6.12/include/asm-i386/pgtable-2level-defs.h linux-2.6.12.new/include/asm-i386/pgtable-2level-defs.h +--- linux-2.6.12/include/asm-i386/pgtable-2level-defs.h 2005-06-17 20:48:29.000000000 +0100 ++++ linux-2.6.12.new/include/asm-i386/pgtable-2level-defs.h 2005-07-11 16:28:09.733164251 +0100 +@@ -1,6 +1,8 @@ + #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 -urNpP linux-2.6.12/include/asm-i386/pgtable-3level-defs.h linux-2.6.12.new/include/asm-i386/pgtable-3level-defs.h +--- linux-2.6.12/include/asm-i386/pgtable-3level-defs.h 2005-06-17 20:48:29.000000000 +0100 ++++ linux-2.6.12.new/include/asm-i386/pgtable-3level-defs.h 2005-07-11 16:28:09.755164902 +0100 +@@ -1,6 +1,8 @@ + #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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |