From: Andi Kleen ppc64 works with 3 levels (thanks to dwmw2) Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc64/kernel/eeh.c | 2 +- 25-akpm/arch/ppc64/kernel/process.c | 2 +- 25-akpm/arch/ppc64/mm/hash_utils.c | 2 +- 25-akpm/arch/ppc64/mm/hugetlbpage.c | 2 +- 25-akpm/arch/ppc64/mm/init.c | 7 ++++++- 25-akpm/include/asm-ppc64/page.h | 2 ++ 25-akpm/include/asm-ppc64/pgalloc.h | 8 ++------ 25-akpm/include/asm-ppc64/pgtable.h | 10 ++++------ 8 files changed, 18 insertions(+), 17 deletions(-) diff -puN arch/ppc64/kernel/eeh.c~4level-architecture-changes-for-ppc64 arch/ppc64/kernel/eeh.c --- 25/arch/ppc64/kernel/eeh.c~4level-architecture-changes-for-ppc64 2004-11-15 20:00:50.568110824 -0800 +++ 25-akpm/arch/ppc64/kernel/eeh.c 2004-11-15 20:00:50.581108848 -0800 @@ -482,7 +482,7 @@ static inline unsigned long eeh_token_to pte_t *ptep; unsigned long pa; - ptep = find_linux_pte(ioremap_mm.pgd, token); + ptep = find_linux_pte((pgd_t *)ioremap_mm.pml4, token); if (!ptep) return token; pa = pte_pfn(*ptep) << PAGE_SHIFT; diff -puN arch/ppc64/kernel/process.c~4level-architecture-changes-for-ppc64 arch/ppc64/kernel/process.c --- 25/arch/ppc64/kernel/process.c~4level-architecture-changes-for-ppc64 2004-11-15 20:00:50.569110672 -0800 +++ 25-akpm/arch/ppc64/kernel/process.c 2004-11-15 20:00:50.582108696 -0800 @@ -58,7 +58,7 @@ struct task_struct *last_task_used_altiv #endif struct mm_struct ioremap_mm = { - .pgd = ioremap_dir, + .pml4 = (pml4_t *)ioremap_dir, .mm_users = ATOMIC_INIT(2), .mm_count = ATOMIC_INIT(1), .cpu_vm_mask = CPU_MASK_ALL, diff -puN arch/ppc64/mm/hash_utils.c~4level-architecture-changes-for-ppc64 arch/ppc64/mm/hash_utils.c --- 25/arch/ppc64/mm/hash_utils.c~4level-architecture-changes-for-ppc64 2004-11-15 20:00:50.571110368 -0800 +++ 25-akpm/arch/ppc64/mm/hash_utils.c 2004-11-15 20:00:50.583108544 -0800 @@ -315,7 +315,7 @@ int hash_page(unsigned long ea, unsigned break; } - pgdir = mm->pgd; + pgdir = (pgd_t *)mm->pml4; if (pgdir == NULL) return 1; diff -puN arch/ppc64/mm/hugetlbpage.c~4level-architecture-changes-for-ppc64 arch/ppc64/mm/hugetlbpage.c --- 25/arch/ppc64/mm/hugetlbpage.c~4level-architecture-changes-for-ppc64 2004-11-15 20:00:50.572110216 -0800 +++ 25-akpm/arch/ppc64/mm/hugetlbpage.c 2004-11-15 20:00:50.583108544 -0800 @@ -216,7 +216,7 @@ static int prepare_low_seg_for_htlb(stru spin_lock(&mm->page_table_lock); tlb = tlb_gather_mmu(mm, 0); for (addr = start; addr < end; addr += PMD_SIZE) { - pgd_t *pgd = pgd_offset(mm, addr); + pgd_t *pgd = pml4_pgd_offset(pml4_offset(mm, addr), addr); pmd_t *pmd; struct page *page; pte_t *pte; diff -puN arch/ppc64/mm/init.c~4level-architecture-changes-for-ppc64 arch/ppc64/mm/init.c --- 25/arch/ppc64/mm/init.c~4level-architecture-changes-for-ppc64 2004-11-15 20:00:50.574109912 -0800 +++ 25-akpm/arch/ppc64/mm/init.c 2004-11-15 20:00:50.584108392 -0800 @@ -849,7 +849,7 @@ void update_mmu_cache(struct vm_area_str if (!pte_young(pte)) return; - pgdir = vma->vm_mm->pgd; + pgdir = (pgd_t *)vma->vm_mm->pml4; if (pgdir == NULL) return; @@ -900,3 +900,8 @@ void pgtable_cache_init(void) if (!zero_cache) panic("pgtable_cache_init(): could not create zero_cache!\n"); } + +pgd_t *__pgd_alloc(struct mm_struct *mm, pml4_t *dummy, unsigned long address) +{ + return kmem_cache_alloc(zero_cache, GFP_KERNEL); +} diff -puN include/asm-ppc64/page.h~4level-architecture-changes-for-ppc64 include/asm-ppc64/page.h --- 25/include/asm-ppc64/page.h~4level-architecture-changes-for-ppc64 2004-11-15 20:00:50.575109760 -0800 +++ 25-akpm/include/asm-ppc64/page.h 2004-11-15 20:00:50.585108240 -0800 @@ -235,5 +235,7 @@ extern int page_is_ram(unsigned long pfn #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#include + #endif /* __KERNEL__ */ #endif /* _PPC64_PAGE_H */ diff -puN include/asm-ppc64/pgalloc.h~4level-architecture-changes-for-ppc64 include/asm-ppc64/pgalloc.h --- 25/include/asm-ppc64/pgalloc.h~4level-architecture-changes-for-ppc64 2004-11-15 20:00:50.577109456 -0800 +++ 25-akpm/include/asm-ppc64/pgalloc.h 2004-11-15 20:00:50.585108240 -0800 @@ -18,12 +18,6 @@ extern kmem_cache_t *zero_cache; * 2 of the License, or (at your option) any later version. */ -static inline pgd_t * -pgd_alloc(struct mm_struct *mm) -{ - return kmem_cache_alloc(zero_cache, GFP_KERNEL); -} - static inline void pgd_free(pgd_t *pgd) { @@ -107,4 +101,6 @@ void __pte_free_tlb(struct mmu_gather *t #define check_pgt_cache() do { } while (0) +#include + #endif /* _PPC64_PGALLOC_H */ diff -puN include/asm-ppc64/pgtable.h~4level-architecture-changes-for-ppc64 include/asm-ppc64/pgtable.h --- 25/include/asm-ppc64/pgtable.h~4level-architecture-changes-for-ppc64 2004-11-15 20:00:50.578109304 -0800 +++ 25-akpm/include/asm-ppc64/pgtable.h 2004-11-15 20:00:50.586108088 -0800 @@ -38,7 +38,7 @@ #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) -#define USER_PTRS_PER_PGD (1024) +#define USER_PGDS_IN_LAST_PML4 (1024) #define FIRST_USER_PGD_NR 0 #define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ @@ -228,7 +228,7 @@ void hugetlb_mm_free_pgd(struct mm_struc /* to avoid overflow in free_pgtables we don't use PTRS_PER_PGD here */ #define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x7ff) -#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) +#define pgd_index_k(address) pgd_index(address) /* Find an entry in the second-level page table.. */ #define pmd_offset(dir,addr) \ @@ -243,10 +243,6 @@ void hugetlb_mm_free_pgd(struct mm_struc #define pte_unmap(pte) do { } while(0) #define pte_unmap_nested(pte) do { } while(0) -/* to find an entry in a kernel page-table-directory */ -/* This now only contains the vmalloc pages */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) - /* to find an entry in the ioremap page-table-directory */ #define pgd_offset_i(address) (ioremap_pgd + pgd_index(address)) @@ -558,4 +554,6 @@ static inline pte_t *find_linux_pte(pgd_ #define __HAVE_ARCH_PTE_SAME #include +#include + #endif /* _PPC64_PGTABLE_H */ _