mips: add support for folded p4d page tables
Implement primitives necessary for the 4th level folding, add walks of p4d level where appropriate, replace 5leve-fixup.h with pgtable-nop4d.h and drop usage of __ARCH_USE_5LEVEL_HACK. Signed-off-by: Mike Rapoport <rppt@linux.ibm.com> Signed-off-by: Paul Burton <paulburton@kernel.org> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: James Hogan <jhogan@kernel.org> Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org Cc: Mike Rapoport <rppt@kernel.org>
This commit is contained in:

committed by
Paul Burton

parent
31168f033e
commit
2bee1b5848
@@ -241,6 +241,7 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma,
|
||||
int exec = vma->vm_flags & VM_EXEC;
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
pgd_t *pgdp;
|
||||
p4d_t *p4dp;
|
||||
pud_t *pudp;
|
||||
pmd_t *pmdp;
|
||||
pte_t *ptep;
|
||||
@@ -253,7 +254,8 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma,
|
||||
return;
|
||||
|
||||
pgdp = pgd_offset(mm, addr);
|
||||
pudp = pud_offset(pgdp, addr);
|
||||
p4dp = p4d_offset(pgdp, addr);
|
||||
pudp = pud_offset(p4dp, addr);
|
||||
pmdp = pmd_offset(pudp, addr);
|
||||
ptep = pte_offset(pmdp, addr);
|
||||
|
||||
|
@@ -654,6 +654,7 @@ static inline void local_r4k_flush_cache_page(void *args)
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
int map_coherent = 0;
|
||||
pgd_t *pgdp;
|
||||
p4d_t *p4dp;
|
||||
pud_t *pudp;
|
||||
pmd_t *pmdp;
|
||||
pte_t *ptep;
|
||||
@@ -668,7 +669,8 @@ static inline void local_r4k_flush_cache_page(void *args)
|
||||
|
||||
addr &= PAGE_MASK;
|
||||
pgdp = pgd_offset(mm, addr);
|
||||
pudp = pud_offset(pgdp, addr);
|
||||
p4dp = p4d_offset(pgdp, addr);
|
||||
pudp = pud_offset(p4dp, addr);
|
||||
pmdp = pmd_offset(pudp, addr);
|
||||
ptep = pte_offset(pmdp, addr);
|
||||
|
||||
|
@@ -170,6 +170,7 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
|
||||
int exec = vma->vm_flags & VM_EXEC;
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
pgd_t *pgdp;
|
||||
p4d_t *p4dp;
|
||||
pud_t *pudp;
|
||||
pmd_t *pmdp;
|
||||
pte_t *ptep;
|
||||
@@ -183,7 +184,8 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
|
||||
|
||||
page &= PAGE_MASK;
|
||||
pgdp = pgd_offset(mm, page);
|
||||
pudp = pud_offset(pgdp, page);
|
||||
p4dp = p4d_offset(pgdp, page);
|
||||
pudp = pud_offset(p4dp, page);
|
||||
pmdp = pmd_offset(pudp, page);
|
||||
ptep = pte_offset(pmdp, page);
|
||||
|
||||
|
@@ -294,6 +294,7 @@ vmalloc_fault:
|
||||
*/
|
||||
int offset = pgd_index(address);
|
||||
pgd_t *pgd, *pgd_k;
|
||||
p4d_t *p4d, *p4d_k;
|
||||
pud_t *pud, *pud_k;
|
||||
pmd_t *pmd, *pmd_k;
|
||||
pte_t *pte_k;
|
||||
@@ -305,8 +306,13 @@ vmalloc_fault:
|
||||
goto no_context;
|
||||
set_pgd(pgd, *pgd_k);
|
||||
|
||||
pud = pud_offset(pgd, address);
|
||||
pud_k = pud_offset(pgd_k, address);
|
||||
p4d = p4d_offset(pgd, address);
|
||||
p4d_k = p4d_offset(pgd_k, address);
|
||||
if (!p4d_present(*p4d_k))
|
||||
goto no_context;
|
||||
|
||||
pud = pud_offset(p4d, address);
|
||||
pud_k = pud_offset(p4d_k, address);
|
||||
if (!pud_present(*pud_k))
|
||||
goto no_context;
|
||||
|
||||
|
@@ -25,11 +25,13 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr,
|
||||
unsigned long sz)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
p4d_t *p4d;
|
||||
pud_t *pud;
|
||||
pte_t *pte = NULL;
|
||||
|
||||
pgd = pgd_offset(mm, addr);
|
||||
pud = pud_alloc(mm, pgd, addr);
|
||||
p4d = p4d_alloc(mm, pgd, addr);
|
||||
pud = pud_alloc(mm, p4d, addr);
|
||||
if (pud)
|
||||
pte = (pte_t *)pmd_alloc(mm, pud, addr);
|
||||
|
||||
@@ -40,14 +42,18 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
|
||||
unsigned long sz)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
p4d_t *p4d;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd = NULL;
|
||||
|
||||
pgd = pgd_offset(mm, addr);
|
||||
if (pgd_present(*pgd)) {
|
||||
pud = pud_offset(pgd, addr);
|
||||
if (pud_present(*pud))
|
||||
pmd = pmd_offset(pud, addr);
|
||||
p4d = p4d_offset(pgd, addr);
|
||||
if (p4d_present(*p4d)) {
|
||||
pud = pud_offset(p4d, addr);
|
||||
if (pud_present(*pud))
|
||||
pmd = pmd_offset(pud, addr);
|
||||
}
|
||||
}
|
||||
return (pte_t *) pmd;
|
||||
}
|
||||
|
@@ -78,11 +78,15 @@ static int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
|
||||
flush_cache_all();
|
||||
BUG_ON(address >= end);
|
||||
do {
|
||||
p4d_t *p4d;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
|
||||
error = -ENOMEM;
|
||||
pud = pud_alloc(&init_mm, dir, address);
|
||||
p4d = p4d_alloc(&init_mm, dir, address);
|
||||
if (!p4d)
|
||||
break;
|
||||
pud = pud_alloc(&init_mm, p4d, address);
|
||||
if (!pud)
|
||||
break;
|
||||
pmd = pmd_alloc(&init_mm, pud, address);
|
||||
|
@@ -56,6 +56,7 @@ void __init pagetable_init(void)
|
||||
pgd_t *pgd_base;
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
pgd_t *pgd;
|
||||
p4d_t *p4d;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
@@ -82,7 +83,8 @@ void __init pagetable_init(void)
|
||||
fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
|
||||
|
||||
pgd = swapper_pg_dir + pgd_index(vaddr);
|
||||
pud = pud_offset(pgd, vaddr);
|
||||
p4d = p4d_offset(pgd, vaddr);
|
||||
pud = pud_offset(p4d, vaddr);
|
||||
pmd = pmd_offset(pud, vaddr);
|
||||
pte = pte_offset_kernel(pmd, vaddr);
|
||||
pkmap_page_table = pte;
|
||||
|
@@ -295,6 +295,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
|
||||
{
|
||||
unsigned long flags;
|
||||
pgd_t *pgdp;
|
||||
p4d_t *p4dp;
|
||||
pud_t *pudp;
|
||||
pmd_t *pmdp;
|
||||
pte_t *ptep;
|
||||
@@ -320,7 +321,8 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
|
||||
mtc0_tlbw_hazard();
|
||||
tlb_probe();
|
||||
tlb_probe_hazard();
|
||||
pudp = pud_offset(pgdp, address);
|
||||
p4dp = p4d_offset(pgdp, address);
|
||||
pudp = pud_offset(p4dp, address);
|
||||
pmdp = pmd_offset(pudp, address);
|
||||
idx = read_c0_index();
|
||||
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
||||
|
Reference in New Issue
Block a user