aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>2018-02-14 13:25:40 -0500
committerIngo Molnar <mingo@kernel.org>2018-02-16 04:48:48 -0500
commit98219dda2ab56ce2a967fdebf81e838d676d9ddc (patch)
treea8c3e987dfd3ad335dd24231e3752801bca92173
parent6f9dd329717f696f578347c0781a0247db957596 (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.h10
-rw-r--r--arch/x86/include/asm/pgalloc.h5
-rw-r--r--arch/x86/include/asm/pgtable.h11
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
570static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) 570static 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
577static inline void pgd_clear(pgd_t *pgdp) 578static 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
168static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, p4d_t *p4d) 168static 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);
191static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, 193static 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
860static inline int pgd_present(pgd_t pgd) 860static 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. */
877static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) 879static 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
892static inline int pgd_none(pgd_t pgd) 899static 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