asm-generic: introduce 5level-fixup.h

We are going to switch core MM to 5-level paging abstraction.

This is preparation step which adds <asm-generic/5level-fixup.h>
As with 4level-fixup.h, the new header allows quickly make all
architectures compatible with 5-level paging in core MM.

In long run we would like to switch architectures to properly folded p4d
level by using <asm-generic/pgtable-nop4d.h>, but it requires more
changes to arch-specific code.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Kirill A. Shutemov 2017-03-09 17:24:03 +03:00 committed by Linus Torvalds
parent 6fb895692a
commit 505a60e225
3 changed files with 46 additions and 1 deletions

View File

@ -15,7 +15,6 @@
((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \ ((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \
NULL: pmd_offset(pud, address)) NULL: pmd_offset(pud, address))
#define pud_alloc(mm, pgd, address) (pgd)
#define pud_offset(pgd, start) (pgd) #define pud_offset(pgd, start) (pgd)
#define pud_none(pud) 0 #define pud_none(pud) 0
#define pud_bad(pud) 0 #define pud_bad(pud) 0
@ -35,4 +34,6 @@
#undef pud_addr_end #undef pud_addr_end
#define pud_addr_end(addr, end) (end) #define pud_addr_end(addr, end) (end)
#include <asm-generic/5level-fixup.h>
#endif #endif

View File

@ -0,0 +1,41 @@
#ifndef _5LEVEL_FIXUP_H
#define _5LEVEL_FIXUP_H
#define __ARCH_HAS_5LEVEL_HACK
#define __PAGETABLE_P4D_FOLDED
#define P4D_SHIFT PGDIR_SHIFT
#define P4D_SIZE PGDIR_SIZE
#define P4D_MASK PGDIR_MASK
#define PTRS_PER_P4D 1
#define p4d_t pgd_t
#define pud_alloc(mm, p4d, address) \
((unlikely(pgd_none(*(p4d))) && __pud_alloc(mm, p4d, address)) ? \
NULL : pud_offset(p4d, address))
#define p4d_alloc(mm, pgd, address) (pgd)
#define p4d_offset(pgd, start) (pgd)
#define p4d_none(p4d) 0
#define p4d_bad(p4d) 0
#define p4d_present(p4d) 1
#define p4d_ERROR(p4d) do { } while (0)
#define p4d_clear(p4d) pgd_clear(p4d)
#define p4d_val(p4d) pgd_val(p4d)
#define p4d_populate(mm, p4d, pud) pgd_populate(mm, p4d, pud)
#define p4d_page(p4d) pgd_page(p4d)
#define p4d_page_vaddr(p4d) pgd_page_vaddr(p4d)
#define __p4d(x) __pgd(x)
#define set_p4d(p4dp, p4d) set_pgd(p4dp, p4d)
#undef p4d_free_tlb
#define p4d_free_tlb(tlb, x, addr) do { } while (0)
#define p4d_free(mm, x) do { } while (0)
#define __p4d_free_tlb(tlb, x, addr) do { } while (0)
#undef p4d_addr_end
#define p4d_addr_end(addr, end) (end)
#endif

View File

@ -1619,11 +1619,14 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address);
* Remove it when 4level-fixup.h has been removed. * Remove it when 4level-fixup.h has been removed.
*/ */
#if defined(CONFIG_MMU) && !defined(__ARCH_HAS_4LEVEL_HACK) #if defined(CONFIG_MMU) && !defined(__ARCH_HAS_4LEVEL_HACK)
#ifndef __ARCH_HAS_5LEVEL_HACK
static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
{ {
return (unlikely(pgd_none(*pgd)) && __pud_alloc(mm, pgd, address))? return (unlikely(pgd_none(*pgd)) && __pud_alloc(mm, pgd, address))?
NULL: pud_offset(pgd, address); NULL: pud_offset(pgd, address);
} }
#endif /* !__ARCH_HAS_5LEVEL_HACK */
static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
{ {