Skip to content

Commit

Permalink
Merge branch 'prep-for-5level'
Browse files Browse the repository at this point in the history
Merge 5-level page table prep from Kirill Shutemov:
 "Here's relatively low-risk part of 5-level paging patchset. Merging it
  now will make x86 5-level paging enabling in v4.12 easier.

  The first patch is actually x86-specific: detect 5-level paging
  support. It boils down to single define.

  The rest of patchset converts Linux MMU abstraction from 4- to 5-level
  paging.

  Enabling of new abstraction in most cases requires adding single line
  of code in arch-specific code. The rest is taken care by asm-generic/.

  Changes to mm/ code are mostly mechanical: add support for new page
  table level -- p4d_t -- where we deal with pud_t now.

  v2:
   - fix build on microblaze (Michal);
   - comment for __ARCH_HAS_5LEVEL_HACK in kasan_populate_zero_shadow();
   - acks from Michal"

* emailed patches from Kirill A Shutemov <kirill.shutemov@linux.intel.com>:
  mm: introduce __p4d_alloc()
  mm: convert generic code to 5-level paging
  asm-generic: introduce <asm-generic/pgtable-nop4d.h>
  arch, mm: convert all architectures to use 5level-fixup.h
  asm-generic: introduce __ARCH_USE_5LEVEL_HACK
  asm-generic: introduce 5level-fixup.h
  x86/cpufeature: Add 5-level paging detection
  • Loading branch information
torvalds committed Mar 10, 2017
2 parents 8fe3cca + 90eceff commit baeedc7
Show file tree
Hide file tree
Showing 64 changed files with 868 additions and 147 deletions.
1 change: 1 addition & 0 deletions arch/arc/include/asm/hugepage.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define _ASM_ARC_HUGEPAGE_H

#include <linux/types.h>
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

static inline pte_t pmd_pte(pmd_t pmd)
Expand Down
1 change: 1 addition & 0 deletions arch/arc/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include <asm/page.h>
#include <asm/mmu.h>
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>
#include <linux/const.h>

Expand Down
1 change: 1 addition & 0 deletions arch/arm/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#else

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>
#include <asm/memory.h>
#include <asm/pgtable-hwdef.h>
Expand Down
4 changes: 4 additions & 0 deletions arch/arm64/include/asm/pgtable-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ typedef struct { pteval_t pgprot; } pgprot_t;
#define __pgprot(x) ((pgprot_t) { (x) } )

#if CONFIG_PGTABLE_LEVELS == 2
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>
#elif CONFIG_PGTABLE_LEVELS == 3
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>
#elif CONFIG_PGTABLE_LEVELS == 4
#include <asm-generic/5level-fixup.h>
#endif

#endif /* __ASM_PGTABLE_TYPES_H */
1 change: 1 addition & 0 deletions arch/avr32/include/asm/pgtable-2level.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#ifndef __ASM_AVR32_PGTABLE_2LEVEL_H
#define __ASM_AVR32_PGTABLE_2LEVEL_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

/*
Expand Down
1 change: 1 addition & 0 deletions arch/cris/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define _CRIS_PGTABLE_H

#include <asm/page.h>
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

#ifndef __ASSEMBLY__
Expand Down
1 change: 1 addition & 0 deletions arch/frv/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#ifndef _ASM_PGTABLE_H
#define _ASM_PGTABLE_H

#include <asm-generic/5level-fixup.h>
#include <asm/mem-layout.h>
#include <asm/setup.h>
#include <asm/processor.h>
Expand Down
1 change: 1 addition & 0 deletions arch/h8300/include/asm/pgtable.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef _H8300_PGTABLE_H
#define _H8300_PGTABLE_H
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>
#include <asm-generic/pgtable.h>
#define pgtable_cache_init() do { } while (0)
Expand Down
1 change: 1 addition & 0 deletions arch/hexagon/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*/
#include <linux/swap.h>
#include <asm/page.h>
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

/* A handy thing to have if one has the RAM. Declared in head.S */
Expand Down
2 changes: 2 additions & 0 deletions arch/ia64/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,8 +587,10 @@ extern struct page *zero_page_memmap_ptr;


#if CONFIG_PGTABLE_LEVELS == 3
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>
#endif
#include <asm-generic/5level-fixup.h>
#include <asm-generic/pgtable.h>

#endif /* _ASM_IA64_PGTABLE_H */
1 change: 1 addition & 0 deletions arch/metag/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define _METAG_PGTABLE_H

#include <asm/pgtable-bits.h>
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

