aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Capper <steve.capper@linaro.org>2014-02-25 05:02:13 -0500
committerCatalin Marinas <catalin.marinas@arm.com>2014-03-14 14:02:10 -0400
commit9c7e535fcc1725fc2e2d4f0d9dd14137f0243e23 (patch)
tree59598b3e9733e62d6ec8e10270dc7b7664916700
parentc209f79940ac0c75ae8d2f503a2b9d86255e266c (diff)
arm64: mm: Route pmd thp functions through pte equivalents
Rather than have separate hugetlb and transparent huge page pmd manipulation functions, re-wire our thp functions to simply call the pte equivalents. This allows THP to take advantage of the new PTE_WRITE logic introduced in: c2c93e5 arm64: mm: Introduce PTE_WRITE To represent splitting THPs we use the PTE_SPECIAL bit as this is not used for pmds. Signed-off-by: Steve Capper <steve.capper@linaro.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/include/asm/pgtable.h52
1 files changed, 24 insertions, 28 deletions
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 72c9ac38cdd9..ae10350f75ec 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -227,36 +227,36 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
227 227
228#define __HAVE_ARCH_PTE_SPECIAL 228#define __HAVE_ARCH_PTE_SPECIAL
229 229
230/* 230static inline pte_t pmd_pte(pmd_t pmd)
231 * Software PMD bits for THP 231{
232 */ 232 return __pte(pmd_val(pmd));
233}
233 234
234#define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55) 235static inline pmd_t pte_pmd(pte_t pte)
235#define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 57) 236{
237 return __pmd(pte_val(pte));
238}
236 239
237/* 240/*
238 * THP definitions. 241 * THP definitions.
239 */ 242 */
240#define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF)
241
242#define __HAVE_ARCH_PMD_WRITE
243#define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY))
244 243
245#ifdef CONFIG_TRANSPARENT_HUGEPAGE 244#ifdef CONFIG_TRANSPARENT_HUGEPAGE
246#define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT)) 245#define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
247#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING) 246#define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd))
248#endif 247#endif
249 248
250#define PMD_BIT_FUNC(fn,op) \ 249#define pmd_young(pmd) pte_young(pmd_pte(pmd))
251static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; } 250#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
251#define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd)))
252#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
253#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
254#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
255#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
256#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) &= ~PMD_TYPE_MASK))
252 257
253PMD_BIT_FUNC(wrprotect, |= PMD_SECT_RDONLY); 258#define __HAVE_ARCH_PMD_WRITE
254PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF); 259#define pmd_write(pmd) pte_write(pmd_pte(pmd))
255PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
256PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY);
257PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY);
258PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
259PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
260 260
261#define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT)) 261#define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
262 262
@@ -266,15 +266,6 @@ PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
266 266
267#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) 267#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
268 268
269static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
270{
271 const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN |
272 PMD_SECT_RDONLY | PMD_SECT_PROT_NONE |
273 PMD_SECT_VALID;
274 pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
275 return pmd;
276}
277
278#define set_pmd_at(mm, addr, pmdp, pmd) set_pmd(pmdp, pmd) 269#define set_pmd_at(mm, addr, pmdp, pmd) set_pmd(pmdp, pmd)
279 270
280static inline int has_transparent_hugepage(void) 271static inline int has_transparent_hugepage(void)
@@ -383,6 +374,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
383 return pte; 374 return pte;
384} 375}
385 376
377static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
378{
379 return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
380}
381
386extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; 382extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
387extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; 383extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
388 384