Commit fe1e8c3e authored by Kirill A. Shutemov's avatar Kirill A. Shutemov Committed by Ingo Molnar

x86/mm: Extend headers with basic definitions to support 5-level paging

This patch extends x86 headers to enable 5-level paging support.

It's still based on <asm-generic/5level-fixup.h>. We will get to the
point where we can have <asm-generic/pgtable-nop4d.h> later.
Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-mm@kvack.org
Link: http://lkml.kernel.org/r/20170313143309.16020-2-kirill.shutemov@linux.intel.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 3e6ef9c8
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
typedef unsigned long pteval_t; typedef unsigned long pteval_t;
typedef unsigned long pmdval_t; typedef unsigned long pmdval_t;
typedef unsigned long pudval_t; typedef unsigned long pudval_t;
typedef unsigned long p4dval_t;
typedef unsigned long pgdval_t; typedef unsigned long pgdval_t;
typedef unsigned long pgprotval_t; typedef unsigned long pgprotval_t;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
typedef u64 pteval_t; typedef u64 pteval_t;
typedef u64 pmdval_t; typedef u64 pmdval_t;
typedef u64 pudval_t; typedef u64 pudval_t;
typedef u64 p4dval_t;
typedef u64 pgdval_t; typedef u64 pgdval_t;
typedef u64 pgprotval_t; typedef u64 pgprotval_t;
......
...@@ -179,6 +179,17 @@ static inline unsigned long pud_pfn(pud_t pud) ...@@ -179,6 +179,17 @@ static inline unsigned long pud_pfn(pud_t pud)
return (pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT; return (pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT;
} }
static inline unsigned long p4d_pfn(p4d_t p4d)
{
return (p4d_val(p4d) & p4d_pfn_mask(p4d)) >> PAGE_SHIFT;
}
static inline int p4d_large(p4d_t p4d)
{
/* No 512 GiB pages yet */
return 0;
}
#define pte_page(pte) pfn_to_page(pte_pfn(pte)) #define pte_page(pte) pfn_to_page(pte_pfn(pte))
static inline int pmd_large(pmd_t pte) static inline int pmd_large(pmd_t pte)
...@@ -770,6 +781,16 @@ static inline int pud_large(pud_t pud) ...@@ -770,6 +781,16 @@ static inline int pud_large(pud_t pud)
} }
#endif /* CONFIG_PGTABLE_LEVELS > 2 */ #endif /* CONFIG_PGTABLE_LEVELS > 2 */
static inline unsigned long pud_index(unsigned long address)
{
return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
}
static inline unsigned long p4d_index(unsigned long address)
{
return (address >> P4D_SHIFT) & (PTRS_PER_P4D - 1);
}
#if CONFIG_PGTABLE_LEVELS > 3 #if CONFIG_PGTABLE_LEVELS > 3
static inline int pgd_present(pgd_t pgd) static inline int pgd_present(pgd_t pgd)
{ {
...@@ -788,11 +809,6 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd) ...@@ -788,11 +809,6 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd)
#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) #define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
/* to find an entry in a page-table-directory. */ /* to find an entry in a page-table-directory. */
static inline unsigned long pud_index(unsigned long address)
{
return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
}
static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
{ {
return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(address); return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(address);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
typedef unsigned long pteval_t; typedef unsigned long pteval_t;
typedef unsigned long pmdval_t; typedef unsigned long pmdval_t;
typedef unsigned long pudval_t; typedef unsigned long pudval_t;
typedef unsigned long p4dval_t;
typedef unsigned long pgdval_t; typedef unsigned long pgdval_t;
typedef unsigned long pgprotval_t; typedef unsigned long pgprotval_t;
......
...@@ -272,9 +272,20 @@ static inline pgdval_t pgd_flags(pgd_t pgd) ...@@ -272,9 +272,20 @@ static inline pgdval_t pgd_flags(pgd_t pgd)
return native_pgd_val(pgd) & PTE_FLAGS_MASK; return native_pgd_val(pgd) & PTE_FLAGS_MASK;
} }
#if CONFIG_PGTABLE_LEVELS > 3 #if CONFIG_PGTABLE_LEVELS > 4
#error FIXME
#else
#include <asm-generic/5level-fixup.h> #include <asm-generic/5level-fixup.h>
static inline p4dval_t native_p4d_val(p4d_t p4d)
{
return native_pgd_val(p4d);
}
#endif
#if CONFIG_PGTABLE_LEVELS > 3
typedef struct { pudval_t pud; } pud_t; typedef struct { pudval_t pud; } pud_t;
static inline pud_t native_make_pud(pmdval_t val) static inline pud_t native_make_pud(pmdval_t val)
...@@ -318,6 +329,22 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) ...@@ -318,6 +329,22 @@ static inline pmdval_t native_pmd_val(pmd_t pmd)
} }
#endif #endif
static inline p4dval_t p4d_pfn_mask(p4d_t p4d)
{
/* No 512 GiB huge pages yet */
return PTE_PFN_MASK;
}
static inline p4dval_t p4d_flags_mask(p4d_t p4d)
{
return ~p4d_pfn_mask(p4d);
}
static inline p4dval_t p4d_flags(p4d_t p4d)
{
return native_p4d_val(p4d) & p4d_flags_mask(p4d);
}
static inline pudval_t pud_pfn_mask(pud_t pud) static inline pudval_t pud_pfn_mask(pud_t pud)
{ {
if (native_pud_val(pud) & _PAGE_PSE) if (native_pud_val(pud) & _PAGE_PSE)
...@@ -461,6 +488,7 @@ enum pg_level { ...@@ -461,6 +488,7 @@ enum pg_level {
PG_LEVEL_4K, PG_LEVEL_4K,
PG_LEVEL_2M, PG_LEVEL_2M,
PG_LEVEL_1G, PG_LEVEL_1G,
PG_LEVEL_512G,
PG_LEVEL_NUM PG_LEVEL_NUM
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment