All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20180913142328.GA3576@redhat.com>

diff --git a/a/1.txt b/N1/1.txt
index 1ba158b..026724f 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -47,7 +47,7 @@ On Thu, Sep 13, 2018 at 03:37:22PM +0800, Peter Xu wrote:
 > > > unwrite protect pages in a range that is write protected ie the vma
 > > > !(vm_flags & VM_WRITE).
 > > > 
-> > > Signed-off-by: Jerome Glisse <jglisse@redhat.com>
+> > > Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
 > > > ---
 > > >  mm/userfaultfd.c | 2 +-
 > > >  1 file changed, 1 insertion(+), 1 deletion(-)
@@ -116,3 +116,243 @@ On Thu, Sep 13, 2018 at 03:37:22PM +0800, Peter Xu wrote:
 
 I missed that reply and forgot about PAGE_COPY ... So below is
 what i believe a proper fix for your issue:
+
+
+From 4362d8a3bb44b756209a44f1342e1c568ad6c3e6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= <jglisse@redhat.com>
+Date: Thu, 13 Sep 2018 10:16:30 -0400
+Subject: [PATCH] mm/mprotect: add a mkwrite paramater to change_protection()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The mkwrite parameter allow to change read only pte to write one which
+is needed by userfaultfd to un-write-protect after a fault have been
+handled.
+
+Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
+---
+ include/linux/huge_mm.h |  2 +-
+ include/linux/mm.h      |  3 ++-
+ mm/huge_memory.c        |  5 ++++-
+ mm/mempolicy.c          |  2 +-
+ mm/mprotect.c           | 37 +++++++++++++++++++++----------------
+ mm/userfaultfd.c        |  2 +-
+ 6 files changed, 30 insertions(+), 21 deletions(-)
+
+diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
+index a8a126259bc4..b51ff7f8e65c 100644
+--- a/include/linux/huge_mm.h
++++ b/include/linux/huge_mm.h
+@@ -45,7 +45,7 @@ extern bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
+ 			 pmd_t *old_pmd, pmd_t *new_pmd, bool *need_flush);
+ extern int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
+ 			unsigned long addr, pgprot_t newprot,
+-			int prot_numa);
++			int prot_numa, bool mkwrite);
+ int vmf_insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
+ 			pmd_t *pmd, pfn_t pfn, bool write);
+ int vmf_insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 5d5c7fd07dc0..2bbf3e33bf9e 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1492,7 +1492,8 @@ extern unsigned long move_page_tables(struct vm_area_struct *vma,
+ 		bool need_rmap_locks);
+ extern unsigned long change_protection(struct vm_area_struct *vma, unsigned long start,
+ 			      unsigned long end, pgprot_t newprot,
+-			      int dirty_accountable, int prot_numa);
++			      int dirty_accountable, int prot_numa,
++			      bool mkwrite);
+ extern int mprotect_fixup(struct vm_area_struct *vma,
+ 			  struct vm_area_struct **pprev, unsigned long start,
+ 			  unsigned long end, unsigned long newflags);
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index abf621aba672..49853f0b1570 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -1842,7 +1842,8 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
+  *  - HPAGE_PMD_NR is protections changed and TLB flush necessary
+  */
+ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
+-		unsigned long addr, pgprot_t newprot, int prot_numa)
++		unsigned long addr, pgprot_t newprot, int prot_numa,
++		bool mkwrite)
+ {
+ 	struct mm_struct *mm = vma->vm_mm;
+ 	spinlock_t *ptl;
+@@ -1925,6 +1926,8 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
+ 	entry = pmd_modify(entry, newprot);
+ 	if (preserve_write)
+ 		entry = pmd_mk_savedwrite(entry);
++	if (mkwrite)
++		entry = pmd_mkwrite(entry);
+ 	ret = HPAGE_PMD_NR;
+ 	set_pmd_at(mm, addr, pmd, entry);
+ 	BUG_ON(vma_is_anonymous(vma) && !preserve_write && pmd_write(entry));
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index 4ce44d3ff03d..2d0ee09e6b26 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -579,7 +579,7 @@ unsigned long change_prot_numa(struct vm_area_struct *vma,
+ {
+ 	int nr_updated;
+ 
+-	nr_updated = change_protection(vma, addr, end, PAGE_NONE, 0, 1);
++	nr_updated = change_protection(vma, addr, end, PAGE_NONE, 0, 1, false);
+ 	if (nr_updated)
+ 		count_vm_numa_events(NUMA_PTE_UPDATES, nr_updated);
+ 
+diff --git a/mm/mprotect.c b/mm/mprotect.c
+index 58b629bb70de..792669cfb7e1 100644
+--- a/mm/mprotect.c
++++ b/mm/mprotect.c
+@@ -36,7 +36,7 @@
+ 
+ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+ 		unsigned long addr, unsigned long end, pgprot_t newprot,
+-		int dirty_accountable, int prot_numa)
++		int dirty_accountable, int prot_numa, bool mkwrite)
+ {
+ 	struct mm_struct *mm = vma->vm_mm;
+ 	pte_t *pte, oldpte;
+@@ -102,9 +102,9 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+ 				ptent = pte_mk_savedwrite(ptent);
+ 
+ 			/* Avoid taking write faults for known dirty pages */
+-			if (dirty_accountable && pte_dirty(ptent) &&
+-					(pte_soft_dirty(ptent) ||
+-					 !(vma->vm_flags & VM_SOFTDIRTY))) {
++			if (enable_write || (dirty_accountable &&
++			    pte_dirty(ptent) && (pte_soft_dirty(ptent) ||
++			    !(vma->vm_flags & VM_SOFTDIRTY)))) {
+ 				ptent = pte_mkwrite(ptent);
+ 			}
+ 			ptep_modify_prot_commit(mm, addr, pte, ptent);
+@@ -150,7 +150,8 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+ 
+ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
+ 		pud_t *pud, unsigned long addr, unsigned long end,
+-		pgprot_t newprot, int dirty_accountable, int prot_numa)
++		pgprot_t newprot, int dirty_accountable, int prot_numa,
++		bool mkwrite)
+ {
+ 	pmd_t *pmd;
+ 	struct mm_struct *mm = vma->vm_mm;
+@@ -179,7 +180,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
+ 				__split_huge_pmd(vma, pmd, addr, false, NULL);
+ 			} else {
+ 				int nr_ptes = change_huge_pmd(vma, pmd, addr,
+-						newprot, prot_numa);
++						newprot, prot_numa, mkwrite);
+ 
+ 				if (nr_ptes) {
+ 					if (nr_ptes == HPAGE_PMD_NR) {
+@@ -194,7 +195,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
+ 			/* fall through, the trans huge pmd just split */
+ 		}
+ 		this_pages = change_pte_range(vma, pmd, addr, next, newprot,
+-				 dirty_accountable, prot_numa);
++				 dirty_accountable, prot_numa, mkwrite);
+ 		pages += this_pages;
+ next:
+ 		cond_resched();
+@@ -210,7 +211,8 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
+ 
+ static inline unsigned long change_pud_range(struct vm_area_struct *vma,
+ 		p4d_t *p4d, unsigned long addr, unsigned long end,
+-		pgprot_t newprot, int dirty_accountable, int prot_numa)
++		pgprot_t newprot, int dirty_accountable, int prot_numa,
++		bool mkwrite)
+ {
+ 	pud_t *pud;
+ 	unsigned long next;
+@@ -222,7 +224,7 @@ static inline unsigned long change_pud_range(struct vm_area_struct *vma,
+ 		if (pud_none_or_clear_bad(pud))
+ 			continue;
+ 		pages += change_pmd_range(vma, pud, addr, next, newprot,
+-				 dirty_accountable, prot_numa);
++				 dirty_accountable, prot_numa, mkwrite);
+ 	} while (pud++, addr = next, addr != end);
+ 
+ 	return pages;
+@@ -230,7 +232,8 @@ static inline unsigned long change_pud_range(struct vm_area_struct *vma,
+ 
+ static inline unsigned long change_p4d_range(struct vm_area_struct *vma,
+ 		pgd_t *pgd, unsigned long addr, unsigned long end,
+-		pgprot_t newprot, int dirty_accountable, int prot_numa)
++		pgprot_t newprot, int dirty_accountable, int prot_numa,
++		bool mkwrite)
+ {
+ 	p4d_t *p4d;
+ 	unsigned long next;
+@@ -242,7 +245,7 @@ static inline unsigned long change_p4d_range(struct vm_area_struct *vma,
+ 		if (p4d_none_or_clear_bad(p4d))
+ 			continue;
+ 		pages += change_pud_range(vma, p4d, addr, next, newprot,
+-				 dirty_accountable, prot_numa);
++				 dirty_accountable, prot_numa, mkwrite);
+ 	} while (p4d++, addr = next, addr != end);
+ 
+ 	return pages;
+@@ -250,7 +253,7 @@ static inline unsigned long change_p4d_range(struct vm_area_struct *vma,
+ 
+ static unsigned long change_protection_range(struct vm_area_struct *vma,
+ 		unsigned long addr, unsigned long end, pgprot_t newprot,
+-		int dirty_accountable, int prot_numa)
++		int dirty_accountable, int prot_numa, mkwrite)
+ {
+ 	struct mm_struct *mm = vma->vm_mm;
+ 	pgd_t *pgd;
+@@ -267,7 +270,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,
+ 		if (pgd_none_or_clear_bad(pgd))
+ 			continue;
+ 		pages += change_p4d_range(vma, pgd, addr, next, newprot,
+-				 dirty_accountable, prot_numa);
++				 dirty_accountable, prot_numa, mkwrite);
+ 	} while (pgd++, addr = next, addr != end);
+ 
+ 	/* Only flush the TLB if we actually modified any entries: */
+@@ -280,14 +283,16 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,
+ 
+ unsigned long change_protection(struct vm_area_struct *vma, unsigned long start,
+ 		       unsigned long end, pgprot_t newprot,
+-		       int dirty_accountable, int prot_numa)
++		       int dirty_accountable, int prot_numa, bool mkwrite)
+ {
+ 	unsigned long pages;
+ 
+ 	if (is_vm_hugetlb_page(vma))
+ 		pages = hugetlb_change_protection(vma, start, end, newprot);
+ 	else
+-		pages = change_protection_range(vma, start, end, newprot, dirty_accountable, prot_numa);
++		pages = change_protection_range(vma, start, end, newprot,
++						dirty_accountable,
++						prot_numa, mkwrite);
+ 
+ 	return pages;
+ }
+@@ -366,7 +371,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
+ 	vma_set_page_prot(vma);
+ 
+ 	change_protection(vma, start, end, vma->vm_page_prot,
+-			  dirty_accountable, 0);
++			  dirty_accountable, 0, false);
+ 
+ 	/*
+ 	 * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
+diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
+index a0379c5ffa7c..c745c5d87523 100644
+--- a/mm/userfaultfd.c
++++ b/mm/userfaultfd.c
+@@ -632,7 +632,7 @@ int mwriteprotect_range(struct mm_struct *dst_mm, unsigned long start,
+ 		newprot = vm_get_page_prot(dst_vma->vm_flags);
+ 
+ 	change_protection(dst_vma, start, start + len, newprot,
+-				!enable_wp, 0);
++			  0, 0, !enable_wp);
+ 
+ 	err = 0;
+ out_unlock:
+-- 
+2.17.1
diff --git a/a/content_digest b/N1/content_digest
index 5b02b7c..f024d98 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -71,7 +71,7 @@
  "> > > unwrite protect pages in a range that is write protected ie the vma\n"
  "> > > !(vm_flags & VM_WRITE).\n"
  "> > > \n"
- "> > > Signed-off-by: Jerome Glisse <jglisse@redhat.com>\n"
+ "> > > Signed-off-by: J\303\251r\303\264me Glisse <jglisse@redhat.com>\n"
  "> > > ---\n"
  "> > >  mm/userfaultfd.c | 2 +-\n"
  "> > >  1 file changed, 1 insertion(+), 1 deletion(-)\n"
@@ -139,6 +139,246 @@
  "> resolving the page fault for uffd-wp tree.\n"
  "\n"
  "I missed that reply and forgot about PAGE_COPY ... So below is\n"
- what i believe a proper fix for your issue:
+ "what i believe a proper fix for your issue:\n"
+ "\n"
+ "\n"
+ "From 4362d8a3bb44b756209a44f1342e1c568ad6c3e6 Mon Sep 17 00:00:00 2001\n"
+ "From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= <jglisse@redhat.com>\n"
+ "Date: Thu, 13 Sep 2018 10:16:30 -0400\n"
+ "Subject: [PATCH] mm/mprotect: add a mkwrite paramater to change_protection()\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=UTF-8\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ "\n"
+ "The mkwrite parameter allow to change read only pte to write one which\n"
+ "is needed by userfaultfd to un-write-protect after a fault have been\n"
+ "handled.\n"
+ "\n"
+ "Signed-off-by: J\303\251r\303\264me Glisse <jglisse@redhat.com>\n"
+ "---\n"
+ " include/linux/huge_mm.h |  2 +-\n"
+ " include/linux/mm.h      |  3 ++-\n"
+ " mm/huge_memory.c        |  5 ++++-\n"
+ " mm/mempolicy.c          |  2 +-\n"
+ " mm/mprotect.c           | 37 +++++++++++++++++++++----------------\n"
+ " mm/userfaultfd.c        |  2 +-\n"
+ " 6 files changed, 30 insertions(+), 21 deletions(-)\n"
+ "\n"
+ "diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h\n"
+ "index a8a126259bc4..b51ff7f8e65c 100644\n"
+ "--- a/include/linux/huge_mm.h\n"
+ "+++ b/include/linux/huge_mm.h\n"
+ "@@ -45,7 +45,7 @@ extern bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,\n"
+ " \t\t\t pmd_t *old_pmd, pmd_t *new_pmd, bool *need_flush);\n"
+ " extern int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,\n"
+ " \t\t\tunsigned long addr, pgprot_t newprot,\n"
+ "-\t\t\tint prot_numa);\n"
+ "+\t\t\tint prot_numa, bool mkwrite);\n"
+ " int vmf_insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,\n"
+ " \t\t\tpmd_t *pmd, pfn_t pfn, bool write);\n"
+ " int vmf_insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,\n"
+ "diff --git a/include/linux/mm.h b/include/linux/mm.h\n"
+ "index 5d5c7fd07dc0..2bbf3e33bf9e 100644\n"
+ "--- a/include/linux/mm.h\n"
+ "+++ b/include/linux/mm.h\n"
+ "@@ -1492,7 +1492,8 @@ extern unsigned long move_page_tables(struct vm_area_struct *vma,\n"
+ " \t\tbool need_rmap_locks);\n"
+ " extern unsigned long change_protection(struct vm_area_struct *vma, unsigned long start,\n"
+ " \t\t\t      unsigned long end, pgprot_t newprot,\n"
+ "-\t\t\t      int dirty_accountable, int prot_numa);\n"
+ "+\t\t\t      int dirty_accountable, int prot_numa,\n"
+ "+\t\t\t      bool mkwrite);\n"
+ " extern int mprotect_fixup(struct vm_area_struct *vma,\n"
+ " \t\t\t  struct vm_area_struct **pprev, unsigned long start,\n"
+ " \t\t\t  unsigned long end, unsigned long newflags);\n"
+ "diff --git a/mm/huge_memory.c b/mm/huge_memory.c\n"
+ "index abf621aba672..49853f0b1570 100644\n"
+ "--- a/mm/huge_memory.c\n"
+ "+++ b/mm/huge_memory.c\n"
+ "@@ -1842,7 +1842,8 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,\n"
+ "  *  - HPAGE_PMD_NR is protections changed and TLB flush necessary\n"
+ "  */\n"
+ " int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,\n"
+ "-\t\tunsigned long addr, pgprot_t newprot, int prot_numa)\n"
+ "+\t\tunsigned long addr, pgprot_t newprot, int prot_numa,\n"
+ "+\t\tbool mkwrite)\n"
+ " {\n"
+ " \tstruct mm_struct *mm = vma->vm_mm;\n"
+ " \tspinlock_t *ptl;\n"
+ "@@ -1925,6 +1926,8 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,\n"
+ " \tentry = pmd_modify(entry, newprot);\n"
+ " \tif (preserve_write)\n"
+ " \t\tentry = pmd_mk_savedwrite(entry);\n"
+ "+\tif (mkwrite)\n"
+ "+\t\tentry = pmd_mkwrite(entry);\n"
+ " \tret = HPAGE_PMD_NR;\n"
+ " \tset_pmd_at(mm, addr, pmd, entry);\n"
+ " \tBUG_ON(vma_is_anonymous(vma) && !preserve_write && pmd_write(entry));\n"
+ "diff --git a/mm/mempolicy.c b/mm/mempolicy.c\n"
+ "index 4ce44d3ff03d..2d0ee09e6b26 100644\n"
+ "--- a/mm/mempolicy.c\n"
+ "+++ b/mm/mempolicy.c\n"
+ "@@ -579,7 +579,7 @@ unsigned long change_prot_numa(struct vm_area_struct *vma,\n"
+ " {\n"
+ " \tint nr_updated;\n"
+ " \n"
+ "-\tnr_updated = change_protection(vma, addr, end, PAGE_NONE, 0, 1);\n"
+ "+\tnr_updated = change_protection(vma, addr, end, PAGE_NONE, 0, 1, false);\n"
+ " \tif (nr_updated)\n"
+ " \t\tcount_vm_numa_events(NUMA_PTE_UPDATES, nr_updated);\n"
+ " \n"
+ "diff --git a/mm/mprotect.c b/mm/mprotect.c\n"
+ "index 58b629bb70de..792669cfb7e1 100644\n"
+ "--- a/mm/mprotect.c\n"
+ "+++ b/mm/mprotect.c\n"
+ "@@ -36,7 +36,7 @@\n"
+ " \n"
+ " static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,\n"
+ " \t\tunsigned long addr, unsigned long end, pgprot_t newprot,\n"
+ "-\t\tint dirty_accountable, int prot_numa)\n"
+ "+\t\tint dirty_accountable, int prot_numa, bool mkwrite)\n"
+ " {\n"
+ " \tstruct mm_struct *mm = vma->vm_mm;\n"
+ " \tpte_t *pte, oldpte;\n"
+ "@@ -102,9 +102,9 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,\n"
+ " \t\t\t\tptent = pte_mk_savedwrite(ptent);\n"
+ " \n"
+ " \t\t\t/* Avoid taking write faults for known dirty pages */\n"
+ "-\t\t\tif (dirty_accountable && pte_dirty(ptent) &&\n"
+ "-\t\t\t\t\t(pte_soft_dirty(ptent) ||\n"
+ "-\t\t\t\t\t !(vma->vm_flags & VM_SOFTDIRTY))) {\n"
+ "+\t\t\tif (enable_write || (dirty_accountable &&\n"
+ "+\t\t\t    pte_dirty(ptent) && (pte_soft_dirty(ptent) ||\n"
+ "+\t\t\t    !(vma->vm_flags & VM_SOFTDIRTY)))) {\n"
+ " \t\t\t\tptent = pte_mkwrite(ptent);\n"
+ " \t\t\t}\n"
+ " \t\t\tptep_modify_prot_commit(mm, addr, pte, ptent);\n"
+ "@@ -150,7 +150,8 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,\n"
+ " \n"
+ " static inline unsigned long change_pmd_range(struct vm_area_struct *vma,\n"
+ " \t\tpud_t *pud, unsigned long addr, unsigned long end,\n"
+ "-\t\tpgprot_t newprot, int dirty_accountable, int prot_numa)\n"
+ "+\t\tpgprot_t newprot, int dirty_accountable, int prot_numa,\n"
+ "+\t\tbool mkwrite)\n"
+ " {\n"
+ " \tpmd_t *pmd;\n"
+ " \tstruct mm_struct *mm = vma->vm_mm;\n"
+ "@@ -179,7 +180,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,\n"
+ " \t\t\t\t__split_huge_pmd(vma, pmd, addr, false, NULL);\n"
+ " \t\t\t} else {\n"
+ " \t\t\t\tint nr_ptes = change_huge_pmd(vma, pmd, addr,\n"
+ "-\t\t\t\t\t\tnewprot, prot_numa);\n"
+ "+\t\t\t\t\t\tnewprot, prot_numa, mkwrite);\n"
+ " \n"
+ " \t\t\t\tif (nr_ptes) {\n"
+ " \t\t\t\t\tif (nr_ptes == HPAGE_PMD_NR) {\n"
+ "@@ -194,7 +195,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,\n"
+ " \t\t\t/* fall through, the trans huge pmd just split */\n"
+ " \t\t}\n"
+ " \t\tthis_pages = change_pte_range(vma, pmd, addr, next, newprot,\n"
+ "-\t\t\t\t dirty_accountable, prot_numa);\n"
+ "+\t\t\t\t dirty_accountable, prot_numa, mkwrite);\n"
+ " \t\tpages += this_pages;\n"
+ " next:\n"
+ " \t\tcond_resched();\n"
+ "@@ -210,7 +211,8 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,\n"
+ " \n"
+ " static inline unsigned long change_pud_range(struct vm_area_struct *vma,\n"
+ " \t\tp4d_t *p4d, unsigned long addr, unsigned long end,\n"
+ "-\t\tpgprot_t newprot, int dirty_accountable, int prot_numa)\n"
+ "+\t\tpgprot_t newprot, int dirty_accountable, int prot_numa,\n"
+ "+\t\tbool mkwrite)\n"
+ " {\n"
+ " \tpud_t *pud;\n"
+ " \tunsigned long next;\n"
+ "@@ -222,7 +224,7 @@ static inline unsigned long change_pud_range(struct vm_area_struct *vma,\n"
+ " \t\tif (pud_none_or_clear_bad(pud))\n"
+ " \t\t\tcontinue;\n"
+ " \t\tpages += change_pmd_range(vma, pud, addr, next, newprot,\n"
+ "-\t\t\t\t dirty_accountable, prot_numa);\n"
+ "+\t\t\t\t dirty_accountable, prot_numa, mkwrite);\n"
+ " \t} while (pud++, addr = next, addr != end);\n"
+ " \n"
+ " \treturn pages;\n"
+ "@@ -230,7 +232,8 @@ static inline unsigned long change_pud_range(struct vm_area_struct *vma,\n"
+ " \n"
+ " static inline unsigned long change_p4d_range(struct vm_area_struct *vma,\n"
+ " \t\tpgd_t *pgd, unsigned long addr, unsigned long end,\n"
+ "-\t\tpgprot_t newprot, int dirty_accountable, int prot_numa)\n"
+ "+\t\tpgprot_t newprot, int dirty_accountable, int prot_numa,\n"
+ "+\t\tbool mkwrite)\n"
+ " {\n"
+ " \tp4d_t *p4d;\n"
+ " \tunsigned long next;\n"
+ "@@ -242,7 +245,7 @@ static inline unsigned long change_p4d_range(struct vm_area_struct *vma,\n"
+ " \t\tif (p4d_none_or_clear_bad(p4d))\n"
+ " \t\t\tcontinue;\n"
+ " \t\tpages += change_pud_range(vma, p4d, addr, next, newprot,\n"
+ "-\t\t\t\t dirty_accountable, prot_numa);\n"
+ "+\t\t\t\t dirty_accountable, prot_numa, mkwrite);\n"
+ " \t} while (p4d++, addr = next, addr != end);\n"
+ " \n"
+ " \treturn pages;\n"
+ "@@ -250,7 +253,7 @@ static inline unsigned long change_p4d_range(struct vm_area_struct *vma,\n"
+ " \n"
+ " static unsigned long change_protection_range(struct vm_area_struct *vma,\n"
+ " \t\tunsigned long addr, unsigned long end, pgprot_t newprot,\n"
+ "-\t\tint dirty_accountable, int prot_numa)\n"
+ "+\t\tint dirty_accountable, int prot_numa, mkwrite)\n"
+ " {\n"
+ " \tstruct mm_struct *mm = vma->vm_mm;\n"
+ " \tpgd_t *pgd;\n"
+ "@@ -267,7 +270,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,\n"
+ " \t\tif (pgd_none_or_clear_bad(pgd))\n"
+ " \t\t\tcontinue;\n"
+ " \t\tpages += change_p4d_range(vma, pgd, addr, next, newprot,\n"
+ "-\t\t\t\t dirty_accountable, prot_numa);\n"
+ "+\t\t\t\t dirty_accountable, prot_numa, mkwrite);\n"
+ " \t} while (pgd++, addr = next, addr != end);\n"
+ " \n"
+ " \t/* Only flush the TLB if we actually modified any entries: */\n"
+ "@@ -280,14 +283,16 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,\n"
+ " \n"
+ " unsigned long change_protection(struct vm_area_struct *vma, unsigned long start,\n"
+ " \t\t       unsigned long end, pgprot_t newprot,\n"
+ "-\t\t       int dirty_accountable, int prot_numa)\n"
+ "+\t\t       int dirty_accountable, int prot_numa, bool mkwrite)\n"
+ " {\n"
+ " \tunsigned long pages;\n"
+ " \n"
+ " \tif (is_vm_hugetlb_page(vma))\n"
+ " \t\tpages = hugetlb_change_protection(vma, start, end, newprot);\n"
+ " \telse\n"
+ "-\t\tpages = change_protection_range(vma, start, end, newprot, dirty_accountable, prot_numa);\n"
+ "+\t\tpages = change_protection_range(vma, start, end, newprot,\n"
+ "+\t\t\t\t\t\tdirty_accountable,\n"
+ "+\t\t\t\t\t\tprot_numa, mkwrite);\n"
+ " \n"
+ " \treturn pages;\n"
+ " }\n"
+ "@@ -366,7 +371,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,\n"
+ " \tvma_set_page_prot(vma);\n"
+ " \n"
+ " \tchange_protection(vma, start, end, vma->vm_page_prot,\n"
+ "-\t\t\t  dirty_accountable, 0);\n"
+ "+\t\t\t  dirty_accountable, 0, false);\n"
+ " \n"
+ " \t/*\n"
+ " \t * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major\n"
+ "diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c\n"
+ "index a0379c5ffa7c..c745c5d87523 100644\n"
+ "--- a/mm/userfaultfd.c\n"
+ "+++ b/mm/userfaultfd.c\n"
+ "@@ -632,7 +632,7 @@ int mwriteprotect_range(struct mm_struct *dst_mm, unsigned long start,\n"
+ " \t\tnewprot = vm_get_page_prot(dst_vma->vm_flags);\n"
+ " \n"
+ " \tchange_protection(dst_vma, start, start + len, newprot,\n"
+ "-\t\t\t\t!enable_wp, 0);\n"
+ "+\t\t\t  0, 0, !enable_wp);\n"
+ " \n"
+ " \terr = 0;\n"
+ " out_unlock:\n"
+ "-- \n"
+ 2.17.1
 
-0e9577d424e6dd045aa34ffec320977cfc7b905bd58a86ab13a4a64d5293df57
+ad23a3f897e02799c2eeccfa4eab3ad0344c57c963d94288a22e481a405665c9

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.