diff options
author | Steve Capper <steve.capper@linaro.org> | 2014-10-09 18:29:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-09 22:26:00 -0400 |
commit | bd951303be5b4df578c7f30ef78839f1a9d6658c (patch) | |
tree | 573157dd8efc4de9a26b5e10f857840f8fcab02e /arch/arm/include/asm/pgtable.h | |
parent | 2667f50e8b81457fcb4a3dbe6aff3e81ea009e13 (diff) |
arm: mm: introduce special ptes for LPAE
We need a mechanism to tag ptes as being special, this indicates that no
attempt should be made to access the underlying struct page * associated
with the pte. This is used by the fast_gup when operating on ptes as it
has no means to access VMAs (that also contain this information)
locklessly.
The L_PTE_SPECIAL bit is already allocated for LPAE, this patch modifies
pte_special and pte_mkspecial to make use of it, and defines
__HAVE_ARCH_PTE_SPECIAL.
This patch also excludes special ptes from the icache/dcache sync logic.
Signed-off-by: Steve Capper <steve.capper@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dann Frazier <dann.frazier@canonical.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/arm/include/asm/pgtable.h')
-rw-r--r-- | arch/arm/include/asm/pgtable.h | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 01baef07cd0c..90aa4583b308 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -226,7 +226,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) | |||
226 | #define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY)) | 226 | #define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY)) |
227 | #define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG)) | 227 | #define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG)) |
228 | #define pte_exec(pte) (pte_isclear((pte), L_PTE_XN)) | 228 | #define pte_exec(pte) (pte_isclear((pte), L_PTE_XN)) |
229 | #define pte_special(pte) (0) | ||
230 | 229 | ||
231 | #define pte_valid_user(pte) \ | 230 | #define pte_valid_user(pte) \ |
232 | (pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte)) | 231 | (pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte)) |
@@ -245,7 +244,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
245 | unsigned long ext = 0; | 244 | unsigned long ext = 0; |
246 | 245 | ||
247 | if (addr < TASK_SIZE && pte_valid_user(pteval)) { | 246 | if (addr < TASK_SIZE && pte_valid_user(pteval)) { |
248 | __sync_icache_dcache(pteval); | 247 | if (!pte_special(pteval)) |
248 | __sync_icache_dcache(pteval); | ||
249 | ext |= PTE_EXT_NG; | 249 | ext |= PTE_EXT_NG; |
250 | } | 250 | } |
251 | 251 | ||
@@ -264,8 +264,6 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); | |||
264 | PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN); | 264 | PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN); |
265 | PTE_BIT_FUNC(mknexec, |= L_PTE_XN); | 265 | PTE_BIT_FUNC(mknexec, |= L_PTE_XN); |
266 | 266 | ||
267 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
268 | |||
269 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 267 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
270 | { | 268 | { |
271 | const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER | | 269 | const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER | |