Index: highpmd-2.6.7/arch/alpha/mm/remap.c =================================================================== --- highpmd-2.6.7.orig/arch/alpha/mm/remap.c 2004-06-15 22:18:55.000000000 -0700 +++ highpmd-2.6.7/arch/alpha/mm/remap.c 2004-07-01 03:44:01.000000000 -0700 @@ -73,7 +73,7 @@ spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; Index: highpmd-2.6.7/arch/arm/mm/consistent.c =================================================================== --- highpmd-2.6.7.orig/arch/arm/mm/consistent.c 2004-06-15 22:19:44.000000000 -0700 +++ highpmd-2.6.7/arch/arm/mm/consistent.c 2004-07-01 03:44:01.000000000 -0700 @@ -326,7 +326,7 @@ do { pgd = pgd_offset(&init_mm, CONSISTENT_BASE); - pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE); + pmd = pmd_alloc_kernel(&init_mm, pgd, CONSISTENT_BASE); if (!pmd) { printk(KERN_ERR "%s: no pmd tables\n", __func__); ret = -ENOMEM; Index: highpmd-2.6.7/arch/arm/mm/ioremap.c =================================================================== --- highpmd-2.6.7.orig/arch/arm/mm/ioremap.c 2004-06-15 22:19:37.000000000 -0700 +++ highpmd-2.6.7/arch/arm/mm/ioremap.c 2004-07-01 03:50:14.000000000 -0700 @@ -98,7 +98,7 @@ BUG_ON(address >= end); spin_lock(&init_mm.page_table_lock); do { - pmd_t *pmd = pmd_alloc(&init_mm, dir, address); + pmd_t *pmd = pmd_alloc_kernel(&init_mm, dir, address); if (!pmd) { err = -ENOMEM; break; Index: highpmd-2.6.7/arch/arm/mm/minicache.c =================================================================== --- highpmd-2.6.7.orig/arch/arm/mm/minicache.c 2004-06-15 22:19:42.000000000 -0700 +++ highpmd-2.6.7/arch/arm/mm/minicache.c 2004-07-01 03:44:01.000000000 -0700 @@ -58,7 +58,7 @@ spin_lock(&init_mm.page_table_lock); pgd = pgd_offset_k(minicache_address); - pmd = pmd_alloc(&init_mm, pgd, minicache_address); + pmd = pmd_alloc_kernel(&init_mm, pgd, minicache_address); if (!pmd) BUG(); minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address); Index: highpmd-2.6.7/arch/arm/mm/mm-armv.c =================================================================== --- highpmd-2.6.7.orig/arch/arm/mm/mm-armv.c 2004-06-15 22:19:37.000000000 -0700 +++ highpmd-2.6.7/arch/arm/mm/mm-armv.c 2004-07-01 03:44:01.000000000 -0700 @@ -160,7 +160,7 @@ if (vectors_base() == 0) { /* - * This lock is here just to satisfy pmd_alloc and pte_lock + * This lock is here just to satisfy pmd_alloc_map() and pte_lock */ spin_lock(&mm->page_table_lock); @@ -168,20 +168,22 @@ * On ARM, first page must always be allocated since it * contains the machine vectors. */ - new_pmd = pmd_alloc(mm, new_pgd, 0); + new_pmd = pmd_alloc_map(mm, new_pgd, 0); if (!new_pmd) goto no_pmd; - new_pte = pte_alloc_map(mm, new_pmd, 0); - if (!new_pte) + new_pte = pte_alloc_map(mm, new_pgd, &new_pmd, 0); + if (!new_pte) { + pmd_unmap(new_pmd); goto no_pte; + } init_pmd = pmd_offset(init_pgd, 0); init_pte = pte_offset_map_nested(init_pmd, 0); set_pte(new_pte, *init_pte); pte_unmap_nested(init_pte); pte_unmap(new_pte); - + pmd_unmap(new_pmd); spin_unlock(&mm->page_table_lock); } Index: highpmd-2.6.7/arch/arm26/mm/mm-memc.c =================================================================== --- highpmd-2.6.7.orig/arch/arm26/mm/mm-memc.c 2004-06-15 22:20:17.000000000 -0700 +++ highpmd-2.6.7/arch/arm26/mm/mm-memc.c 2004-07-01 03:44:01.000000000 -0700 @@ -79,7 +79,7 @@ goto no_pgd; /* - * This lock is here just to satisfy pmd_alloc and pte_lock + * This lock is here just to satisfy pmd_alloc_kernel() and pte_lock * FIXME: I bet we could avoid taking it pretty much altogether */ spin_lock(&mm->page_table_lock); @@ -88,7 +88,7 @@ * On ARM, first page must always be allocated since it contains * the machine vectors. */ - new_pmd = pmd_alloc(mm, new_pgd, 0); + new_pmd = pmd_alloc_kernel(mm, new_pgd, 0); if (!new_pmd) goto no_pmd; Index: highpmd-2.6.7/arch/cris/mm/ioremap.c =================================================================== --- highpmd-2.6.7.orig/arch/cris/mm/ioremap.c 2004-06-15 22:18:58.000000000 -0700 +++ highpmd-2.6.7/arch/cris/mm/ioremap.c 2004-07-01 03:44:01.000000000 -0700 @@ -78,7 +78,7 @@ spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; Index: highpmd-2.6.7/arch/i386/Kconfig =================================================================== --- highpmd-2.6.7.orig/arch/i386/Kconfig 2004-06-15 22:18:59.000000000 -0700 +++ highpmd-2.6.7/arch/i386/Kconfig 2004-07-01 03:44:01.000000000 -0700 @@ -753,6 +753,16 @@ low memory. Setting this option will put user-space page table entries in high memory. +config HIGHPMD + bool "Allocate 2nd-level pagetables from highmem" + depends on HIGHMEM64G && HIGHPTE + help + The VM uses one lowmem-allocated pmd entry for each pagetable + page of physical memory allocated, and preallocates them all + for 12KB of per-process lowmem overhead. For systems with + extreme amounts of highmem, this cannot be tolerated. Setting + this option will put userspace 2nd-level pagetables in highmem. + config MATH_EMULATION bool "Math emulation" ---help--- Index: highpmd-2.6.7/arch/i386/kernel/vm86.c =================================================================== --- highpmd-2.6.7.orig/arch/i386/kernel/vm86.c 2004-06-15 22:18:58.000000000 -0700 +++ highpmd-2.6.7/arch/i386/kernel/vm86.c 2004-07-01 03:44:01.000000000 -0700 @@ -152,12 +152,14 @@ pgd_clear(pgd); goto out; } - pmd = pmd_offset(pgd, 0xA0000); - if (pmd_none(*pmd)) + pmd = pmd_offset_map(pgd, 0xA0000); + if (pmd_none(*pmd)) { + pmd_unmap(pmd); goto out; - if (pmd_bad(*pmd)) { + } else if (pmd_bad(*pmd)) { pmd_ERROR(*pmd); pmd_clear(pmd); + pmd_unmap(pmd); goto out; } pte = mapped = pte_offset_map(pmd, 0xA0000); @@ -167,6 +169,7 @@ pte++; } pte_unmap(mapped); + pmd_unmap(pmd); out: spin_unlock(&tsk->mm->page_table_lock); preempt_enable(); Index: highpmd-2.6.7/arch/i386/mm/fault.c =================================================================== --- highpmd-2.6.7.orig/arch/i386/mm/fault.c 2004-06-15 22:18:37.000000000 -0700 +++ highpmd-2.6.7/arch/i386/mm/fault.c 2004-07-01 03:44:01.000000000 -0700 @@ -414,6 +414,13 @@ printk(KERN_ALERT " printing eip:\n"); printk("%08lx\n", regs->eip); asm("movl %%cr3,%0":"=r" (page)); +#ifdef CONFIG_HIGHPMD /* Oh boy. Error reporting is going to blow major goats. */ + printk(KERN_ALERT "%%cr3 = 0x%lx\n", page); + /* Mask off flag bits. It should end up 32B-aligned. */ + page &= ~(PTRS_PER_PGD*sizeof(pgd_t) - 1); + printk(KERN_ALERT "*pdpte = 0x%Lx\n", + pgd_val(((pgd_t *)__va(page))[address >> PGDIR_SHIFT])); +#else /* !CONFIG_HIGHPMD */ page = ((unsigned long *) __va(page))[address >> 22]; printk(KERN_ALERT "*pde = %08lx\n", page); /* @@ -429,7 +436,8 @@ page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; printk(KERN_ALERT "*pte = %08lx\n", page); } -#endif +#endif /* !CONFIG_HIGHPTE */ +#endif /* CONFIG_HIGHPMD */ die("Oops", regs, error_code); bust_spinlocks(0); do_exit(SIGKILL); @@ -497,8 +505,8 @@ * and redundant with the set_pmd() on non-PAE. */ - pmd = pmd_offset(pgd, address); - pmd_k = pmd_offset(pgd_k, address); + pmd = pmd_offset_kernel(pgd, address); + pmd_k = pmd_offset_kernel(pgd_k, address); if (!pmd_present(*pmd_k)) goto no_context; set_pmd(pmd, *pmd_k); Index: highpmd-2.6.7/arch/i386/mm/hugetlbpage.c =================================================================== --- highpmd-2.6.7.orig/arch/i386/mm/hugetlbpage.c 2004-06-15 22:20:03.000000000 -0700 +++ highpmd-2.6.7/arch/i386/mm/hugetlbpage.c 2004-07-01 04:25:22.000000000 -0700 @@ -25,8 +25,8 @@ pmd_t *pmd = NULL; pgd = pgd_offset(mm, addr); - pmd = pmd_alloc(mm, pgd, addr); - return (pte_t *) pmd; + pmd = pmd_alloc_map(mm, pgd, addr); + return (pte_t *)pmd; } static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) @@ -35,8 +35,8 @@ pmd_t *pmd = NULL; pgd = pgd_offset(mm, addr); - pmd = pmd_offset(pgd, addr); - return (pte_t *) pmd; + pmd = pmd_offset_map_nested(pgd, addr); + return (pte_t *)pmd; } static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, struct page *page, pte_t * page_table, int write_access) @@ -83,6 +83,8 @@ ptepage = pte_page(entry); get_page(ptepage); set_pte(dst_pte, entry); + pmd_unmap(dst_pte); + pmd_unmap_nested(src_pte); dst->rss += (HPAGE_SIZE / PAGE_SIZE); addr += HPAGE_SIZE; } @@ -120,6 +122,7 @@ get_page(page); pages[i] = page; + pmd_unmap_nested(pte); } if (vmas) @@ -209,18 +212,20 @@ { struct mm_struct *mm = vma->vm_mm; unsigned long address; - pte_t pte; + pte_t pte, *ptep; struct page *page; BUG_ON(start & (HPAGE_SIZE - 1)); BUG_ON(end & (HPAGE_SIZE - 1)); for (address = start; address < end; address += HPAGE_SIZE) { - pte = ptep_get_and_clear(huge_pte_offset(mm, address)); + ptep = huge_pte_offset(mm, address); + pte = ptep_get_and_clear(ptep); if (pte_none(pte)) continue; page = pte_page(pte); put_page(page); + pmd_unmap_nested(ptep); } mm->rss -= (end - start) >> PAGE_SHIFT; flush_tlb_range(vma, start, end); @@ -245,8 +250,10 @@ ret = -ENOMEM; goto out; } - if (!pte_none(*pte)) + if (!pte_none(*pte)) { + pmd_unmap(pte); continue; + } idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); @@ -255,12 +262,14 @@ /* charge the fs quota first */ if (hugetlb_get_quota(mapping)) { ret = -ENOMEM; + pmd_unmap(pte); goto out; } page = alloc_huge_page(); if (!page) { hugetlb_put_quota(mapping); ret = -ENOMEM; + pmd_unmap(pte); goto out; } ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC); @@ -269,10 +278,12 @@ } else { hugetlb_put_quota(mapping); free_huge_page(page); + pmd_unmap(pte); goto out; } } set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE); + pmd_unmap(pte); } out: spin_unlock(&mm->page_table_lock); Index: highpmd-2.6.7/arch/i386/mm/init.c =================================================================== --- highpmd-2.6.7.orig/arch/i386/mm/init.c 2004-06-15 22:19:44.000000000 -0700 +++ highpmd-2.6.7/arch/i386/mm/init.c 2004-07-01 03:49:31.000000000 -0700 @@ -58,10 +58,10 @@ #ifdef CONFIG_X86_PAE pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); - if (pmd_table != pmd_offset(pgd, 0)) + if (pmd_table != pmd_offset_kernel(pgd, 0)) BUG(); #else - pmd_table = pmd_offset(pgd, 0); + pmd_table = pmd_offset_kernel(pgd, 0); #endif return pmd_table; @@ -112,7 +112,7 @@ if (pgd_none(*pgd)) one_md_table_init(pgd); - pmd = pmd_offset(pgd, vaddr); + pmd = pmd_offset_kernel(pgd, vaddr); for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) { if (pmd_none(*pmd)) one_page_table_init(pmd); @@ -214,7 +214,7 @@ EXPORT_SYMBOL(kmap_pte); #define kmap_get_fixmap_pte(vaddr) \ - pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) + pte_offset_kernel(pmd_offset_kernel(pgd_offset_k(vaddr), (vaddr)), (vaddr)) void __init kmap_init(void) { @@ -238,7 +238,7 @@ page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); pgd = swapper_pg_dir + pgd_index(vaddr); - pmd = pmd_offset(pgd, vaddr); + pmd = pmd_offset_kernel(pgd, vaddr); pte = pte_offset_kernel(pmd, vaddr); pkmap_page_table = pte; } @@ -545,20 +545,9 @@ } kmem_cache_t *pgd_cache; -kmem_cache_t *pmd_cache; void __init pgtable_cache_init(void) { - if (PTRS_PER_PMD > 1) { - pmd_cache = kmem_cache_create("pmd", - PTRS_PER_PMD*sizeof(pmd_t), - PTRS_PER_PMD*sizeof(pmd_t), - 0, - pmd_ctor, - NULL); - if (!pmd_cache) - panic("pgtable_cache_init(): cannot create pmd cache"); - } pgd_cache = kmem_cache_create("pgd", PTRS_PER_PGD*sizeof(pgd_t), PTRS_PER_PGD*sizeof(pgd_t), Index: highpmd-2.6.7/arch/i386/mm/ioremap.c =================================================================== --- highpmd-2.6.7.orig/arch/i386/mm/ioremap.c 2004-06-15 22:19:02.000000000 -0700 +++ highpmd-2.6.7/arch/i386/mm/ioremap.c 2004-07-01 03:44:01.000000000 -0700 @@ -82,7 +82,7 @@ spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; Index: highpmd-2.6.7/arch/i386/mm/pageattr.c =================================================================== --- highpmd-2.6.7.orig/arch/i386/mm/pageattr.c 2004-06-15 22:19:22.000000000 -0700 +++ highpmd-2.6.7/arch/i386/mm/pageattr.c 2004-07-01 03:44:01.000000000 -0700 @@ -23,7 +23,7 @@ pmd_t *pmd; if (pgd_none(*pgd)) return NULL; - pmd = pmd_offset(pgd, address); + pmd = pmd_offset_kernel(pgd, address); if (pmd_none(*pmd)) return NULL; if (pmd_large(*pmd)) @@ -79,7 +79,7 @@ pgd_t *pgd; pmd_t *pmd; pgd = (pgd_t *)page_address(page) + pgd_index(address); - pmd = pmd_offset(pgd, address); + pmd = pmd_offset_kernel(pgd, address); set_pte_atomic((pte_t *)pmd, pte); } spin_unlock_irqrestore(&pgd_lock, flags); @@ -92,7 +92,7 @@ static inline void revert_page(struct page *kpte_page, unsigned long address) { pte_t *linear = (pte_t *) - pmd_offset(pgd_offset(&init_mm, address), address); + pmd_offset_kernel(pgd_offset_k(address), address); set_pmd_pte(linear, address, pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT, PAGE_KERNEL_LARGE)); Index: highpmd-2.6.7/arch/i386/mm/pgtable.c =================================================================== --- highpmd-2.6.7.orig/arch/i386/mm/pgtable.c 2004-06-15 22:20:26.000000000 -0700 +++ highpmd-2.6.7/arch/i386/mm/pgtable.c 2004-07-01 03:44:01.000000000 -0700 @@ -70,7 +70,7 @@ BUG(); return; } - pmd = pmd_offset(pgd, vaddr); + pmd = pmd_offset_kernel(pgd, vaddr); if (pmd_none(*pmd)) { BUG(); return; @@ -110,7 +110,7 @@ printk ("set_pmd_pfn: pgd_none\n"); return; /* BUG(); */ } - pmd = pmd_offset(pgd, vaddr); + pmd = pmd_offset_kernel(pgd, vaddr); set_pmd(pmd, pfn_pmd(pfn, flags)); /* * It's enough to flush this one mapping. @@ -152,11 +152,6 @@ return pte; } -void pmd_ctor(void *pmd, kmem_cache_t *cache, unsigned long flags) -{ - memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); -} - /* * List of all pgd's needed for non-PAE so it can invalidate entries * in both cached and uncached pgd's; not needed for PAE since the @@ -232,16 +227,22 @@ return pgd; for (i = 0; i < USER_PTRS_PER_PGD; ++i) { - pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); + struct page *pmd; +#ifdef CONFIG_HIGHPMD + pmd = alloc_page(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT); +#else + pmd = alloc_page(GFP_KERNEL|__GFP_REPEAT); +#endif if (!pmd) goto out_oom; - set_pgd(&pgd[i], __pgd(1 + __pa((u64)((u32)pmd)))); + clear_highpage(pmd); + set_pgd(&pgd[i], __pgd(1ULL | (u64)page_to_pfn(pmd) << PAGE_SHIFT)); } return pgd; out_oom: for (i--; i >= 0; i--) - kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); + __free_page(pgd_page(pgd[i])); kmem_cache_free(pgd_cache, pgd); return NULL; } @@ -253,7 +254,7 @@ /* 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)); + __free_page(pgd_page(pgd[i])); /* in the non-PAE case, clear_page_tables() clears user pgd entries */ kmem_cache_free(pgd_cache, pgd); } Index: highpmd-2.6.7/arch/ia64/mm/hugetlbpage.c =================================================================== --- highpmd-2.6.7.orig/arch/ia64/mm/hugetlbpage.c 2004-06-15 22:19:23.000000000 -0700 +++ highpmd-2.6.7/arch/ia64/mm/hugetlbpage.c 2004-07-01 03:44:01.000000000 -0700 @@ -33,9 +33,9 @@ pte_t *pte = NULL; pgd = pgd_offset(mm, taddr); - pmd = pmd_alloc(mm, pgd, taddr); + pmd = pmd_alloc_map(mm, pgd, taddr); if (pmd) - pte = pte_alloc_map(mm, pmd, taddr); + pte = pte_alloc_map(mm, pgd, &pmd, taddr); return pte; } Index: highpmd-2.6.7/arch/ia64/mm/init.c =================================================================== --- highpmd-2.6.7.orig/arch/ia64/mm/init.c 2004-06-15 22:19:22.000000000 -0700 +++ highpmd-2.6.7/arch/ia64/mm/init.c 2004-07-01 03:44:01.000000000 -0700 @@ -234,10 +234,10 @@ spin_lock(&init_mm.page_table_lock); { - pmd = pmd_alloc(&init_mm, pgd, address); + pmd = pmd_alloc_kernel(&init_mm, pgd, address); if (!pmd) goto out; - pte = pte_alloc_map(&init_mm, pmd, address); + pte = pte_alloc_map(&init_mm, pgd, &pmd, address); if (!pte) goto out; if (!pte_none(*pte)) { Index: highpmd-2.6.7/arch/m68k/kernel/head.S =================================================================== --- highpmd-2.6.7.orig/arch/m68k/kernel/head.S 2004-06-15 22:20:26.000000000 -0700 +++ highpmd-2.6.7/arch/m68k/kernel/head.S 2004-07-01 03:44:01.000000000 -0700 @@ -110,7 +110,7 @@ * * These routines are used by other mmu routines to get a pointer into * a table, if necessary a new table is allocated. These routines are working - * basically like pmd_alloc() and pte_alloc() in . The root + * basically like pmd_alloc_map() and pte_alloc_map() in . The root * table needs of course only to be allocated once in mmu_get_root_table_entry, * so that here also some mmu specific initialization is done. The second page * at the start of the kernel (the first page is unmapped later) is used for Index: highpmd-2.6.7/arch/m68k/mm/kmap.c =================================================================== --- highpmd-2.6.7.orig/arch/m68k/mm/kmap.c 2004-06-15 22:20:04.000000000 -0700 +++ highpmd-2.6.7/arch/m68k/mm/kmap.c 2004-07-01 03:44:01.000000000 -0700 @@ -189,7 +189,7 @@ printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr); #endif pgd_dir = pgd_offset_k(virtaddr); - pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr); + pmd_dir = pmd_alloc_kernel(&init_mm, pgd_dir, virtaddr); if (!pmd_dir) { printk("ioremap: no mem for pmd_dir\n"); return NULL; Index: highpmd-2.6.7/arch/m68k/sun3x/dvma.c =================================================================== --- highpmd-2.6.7.orig/arch/m68k/sun3x/dvma.c 2004-06-15 22:18:59.000000000 -0700 +++ highpmd-2.6.7/arch/m68k/sun3x/dvma.c 2004-07-01 03:44:01.000000000 -0700 @@ -102,7 +102,7 @@ pmd_t *pmd; unsigned long end2; - if((pmd = pmd_alloc(&init_mm, pgd, vaddr)) == NULL) { + if((pmd = pmd_alloc_kernel(&init_mm, pgd, vaddr)) == NULL) { ret = -ENOMEM; goto out; } Index: highpmd-2.6.7/arch/mips/mm/ioremap.c =================================================================== --- highpmd-2.6.7.orig/arch/mips/mm/ioremap.c 2004-06-15 22:19:23.000000000 -0700 +++ highpmd-2.6.7/arch/mips/mm/ioremap.c 2004-07-01 03:44:01.000000000 -0700 @@ -80,7 +80,7 @@ spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; Index: highpmd-2.6.7/arch/parisc/kernel/pci-dma.c =================================================================== --- highpmd-2.6.7.orig/arch/parisc/kernel/pci-dma.c 2004-06-15 22:20:03.000000000 -0700 +++ highpmd-2.6.7/arch/parisc/kernel/pci-dma.c 2004-07-01 03:44:01.000000000 -0700 @@ -133,7 +133,7 @@ do { pmd_t *pmd; - pmd = pmd_alloc(NULL, dir, vaddr); + pmd = pmd_alloc_kernel(NULL, dir, vaddr); if (!pmd) return -ENOMEM; if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr)) Index: highpmd-2.6.7/arch/parisc/mm/ioremap.c =================================================================== --- highpmd-2.6.7.orig/arch/parisc/mm/ioremap.c 2004-06-15 22:19:13.000000000 -0700 +++ highpmd-2.6.7/arch/parisc/mm/ioremap.c 2004-07-01 03:44:01.000000000 -0700 @@ -77,7 +77,7 @@ spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(dir, address); + pmd = pmd_alloc_kernel(dir, address); error = -ENOMEM; if (!pmd) break; Index: highpmd-2.6.7/arch/ppc64/mm/init.c =================================================================== --- highpmd-2.6.7.orig/arch/ppc64/mm/init.c 2004-06-15 22:19:36.000000000 -0700 +++ highpmd-2.6.7/arch/ppc64/mm/init.c 2004-07-01 03:44:01.000000000 -0700 @@ -151,7 +151,7 @@ if (mem_init_done) { spin_lock(&ioremap_mm.page_table_lock); pgdp = pgd_offset_i(ea); - pmdp = pmd_alloc(&ioremap_mm, pgdp, ea); + pmdp = pmd_alloc_kernel(&ioremap_mm, pgdp, ea); ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea); pa = abs_to_phys(pa); Index: highpmd-2.6.7/arch/s390/mm/ioremap.c =================================================================== --- highpmd-2.6.7.orig/arch/s390/mm/ioremap.c 2004-06-15 22:18:59.000000000 -0700 +++ highpmd-2.6.7/arch/s390/mm/ioremap.c 2004-07-01 03:44:01.000000000 -0700 @@ -83,7 +83,7 @@ spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; Index: highpmd-2.6.7/arch/sh/mm/ioremap.c =================================================================== --- highpmd-2.6.7.orig/arch/sh/mm/ioremap.c 2004-06-15 22:19:36.000000000 -0700 +++ highpmd-2.6.7/arch/sh/mm/ioremap.c 2004-07-01 03:44:01.000000000 -0700 @@ -45,7 +45,7 @@ } while (address && (address < end)); } -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, +static inline int remap_area_pmd(pgd_t *pgd, pmd_t * pmd, unsigned long address, unsigned long size, unsigned long phys_addr, unsigned long flags) { unsigned long end; @@ -83,11 +83,11 @@ spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_map(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; - if (remap_area_pmd(pmd, address, end - address, + if (remap_area_pmd(dir, pmd, address, end - address, phys_addr + address, flags)) break; error = 0; Index: highpmd-2.6.7/arch/sparc/mm/generic.c =================================================================== --- highpmd-2.6.7.orig/arch/sparc/mm/generic.c 2004-06-15 22:20:03.000000000 -0700 +++ highpmd-2.6.7/arch/sparc/mm/generic.c 2004-07-01 03:44:01.000000000 -0700 @@ -67,7 +67,7 @@ } while (address < end); } -static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigned long size, +static inline int io_remap_pmd_range(pgd_t *pgd, pmd_t * pmd, unsigned long address, unsigned long size, unsigned long offset, pgprot_t prot, int space) { unsigned long end; @@ -78,7 +78,7 @@ end = PGDIR_SIZE; offset -= address; do { - pte_t * pte = pte_alloc_map(current->mm, pmd, address); + pte_t * pte = pte_alloc_map(current->mm, pgd, &pmd, address); if (!pte) return -ENOMEM; io_remap_pte_range(pte, address, end - address, address + offset, prot, space); @@ -103,11 +103,11 @@ spin_lock(&mm->page_table_lock); while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); + pmd_t *pmd = pmd_alloc_map(current->mm, dir, from); error = -ENOMEM; if (!pmd) break; - error = io_remap_pmd_range(pmd, from, end - from, offset + from, prot, space); + error = io_remap_pmd_range(pgd, pmd, from, end - from, offset + from, prot, space); if (error) break; from = (from + PGDIR_SIZE) & PGDIR_MASK; Index: highpmd-2.6.7/arch/sparc/mm/srmmu.c =================================================================== --- highpmd-2.6.7.orig/arch/sparc/mm/srmmu.c 2004-06-15 22:19:36.000000000 -0700 +++ highpmd-2.6.7/arch/sparc/mm/srmmu.c 2004-07-01 03:44:01.000000000 -0700 @@ -2164,7 +2164,7 @@ BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM); BTFIXUPSET_SETHI(none_mask, 0xF0000000); @@ -2196,7 +2196,7 @@ BTFIXUPSET_CALL(pte_alloc_one_kernel, srmmu_pte_alloc_one_kernel, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pte_alloc_one, srmmu_pte_alloc_one, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(free_pmd_fast, srmmu_pmd_free, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_alloc_one, srmmu_pmd_alloc_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__pmd_alloc_one, srmmu_pmd_alloc_one, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(free_pgd_fast, srmmu_free_pgd_fast, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(get_pgd_fast, srmmu_get_pgd_fast, BTFIXUPCALL_NORM); Index: highpmd-2.6.7/arch/sparc/mm/sun4c.c =================================================================== --- highpmd-2.6.7.orig/arch/sparc/mm/sun4c.c 2004-06-15 22:19:44.000000000 -0700 +++ highpmd-2.6.7/arch/sparc/mm/sun4c.c 2004-07-01 03:44:01.000000000 -0700 @@ -2221,7 +2221,7 @@ BTFIXUPSET_CALL(pte_alloc_one_kernel, sun4c_pte_alloc_one_kernel, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pte_alloc_one, sun4c_pte_alloc_one, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(free_pmd_fast, sun4c_free_pmd_fast, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(pmd_alloc_one, sun4c_pmd_alloc_one, BTFIXUPCALL_RETO0); + BTFIXUPSET_CALL(__pmd_alloc_one, sun4c_pmd_alloc_one, BTFIXUPCALL_RETO0); BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(get_pgd_fast, sun4c_get_pgd_fast, BTFIXUPCALL_NORM); @@ -2266,5 +2266,5 @@ /* These should _never_ get called with two level tables. */ BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0); + BTFIXUPSET_CALL(__pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0); } Index: highpmd-2.6.7/arch/sparc64/mm/generic.c =================================================================== --- highpmd-2.6.7.orig/arch/sparc64/mm/generic.c 2004-06-15 22:19:52.000000000 -0700 +++ highpmd-2.6.7/arch/sparc64/mm/generic.c 2004-07-01 03:44:01.000000000 -0700 @@ -85,7 +85,7 @@ } while (address < end); } -static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigned long size, +static inline int io_remap_pmd_range(pgd_t *pgd, pmd_t * pmd, unsigned long address, unsigned long size, unsigned long offset, pgprot_t prot, int space) { unsigned long end; @@ -96,7 +96,7 @@ end = PGDIR_SIZE; offset -= address; do { - pte_t * pte = pte_alloc_map(current->mm, pmd, address); + pte_t * pte = pte_alloc_map(current->mm, pgd, &pmd, address); if (!pte) return -ENOMEM; io_remap_pte_range(pte, address, end - address, address + offset, prot, space); @@ -122,11 +122,11 @@ spin_lock(&mm->page_table_lock); while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); + pmd_t *pmd = pmd_alloc_map(current->mm, dir, from); error = -ENOMEM; if (!pmd) break; - error = io_remap_pmd_range(pmd, from, end - from, offset + from, prot, space); + error = io_remap_pmd_range(pgd, pmd, from, end - from, offset + from, prot, space); if (error) break; from = (from + PGDIR_SIZE) & PGDIR_MASK; Index: highpmd-2.6.7/arch/sparc64/mm/hugetlbpage.c =================================================================== --- highpmd-2.6.7.orig/arch/sparc64/mm/hugetlbpage.c 2004-06-15 22:19:42.000000000 -0700 +++ highpmd-2.6.7/arch/sparc64/mm/hugetlbpage.c 2004-07-01 03:44:01.000000000 -0700 @@ -29,9 +29,11 @@ pgd = pgd_offset(mm, addr); if (pgd) { - pmd = pmd_alloc(mm, pgd, addr); - if (pmd) - pte = pte_alloc_map(mm, pmd, addr); + pmd = pmd_alloc_map(mm, pgd, addr); + if (pmd) { + pte = pte_alloc_map(mm, pgd, &pmd, addr); + pmd_unmap(pmd); + } } return pte; } @@ -44,9 +46,11 @@ pgd = pgd_offset(mm, addr); if (pgd) { - pmd = pmd_offset(pgd, addr); - if (pmd) + pmd = pmd_offset_map(pgd, addr); + if (pmd) { pte = pte_offset_map(pmd, addr); + pmd_unmap(pmd); + } } return pte; } Index: highpmd-2.6.7/arch/x86_64/ia32/syscall32.c =================================================================== --- highpmd-2.6.7.orig/arch/x86_64/ia32/syscall32.c 2004-06-15 22:19:37.000000000 -0700 +++ highpmd-2.6.7/arch/x86_64/ia32/syscall32.c 2004-07-01 03:51:23.000000000 -0700 @@ -41,8 +41,8 @@ down_read(&mm->mmap_sem); spin_lock(&mm->page_table_lock); - pmd = pmd_alloc(mm, pgd_offset(mm, address), address); - if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) { + pmd = pmd_alloc_map(mm, pgd_offset(mm, address), address); + if (pmd && (pte = pte_alloc_map(mm, &pmd, address)) != NULL) { if (pte_none(*pte)) { set_pte(pte, mk_pte(virt_to_page(syscall32_page), Index: highpmd-2.6.7/arch/x86_64/mm/ioremap.c =================================================================== --- highpmd-2.6.7.orig/arch/x86_64/mm/ioremap.c 2004-06-15 22:20:03.000000000 -0700 +++ highpmd-2.6.7/arch/x86_64/mm/ioremap.c 2004-07-01 03:44:01.000000000 -0700 @@ -82,7 +82,7 @@ spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; Index: highpmd-2.6.7/drivers/char/drm/drm_memory.h =================================================================== --- highpmd-2.6.7.orig/drivers/char/drm/drm_memory.h 2004-06-15 22:19:01.000000000 -0700 +++ highpmd-2.6.7/drivers/char/drm/drm_memory.h 2004-07-01 03:44:01.000000000 -0700 @@ -125,7 +125,7 @@ drm_follow_page (void *vaddr) { pgd_t *pgd = pgd_offset_k((unsigned long) vaddr); - pmd_t *pmd = pmd_offset(pgd, (unsigned long) vaddr); + pmd_t *pmd = pmd_offset_kernel(pgd, (unsigned long)vaddr); pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr); return pte_pfn(*ptep) << PAGE_SHIFT; } Index: highpmd-2.6.7/fs/exec.c =================================================================== --- highpmd-2.6.7.orig/fs/exec.c 2004-06-15 22:19:13.000000000 -0700 +++ highpmd-2.6.7/fs/exec.c 2004-07-01 04:38:01.000000000 -0700 @@ -310,10 +310,10 @@ pgd = pgd_offset(mm, address); spin_lock(&mm->page_table_lock); - pmd = pmd_alloc(mm, pgd, address); + pmd = pmd_alloc_map(mm, pgd, address); if (!pmd) goto out; - pte = pte_alloc_map(mm, pmd, address); + pte = pte_alloc_map(mm, pgd, &pmd, address); if (!pte) goto out; if (!pte_none(*pte)) { @@ -326,11 +326,14 @@ page, vma->vm_page_prot)))); page_add_anon_rmap(page, vma, address); pte_unmap(pte); + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); /* no need for flush_tlb */ return; out: + if (pmd) + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); out_sig: __free_page(page); Index: highpmd-2.6.7/include/asm-alpha/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-alpha/pgalloc.h 2004-06-15 22:18:38.000000000 -0700 +++ highpmd-2.6.7/include/asm-alpha/pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -24,9 +24,9 @@ } static inline void -pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) +pgd_populate(struct mm_struct *mm, pgd_t *pgd, struct page *pmd) { - pgd_set(pgd, pmd); + pgd_set(pgd, page_address(pmd)); } extern pgd_t *pgd_alloc(struct mm_struct *mm); @@ -37,19 +37,29 @@ free_page((unsigned long)pgd); } -static inline pmd_t * +static inline struct page * pmd_alloc_one(struct mm_struct *mm, unsigned long address) { - pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); - if (ret) - clear_page(ret); - return ret; + struct page *page = alloc_page(GFP_KERNEL|__GFP_REPEAT); + if (page) + clear_highpage(page); + return page; +} + +static inline pmd_t * +pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) +{ + struct page *page = pmd_alloc_one(mm, addr); + if (page) + return page_address(page); + else + return NULL; } static inline void -pmd_free(pmd_t *pmd) +pmd_free(struct page *pmd) { - free_page((unsigned long)pmd); + __free_page(pmd); } extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); Index: highpmd-2.6.7/include/asm-alpha/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-alpha/pgtable.h 2004-06-15 22:19:03.000000000 -0700 +++ highpmd-2.6.7/include/asm-alpha/pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -228,9 +228,11 @@ #define pmd_page(pmd) (mem_map + ((pmd_val(pmd) & _PFN_MASK) >> 32)) #endif -extern inline unsigned long pgd_page(pgd_t pgd) +extern inline unsigned long __pgd_page(pgd_t pgd) { return PAGE_OFFSET + ((pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); } +#define pgd_page(pgd) virt_to_page(__pgd_page(pgd)) + extern inline int pte_none(pte_t pte) { return !pte_val(pte); } extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; } extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } @@ -279,9 +281,15 @@ /* Find an entry in the second-level page table.. */ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) { - return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); + return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); } +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + /* Find an entry in the third-level page table.. */ extern inline pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address) { Index: highpmd-2.6.7/include/asm-arm/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-arm/pgalloc.h 2004-06-15 22:20:04.000000000 -0700 +++ highpmd-2.6.7/include/asm-arm/pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -17,7 +17,8 @@ /* * Since we have only two-level page tables, these are trivial */ -#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm,addr) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm,addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(pmd) do { } while (0) #define pgd_populate(mm,pmd,pte) BUG() Index: highpmd-2.6.7/include/asm-arm/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-arm/pgtable.h 2004-06-15 22:19:02.000000000 -0700 +++ highpmd-2.6.7/include/asm-arm/pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -373,6 +373,11 @@ /* Find an entry in the second-level page table.. */ #define pmd_offset(dir, addr) ((pmd_t *)(dir)) +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) /* Find an entry in the third-level page table.. */ #define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) Index: highpmd-2.6.7/include/asm-arm26/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-arm26/pgalloc.h 2004-06-15 22:20:26.000000000 -0700 +++ highpmd-2.6.7/include/asm-arm26/pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -55,7 +55,8 @@ * is thrown away. It just cant be zero. -IM */ -#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm,addr) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm,addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(pmd) do { } while (0) #define pgd_populate(mm,pmd,pte) BUG() Index: highpmd-2.6.7/include/asm-arm26/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-arm26/pgtable.h 2004-06-15 22:18:58.000000000 -0700 +++ highpmd-2.6.7/include/asm-arm26/pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -99,7 +99,7 @@ * on arm26 we have no 2nd level page table. we simulate this by removing the * PMD. * - * pgd_none is 0 to prevernt pmd_alloc() calling __pmd_alloc(). This causes it + * pgd_none is 0 to prevernt pmd_alloc_map() calling __pmd_alloc(). This causes it * to return pmd_offset(pgd,addr) which is a pointer to the pgd (IOW, a no-op). * * however, to work this way, whilst we are allocating 32 pgds, containing 32 @@ -134,7 +134,7 @@ #define _PMD_PRESENT (0x01) -/* These definitions allow us to optimise out stuff like pmd_alloc() */ +/* These definitions allow us to optimise out stuff like pmd_alloc_map() */ #define pgd_none(pgd) (0) #define pgd_bad(pgd) (0) #define pgd_present(pgd) (1) @@ -188,6 +188,12 @@ #define pte_unmap(pte) do { } while (0) #define pte_unmap_nested(pte) do { } while (0) +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pgd, addr) do { } while (0) +#define pmd_unmap_nested(pgd, addr) do { } while (0) + #define _PAGE_PRESENT 0x01 #define _PAGE_READONLY 0x02 Index: highpmd-2.6.7/include/asm-cris/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-cris/pgalloc.h 2004-06-15 22:19:52.000000000 -0700 +++ highpmd-2.6.7/include/asm-cris/pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -57,7 +57,8 @@ * the pgd will always be present.. */ -#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm, addr) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() Index: highpmd-2.6.7/include/asm-cris/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-cris/pgtable.h 2004-06-15 22:18:52.000000000 -0700 +++ highpmd-2.6.7/include/asm-cris/pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -288,6 +288,12 @@ return (pmd_t *) dir; } +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + /* Find an entry in the third-level page table.. */ #define __pte_offset(address) \ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) Index: highpmd-2.6.7/include/asm-h8300/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-h8300/pgtable.h 2004-06-15 22:19:13.000000000 -0700 +++ highpmd-2.6.7/include/asm-h8300/pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -16,6 +16,11 @@ #define pmd_none(pmd) (1) #define pgd_offset_k(adrdress) ((pgd_t *)0) #define pte_offset_kernel(dir, address) ((pte_t *)0) +#define pmd_offset_kernel(a,b) pmd_offset(a,b) +#define pmd_offset_map(a,b) pmd_offset(a,b) +#define pmd_offset_map_nested(a,b) pmd_offset(a,b) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) #define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */ #define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */ Index: highpmd-2.6.7/include/asm-i386/highmem.h =================================================================== --- highpmd-2.6.7.orig/include/asm-i386/highmem.h 2004-06-15 22:18:57.000000000 -0700 +++ highpmd-2.6.7/include/asm-i386/highmem.h 2004-07-01 03:44:01.000000000 -0700 @@ -41,9 +41,9 @@ * chunk of RAM. */ #if NR_CPUS <= 32 -#define PKMAP_BASE (0xff800000UL) +#define PKMAP_BASE (0xff400000UL) #else -#define PKMAP_BASE (0xff600000UL) +#define PKMAP_BASE (0xfe800000UL) #endif #ifdef CONFIG_X86_PAE #define LAST_PKMAP 512 Index: highpmd-2.6.7/include/asm-i386/kmap_types.h =================================================================== --- highpmd-2.6.7.orig/include/asm-i386/kmap_types.h 2004-06-15 22:19:43.000000000 -0700 +++ highpmd-2.6.7/include/asm-i386/kmap_types.h 2004-07-01 03:59:13.000000000 -0700 @@ -19,11 +19,13 @@ D(6) KM_BIO_DST_IRQ, D(7) KM_PTE0, D(8) KM_PTE1, -D(9) KM_IRQ0, -D(10) KM_IRQ1, -D(11) KM_SOFTIRQ0, -D(12) KM_SOFTIRQ1, -D(13) KM_TYPE_NR +D(9) KM_PMD0, +D(10) KM_PMD1, +D(11) KM_IRQ0, +D(12) KM_IRQ1, +D(13) KM_SOFTIRQ0, +D(14) KM_SOFTIRQ1, +D(15) KM_TYPE_NR }; #undef D Index: highpmd-2.6.7/include/asm-i386/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-i386/pgalloc.h 2004-06-15 22:18:57.000000000 -0700 +++ highpmd-2.6.7/include/asm-i386/pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -45,7 +45,8 @@ * (In the PAE case we free the pmds as part of the pgd.) */ -#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm, addr) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() Index: highpmd-2.6.7/include/asm-i386/pgtable-2level.h =================================================================== --- highpmd-2.6.7.orig/include/asm-i386/pgtable-2level.h 2004-06-15 22:19:29.000000000 -0700 +++ highpmd-2.6.7/include/asm-i386/pgtable-2level.h 2004-07-01 03:44:01.000000000 -0700 @@ -48,13 +48,15 @@ #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) #define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval) -#define pgd_page(pgd) \ -((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) +#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) + +#define pmd_offset_map(pgd, addr) ({ (pmd_t *)(pgd); }) +#define pmd_offset_map_nested(pgd, addr) pmd_offset_map(pgd, addr) +#define pmd_offset_kernel(pgd, addr) pmd_offset_map(pgd, addr) + +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) -static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *) dir; -} #define ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte_low, 0)) #define pte_same(a, b) ((a).pte_low == (b).pte_low) #define pte_page(x) pfn_to_page(pte_pfn(x)) Index: highpmd-2.6.7/include/asm-i386/pgtable-3level.h =================================================================== --- highpmd-2.6.7.orig/include/asm-i386/pgtable-3level.h 2004-06-15 22:19:52.000000000 -0700 +++ highpmd-2.6.7/include/asm-i386/pgtable-3level.h 2004-07-01 03:44:01.000000000 -0700 @@ -64,12 +64,32 @@ */ static inline void pgd_clear (pgd_t * pgd) { } -#define pgd_page(pgd) \ -((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) +static inline unsigned long pgd_pfn(pgd_t pgd) +{ + return pgd_val(pgd) >> PAGE_SHIFT; +} + +#define pgd_page(pgd) pfn_to_page(pgd_pfn(pgd)) + +#define pmd_offset_kernel(pgd, addr) \ + ((pmd_t *)__va(pgd_val(*(pgd)) & PAGE_MASK) + pmd_index(addr)) /* Find an entry in the second-level page table.. */ -#define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \ - pmd_index(address)) +#ifdef CONFIG_HIGHPMD +#define __pmd_offset(pgd, addr, type) \ + ((pmd_t *)kmap_atomic(pgd_page(*(pgd)), type) + pmd_index(addr)) +#define __pmd_unmap(pmd, type) kunmap_atomic(pmd, type) +#else +#define __pmd_offset(pgd, addr, type) \ + ((pmd_t *)__va(pgd_val(*(pgd)) & PAGE_MASK) + pmd_index(addr)) +#define __pmd_unmap(pmd, type) do { } while (0) +#endif + +#define pmd_offset_map(pgd, addr) __pmd_offset(pgd, addr, KM_PMD0) +#define pmd_offset_map_nested(pgd, addr) __pmd_offset(pgd, addr, KM_PMD1) + +#define pmd_unmap(pmd) __pmd_unmap(pmd, KM_PMD0); +#define pmd_unmap_nested(pmd) __pmd_unmap(pmd, KM_PMD1); static inline pte_t ptep_get_and_clear(pte_t *ptep) { Index: highpmd-2.6.7/include/asm-i386/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-i386/pgtable.h 2004-06-15 22:19:43.000000000 -0700 +++ highpmd-2.6.7/include/asm-i386/pgtable.h 2004-07-01 03:59:52.000000000 -0700 @@ -33,11 +33,9 @@ extern unsigned long empty_zero_page[1024]; extern pgd_t swapper_pg_dir[1024]; extern kmem_cache_t *pgd_cache; -extern kmem_cache_t *pmd_cache; extern spinlock_t pgd_lock; extern struct page *pgd_list; -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); void pgtable_cache_init(void); Index: highpmd-2.6.7/include/asm-ia64/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-ia64/pgalloc.h 2004-06-15 22:18:54.000000000 -0700 +++ highpmd-2.6.7/include/asm-ia64/pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -71,9 +71,9 @@ } static inline void -pgd_populate (struct mm_struct *mm, pgd_t *pgd_entry, pmd_t *pmd) +pgd_populate (struct mm_struct *mm, pgd_t *pgd_entry, struct page *pmd) { - pgd_val(*pgd_entry) = __pa(pmd); + pgd_val(*pgd_entry) = __pa(page_address(pmd)); } @@ -90,8 +90,8 @@ return (pmd_t *)ret; } -static inline pmd_t* -pmd_alloc_one (struct mm_struct *mm, unsigned long addr) +static inline pmd_t * +pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) { pmd_t *pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); @@ -100,9 +100,16 @@ return pmd; } +static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + pmd_t *pmd = pmd_alloc_one_kernel(mm, addr); + return pmd ? virt_to_page(pmd) : NULL; +} + static inline void -pmd_free (pmd_t *pmd) +pmd_free(struct page *page) { + pmd_t *pmd = page_address(page); *(unsigned long *)pmd = (unsigned long) pmd_quicklist; pmd_quicklist = (unsigned long *) pmd; ++pgtable_cache_size; Index: highpmd-2.6.7/include/asm-ia64/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-ia64/pgtable.h 2004-06-15 22:19:09.000000000 -0700 +++ highpmd-2.6.7/include/asm-ia64/pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -258,7 +258,8 @@ #define pgd_bad(pgd) (!ia64_phys_addr_valid(pgd_val(pgd))) #define pgd_present(pgd) (pgd_val(pgd) != 0UL) #define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL) -#define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & _PFN_MASK)) +#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _PFN_MASK)) +#define pgd_page(pgd) virt_to_page(__pgd_page(pgd)) /* * The following have defined behavior only work if pte_present() is true. @@ -327,7 +328,13 @@ /* Find an entry in the second-level page table.. */ #define pmd_offset(dir,addr) \ - ((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) + ((pmd_t *)__pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) + +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) /* * Find an entry in the third-level page table. This looks more complicated than it Index: highpmd-2.6.7/include/asm-m68k/motorola_pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-m68k/motorola_pgalloc.h 2004-06-15 22:20:26.000000000 -0700 +++ highpmd-2.6.7/include/asm-m68k/motorola_pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -63,19 +63,28 @@ } -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +static inline pmd_t *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { return get_pointer_table(); } -static inline int pmd_free(pmd_t *pmd) +static inline struct page *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) { - return free_pointer_table(pmd); + pmd_t *pmd = pmd_alloc_one_kernel(mm, addr); + if (pmd) + return virt_to_page(pmd); + else + return NULL; } -static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) +static inline int pmd_free(struct page *pmd) { - return free_pointer_table(pmd); + return free_pointer_table(page_address(pmd)); +} + +static inline int __pmd_free_tlb(struct mmu_gather *tlb, struct page *pmd) +{ + return free_pointer_table(page_address(pmd)); } @@ -100,9 +109,9 @@ pmd_set(pmd, page_address(page)); } -static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, struct page *pmd) { - pgd_set(pgd, pmd); + pgd_set(pgd, page_address(pmd)); } #endif /* _MOTOROLA_PGALLOC_H */ Index: highpmd-2.6.7/include/asm-m68k/motorola_pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-m68k/motorola_pgtable.h 2004-06-15 22:19:37.000000000 -0700 +++ highpmd-2.6.7/include/asm-m68k/motorola_pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -125,6 +125,7 @@ #define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK)) #define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK)) #define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK)) +#define pgd_page(pgd) virt_to_page(__pgd_page(pgd)) #define pte_none(pte) (!pte_val(pte)) @@ -217,6 +218,12 @@ return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); } +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + /* Find an entry in the third-level page table.. */ static inline pte_t *pte_offset_kernel(pmd_t *pmdp, unsigned long address) { Index: highpmd-2.6.7/include/asm-m68k/sun3_pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-m68k/sun3_pgalloc.h 2004-06-15 22:19:17.000000000 -0700 +++ highpmd-2.6.7/include/asm-m68k/sun3_pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -18,7 +18,8 @@ extern const char bad_pmd_string[]; -#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm,address) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm,address) ({ BUG(); ((pmd_t *)2); }) static inline void pte_free_kernel(pte_t * pte) Index: highpmd-2.6.7/include/asm-m68knommu/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-m68knommu/pgtable.h 2004-06-15 22:19:36.000000000 -0700 +++ highpmd-2.6.7/include/asm-m68knommu/pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -19,7 +19,12 @@ #define pgd_bad(pgd) (0) #define pgd_clear(pgdp) #define kern_addr_valid(addr) (1) -#define pmd_offset(a, b) ((void *)0) +#define pmd_offset(a, b) ((void *)0) +#define pmd_offset_kernel(a, b) pmd_offset(a, b) +#define pmd_offset_map(a, b) pmd_offset(a, b) +#define pmd_offset_map_nested(a, b) pmd_offset(a, b) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) #define PAGE_NONE __pgprot(0) #define PAGE_SHARED __pgprot(0) Index: highpmd-2.6.7/include/asm-mips/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-mips/pgalloc.h 2004-06-15 22:19:28.000000000 -0700 +++ highpmd-2.6.7/include/asm-mips/pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -94,7 +94,8 @@ * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */ -#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm, addr) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) #endif Index: highpmd-2.6.7/include/asm-mips/pgtable-32.h =================================================================== --- highpmd-2.6.7.orig/include/asm-mips/pgtable-32.h 2004-06-15 22:19:26.000000000 -0700 +++ highpmd-2.6.7/include/asm-mips/pgtable-32.h 2004-07-01 03:44:01.000000000 -0700 @@ -185,6 +185,12 @@ return (pmd_t *) dir; } +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + /* Find an entry in the third-level page table.. */ #define __pte_offset(address) \ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) Index: highpmd-2.6.7/include/asm-mips/pgtable-64.h =================================================================== --- highpmd-2.6.7.orig/include/asm-mips/pgtable-64.h 2004-06-15 22:18:57.000000000 -0700 +++ highpmd-2.6.7/include/asm-mips/pgtable-64.h 2004-07-01 03:44:01.000000000 -0700 @@ -177,10 +177,16 @@ /* Find an entry in the second-level page table.. */ static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address) { - return (pmd_t *) pgd_page(*dir) + + return (pmd_t *)page_address(pgd_page(*dir)) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); } +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + /* Find an entry in the third-level page table.. */ #define __pte_offset(address) \ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) Index: highpmd-2.6.7/include/asm-parisc/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-parisc/pgalloc.h 2004-06-15 22:20:04.000000000 -0700 +++ highpmd-2.6.7/include/asm-parisc/pgalloc.h 2004-07-01 03:55:07.000000000 -0700 @@ -54,14 +54,14 @@ /* Three Level Page Table Support for pmd's */ -static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, struct page *pmd) { - pgd_val(*pgd) = _PAGE_TABLE + (__u32)__pa((unsigned long)pmd); + pgd_val(*pgd) = _PAGE_TABLE + (__u32)__pa(page_address(pmd)); } /* NOTE: pmd must be in ZONE_DMA (<4GB) so the pgd pointer can be * housed in 32 bits */ -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +static inline pmd_t *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { pmd_t *pmd = (pmd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT|GFP_DMA, PMD_ORDER); @@ -70,7 +70,7 @@ return pmd; } -static inline void pmd_free(pmd_t *pmd) +static inline void pmd_free(struct page *pmd) { #ifdef __LP64__ if(pmd_val(*pmd) & _PAGE_GATEWAY) @@ -78,7 +78,16 @@ * cannot free it */ return; #endif - free_pages((unsigned long)pmd, PMD_ORDER); + __free_pages(pmd, PMD_ORDER); +} + +static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + pmd_t *pmd = pmd_alloc_one_kernel(mm, addr); + if (pmd) + return virt_to_page(pmd); + else + return NULL; } #else @@ -90,7 +99,8 @@ * inside the pgd, so has no extra memory associated with it. */ -#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm, addr) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm, addr) pmd_alloc_one(mm, addr) #define pmd_free(x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() Index: highpmd-2.6.7/include/asm-parisc/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-parisc/pgtable.h 2004-06-15 22:19:52.000000000 -0700 +++ highpmd-2.6.7/include/asm-parisc/pgtable.h 2004-07-01 03:56:12.000000000 -0700 @@ -268,7 +268,7 @@ #if PT_NLEVELS == 3 -#define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) +#define pgd_page(pgd) virt_to_page(__va(pgd_val(pgd) & PAGE_MASK)) /* For 64 bit we have three level tables */ @@ -377,11 +377,17 @@ #if PT_NLEVELS == 3 #define pmd_offset(dir,address) \ -((pmd_t *) pgd_page(*(dir)) + (((address)>>PMD_SHIFT) & (PTRS_PER_PMD-1))) +((pmd_t *)__pgd_page(*(dir)) + (((address)>>PMD_SHIFT) & (PTRS_PER_PMD-1))) #else #define pmd_offset(dir,addr) ((pmd_t *) dir) #endif +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + /* Find an entry in the third-level page table.. */ #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) #define pte_offset_kernel(pmd, address) \ Index: highpmd-2.6.7/include/asm-ppc/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-ppc/pgalloc.h 2004-06-15 22:18:37.000000000 -0700 +++ highpmd-2.6.7/include/asm-ppc/pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -14,7 +14,8 @@ * We don't have any real pmd's, and this code never triggers because * the pgd will always be present.. */ -#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm,address) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm,addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() Index: highpmd-2.6.7/include/asm-ppc/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-ppc/pgtable.h 2004-06-15 22:19:01.000000000 -0700 +++ highpmd-2.6.7/include/asm-ppc/pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -426,8 +426,9 @@ static inline int pgd_present(pgd_t pgd) { return 1; } #define pgd_clear(xp) do { } while (0) -#define pgd_page(pgd) \ +#define __pgd_page(pgd) \ ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) +#define pgd_page(pgd) virt_to_page(__pgd_page(pgd)) /* * The following only work if pte_present() is true. @@ -601,6 +602,12 @@ return (pmd_t *) dir; } +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + /* Find an entry in the third-level page table.. */ #define pte_index(address) \ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) Index: highpmd-2.6.7/include/asm-ppc64/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-ppc64/pgalloc.h 2004-06-15 22:18:55.000000000 -0700 +++ highpmd-2.6.7/include/asm-ppc64/pgalloc.h 2004-07-01 03:44:01.000000000 -0700 @@ -29,18 +29,27 @@ kmem_cache_free(zero_cache, pgd); } -#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) +#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, page_address(PMD)) static inline pmd_t * -pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) { return kmem_cache_alloc(zero_cache, GFP_KERNEL|__GFP_REPEAT); } +static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + pmd_t *pmd = pmd_alloc_one_kernel(mm, addr); + if (pmd) + return virt_to_page(pmd); + else + return NULL; +} + static inline void -pmd_free(pmd_t *pmd) +pmd_free(struct page *pmd) { - kmem_cache_free(zero_cache, pmd); + kmem_cache_free(zero_cache, page_address(pmd)); } #define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte) Index: highpmd-2.6.7/include/asm-ppc64/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-ppc64/pgtable.h 2004-06-15 22:20:04.000000000 -0700 +++ highpmd-2.6.7/include/asm-ppc64/pgtable.h 2004-07-01 03:44:01.000000000 -0700 @@ -219,7 +219,8 @@ #define pgd_bad(pgd) ((pgd_val(pgd)) == 0) #define pgd_present(pgd) (pgd_val(pgd) != 0UL) #define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL) -#define pgd_page(pgd) (__bpn_to_ba(pgd_val(pgd))) +#define __pgd_page(pgd) (__bpn_to_ba(pgd_val(pgd))) +#define pgd_page(pgd) virt_to_page(__pgd_page(pgd)) /* * Find an entry in a page-table-directory. We combine the address region @@ -232,12 +233,18 @@ /* Find an entry in the second-level page table.. */ #define pmd_offset(dir,addr) \ - ((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) + ((pmd_t *)__pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) /* Find an entry in the third-level page table.. */ #define pte_offset_kernel(dir,addr) \ ((pte_t *) pmd_page_kernel(*(dir)) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) #define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr)) #define pte_unmap(pte) do { } while(0) Index: highpmd-2.6.7/include/asm-s390/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-s390/pgalloc.h 2004-06-15 22:19:37.000000000 -0700 +++ highpmd-2.6.7/include/asm-s390/pgalloc.h 2004-07-01 04:02:08.000000000 -0700 @@ -63,12 +63,13 @@ * We use pmd cache only on s390x, so these are dummy routines. This * code never triggers because the pgd will always be present. */ -#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm,address) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm,addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() #else /* __s390x__ */ -static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) +static inline pmd_t * pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr) { pmd_t *pmd; int i; @@ -81,9 +82,18 @@ return pmd; } -static inline void pmd_free (pmd_t *pmd) +static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - free_pages((unsigned long) pmd, 2); + pmd_t *pmd = pmd_alloc_one_kernel(mm, addr); + if (pmd) + return virt_to_page(pmd); + else + return NULL; +} + +static inline void pmd_free(struct page *pmd) +{ + __free_pages(pmd, 2); } #define __pmd_free_tlb(tlb,pmd) \ @@ -92,9 +102,9 @@ pmd_free(pmd); \ } while (0) -static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, struct page *pmd) { - pgd_val(*pgd) = _PGD_ENTRY | __pa(pmd); + pgd_val(*pgd) = _PGD_ENTRY | __pa(page_address(pmd)); } #endif /* __s390x__ */ Index: highpmd-2.6.7/include/asm-s390/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-s390/pgtable.h 2004-06-15 22:19:44.000000000 -0700 +++ highpmd-2.6.7/include/asm-s390/pgtable.h 2004-07-01 03:44:02.000000000 -0700 @@ -684,6 +684,7 @@ /* to find an entry in a page-table-directory */ #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) +#define pgd_page(pgd) virt_to_page(pgd_page_kernel(pgd)) /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) @@ -705,6 +706,12 @@ #endif /* __s390x__ */ +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + /* Find an entry in the third-level page table.. */ #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) #define pte_offset_kernel(pmd, address) \ Index: highpmd-2.6.7/include/asm-sh/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-sh/pgalloc.h 2004-06-15 22:19:23.000000000 -0700 +++ highpmd-2.6.7/include/asm-sh/pgalloc.h 2004-07-01 03:44:02.000000000 -0700 @@ -80,7 +80,8 @@ * inside the pgd, so has no extra memory associated with it. */ -#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one_kernel(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm, addr) ({ BUG(); ((struct page *)2); }) #define pmd_free(x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() Index: highpmd-2.6.7/include/asm-sh/pgtable-2level.h =================================================================== --- highpmd-2.6.7.orig/include/asm-sh/pgtable-2level.h 2004-06-15 22:20:04.000000000 -0700 +++ highpmd-2.6.7/include/asm-sh/pgtable-2level.h 2004-07-01 03:44:02.000000000 -0700 @@ -48,14 +48,21 @@ #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) #define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval) -#define pgd_page(pgd) \ +#define __pgd_page(pgd) \ ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) +#define pgd_page(pgd) virt_to_page(__pgd_page(pgd)) static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) { return (pmd_t *) dir; } +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) + #define pte_pfn(x) ((unsigned long)(((x).pte >> PAGE_SHIFT))) #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) Index: highpmd-2.6.7/include/asm-sparc/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-sparc/pgalloc.h 2004-06-15 22:18:57.000000000 -0700 +++ highpmd-2.6.7/include/asm-sparc/pgalloc.h 2004-07-01 03:44:02.000000000 -0700 @@ -38,15 +38,24 @@ BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *) #define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp) -#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) +#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, page_address(PMD)) -BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one, struct mm_struct *, unsigned long) -#define pmd_alloc_one(mm, address) BTFIXUP_CALL(pmd_alloc_one)(mm, address) +BTFIXUPDEF_CALL(pmd_t *, __pmd_alloc_one, struct mm_struct *, unsigned long) +#define pmd_alloc_one_kernel(mm, address) BTFIXUP_CALL(__pmd_alloc_one)(mm, address) + +static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + pmd_t *pmd = pmd_alloc_one_kernel(mm, addr); + if (pmd) + return virt_to_page(pmd); + else + return NULL; +} BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *) #define free_pmd_fast(pmd) BTFIXUP_CALL(free_pmd_fast)(pmd) -#define pmd_free(pmd) free_pmd_fast(pmd) +#define pmd_free(pmd) free_pmd_fast(page_address(pmd)) #define __pmd_free_tlb(tlb, pmd) pmd_free(pmd) BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *) Index: highpmd-2.6.7/include/asm-sparc/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-sparc/pgtable.h 2004-06-15 22:19:36.000000000 -0700 +++ highpmd-2.6.7/include/asm-sparc/pgtable.h 2004-07-01 03:44:02.000000000 -0700 @@ -183,10 +183,11 @@ /* */ BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t) -BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page, pgd_t) +BTFIXUPDEF_CALL_CONST(unsigned long, __pgd_page, pgd_t) #define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd) -#define pgd_page(pgd) BTFIXUP_CALL(pgd_page)(pgd) +#define __pgd_page(pgd) BTFIXUP_CALL(__pgd_page)(pgd) +#define pgd_page(pgd) virt_to_page(__pgd_page(pgd)) BTFIXUPDEF_SETHI(none_mask) BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t) @@ -333,6 +334,11 @@ /* Find an entry in the second-level page table.. */ BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long) #define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr) +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) /* Find an entry in the third-level page table.. */ BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long) Index: highpmd-2.6.7/include/asm-sparc64/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-sparc64/pgalloc.h 2004-06-15 22:20:04.000000000 -0700 +++ highpmd-2.6.7/include/asm-sparc64/pgalloc.h 2004-07-01 03:44:02.000000000 -0700 @@ -134,7 +134,7 @@ #define DCACHE_COLOR(address) 0 #endif -#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) +#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, page_address(PMD)) static __inline__ pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address) { @@ -155,7 +155,7 @@ return (pmd_t *)ret; } -static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +static __inline__ pmd_t *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { pmd_t *pmd; @@ -168,6 +168,15 @@ return pmd; } +static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + pmd_t *pmd = pmd_alloc_one_kernel(mm, addr); + if (pmd) + return virt_to_page(pmd); + else + return NULL; +} + static __inline__ void free_pmd_fast(pmd_t *pmd) { unsigned long color = DCACHE_COLOR((unsigned long)pmd); @@ -232,7 +241,7 @@ #define pte_free_kernel(pte) free_pte_fast(pte) #define pte_free(pte) free_pte_fast(page_address(pte)) -#define pmd_free(pmd) free_pmd_fast(pmd) +#define pmd_free(pmd) free_pmd_fast(page_address(pmd)) #define pgd_free(pgd) free_pgd_fast(pgd) #define pgd_alloc(mm) get_pgd_fast() Index: highpmd-2.6.7/include/asm-sparc64/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-sparc64/pgtable.h 2004-06-15 22:18:52.000000000 -0700 +++ highpmd-2.6.7/include/asm-sparc64/pgtable.h 2004-07-01 04:07:10.000000000 -0700 @@ -242,8 +242,7 @@ #define __pmd_page(pmd) \ ((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL))) #define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd)) -#define pgd_page(pgd) \ - ((unsigned long) __va((((unsigned long)pgd_val(pgd))<<11UL))) +#define pgd_page(pgd) virt_to_page(__va((((u64)pgd_val(pgd))<<11UL))) #define pte_none(pte) (!pte_val(pte)) #define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) #define pte_clear(pte) (pte_val(*(pte)) = 0UL) @@ -289,9 +288,13 @@ /* Find an entry in the second-level page table.. */ #define pmd_offset(dir, address) \ - ((pmd_t *) pgd_page(*(dir)) + \ + ((pmd_t *)__va((((u64)pgd_val(pgd))<<11UL)) + \ ((address >> PMD_SHIFT) & (REAL_PTRS_PER_PMD-1))) - +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) /* Find an entry in the third-level page table.. */ #define pte_index(dir, address) \ ((pte_t *) __pmd_page(*(dir)) + \ Index: highpmd-2.6.7/include/asm-um/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-um/pgalloc.h 2004-06-15 22:19:52.000000000 -0700 +++ highpmd-2.6.7/include/asm-um/pgalloc.h 2004-07-01 03:44:02.000000000 -0700 @@ -42,7 +42,8 @@ * inside the pgd, so has no extra memory associated with it. */ -#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_alloc_one(mm, addr) ({ BUG(); ((struct page *)2); }) +#define pmd_alloc_one_kernel(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() Index: highpmd-2.6.7/include/asm-um/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-um/pgtable.h 2004-06-15 22:20:26.000000000 -0700 +++ highpmd-2.6.7/include/asm-um/pgtable.h 2004-07-01 03:44:02.000000000 -0700 @@ -373,6 +373,12 @@ return (pmd_t *) dir; } +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pgd, addr) do { } while (0) +#define pmd_unmap_nested(pgd, addr) do { } while (0) + /* Find an entry in the third-level page table.. */ #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) #define pte_offset_kernel(dir, address) \ Index: highpmd-2.6.7/include/asm-v850/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-v850/pgtable.h 2004-06-15 22:19:42.000000000 -0700 +++ highpmd-2.6.7/include/asm-v850/pgtable.h 2004-07-01 03:44:02.000000000 -0700 @@ -11,6 +11,11 @@ #define pgd_clear(pgdp) ((void)0) #define pmd_offset(a, b) ((void *)0) +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) #define kern_addr_valid(addr) (1) Index: highpmd-2.6.7/include/asm-x86_64/pgalloc.h =================================================================== --- highpmd-2.6.7.orig/include/asm-x86_64/pgalloc.h 2004-06-15 22:19:29.000000000 -0700 +++ highpmd-2.6.7/include/asm-x86_64/pgalloc.h 2004-07-01 03:58:22.000000000 -0700 @@ -10,7 +10,7 @@ #define pmd_populate_kernel(mm, pmd, pte) \ set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte))) #define pgd_populate(mm, pgd, pmd) \ - set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pmd))) + set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(page_address(pmd)))) static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) { @@ -22,17 +22,25 @@ return (pmd_t *)get_zeroed_page(GFP_KERNEL); } -extern __inline__ void pmd_free(pmd_t *pmd) +extern __inline__ void pmd_free(struct page *pmd) { - BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); - free_page((unsigned long)pmd); + __free_page(pmd); } -static inline pmd_t *pmd_alloc_one (struct mm_struct *mm, unsigned long addr) +static inline pmd_t *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) { return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); } +static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + pmd_t *pmd = pmd_alloc_one_kernel(mm, addr); + if (pmd) + return virt_to_page(pmd); + else + return NULL; +} + static inline pgd_t *pgd_alloc (struct mm_struct *mm) { return (pgd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); Index: highpmd-2.6.7/include/asm-x86_64/pgtable.h =================================================================== --- highpmd-2.6.7.orig/include/asm-x86_64/pgtable.h 2004-06-15 22:19:43.000000000 -0700 +++ highpmd-2.6.7/include/asm-x86_64/pgtable.h 2004-07-01 03:44:02.000000000 -0700 @@ -98,8 +98,9 @@ pml4_val(*dst) = pml4_val(val); } -#define pgd_page(pgd) \ +#define __pgd_page(pgd) \ ((unsigned long) __va(pgd_val(pgd) & PHYSICAL_PAGE_MASK)) +#define pgd_page(pgd) virt_to_page(__pgd_page(pgd)) #define ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte, 0)) #define pte_same(a, b) ((a).pte == (b).pte) @@ -334,8 +335,13 @@ #define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) -#define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \ +#define pmd_offset(dir, address) ((pmd_t *)__pgd_page(*(dir)) + \ pmd_index(address)) +#define pmd_offset_kernel(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map(pgd, addr) pmd_offset(pgd, addr) +#define pmd_offset_map_nested(pgd, addr) pmd_offset(pgd, addr) +#define pmd_unmap(pmd) do { } while (0) +#define pmd_unmap_nested(pmd) do { } while (0) #define pmd_none(x) (!pmd_val(x)) #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) Index: highpmd-2.6.7/include/linux/mm.h =================================================================== --- highpmd-2.6.7.orig/include/linux/mm.h 2004-06-15 22:18:56.000000000 -0700 +++ highpmd-2.6.7/include/linux/mm.h 2004-07-01 03:44:02.000000000 -0700 @@ -531,8 +531,9 @@ extern int vmtruncate(struct inode * inode, loff_t offset); extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)); +pmd_t *FASTCALL(__pmd_alloc_kernel(struct mm_struct *mm, pgd_t *pmd, unsigned long address)); extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address)); -extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address)); +pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmd, unsigned long address)); extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot); extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot); extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access); @@ -579,12 +580,11 @@ * inlining and the symmetry break with pte_alloc_map() that does all * of this out-of-line. */ -static inline pmd_t *pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) -{ - if (pgd_none(*pgd)) - return __pmd_alloc(mm, pgd, address); - return pmd_offset(pgd, address); -} +#define pmd_alloc_map(mm, pgd, addr) \ + (pgd_none(*(pgd))? __pmd_alloc(mm,pgd,addr): pmd_offset_map(pgd,addr)) + +#define pmd_alloc_kernel(mm, pgd, addr) \ + (pgd_none(*(pgd))? __pmd_alloc_kernel(mm,pgd,addr): pmd_offset_kernel(pgd,addr)) extern void free_area_init(unsigned long * zones_size); extern void free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap, Index: highpmd-2.6.7/mm/fremap.c =================================================================== --- highpmd-2.6.7.orig/mm/fremap.c 2004-06-15 22:18:52.000000000 -0700 +++ highpmd-2.6.7/mm/fremap.c 2004-07-01 04:30:59.000000000 -0700 @@ -70,11 +70,11 @@ pgd = pgd_offset(mm, addr); spin_lock(&mm->page_table_lock); - pmd = pmd_alloc(mm, pgd, addr); + pmd = pmd_alloc_map(mm, pgd, addr); if (!pmd) goto err_unlock; - pte = pte_alloc_map(mm, pmd, addr); + pte = pte_alloc_map(mm, pgd, &pmd, addr); if (!pte) goto err_unlock; @@ -86,6 +86,7 @@ page_add_file_rmap(page); pte_val = *pte; pte_unmap(pte); + pmd_unmap(pmd); update_mmu_cache(vma, addr, pte_val); err = 0; @@ -112,11 +113,11 @@ pgd = pgd_offset(mm, addr); spin_lock(&mm->page_table_lock); - pmd = pmd_alloc(mm, pgd, addr); + pmd = pmd_alloc_map(mm, pgd, addr); if (!pmd) goto err_unlock; - pte = pte_alloc_map(mm, pmd, addr); + pte = pte_alloc_map(mm, pgd, &pmd, addr); if (!pte) goto err_unlock; @@ -125,6 +126,7 @@ set_pte(pte, pgoff_to_pte(pgoff)); pte_val = *pte; pte_unmap(pte); + pmd_unmap(pmd); update_mmu_cache(vma, addr, pte_val); spin_unlock(&mm->page_table_lock); return 0; Index: highpmd-2.6.7/mm/memory.c =================================================================== --- highpmd-2.6.7.orig/mm/memory.c 2004-06-15 22:19:22.000000000 -0700 +++ highpmd-2.6.7/mm/memory.c 2004-07-01 07:05:43.000000000 -0700 @@ -112,6 +112,7 @@ { int j; pmd_t * pmd; + struct page *page; if (pgd_none(*dir)) return; @@ -120,11 +121,13 @@ pgd_clear(dir); return; } - pmd = pmd_offset(dir, 0); + page = pgd_page(*dir); + pmd = pmd_offset_map(dir, 0); pgd_clear(dir); for (j = 0; j < PTRS_PER_PMD ; j++) free_one_pmd(tlb, pmd+j); - pmd_free_tlb(tlb, pmd); + pmd_unmap(pmd); + pmd_free_tlb(tlb, page); } /* @@ -144,30 +147,33 @@ } while (--nr); } -pte_t fastcall * pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address) +pte_t fastcall * pte_alloc_map(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmd, unsigned long address) { - if (!pmd_present(*pmd)) { + if (!pmd_present(**pmd)) { struct page *new; + pmd_unmap(*pmd); spin_unlock(&mm->page_table_lock); new = pte_alloc_one(mm, address); spin_lock(&mm->page_table_lock); - if (!new) + if (!new) { + *pmd = NULL; return NULL; - + } + *pmd = pmd_offset_map(pgd, address); /* * Because we dropped the lock, we should re-check the * entry, as somebody else could have populated it.. */ - if (pmd_present(*pmd)) { + if (pmd_present(**pmd)) { pte_free(new); goto out; } inc_page_state(nr_page_table_pages); - pmd_populate(mm, pmd, new); + pmd_populate(mm, *pmd, new); } out: - return pte_offset_map(pmd, address); + return pte_offset_map(*pmd, address); } pte_t fastcall * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address) @@ -206,7 +212,7 @@ * variable count and make things faster. -jj * * dst->page_table_lock is held on entry and exit, - * but may be dropped within pmd_alloc() and pte_alloc_map(). + * but may be dropped within pmd_alloc_map() and pte_alloc_map(). */ int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma) @@ -241,11 +247,10 @@ continue; } - src_pmd = pmd_offset(src_pgd, address); - dst_pmd = pmd_alloc(dst, dst_pgd, address); + dst_pmd = pmd_alloc_map(dst, dst_pgd, address); if (!dst_pmd) goto nomem; - + src_pmd = pmd_offset_map_nested(src_pgd, address); do { pte_t * src_pte, * dst_pte; @@ -258,15 +263,20 @@ pmd_clear(src_pmd); skip_copy_pte_range: address = (address + PMD_SIZE) & PMD_MASK; - if (address >= end) + if (address >= end) { + pmd_unmap(dst_pmd); + pmd_unmap_nested(src_pmd); goto out; + } goto cont_copy_pmd_range; } - dst_pte = pte_alloc_map(dst, dst_pmd, address); + pmd_unmap_nested(src_pmd); + dst_pte = pte_alloc_map(dst, dst_pgd, &dst_pmd, address); if (!dst_pte) goto nomem; spin_lock(&src->page_table_lock); + src_pmd = pmd_offset_map_nested(src_pgd, address); src_pte = pte_offset_map_nested(src_pmd, address); do { pte_t pte = *src_pte; @@ -324,6 +334,8 @@ if (address >= end) { pte_unmap_nested(src_pte); pte_unmap(dst_pte); + pmd_unmap_nested(src_pmd); + pmd_unmap(dst_pmd); goto out_unlock; } src_pte++; @@ -332,11 +344,12 @@ pte_unmap_nested(src_pte-1); pte_unmap(dst_pte-1); spin_unlock(&src->page_table_lock); - cond_resched_lock(&dst->page_table_lock); cont_copy_pmd_range: src_pmd++; dst_pmd++; } while ((unsigned long)src_pmd & PMD_TABLE_MASK); + pmd_unmap_nested(src_pmd-1); + pmd_unmap(dst_pmd-1); } out_unlock: spin_unlock(&src->page_table_lock); @@ -441,7 +454,7 @@ pgd_clear(dir); return; } - pmd = pmd_offset(dir, address); + pmd = pmd_offset_map(dir, address); end = address + size; if (end > ((address + PGDIR_SIZE) & PGDIR_MASK)) end = ((address + PGDIR_SIZE) & PGDIR_MASK); @@ -450,6 +463,7 @@ address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address && (address < end)); + pmd_unmap(pmd - 1); } static void unmap_page_range(struct mmu_gather *tlb, @@ -620,15 +634,19 @@ if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) goto out; - pmd = pmd_offset(pgd, address); + pmd = pmd_offset_map(pgd, address); if (pmd_none(*pmd)) - goto out; - if (pmd_huge(*pmd)) - return follow_huge_pmd(mm, address, pmd, write); + goto out_unmap; + if (pmd_huge(*pmd)) { + page = follow_huge_pmd(mm, address, pmd, write); + pmd_unmap(pmd); + return page; + } if (unlikely(pmd_bad(*pmd))) - goto out; + goto out_unmap; ptep = pte_offset_map(pmd, address); + pmd_unmap(pmd); if (!ptep) goto out; @@ -649,6 +667,9 @@ out: return NULL; +out_unmap: + pmd_unmap(pmd); + goto out; } /* @@ -671,6 +692,7 @@ { pgd_t *pgd; pmd_t *pmd; + int ret; /* Check if the vma is for an anonymous mapping. */ if (vma->vm_ops && vma->vm_ops->nopage) @@ -682,12 +704,14 @@ return 1; /* Check if page middle directory entry exists. */ - pmd = pmd_offset(pgd, address); + pmd = pmd_offset_map(pgd, address); if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) - return 1; - + ret = 1; + else /* There is a pte slot for 'address' in 'mm'. */ - return 0; + ret = 0; + pmd_unmap(pmd); + return ret; } @@ -721,7 +745,7 @@ pgd = pgd_offset_k(pg); if (!pgd) return i ? : -EFAULT; - pmd = pmd_offset(pgd, pg); + pmd = pmd_offset_kernel(pgd, pg); if (!pmd) return i ? : -EFAULT; pte = pte_offset_kernel(pmd, pg); @@ -835,8 +859,8 @@ } while (address && (address < end)); } -static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, - unsigned long size, pgprot_t prot) +static inline int zeromap_pmd_range(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmd, + unsigned long address, unsigned long size, pgprot_t prot) { unsigned long base, end; @@ -846,13 +870,13 @@ if (end > PGDIR_SIZE) end = PGDIR_SIZE; do { - pte_t * pte = pte_alloc_map(mm, pmd, base + address); + pte_t *pte = pte_alloc_map(mm, pgd, pmd, base + address); if (!pte) return -ENOMEM; zeromap_pte_range(pte, base + address, end - address, prot); pte_unmap(pte); address = (address + PMD_SIZE) & PMD_MASK; - pmd++; + (*pmd)++; } while (address && (address < end)); return 0; } @@ -872,13 +896,14 @@ spin_lock(&mm->page_table_lock); do { - pmd_t *pmd = pmd_alloc(mm, dir, address); + pmd_t *pmd = pmd_alloc_map(mm, dir, address); error = -ENOMEM; if (!pmd) break; - error = zeromap_pmd_range(mm, pmd, address, end - address, prot); + error = zeromap_pmd_range(mm, dir, &pmd, address, end - address, prot); if (error) break; + pmd_unmap(pmd - 1); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); @@ -916,8 +941,9 @@ } while (address && (address < end)); } -static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long phys_addr, pgprot_t prot) +static inline int remap_pmd_range(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmd, + unsigned long address, unsigned long size, + unsigned long phys_addr, pgprot_t prot) { unsigned long base, end; @@ -928,13 +954,13 @@ end = PGDIR_SIZE; phys_addr -= address; do { - pte_t * pte = pte_alloc_map(mm, pmd, base + address); + pte_t *pte = pte_alloc_map(mm, pgd, pmd, base + address); if (!pte) return -ENOMEM; remap_pte_range(pte, base + address, end - address, address + phys_addr, prot); pte_unmap(pte); address = (address + PMD_SIZE) & PMD_MASK; - pmd++; + (*pmd)++; } while (address && (address < end)); return 0; } @@ -956,13 +982,14 @@ spin_lock(&mm->page_table_lock); do { - pmd_t *pmd = pmd_alloc(mm, dir, from); + pmd_t *pmd = pmd_alloc_map(mm, dir, from); error = -ENOMEM; if (!pmd) break; - error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot); + error = remap_pmd_range(mm, dir, &pmd, from, end - from, phys_addr + from, prot); if (error) break; + pmd_unmap(pmd - 1); from = (from + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (from && (from < end)); @@ -1038,6 +1065,7 @@ * data, but for the moment just pretend this is OOM. */ pte_unmap(page_table); + pmd_unmap(pmd); printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n", address); spin_unlock(&mm->page_table_lock); @@ -1055,11 +1083,13 @@ ptep_set_access_flags(vma, address, page_table, entry, 1); update_mmu_cache(vma, address, entry); pte_unmap(page_table); + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); return VM_FAULT_MINOR; } } pte_unmap(page_table); + pmd_unmap(pmd); /* * Ok, we need to copy. Oh, well.. @@ -1078,6 +1108,7 @@ * Re-check the pte - we dropped the lock */ spin_lock(&mm->page_table_lock); + pmd = pmd_offset_map(pgd_offset(mm, address), address); page_table = pte_offset_map(pmd, address); if (likely(pte_same(*page_table, pte))) { if (PageReserved(old_page)) @@ -1092,6 +1123,7 @@ new_page = old_page; } pte_unmap(page_table); + pmd_unmap(pmd); page_cache_release(new_page); page_cache_release(old_page); spin_unlock(&mm->page_table_lock); @@ -1304,6 +1336,7 @@ int ret = VM_FAULT_MINOR; pte_unmap(page_table); + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); page = lookup_swap_cache(entry); if (!page) { @@ -1315,12 +1348,14 @@ * we released the page table lock. */ spin_lock(&mm->page_table_lock); + pmd = pmd_offset_map(pgd_offset(mm, address), address); page_table = pte_offset_map(pmd, address); if (likely(pte_same(*page_table, orig_pte))) ret = VM_FAULT_OOM; else ret = VM_FAULT_MINOR; pte_unmap(page_table); + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); goto out; } @@ -1338,9 +1373,11 @@ * released the page table lock. */ spin_lock(&mm->page_table_lock); + pmd = pmd_offset_map(pgd_offset(mm, address), address); page_table = pte_offset_map(pmd, address); if (unlikely(!pte_same(*page_table, orig_pte))) { pte_unmap(page_table); + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); unlock_page(page); page_cache_release(page); @@ -1375,6 +1412,7 @@ /* No need to invalidate - it was non-present before */ update_mmu_cache(vma, address, pte); + pmd_unmap(pmd); pte_unmap(page_table); spin_unlock(&mm->page_table_lock); out: @@ -1401,6 +1439,7 @@ if (write_access) { /* Allocate our own private page. */ pte_unmap(page_table); + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); if (unlikely(anon_vma_prepare(vma))) @@ -1411,9 +1450,11 @@ clear_user_highpage(page, addr); spin_lock(&mm->page_table_lock); + pmd = pmd_offset_map(pgd_offset(mm, addr), addr); page_table = pte_offset_map(pmd, addr); if (!pte_none(*page_table)) { + pmd_unmap(pmd); pte_unmap(page_table); page_cache_release(page); spin_unlock(&mm->page_table_lock); @@ -1429,8 +1470,8 @@ } set_pte(page_table, entry); + pmd_unmap(pmd); pte_unmap(page_table); - /* No need to invalidate - it was non-present before */ update_mmu_cache(vma, addr, entry); spin_unlock(&mm->page_table_lock); @@ -1467,6 +1508,7 @@ return do_anonymous_page(mm, vma, page_table, pmd, write_access, address); pte_unmap(page_table); + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); if (vma->vm_file) { @@ -1513,6 +1555,7 @@ page_cache_release(new_page); goto retry; } + pmd = pmd_offset_map(pgd_offset(mm, address), address); page_table = pte_offset_map(pmd, address); /* @@ -1540,9 +1583,11 @@ } else page_add_file_rmap(new_page); pte_unmap(page_table); + pmd_unmap(pmd); } else { /* One of our sibling threads was faster, back out. */ pte_unmap(page_table); + pmd_unmap(pmd); page_cache_release(new_page); spin_unlock(&mm->page_table_lock); goto out; @@ -1584,6 +1629,7 @@ pgoff = pte_to_pgoff(*pte); pte_unmap(pte); + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); err = vma->vm_ops->populate(vma, address & PAGE_MASK, PAGE_SIZE, vma->vm_page_prot, pgoff, 0); @@ -1645,6 +1691,7 @@ ptep_set_access_flags(vma, address, pte, entry, write_access); update_mmu_cache(vma, address, entry); pte_unmap(pte); + pmd_unmap(pmd); spin_unlock(&mm->page_table_lock); return VM_FAULT_MINOR; } @@ -1671,10 +1718,10 @@ * and the SMP-safe atomic PTE updates. */ spin_lock(&mm->page_table_lock); - pmd = pmd_alloc(mm, pgd, address); + pmd = pmd_alloc_map(mm, pgd, address); if (pmd) { - pte_t * pte = pte_alloc_map(mm, pmd, address); + pte_t *pte = pte_alloc_map(mm, pgd, &pmd, address); if (pte) return handle_pte_fault(mm, vma, address, write_access, pte, pmd); } @@ -1693,10 +1740,33 @@ */ pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) { + struct page *page; + + spin_unlock(&mm->page_table_lock); + page = pmd_alloc_one(mm, address); + spin_lock(&mm->page_table_lock); + if (!page) + return NULL; + + /* + * Because we dropped the lock, we should re-check the + * entry, as somebody else could have populated it.. + */ + if (pgd_present(*pgd)) { + pmd_free(page); + goto out; + } + pgd_populate(mm, pgd, page); +out: + return pmd_offset_map(pgd, address); +} + +pmd_t *__pmd_alloc_kernel(struct mm_struct *mm, pgd_t *pgd, unsigned long address) +{ pmd_t *new; spin_unlock(&mm->page_table_lock); - new = pmd_alloc_one(mm, address); + new = pmd_alloc_one_kernel(mm, address); spin_lock(&mm->page_table_lock); if (!new) return NULL; @@ -1706,12 +1776,12 @@ * entry, as somebody else could have populated it.. */ if (pgd_present(*pgd)) { - pmd_free(new); + pmd_free(virt_to_page(new)); goto out; } - pgd_populate(mm, pgd, new); + pgd_populate(mm, pgd, virt_to_page(new)); out: - return pmd_offset(pgd, address); + return pmd_offset_kernel(pgd, address); } int make_pages_present(unsigned long addr, unsigned long end) @@ -1745,7 +1815,7 @@ pte_t *ptep, pte; if (!pgd_none(*pgd)) { - pmd = pmd_offset(pgd, addr); + pmd = pmd_offset_map(pgd, addr); if (!pmd_none(*pmd)) { preempt_disable(); ptep = pte_offset_map(pmd, addr); @@ -1755,6 +1825,7 @@ pte_unmap(ptep); preempt_enable(); } + pmd_unmap(pmd); } return page; } Index: highpmd-2.6.7/mm/mprotect.c =================================================================== --- highpmd-2.6.7.orig/mm/mprotect.c 2004-06-15 22:20:27.000000000 -0700 +++ highpmd-2.6.7/mm/mprotect.c 2004-07-01 03:44:02.000000000 -0700 @@ -74,7 +74,7 @@ pgd_clear(pgd); return; } - pmd = pmd_offset(pgd, address); + pmd = pmd_offset_map(pgd, address); address &= ~PGDIR_MASK; end = address + size; if (end > PGDIR_SIZE) @@ -84,6 +84,7 @@ address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address && (address < end)); + pmd_unmap(pmd - 1); } static void Index: highpmd-2.6.7/mm/mremap.c =================================================================== --- highpmd-2.6.7.orig/mm/mremap.c 2004-06-15 22:19:35.000000000 -0700 +++ highpmd-2.6.7/mm/mremap.c 2004-07-01 04:47:57.000000000 -0700 @@ -37,7 +37,7 @@ goto end; } - pmd = pmd_offset(pgd, addr); + pmd = pmd_offset_map_nested(pgd, addr); if (pmd_none(*pmd)) goto end; if (pmd_bad(*pmd)) { @@ -52,6 +52,7 @@ pte = NULL; } end: + pmd_unmap_nested(pmd); return pte; } @@ -59,24 +60,31 @@ { pgd_t *pgd; pmd_t *pmd; + pte_t *pte; pgd = pgd_offset(mm, addr); if (pgd_none(*pgd)) return NULL; - pmd = pmd_offset(pgd, addr); - if (!pmd_present(*pmd)) - return NULL; - return pte_offset_map(pmd, addr); + pmd = pmd_offset_map(pgd, addr); + if (pmd_present(*pmd)) + pte = pte_offset_map(pmd, addr); + else + pte = NULL; + pmd_unmap(pmd); + return pte; } static inline pte_t *alloc_one_pte_map(struct mm_struct *mm, unsigned long addr) { + pgd_t *pgd; pmd_t *pmd; pte_t *pte = NULL; - pmd = pmd_alloc(mm, pgd_offset(mm, addr), addr); + pgd = pgd_offset(mm, addr); + pmd = pmd_alloc_map(mm, pgd, addr); if (pmd) - pte = pte_alloc_map(mm, pmd, addr); + pte = pte_alloc_map(mm, pgd, &pmd, addr); + pmd_unmap(pmd); return pte; } Index: highpmd-2.6.7/mm/msync.c =================================================================== --- highpmd-2.6.7.orig/mm/msync.c 2004-06-15 22:19:13.000000000 -0700 +++ highpmd-2.6.7/mm/msync.c 2004-07-01 03:44:02.000000000 -0700 @@ -81,7 +81,7 @@ pgd_clear(pgd); return 0; } - pmd = pmd_offset(pgd, address); + pmd = pmd_offset_map(pgd, address); if ((address & PGDIR_MASK) != (end & PGDIR_MASK)) end = (address & PGDIR_MASK) + PGDIR_SIZE; error = 0; @@ -90,6 +90,7 @@ address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address && (address < end)); + pmd_unmap(pmd - 1); return error; } Index: highpmd-2.6.7/mm/slab.c =================================================================== --- highpmd-2.6.7.orig/mm/slab.c 2004-06-15 22:19:44.000000000 -0700 +++ highpmd-2.6.7/mm/slab.c 2004-07-01 03:44:02.000000000 -0700 @@ -3033,7 +3033,7 @@ printk("No pgd.\n"); break; } - pmd = pmd_offset(pgd, addr); + pmd = pmd_offset_kernel(pgd, addr); if (pmd_none(*pmd)) { printk("No pmd.\n"); break; Index: highpmd-2.6.7/mm/swapfile.c =================================================================== --- highpmd-2.6.7.orig/mm/swapfile.c 2004-06-15 22:19:01.000000000 -0700 +++ highpmd-2.6.7/mm/swapfile.c 2004-07-01 03:44:02.000000000 -0700 @@ -493,7 +493,7 @@ pgd_clear(dir); return 0; } - pmd = pmd_offset(dir, address); + pmd = pmd_offset_map(dir, address); offset = address & PGDIR_MASK; address &= ~PGDIR_MASK; end = address + size; @@ -509,6 +509,7 @@ address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address && (address < end)); + pmd_unmap(pmd - 1); return 0; } Index: highpmd-2.6.7/mm/vmalloc.c =================================================================== --- highpmd-2.6.7.orig/mm/vmalloc.c 2004-06-15 22:19:36.000000000 -0700 +++ highpmd-2.6.7/mm/vmalloc.c 2004-07-01 03:44:02.000000000 -0700 @@ -71,7 +71,7 @@ return; } - pmd = pmd_offset(dir, address); + pmd = pmd_offset_kernel(dir, address); address &= ~PGDIR_MASK; end = address + size; if (end > PGDIR_SIZE) @@ -161,7 +161,7 @@ dir = pgd_offset_k(address); spin_lock(&init_mm.page_table_lock); do { - pmd_t *pmd = pmd_alloc(&init_mm, dir, address); + pmd_t *pmd = pmd_alloc_kernel(&init_mm, dir, address); if (!pmd) { err = -ENOMEM; break; Index: highpmd-2.6.7/mm/rmap.c =================================================================== --- highpmd-2.6.7.orig/mm/rmap.c 2004-06-15 22:20:03.000000000 -0700 +++ highpmd-2.6.7/mm/rmap.c 2004-07-01 04:43:43.000000000 -0700 @@ -215,10 +215,11 @@ if (!pgd_present(*pgd)) goto out_unlock; - pmd = pmd_offset(pgd, address); - if (!pmd_present(*pmd)) + pmd = pmd_offset_map(pgd, address); + if (!pmd_present(*pmd)) { + pmd_unmap(pmd); goto out_unlock; - + } pte = pte_offset_map(pmd, address); if (!pte_present(*pte)) goto out_unmap; @@ -232,6 +233,7 @@ (*mapcount)--; out_unmap: + pmd_unmap(pmd); pte_unmap(pte); out_unlock: spin_unlock(&mm->page_table_lock); @@ -448,9 +450,11 @@ if (!pgd_present(*pgd)) goto out_unlock; - pmd = pmd_offset(pgd, address); - if (!pmd_present(*pmd)) + pmd = pmd_offset_map(pgd, address); + if (!pmd_present(*pmd)) { + pmd_unmap(pmd); goto out_unlock; + } pte = pte_offset_map(pmd, address); if (!pte_present(*pte)) @@ -513,6 +517,7 @@ page_cache_release(page); out_unmap: + pmd_unmap(pmd); pte_unmap(pte); out_unlock: spin_unlock(&mm->page_table_lock); @@ -573,9 +578,11 @@ if (!pgd_present(*pgd)) goto out_unlock; - pmd = pmd_offset(pgd, address); - if (!pmd_present(*pmd)) + pmd = pmd_offset_map(pgd, address); + if (!pmd_present(*pmd)) { + pmd_unmap(pmd); goto out_unlock; + } for (pte = pte_offset_map(pmd, address); address < end; pte++, address += PAGE_SIZE) { @@ -612,7 +619,7 @@ mm->rss--; (*mapcount)--; } - + pmd_unmap(pmd); pte_unmap(pte); out_unlock: