diff -urpN -X /home/fletch/.diff.exclude 700-config_irqbal/arch/i386/mm/init.c 801-separate_pmd/arch/i386/mm/init.c --- 700-config_irqbal/arch/i386/mm/init.c Wed Aug 13 20:24:18 2003 +++ 801-separate_pmd/arch/i386/mm/init.c Wed Aug 13 20:50:53 2003 @@ -511,6 +511,7 @@ void __init mem_init(void) kmem_cache_t *pgd_cache; kmem_cache_t *pmd_cache; +kmem_cache_t *kernel_pmd_cache; void __init pgtable_cache_init(void) { @@ -523,6 +524,15 @@ void __init pgtable_cache_init(void) NULL); if (!pmd_cache) panic("pgtable_cache_init(): cannot create pmd cache"); + + kernel_pmd_cache = kmem_cache_create("pae_kernel_pmd", + (PTRS_PER_PMD*sizeof(pmd_t))*KERNEL_PGD_PTRS, + 0, + SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, + kernel_pmd_ctor, + NULL); + if (!kernel_pmd_cache) + panic("pgtable_cache_init(): cannot create kernel pmd cache"); } pgd_cache = kmem_cache_create("pgd", PTRS_PER_PGD*sizeof(pgd_t), diff -urpN -X /home/fletch/.diff.exclude 700-config_irqbal/arch/i386/mm/pgtable.c 801-separate_pmd/arch/i386/mm/pgtable.c --- 700-config_irqbal/arch/i386/mm/pgtable.c Wed Aug 13 20:24:18 2003 +++ 801-separate_pmd/arch/i386/mm/pgtable.c Wed Aug 13 20:50:53 2003 @@ -157,6 +157,15 @@ void pmd_ctor(void *pmd, kmem_cache_t *c memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); } +void kernel_pmd_ctor(void *__pmd, kmem_cache_t *kernel_pmd_cache, unsigned long flags) +{ + int i; + for (i=USER_PGD_PTRS; i= 0; i--) - kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); + for (i--; i >= 0; i--) { + pmd_t *pmd = pmd_offset(&pgd[i],0); + kmem_cache_free(pmd_cache, pmd); + } kmem_cache_free(pgd_cache, pgd); return NULL; } @@ -231,9 +251,19 @@ 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 < PTRS_PER_PGD; i++) { + pmd_t *pmd_to_free = pmd_offset(&pgd[i],0); + + set_pgd(&pgd[i], __pgd(0)); + + if (i < USER_PGD_PTRS) { + kmem_cache_free(pmd_cache, pmd_to_free); + } else if (i == USER_PGD_PTRS) { + kmem_cache_free(kernel_pmd_cache, pmd_to_free); + } + } + } /* in the non-PAE case, clear_page_tables() clears user pgd entries */ kmem_cache_free(pgd_cache, pgd); } diff -urpN -X /home/fletch/.diff.exclude 700-config_irqbal/include/asm-i386/pgtable.h 801-separate_pmd/include/asm-i386/pgtable.h --- 700-config_irqbal/include/asm-i386/pgtable.h Wed Aug 13 20:24:30 2003 +++ 801-separate_pmd/include/asm-i386/pgtable.h Wed Aug 13 20:50:53 2003 @@ -34,9 +34,11 @@ extern unsigned long empty_zero_page[102 extern pgd_t swapper_pg_dir[1024]; extern kmem_cache_t *pgd_cache; extern kmem_cache_t *pmd_cache; +extern kmem_cache_t *kernel_pmd_cache; extern spinlock_t pgd_lock; extern struct list_head pgd_list; +void kernel_pmd_ctor(void *, kmem_cache_t *, unsigned long); void pmd_ctor(void *, kmem_cache_t *, unsigned long); void pgd_ctor(void *, kmem_cache_t *, unsigned long); void pgd_dtor(void *, kmem_cache_t *, unsigned long);