
From: Andi Kleen <ak@suse.de>

alpha		works with 3 levels (thanks to viro for testing) 

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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 = &current_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 <asm-generic/nopml4-page.h>
+
 #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 <asm-generic/nopml4-pgalloc.h>
+
 #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 <asm-generic/nopml4-pgtable.h>
+
 #endif /* _ALPHA_PGTABLE_H */
_