/* Invalid regions on Meta: 0x00000000-0x001FFFFF and 0xFFFF0000-0xFFFFFFFF */
Expand Down
3 changes: 2 additions & 1 deletion arch/microblaze/include/asm/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ typedef struct { unsigned long pgd; } pgd_t;
# else /* CONFIG_MMU */
typedef struct { unsigned long ste[64]; } pmd_t;
typedef struct { pmd_t pue[1]; } pud_t;
typedef struct { pud_t pge[1]; } pgd_t;
typedef struct { pud_t p4e[1]; } p4d_t;
typedef struct { p4d_t pge[1]; } pgd_t;
# endif /* CONFIG_MMU */

# define pte_val(x) ((x).pte)
Expand Down
1 change: 1 addition & 0 deletions arch/mips/include/asm/pgtable-32.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <asm/cachectl.h>
#include <asm/fixmap.h>

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

extern int temp_tlb_entry;
Expand Down
1 change: 1 addition & 0 deletions arch/mips/include/asm/pgtable-64.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <asm/cachectl.h>
#include <asm/fixmap.h>

#define __ARCH_USE_5LEVEL_HACK
#if defined(CONFIG_PAGE_SIZE_64KB) && !defined(CONFIG_MIPS_VA_BITS_48)
#include <asm-generic/pgtable-nopmd.h>
#else
Expand Down
1 change: 1 addition & 0 deletions arch/mn10300/include/asm/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) })
#define __pgprot(x) ((pgprot_t) { (x) })

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

#endif /* !__ASSEMBLY__ */
Expand Down
1 change: 1 addition & 0 deletions arch/nios2/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <asm/tlbflush.h>

#include <asm/pgtable-bits.h>
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

#define FIRST_USER_ADDRESS 0UL
Expand Down
1 change: 1 addition & 0 deletions arch/openrisc/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#ifndef __ASM_OPENRISC_PGTABLE_H
#define __ASM_OPENRISC_PGTABLE_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

#ifndef __ASSEMBLY__
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/book3s/32/pgtable.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _ASM_POWERPC_BOOK3S_32_PGTABLE_H
#define _ASM_POWERPC_BOOK3S_32_PGTABLE_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

#include <asm/book3s/32/hash.h>
Expand Down
3 changes: 3 additions & 0 deletions arch/powerpc/include/asm/book3s/64/pgtable.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#ifndef _ASM_POWERPC_BOOK3S_64_PGTABLE_H_
#define _ASM_POWERPC_BOOK3S_64_PGTABLE_H_

#include <asm-generic/5level-fixup.h>

#ifndef __ASSEMBLY__
#include <linux/mmdebug.h>
#endif

/*
* Common bits between hash and Radix page table
*/
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/nohash/32/pgtable.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _ASM_POWERPC_NOHASH_32_PGTABLE_H
#define _ASM_POWERPC_NOHASH_32_PGTABLE_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

#ifndef __ASSEMBLY__
Expand Down
3 changes: 3 additions & 0 deletions arch/powerpc/include/asm/nohash/64/pgtable-4k.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H
#define _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H

#include <asm-generic/5level-fixup.h>

/*
* Entries per page directory level. The PTE level must use a 64b record
* for each page table entry. The PMD and PGD level use a 32b record for
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/nohash/64/pgtable-64k.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H
#define _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>


Expand Down
1 change: 1 addition & 0 deletions arch/s390/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* the S390 page table tree.
*/
#ifndef __ASSEMBLY__
#include <asm-generic/5level-fixup.h>
#include <linux/sched.h>
#include <linux/mm_types.h>
#include <linux/page-flags.h>
Expand Down
1 change: 1 addition & 0 deletions arch/score/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _ASM_SCORE_PGTABLE_H

#include <linux/const.h>
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

#include <asm/fixmap.h>
Expand Down
1 change: 1 addition & 0 deletions arch/sh/include/asm/pgtable-2level.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef __ASM_SH_PGTABLE_2LEVEL_H
#define __ASM_SH_PGTABLE_2LEVEL_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

/*
Expand Down
1 change: 1 addition & 0 deletions arch/sh/include/asm/pgtable-3level.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef __ASM_SH_PGTABLE_3LEVEL_H
#define __ASM_SH_PGTABLE_3LEVEL_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>

/*
Expand Down
1 change: 1 addition & 0 deletions arch/sparc/include/asm/pgtable_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* the SpitFire page tables.
*/

#include <asm-generic/5level-fixup.h>
#include <linux/compiler.h>
#include <linux/const.h>
#include <asm/types.h>
Expand Down
1 change: 1 addition & 0 deletions arch/tile/include/asm/pgtable_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ extern unsigned long VMALLOC_RESERVE /* = CONFIG_VMALLOC_RESERVE */;
#define MAXMEM (_VMALLOC_START - PAGE_OFFSET)

