diff options
author | Mark Rutland <mark.rutland@arm.com> | 2016-01-25 06:45:06 -0500 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2016-02-16 10:10:46 -0500 |
commit | 1e531cce68c92b46c7d29f36a72f9a3e5886678f (patch) | |
tree | 78eb4a816458502813be0927a0ec1145a2332f4b | |
parent | 316b39db06718d59d82736df9fc65cf05b467cc7 (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.h | 26 |
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 | ||
45 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | 45 | static 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 | ||
50 | static 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 | ||
55 | static 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 | ||
65 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) | 74 | static 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 | ||
79 | static 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 | ||
84 | static 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 | ||
72 | extern pgd_t *pgd_alloc(struct mm_struct *mm); | 90 | extern pgd_t *pgd_alloc(struct mm_struct *mm); |