]> git.proxmox.com Git - pve-kernel.git/blob - swapops-0004-mm-ksm-handle-protnone-saved-writes-when-making-page.patch
3b48e10714cedc3dd9d4d3d2065ed76204e8e675
[pve-kernel.git] / swapops-0004-mm-ksm-handle-protnone-saved-writes-when-making-page.patch
1 From 361de9fb44163c4e693022786af380a2b2298c6d Mon Sep 17 00:00:00 2001
2 From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
3 Date: Fri, 24 Feb 2017 14:59:19 -0800
4 Subject: [PATCH 4/4] mm/ksm: handle protnone saved writes when making page
5 write protect
6
7 Without this KSM will consider the page write protected, but a numa
8 fault can later mark the page writable. This can result in memory
9 corruption.
10
11 Link: http://lkml.kernel.org/r/1487498625-10891-3-git-send-email-aneesh.kumar@linux.vnet.ibm.com
12 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
13 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
14 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
15 (backported from commit 595cd8f256d24face93b2722927ec9c980419c26)
16 Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
17 ---
18 include/asm-generic/pgtable.h | 8 ++++++++
19 mm/ksm.c | 9 +++++++--
20 2 files changed, 15 insertions(+), 2 deletions(-)
21
22 diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
23 index b6f3a8a4b738..8c8ba48bef0b 100644
24 --- a/include/asm-generic/pgtable.h
25 +++ b/include/asm-generic/pgtable.h
26 @@ -200,6 +200,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
27 #define pte_mk_savedwrite pte_mkwrite
28 #endif
29
30 +#ifndef pte_clear_savedwrite
31 +#define pte_clear_savedwrite pte_wrprotect
32 +#endif
33 +
34 #ifndef pmd_savedwrite
35 #define pmd_savedwrite pmd_write
36 #endif
37 @@ -208,6 +212,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
38 #define pmd_mk_savedwrite pmd_mkwrite
39 #endif
40
41 +#ifndef pmd_clear_savedwrite
42 +#define pmd_clear_savedwrite pmd_wrprotect
43 +#endif
44 +
45 #ifndef __HAVE_ARCH_PMDP_SET_WRPROTECT
46 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
47 static inline void pmdp_set_wrprotect(struct mm_struct *mm,
48 diff --git a/mm/ksm.c b/mm/ksm.c
49 index fed4afd8293b..099dfa45d596 100644
50 --- a/mm/ksm.c
51 +++ b/mm/ksm.c
52 @@ -878,7 +878,8 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
53 if (!ptep)
54 goto out_mn;
55
56 - if (pte_write(*ptep) || pte_dirty(*ptep)) {
57 + if (pte_write(*ptep) || pte_dirty(*ptep) ||
58 + (pte_protnone(*ptep) && pte_savedwrite(*ptep))) {
59 pte_t entry;
60
61 swapped = PageSwapCache(page);
62 @@ -903,7 +904,11 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
63 }
64 if (pte_dirty(entry))
65 set_page_dirty(page);
66 - entry = pte_mkclean(pte_wrprotect(entry));
67 +
68 + if (pte_protnone(entry))
69 + entry = pte_mkclean(pte_clear_savedwrite(entry));
70 + else
71 + entry = pte_mkclean(pte_wrprotect(entry));
72 set_pte_at_notify(mm, addr, ptep, entry);
73 }
74 *orig_pte = *ptep;
75 --
76 2.7.4
77