aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2016-01-25 06:45:06 -0500
committerCatalin Marinas <catalin.marinas@arm.com>2016-02-16 10:10:46 -0500
commit1e531cce68c92b46c7d29f36a72f9a3e5886678f (patch)
tree78eb4a816458502813be0927a0ec1145a2332f4b
parent316b39db06718d59d82736df9fc65cf05b467cc7 (diff)
arm64: mm: add __{pud,pgd}_populate
We currently have __pmd_populate for creating a pmd table entry given the physical address of a pte, but don't have equivalents for the pud or pgd levels of table. To enable us to manipulate tables which are mapped outside of the linear mapping (where we have a PA, but not a linear map VA), it is useful to have these functions. This patch adds __{pud,pgd}_populate. As these should not be called when the kernel uses folded {pmd,pud}s, in these cases they expand to BUILD_BUG(). So long as the appropriate checks are made on the {pud,pgd} entry prior to attempting population, these should be optimized out at compile time. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Tested-by: Jeremy Linton <jeremy.linton@arm.com> Cc: Laura Abbott <labbott@fedoraproject.org> Cc: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/include/asm/pgalloc.h26
1 files changed, 22 insertions, 4 deletions
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index c15053902942..ff98585d085a 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -42,11 +42,20 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
42 free_page((unsigned long)pmd); 42 free_page((unsigned long)pmd);
43} 43}
44 44
45static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) 45static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
46{ 46{
47 set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE)); 47 set_pud(pud, __pud(pmd | prot));
48} 48}
49 49
50static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
51{
52 __pud_populate(pud, __pa(pmd), PMD_TYPE_TABLE);
53}
54#else
55static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
56{
57 BUILD_BUG();
58}
50#endif /* CONFIG_PGTABLE_LEVELS > 2 */ 59#endif /* CONFIG_PGTABLE_LEVELS > 2 */
51 60
52#if CONFIG_PGTABLE_LEVELS > 3 61#if CONFIG_PGTABLE_LEVELS > 3
@@ -62,11 +71,20 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud)
62 free_page((unsigned long)pud); 71 free_page((unsigned long)pud);
63} 72}
64 73
65static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) 74static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot)
66{ 75{
67 set_pgd(pgd, __pgd(__pa(pud) | PUD_TYPE_TABLE)); 76 set_pgd(pgdp, __pgd(pud | prot));
68} 77}
69 78
79static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
80{
81 __pgd_populate(pgd, __pa(pud), PUD_TYPE_TABLE);
82}
83#else
84static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot)
85{
86 BUILD_BUG();
87}
70#endif /* CONFIG_PGTABLE_LEVELS > 3 */ 88#endif /* CONFIG_PGTABLE_LEVELS > 3 */
71 89
72extern pgd_t *pgd_alloc(struct mm_struct *mm); 90extern pgd_t *pgd_alloc(struct mm_struct *mm);