From: Andi Kleen sparc32 converted, not compile tested Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- 25-akpm/arch/sparc/mm/fault.c | 10 +++++----- 25-akpm/arch/sparc/mm/generic.c | 2 +- 25-akpm/arch/sparc/mm/init.c | 7 ++++++- 25-akpm/arch/sparc/mm/io-unit.c | 2 +- 25-akpm/arch/sparc/mm/iommu.c | 2 +- 25-akpm/arch/sparc/mm/srmmu.c | 25 +++++++++++++------------ 25-akpm/arch/sparc/mm/sun4c.c | 2 +- 25-akpm/include/asm-sparc/page.h | 2 ++ 25-akpm/include/asm-sparc/pgalloc.h | 3 ++- 25-akpm/include/asm-sparc/pgtable.h | 10 +++------- 10 files changed, 35 insertions(+), 30 deletions(-) diff -puN arch/sparc/mm/fault.c~4level-architecture-changes-for-sparc arch/sparc/mm/fault.c --- 25/arch/sparc/mm/fault.c~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.839765480 -0800 +++ 25-akpm/arch/sparc/mm/fault.c 2004-11-15 20:00:52.856762896 -0800 @@ -148,8 +148,8 @@ static void unhandled_fault(unsigned lon printk(KERN_ALERT "tsk->{mm,active_mm}->context = %08lx\n", (tsk->mm ? tsk->mm->context : tsk->active_mm->context)); printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %08lx\n", - (tsk->mm ? (unsigned long) tsk->mm->pgd : - (unsigned long) tsk->active_mm->pgd)); + (tsk->mm ? (unsigned long) tsk->mm->pml4 : + (unsigned long) tsk->active_mm->pml4)); die_if_kernel("Oops", regs); } @@ -396,8 +396,8 @@ vmalloc_fault: pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; - pgd = tsk->active_mm->pgd + offset; - pgd_k = init_mm.pgd + offset; + pgd = (pgd_t *)(tsk->active_mm->pml4) + offset; + pgd_k = (pgd_t *)(init_mm.pml4) + offset; if (!pgd_present(*pgd)) { if (!pgd_present(*pgd_k)) @@ -446,7 +446,7 @@ asmlinkage void do_sun4c_fault(struct pt BUG(); /* P3 Oops already, you bitch */ } - pgdp = pgd_offset(mm, address); + pgdp = pml4_pgd_offset(pml4_offset(mm, address), address); ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, address); if (pgd_val(*pgdp)) { diff -puN arch/sparc/mm/generic.c~4level-architecture-changes-for-sparc arch/sparc/mm/generic.c --- 25/arch/sparc/mm/generic.c~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.840765328 -0800 +++ 25-akpm/arch/sparc/mm/generic.c 2004-11-15 20:00:52.856762896 -0800 @@ -98,7 +98,7 @@ int io_remap_page_range(struct vm_area_s prot = __pgprot(pg_iobits); offset -= from; - dir = pgd_offset(mm, from); + dir = pml4_pgd_offset(pml4_offset(mm, from), from); flush_cache_range(vma, beg, end); spin_lock(&mm->page_table_lock); diff -puN arch/sparc/mm/init.c~4level-architecture-changes-for-sparc arch/sparc/mm/init.c --- 25/arch/sparc/mm/init.c~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.842765024 -0800 +++ 25-akpm/arch/sparc/mm/init.c 2004-11-15 20:00:52.857762744 -0800 @@ -63,7 +63,7 @@ EXPORT_SYMBOL(kmap_prot); 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(pml4_pgd_offset_k(pml4_offset_k(vaddr), vaddr), (vaddr)), (vaddr)) void __init kmap_init(void) { @@ -518,3 +518,8 @@ void sparc_flush_page_to_ram(struct page if (vaddr) __flush_page_to_ram(vaddr); } + +pgd_t *__pgd_alloc(struct mm_struct *mm, pml4_t *pml4, unsigned long addr) +{ + return get_pgd_fast(); +} diff -puN arch/sparc/mm/iommu.c~4level-architecture-changes-for-sparc arch/sparc/mm/iommu.c --- 25/arch/sparc/mm/iommu.c~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.844764720 -0800 +++ 25-akpm/arch/sparc/mm/iommu.c 2004-11-15 20:00:52.857762744 -0800 @@ -349,7 +349,7 @@ static int iommu_map_dma_area(dma_addr_t else __flush_page_to_ram(page); - pgdp = pgd_offset(&init_mm, addr); + pgdp = pml4_pgd_offset(pml4_offset(&init_mm,addr),addr); pmdp = pmd_offset(pgdp, addr); ptep = pte_offset_map(pmdp, addr); diff -puN arch/sparc/mm/io-unit.c~4level-architecture-changes-for-sparc arch/sparc/mm/io-unit.c --- 25/arch/sparc/mm/io-unit.c~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.845764568 -0800 +++ 25-akpm/arch/sparc/mm/io-unit.c 2004-11-15 20:00:52.858762592 -0800 @@ -196,7 +196,7 @@ static int iounit_map_dma_area(dma_addr_ pte_t *ptep; long i; - pgdp = pgd_offset(init_task.mm, addr); + pgdp = pml4_pgd_offset(pml4_offset(init_task.mm, addr), addr); pmdp = pmd_offset(pgdp, addr); ptep = pte_offset_map(pmdp, addr); diff -puN arch/sparc/mm/srmmu.c~4level-architecture-changes-for-sparc arch/sparc/mm/srmmu.c --- 25/arch/sparc/mm/srmmu.c~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.847764264 -0800 +++ 25-akpm/arch/sparc/mm/srmmu.c 2004-11-15 20:00:52.860762288 -0800 @@ -257,7 +257,7 @@ static inline pte_t srmmu_pte_modify(pte /* to find an entry in a top-level page table... */ extern inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address) -{ return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); } +{ return (pgd_t *)(mm->pml4) + (address >> SRMMU_PGDIR_SHIFT); } /* Find an entry in the second-level page table.. */ static inline pmd_t *srmmu_pmd_offset(pgd_t * dir, unsigned long address) @@ -419,7 +419,7 @@ void srmmu_nocache_init(void) srmmu_swapper_pg_dir = (pgd_t *)__srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); memset(__nocache_fix(srmmu_swapper_pg_dir), 0, SRMMU_PGD_TABLE_SIZE); - init_mm.pgd = srmmu_swapper_pg_dir; + init_mm.pml4 = (pgd_t *)srmmu_swapper_pg_dir; srmmu_early_allocate_ptable_skeleton(SRMMU_NOCACHE_VADDR, srmmu_nocache_end); @@ -427,7 +427,7 @@ void srmmu_nocache_init(void) vaddr = SRMMU_NOCACHE_VADDR; while (vaddr < srmmu_nocache_end) { - pgd = pgd_offset_k(vaddr); + pgd = pml4_pgd_offset_k(pml4_offset_k(vaddr), vaddr); pmd = srmmu_pmd_offset(__nocache_fix(pgd), vaddr); pte = srmmu_pte_offset(__nocache_fix(pmd), vaddr); @@ -452,7 +452,7 @@ static inline pgd_t *srmmu_get_pgd_fast( pgd = (pgd_t *)__srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); if (pgd) { - pgd_t *init = pgd_offset_k(0); + pgd_t *init = pml4_pgd_offset_k(pml4_offset_k(0), 0); memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); @@ -562,7 +562,8 @@ static void srmmu_switch_mm(struct mm_st spin_lock(&srmmu_context_spinlock); alloc_context(old_mm, mm); spin_unlock(&srmmu_context_spinlock); - srmmu_ctxd_set(&srmmu_context_table[mm->context], mm->pgd); + srmmu_ctxd_set(&srmmu_context_table[mm->context], + (pgd_t *)mm->pml4); } if (is_hypersparc) @@ -581,7 +582,7 @@ static inline void srmmu_mapioaddr(unsig unsigned long tmp; physaddr &= PAGE_MASK; - pgdp = pgd_offset_k(virt_addr); + pgdp = pml4_pgd_offset_k(pml4_offset_k(virt_addr), virt_addr); pmdp = srmmu_pmd_offset(pgdp, virt_addr); ptep = srmmu_pte_offset(pmdp, virt_addr); tmp = (physaddr >> 4) | SRMMU_ET_PTE; @@ -615,7 +616,7 @@ static inline void srmmu_unmapioaddr(uns pmd_t *pmdp; pte_t *ptep; - pgdp = pgd_offset_k(virt_addr); + pgdp = pml4_pgd_offset_k(pml4_offset_k(virt_addr), virt_addr); pmdp = srmmu_pmd_offset(pgdp, virt_addr); ptep = srmmu_pte_offset(pmdp, virt_addr); @@ -1056,7 +1057,7 @@ void __init srmmu_early_allocate_ptable_ pte_t *ptep; while(start < end) { - pgdp = pgd_offset_k(start); + pgdp = pml4_pgd_offset_k(pml4_offset_k(start), start); if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { pmdp = (pmd_t *) __srmmu_get_nocache( SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); @@ -1086,7 +1087,7 @@ void __init srmmu_allocate_ptable_skelet pte_t *ptep; while(start < end) { - pgdp = pgd_offset_k(start); + pgdp = pml4_pgd_offset_k(pml4_offset_k(start), start); if(srmmu_pgd_none(*pgdp)) { pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if (pmdp == NULL) @@ -1146,7 +1147,7 @@ void __init srmmu_inherit_prom_mappings( what = 2; } - pgdp = pgd_offset_k(start); + pgdp = pml4_pgd_offset_k(pml4_offset_k(start), start); if(what == 2) { *(pgd_t *)__nocache_fix(pgdp) = __pgd(prompte); start += SRMMU_PGDIR_SIZE; @@ -1191,7 +1192,7 @@ void __init srmmu_inherit_prom_mappings( /* Create a third-level SRMMU 16MB page mapping. */ static void __init do_large_mapping(unsigned long vaddr, unsigned long phys_base) { - pgd_t *pgdp = pgd_offset_k(vaddr); + pgd_t *pgdp = pml4_pgd_offset_k(pml4_offset_k(vaddr), vaddr); unsigned long big_pte; big_pte = KERNEL_PTE(phys_base >> 4); @@ -1311,7 +1312,7 @@ void __init srmmu_paging_init(void) __fix_to_virt(__end_of_fixed_addresses - 1), FIXADDR_TOP); srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_END); - pgd = pgd_offset_k(PKMAP_BASE); + pgd = pml4_pgd_offset_k(pml4_offset_k(PKMAP_BASE), PKMAP_BASE); pmd = srmmu_pmd_offset(pgd, PKMAP_BASE); pte = srmmu_pte_offset(pmd, PKMAP_BASE); pkmap_page_table = pte; diff -puN arch/sparc/mm/sun4c.c~4level-architecture-changes-for-sparc arch/sparc/mm/sun4c.c --- 25/arch/sparc/mm/sun4c.c~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.848764112 -0800 +++ 25-akpm/arch/sparc/mm/sun4c.c 2004-11-15 20:00:52.862761984 -0800 @@ -1847,7 +1847,7 @@ static unsigned long sun4c_pgd_page(pgd_ /* to find an entry in a page-table-directory */ static inline pgd_t *sun4c_pgd_offset(struct mm_struct * mm, unsigned long address) { - return mm->pgd + (address >> SUN4C_PGDIR_SHIFT); + return (pgd_t *)mm->pml4 + (address >> SUN4C_PGDIR_SHIFT); } /* Find an entry in the second-level page table.. */ diff -puN include/asm-sparc/page.h~4level-architecture-changes-for-sparc include/asm-sparc/page.h --- 25/include/asm-sparc/page.h~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.850763808 -0800 +++ 25-akpm/include/asm-sparc/page.h 2004-11-15 20:00:52.863761832 -0800 @@ -176,6 +176,8 @@ extern unsigned long pfn_base; #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#include + #endif /* __KERNEL__ */ #endif /* _SPARC_PAGE_H */ diff -puN include/asm-sparc/pgalloc.h~4level-architecture-changes-for-sparc include/asm-sparc/pgalloc.h --- 25/include/asm-sparc/pgalloc.h~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.851763656 -0800 +++ 25-akpm/include/asm-sparc/pgalloc.h 2004-11-15 20:00:52.863761832 -0800 @@ -34,7 +34,6 @@ BTFIXUPDEF_CALL(void, free_pgd_fast, pgd #define free_pgd_fast(pgd) BTFIXUP_CALL(free_pgd_fast)(pgd) #define pgd_free(pgd) free_pgd_fast(pgd) -#define pgd_alloc(mm) get_pgd_fast() BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *) #define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp) @@ -66,4 +65,6 @@ BTFIXUPDEF_CALL(void, pte_free, struct p #define pte_free(pte) BTFIXUP_CALL(pte_free)(pte) #define __pte_free_tlb(tlb, pte) pte_free(pte) +#include + #endif /* _SPARC_PGALLOC_H */ diff -puN include/asm-sparc/pgtable.h~4level-architecture-changes-for-sparc include/asm-sparc/pgtable.h --- 25/include/asm-sparc/pgtable.h~4level-architecture-changes-for-sparc 2004-11-15 20:00:52.852763504 -0800 +++ 25-akpm/include/asm-sparc/pgtable.h 2004-11-15 20:00:52.864761680 -0800 @@ -60,7 +60,7 @@ BTFIXUPDEF_INT(page_kernel) #define PTRS_PER_PTE 1024 #define PTRS_PER_PMD BTFIXUP_SIMM13(ptrs_per_pmd) #define PTRS_PER_PGD BTFIXUP_SIMM13(ptrs_per_pgd) -#define USER_PTRS_PER_PGD BTFIXUP_SIMM13(user_ptrs_per_pgd) +#define USER_PGDS_IN_LAST_PML4 BTFIXUP_SIMM13(user_ptrs_per_pgd) #define FIRST_USER_PGD_NR 0 #define PTE_SIZE (PTRS_PER_PTE*4) @@ -280,12 +280,7 @@ extern __inline__ pte_t pte_modify(pte_t } #define pgd_index(address) ((address) >> PGDIR_SHIFT) - -/* to find an entry in a page-table-directory */ -#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) - -/* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) +#define pgd_index_k(address) pgd_index(address) /* Find an entry in the second-level page table.. */ BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long) @@ -434,6 +429,7 @@ extern int io_remap_page_range(struct vm unsigned long size, pgprot_t prot, int space); #include +#include #endif /* !(__ASSEMBLY__) */ _