diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2018-02-14 13:25:40 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2018-02-16 04:48:48 -0500 |
commit | 98219dda2ab56ce2a967fdebf81e838d676d9ddc (patch) | |
tree | a8c3e987dfd3ad335dd24231e3752801bca92173 | |
parent | 6f9dd329717f696f578347c0781a0247db957596 (diff) |
x86/mm: Fold p4d page table layer at runtime
Change page table helpers to fold p4d at runtime.
The logic is the same as in <asm-generic/pgtable-nop4d.h>.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
Link: http://lkml.kernel.org/r/20180214182542.69302-8-kirill.shutemov@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/include/asm/paravirt.h | 10 | ||||
-rw-r--r-- | arch/x86/include/asm/pgalloc.h | 5 | ||||
-rw-r--r-- | arch/x86/include/asm/pgtable.h | 11 |
3 files changed, 20 insertions, 6 deletions
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 892df375b615..3fbaad238a94 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -569,14 +569,16 @@ static inline p4dval_t p4d_val(p4d_t p4d) | |||
569 | 569 | ||
570 | static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) | 570 | static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) |
571 | { | 571 | { |
572 | pgdval_t val = native_pgd_val(pgd); | 572 | if (pgtable_l5_enabled) |
573 | 573 | PVOP_VCALL2(pv_mmu_ops.set_pgd, pgdp, native_pgd_val(pgd)); | |
574 | PVOP_VCALL2(pv_mmu_ops.set_pgd, pgdp, val); | 574 | else |
575 | set_p4d((p4d_t *)(pgdp), (p4d_t) { pgd.pgd }); | ||
575 | } | 576 | } |
576 | 577 | ||
577 | static inline void pgd_clear(pgd_t *pgdp) | 578 | static inline void pgd_clear(pgd_t *pgdp) |
578 | { | 579 | { |
579 | set_pgd(pgdp, __pgd(0)); | 580 | if (pgtable_l5_enabled) |
581 | set_pgd(pgdp, __pgd(0)); | ||
580 | } | 582 | } |
581 | 583 | ||
582 | #endif /* CONFIG_PGTABLE_LEVELS == 5 */ | 584 | #endif /* CONFIG_PGTABLE_LEVELS == 5 */ |
diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h index aff42e1da6ee..263c142a6a6c 100644 --- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h | |||
@@ -167,6 +167,8 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, | |||
167 | #if CONFIG_PGTABLE_LEVELS > 4 | 167 | #if CONFIG_PGTABLE_LEVELS > 4 |
168 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, p4d_t *p4d) | 168 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, p4d_t *p4d) |
169 | { | 169 | { |
170 | if (!pgtable_l5_enabled) | ||
171 | return; | ||
170 | paravirt_alloc_p4d(mm, __pa(p4d) >> PAGE_SHIFT); | 172 | paravirt_alloc_p4d(mm, __pa(p4d) >> PAGE_SHIFT); |
171 | set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(p4d))); | 173 | set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(p4d))); |
172 | } | 174 | } |
@@ -191,7 +193,8 @@ extern void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d); | |||
191 | static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, | 193 | static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, |
192 | unsigned long address) | 194 | unsigned long address) |
193 | { | 195 | { |
194 | ___p4d_free_tlb(tlb, p4d); | 196 | if (pgtable_l5_enabled) |
197 | ___p4d_free_tlb(tlb, p4d); | ||
195 | } | 198 | } |
196 | 199 | ||
197 | #endif /* CONFIG_PGTABLE_LEVELS > 4 */ | 200 | #endif /* CONFIG_PGTABLE_LEVELS > 4 */ |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 63c2552b6b65..c8baa7f12d1b 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -65,7 +65,7 @@ extern pmdval_t early_pmd_flags; | |||
65 | 65 | ||
66 | #ifndef __PAGETABLE_P4D_FOLDED | 66 | #ifndef __PAGETABLE_P4D_FOLDED |
67 | #define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd) | 67 | #define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd) |
68 | #define pgd_clear(pgd) native_pgd_clear(pgd) | 68 | #define pgd_clear(pgd) (pgtable_l5_enabled ? native_pgd_clear(pgd) : 0) |
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | #ifndef set_p4d | 71 | #ifndef set_p4d |
@@ -859,6 +859,8 @@ static inline unsigned long p4d_index(unsigned long address) | |||
859 | #if CONFIG_PGTABLE_LEVELS > 4 | 859 | #if CONFIG_PGTABLE_LEVELS > 4 |
860 | static inline int pgd_present(pgd_t pgd) | 860 | static inline int pgd_present(pgd_t pgd) |
861 | { | 861 | { |
862 | if (!pgtable_l5_enabled) | ||
863 | return 1; | ||
862 | return pgd_flags(pgd) & _PAGE_PRESENT; | 864 | return pgd_flags(pgd) & _PAGE_PRESENT; |
863 | } | 865 | } |
864 | 866 | ||
@@ -876,6 +878,8 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd) | |||
876 | /* to find an entry in a page-table-directory. */ | 878 | /* to find an entry in a page-table-directory. */ |
877 | static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) | 879 | static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) |
878 | { | 880 | { |
881 | if (!pgtable_l5_enabled) | ||
882 | return (p4d_t *)pgd; | ||
879 | return (p4d_t *)pgd_page_vaddr(*pgd) + p4d_index(address); | 883 | return (p4d_t *)pgd_page_vaddr(*pgd) + p4d_index(address); |
880 | } | 884 | } |
881 | 885 | ||
@@ -883,6 +887,9 @@ static inline int pgd_bad(pgd_t pgd) | |||
883 | { | 887 | { |
884 | unsigned long ignore_flags = _PAGE_USER; | 888 | unsigned long ignore_flags = _PAGE_USER; |
885 | 889 | ||
890 | if (!pgtable_l5_enabled) | ||
891 | return 0; | ||
892 | |||
886 | if (IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) | 893 | if (IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) |
887 | ignore_flags |= _PAGE_NX; | 894 | ignore_flags |= _PAGE_NX; |
888 | 895 | ||
@@ -891,6 +898,8 @@ static inline int pgd_bad(pgd_t pgd) | |||
891 | 898 | ||
892 | static inline int pgd_none(pgd_t pgd) | 899 | static inline int pgd_none(pgd_t pgd) |
893 | { | 900 | { |
901 | if (!pgtable_l5_enabled) | ||
902 | return 0; | ||
894 | /* | 903 | /* |
895 | * There is no need to do a workaround for the KNL stray | 904 | * There is no need to do a workaround for the KNL stray |
896 | * A/D bit erratum here. PGDs only point to page tables | 905 | * A/D bit erratum here. PGDs only point to page tables |