1 From 02522463c84748b3b8ad770f9424bcfa70a5b4c4 Mon Sep 17 00:00:00 2001
2 From: Will Deacon <will.deacon@arm.com>
3 Date: Wed, 9 Jan 2013 11:08:10 +0000
4 Subject: arm64: mm: only wrprotect clean ptes if they are present
6 From: Will Deacon <will.deacon@arm.com>
8 commit 02522463c84748b3b8ad770f9424bcfa70a5b4c4 upstream.
10 Marking non-present ptes as read-only can corrupt file ptes, breaking
11 things like swap and file mappings.
13 This patch ensures that we only manipulate user pte bits when the pte
16 Signed-off-by: Will Deacon <will.deacon@arm.com>
17 Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
18 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
21 arch/arm64/include/asm/pgtable.h | 16 +++++++++-------
22 1 file changed, 9 insertions(+), 7 deletions(-)
24 --- a/arch/arm64/include/asm/pgtable.h
25 +++ b/arch/arm64/include/asm/pgtable.h
26 @@ -132,9 +132,8 @@ extern struct page *empty_zero_page;
27 #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY))
28 #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
30 -#define pte_present_exec_user(pte) \
31 - ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \
32 - (PTE_VALID | PTE_USER))
33 +#define pte_present_user(pte) \
34 + ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
36 #define PTE_BIT_FUNC(fn,op) \
37 static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
38 @@ -157,10 +156,13 @@ extern void __sync_icache_dcache(pte_t p
39 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
40 pte_t *ptep, pte_t pte)
42 - if (pte_present_exec_user(pte))
43 - __sync_icache_dcache(pte, addr);
44 - if (!pte_dirty(pte))
45 - pte = pte_wrprotect(pte);
46 + if (pte_present_user(pte)) {
48 + __sync_icache_dcache(pte, addr);
49 + if (!pte_dirty(pte))
50 + pte = pte_wrprotect(pte);