[PATCH 1/17] 4level support for alpha

From: Andreas Kleen
Date: Mon Oct 25 2004 - 02:29:49 EST


4level support for alpha

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

Signed-off-by: Andi Kleen <ak@xxxxxxx>

diff -urpN -X ../KDIFX linux-2.6.10rc1/arch/alpha/mm/fault.c linux-2.6.10rc1-4level/arch/alpha/mm/fault.c
--- linux-2.6.10rc1/arch/alpha/mm/fault.c 2004-10-19 01:54:59.000000000 +0200
+++ linux-2.6.10rc1-4level/arch/alpha/mm/fault.c 2004-10-25 04:48:09.000000000 +0200
@@ -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 -urpN -X ../KDIFX linux-2.6.10rc1/arch/alpha/mm/init.c linux-2.6.10rc1-4level/arch/alpha/mm/init.c
--- linux-2.6.10rc1/arch/alpha/mm/init.c 2004-08-15 19:45:01.000000000 +0200
+++ linux-2.6.10rc1-4level/arch/alpha/mm/init.c 2004-10-25 04:48:09.000000000 +0200
@@ -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 -urpN -X ../KDIFX linux-2.6.10rc1/arch/alpha/mm/remap.c linux-2.6.10rc1-4level/arch/alpha/mm/remap.c
--- linux-2.6.10rc1/arch/alpha/mm/remap.c 2004-03-21 21:12:07.000000000 +0100
+++ linux-2.6.10rc1-4level/arch/alpha/mm/remap.c 2004-10-25 04:48:09.000000000 +0200
@@ -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 -urpN -X ../KDIFX linux-2.6.10rc1/include/asm-alpha/mmu_context.h linux-2.6.10rc1-4level/include/asm-alpha/mmu_context.h
--- linux-2.6.10rc1/include/asm-alpha/mmu_context.h 2004-10-19 01:55:31.000000000 +0200
+++ linux-2.6.10rc1-4level/include/asm-alpha/mmu_context.h 2004-10-25 04:48:10.000000000 +0200
@@ -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 -urpN -X ../KDIFX linux-2.6.10rc1/include/asm-alpha/page.h linux-2.6.10rc1-4level/include/asm-alpha/page.h
--- linux-2.6.10rc1/include/asm-alpha/page.h 2004-10-19 01:55:31.000000000 +0200
+++ linux-2.6.10rc1-4level/include/asm-alpha/page.h 2004-10-25 04:48:10.000000000 +0200
@@ -109,4 +109,6 @@ extern __inline__ int get_order(unsigned

#endif /* __KERNEL__ */

+#include <asm-generic/nopml4-page.h>
+
#endif /* _ALPHA_PAGE_H */
diff -urpN -X ../KDIFX linux-2.6.10rc1/include/asm-alpha/pgalloc.h linux-2.6.10rc1-4level/include/asm-alpha/pgalloc.h
--- linux-2.6.10rc1/include/asm-alpha/pgalloc.h 2004-08-15 19:45:44.000000000 +0200
+++ linux-2.6.10rc1-4level/include/asm-alpha/pgalloc.h 2004-10-25 04:48:10.000000000 +0200
@@ -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 -urpN -X ../KDIFX linux-2.6.10rc1/include/asm-alpha/pgtable.h linux-2.6.10rc1-4level/include/asm-alpha/pgtable.h
--- linux-2.6.10rc1/include/asm-alpha/pgtable.h 2004-10-25 04:47:34.000000000 +0200
+++ linux-2.6.10rc1-4level/include/asm-alpha/pgtable.h 2004-10-25 04:48:10.000000000 +0200
@@ -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)
@@ -349,4 +346,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 */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/