ARC: mm: support 3 levels of page tables
ARCv2 MMU is software walked and Linux implements 2 levels of paging: pgd/pte.
Forthcoming hw will have multiple levels, so this change preps mm code
for same. It is also fun to try multi levels even on soft-walked code to
ensure generic mm code is robust to handle.
overview
________
2 levels {pgd, pte} : pmd is folded but pmd_* macros are valid and operate on pgd
3 levels {pgd, pmd, pte}:
- pud is folded and pud_* macros point to pgd
- pmd_* macros operate on actual pmd
code changes
____________
1. #include <asm-generic/pgtable-nopud.h>
2. Define CONFIG_PGTABLE_LEVELS 3
3a. Define PMD_SHIFT, PMD_SIZE, PMD_MASK, pmd_t
3b. Define pmd_val() which actually deals with pmd
(pmd_offset(), pmd_index() are provided by generic code)
3c. pmd_alloc_one()/pmd_free() also provided by generic code
(pmd_populate/pmd_free already exist)
4. Define pud_none(), pud_bad() macros based on generic pud_val() which
internally pertains to pgd now.
4b. define pud_populate() to just setup pgd
Acked-by: Mike Rapoport <rppt@linux.ibm.com>
Signed-off-by: Vineet Gupta <vgupta@kernel.org>
This commit is contained in:
@@ -39,6 +39,8 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
|
||||
if (!pgd_present(*pgd_k))
|
||||
goto bad_area;
|
||||
|
||||
set_pgd(pgd, *pgd_k);
|
||||
|
||||
p4d = p4d_offset(pgd, address);
|
||||
p4d_k = p4d_offset(pgd_k, address);
|
||||
if (!p4d_present(*p4d_k))
|
||||
@@ -49,6 +51,8 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
|
||||
if (!pud_present(*pud_k))
|
||||
goto bad_area;
|
||||
|
||||
set_pud(pud, *pud_k);
|
||||
|
||||
pmd = pmd_offset(pud, address);
|
||||
pmd_k = pmd_offset(pud_k, address);
|
||||
if (!pmd_present(*pmd_k))
|
||||
|
||||
Reference in New Issue
Block a user