From: Andi Kleen alpha works with 3 levels (thanks to viro for testing) Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- 25-akpm/arch/alpha/mm/fault.c | 2 +- 25-akpm/arch/alpha/mm/init.c | 6 +++--- 25-akpm/arch/alpha/mm/remap.c | 2 +- 25-akpm/include/asm-alpha/mmu_context.h | 4 ++-- 25-akpm/include/asm-alpha/page.h | 2 ++ 25-akpm/include/asm-alpha/pgalloc.h | 4 ++-- 25-akpm/include/asm-alpha/pgtable.h | 9 ++++----- 7 files changed, 15 insertions(+), 14 deletions(-) diff -puN arch/alpha/mm/fault.c~4level-architecture-changes-for-alpha arch/alpha/mm/fault.c --- 25/arch/alpha/mm/fault.c~4level-architecture-changes-for-alpha 2004-11-03 21:53:14.088926232 -0800 +++ 25-akpm/arch/alpha/mm/fault.c 2004-11-03 21:53:14.100924408 -0800 @@ -51,7 +51,7 @@ __load_new_mm_context(struct mm_struct * pcb = ¤t_thread_info()->pcb; pcb->asn = mmc & HARDWARE_ASN_MASK; - pcb->ptbr = ((unsigned long) next_mm->pgd - IDENT_ADDR) >> PAGE_SHIFT; + pcb->ptbr = ((unsigned long) next_mm->pml4 - IDENT_ADDR) >> PAGE_SHIFT; __reload_thread(pcb); } diff -puN arch/alpha/mm/init.c~4level-architecture-changes-for-alpha arch/alpha/mm/init.c --- 25/arch/alpha/mm/init.c~4level-architecture-changes-for-alpha 2004-11-03 21:53:14.089926080 -0800 +++ 25-akpm/arch/alpha/mm/init.c 2004-11-03 21:53:14.100924408 -0800 @@ -38,12 +38,12 @@ extern void die_if_kernel(char *,struct static struct pcb_struct original_pcb; pgd_t * -pgd_alloc(struct mm_struct *mm) +__pgd_alloc(struct mm_struct *mm, pml4_t *dummy, unsigned long addr) { pgd_t *ret, *init; ret = (pgd_t *)__get_free_page(GFP_KERNEL); - init = pgd_offset(&init_mm, 0UL); + init = pml4_pgd_offset(pml4_offset_k(0UL), 0UL); if (ret) { clear_page(ret); #ifdef CONFIG_ALPHA_LARGE_VMALLOC @@ -222,7 +222,7 @@ callback_init(void * kernel_end) kernel_end = two_pages + 2*PAGE_SIZE; memset(two_pages, 0, 2*PAGE_SIZE); - pgd = pgd_offset_k(VMALLOC_START); + pgd = pml4_pgd_offset(pml4_offset_k(VMALLOC_START), VMALLOC_START); pgd_set(pgd, (pmd_t *)two_pages); pmd = pmd_offset(pgd, VMALLOC_START); pmd_set(pmd, (pte_t *)(two_pages + PAGE_SIZE)); diff -puN arch/alpha/mm/remap.c~4level-architecture-changes-for-alpha arch/alpha/mm/remap.c --- 25/arch/alpha/mm/remap.c~4level-architecture-changes-for-alpha 2004-11-03 21:53:14.090925928 -0800 +++ 25-akpm/arch/alpha/mm/remap.c 2004-11-03 21:53:14.101924256 -0800 @@ -66,7 +66,7 @@ __alpha_remap_area_pages(unsigned long a unsigned long end = address + size; phys_addr -= address; - dir = pgd_offset(&init_mm, address); + dir = pml4_pgd_offset(pml4_offset_k(address), address); flush_cache_all(); if (address >= end) BUG(); diff -puN include/asm-alpha/mmu_context.h~4level-architecture-changes-for-alpha include/asm-alpha/mmu_context.h --- 25/include/asm-alpha/mmu_context.h~4level-architecture-changes-for-alpha 2004-11-03 21:53:14.092925624 -0800 +++ 25-akpm/include/asm-alpha/mmu_context.h 2004-11-03 21:53:14.101924256 -0800 @@ -236,7 +236,7 @@ init_new_context(struct task_struct *tsk mm->context[i] = 0; if (tsk != current) tsk->thread_info->pcb.ptbr - = ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT; + = ((unsigned long)mm->pml4 - IDENT_ADDR) >> PAGE_SHIFT; return 0; } @@ -250,7 +250,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { tsk->thread_info->pcb.ptbr - = ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT; + = ((unsigned long)mm->pml4 - IDENT_ADDR) >> PAGE_SHIFT; } #ifdef __MMU_EXTERN_INLINE diff -puN include/asm-alpha/page.h~4level-architecture-changes-for-alpha include/asm-alpha/page.h --- 25/include/asm-alpha/page.h~4level-architecture-changes-for-alpha 2004-11-03 21:53:14.094925320 -0800 +++ 25-akpm/include/asm-alpha/page.h 2004-11-03 21:53:14.102924104 -0800 @@ -109,4 +109,6 @@ extern __inline__ int get_order(unsigned #endif /* __KERNEL__ */ +#include + #endif /* _ALPHA_PAGE_H */ diff -puN include/asm-alpha/pgalloc.h~4level-architecture-changes-for-alpha include/asm-alpha/pgalloc.h --- 25/include/asm-alpha/pgalloc.h~4level-architecture-changes-for-alpha 2004-11-03 21:53:14.095925168 -0800 +++ 25-akpm/include/asm-alpha/pgalloc.h 2004-11-03 21:53:14.102924104 -0800 @@ -29,8 +29,6 @@ pgd_populate(struct mm_struct *mm, pgd_t pgd_set(pgd, pmd); } -extern pgd_t *pgd_alloc(struct mm_struct *mm); - static inline void pgd_free(pgd_t *pgd) { @@ -77,4 +75,6 @@ pte_free(struct page *page) #define check_pgt_cache() do { } while (0) +#include + #endif /* _ALPHA_PGALLOC_H */ diff -puN include/asm-alpha/pgtable.h~4level-architecture-changes-for-alpha include/asm-alpha/pgtable.h --- 25/include/asm-alpha/pgtable.h~4level-architecture-changes-for-alpha 2004-11-03 21:53:14.096925016 -0800 +++ 25-akpm/include/asm-alpha/pgtable.h 2004-11-03 21:53:14.103923952 -0800 @@ -38,7 +38,7 @@ #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) #define PTRS_PER_PMD (1UL << (PAGE_SHIFT-3)) #define PTRS_PER_PGD (1UL << (PAGE_SHIFT-3)) -#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) +#define USER_PGDS_IN_FIRST_PML4 (TASK_SIZE / PGDIR_SIZE) #define FIRST_USER_PGD_NR 0 /* Number of pointers that fit on a page: this will go away. */ @@ -269,12 +269,9 @@ extern inline pte_t pte_mkyoung(pte_t pt #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) -/* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) - /* 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_index_k(address) pgd_index(address) /* Find an entry in the second-level page table.. */ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) @@ -353,4 +350,6 @@ extern void paging_init(void); /* We have our own get_unmapped_area to cope with ADDR_LIMIT_32BIT. */ #define HAVE_ARCH_UNMAPPED_AREA +#include + #endif /* _ALPHA_PGTABLE_H */ _