/* We have no pmd or pud since we are strictly a two-level page table */
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

static inline int pud_huge_page(pud_t pud) { return 0; }
Expand Down
1 change: 1 addition & 0 deletions arch/tile/include/asm/pgtable_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#ifndef __ASSEMBLY__

/* We have no pud since we are a three-level page table. */
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>

/*
Expand Down
1 change: 1 addition & 0 deletions arch/um/include/asm/pgtable-2level.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#ifndef __UM_PGTABLE_2LEVEL_H
#define __UM_PGTABLE_2LEVEL_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

/* PGDIR_SHIFT determines what a third-level page table entry can map */
Expand Down
1 change: 1 addition & 0 deletions arch/um/include/asm/pgtable-3level.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef __UM_PGTABLE_3LEVEL_H
#define __UM_PGTABLE_3LEVEL_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>

/* PGDIR_SHIFT determines what a third-level page table entry can map */
Expand Down
1 change: 1 addition & 0 deletions arch/unicore32/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#ifndef __UNICORE_PGTABLE_H__
#define __UNICORE_PGTABLE_H__

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>
#include <asm/cpu-single.h>

Expand Down
3 changes: 2 additions & 1 deletion arch/x86/include/asm/cpufeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,8 @@
#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
#define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */
#define X86_FEATURE_RDPID (16*32+ 22) /* RDPID instruction */
#define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */
#define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */

/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */
#define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */
Expand Down
4 changes: 4 additions & 0 deletions arch/x86/include/asm/pgtable_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ static inline pgdval_t pgd_flags(pgd_t pgd)
}

#if CONFIG_PGTABLE_LEVELS > 3
#include <asm-generic/5level-fixup.h>

typedef struct { pudval_t pud; } pud_t;

static inline pud_t native_make_pud(pmdval_t val)
Expand All @@ -285,6 +287,7 @@ static inline pudval_t native_pud_val(pud_t pud)
return pud.pud;
}
#else
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>

static inline pudval_t native_pud_val(pud_t pud)
Expand All @@ -306,6 +309,7 @@ static inline pmdval_t native_pmd_val(pmd_t pmd)
return pmd.pmd;
}
#else
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>

static inline pmdval_t native_pmd_val(pmd_t pmd)
Expand Down
1 change: 1 addition & 0 deletions arch/xtensa/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#ifndef _XTENSA_PGTABLE_H
#define _XTENSA_PGTABLE_H

#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>
#include <asm/page.h>
#include <asm/kmem_layout.h>
Expand Down
9 changes: 7 additions & 2 deletions drivers/misc/sgi-gru/grufault.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,15 +219,20 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
int write, unsigned long *paddr, int *pageshift)
{
pgd_t *pgdp;
pmd_t *pmdp;
p4d_t *p4dp;
pud_t *pudp;
pmd_t *pmdp;
pte_t pte;

pgdp = pgd_offset(vma->vm_mm, vaddr);
if (unlikely(pgd_none(*pgdp)))
goto err;

pudp = pud_offset(pgdp, vaddr);
p4dp = p4d_offset(pgdp, vaddr);
if (unlikely(p4d_none(*p4dp)))
goto err;

pudp = pud_offset(p4dp, vaddr);
if (unlikely(pud_none(*pudp)))
goto err;

Expand Down
6 changes: 5 additions & 1 deletion fs/userfaultfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
{
struct mm_struct *mm = ctx->mm;
pgd_t *pgd;
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd, _pmd;
pte_t *pte;
Expand All @@ -275,7 +276,10 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
pgd = pgd_offset(mm, address);
if (!pgd_present(*pgd))
goto out;
pud = pud_offset(pgd, address);
p4d = p4d_offset(pgd, address);
if (!p4d_present(*p4d))
goto out;
pud = pud_offset(p4d, address);
if (!pud_present(*pud))
goto out;
pmd = pmd_offset(pud, address);
Expand Down
3 changes: 2 additions & 1 deletion include/asm-generic/4level-fixup.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \
NULL: pmd_offset(pud, address))

#define pud_alloc(mm, pgd, address) (pgd)
#define pud_offset(pgd, start) (pgd)
#define pud_none(pud) 0
#define pud_bad(pud) 0
Expand All @@ -35,4 +34,6 @@
#undef pud_addr_end
#define pud_addr_end(addr, end) (end)

#include <asm-generic/5level-fixup.h>

#endif
Loading

0 comments on commit baeedc7

Please sign in to comment.