]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.7.4/arm64-mm-only-wrprotect-clean-ptes-if-they-are-present.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.7.4 / arm64-mm-only-wrprotect-clean-ptes-if-they-are-present.patch
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
5
6 From: Will Deacon <will.deacon@arm.com>
7
8 commit 02522463c84748b3b8ad770f9424bcfa70a5b4c4 upstream.
9
10 Marking non-present ptes as read-only can corrupt file ptes, breaking
11 things like swap and file mappings.
12
13 This patch ensures that we only manipulate user pte bits when the pte
14 is marked present.
15
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>
19
20 ---
21 arch/arm64/include/asm/pgtable.h | 16 +++++++++-------
22 1 file changed, 9 insertions(+), 7 deletions(-)
23
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))
29
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))
35
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)
41 {
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)) {
47 + if (pte_exec(pte))
48 + __sync_icache_dcache(pte, addr);
49 + if (!pte_dirty(pte))
50 + pte = pte_wrprotect(pte);
51 + }
52 +
53 set_pte(ptep, pte);
54 }
55