All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: linux-mm@kvack.org, linux-kernel@vger.kernel.org
Cc: peterx@redhat.com, Nadav Amit <nadav.amit@gmail.com>,
	Hugh Dickins <hughd@google.com>,
	David Hildenbrand <david@redhat.com>,
	Axel Rasmussen <axelrasmussen@google.com>,
	Matthew Wilcox <willy@infradead.org>,
	Alistair Popple <apopple@nvidia.com>,
	Mike Rapoport <rppt@linux.vnet.ibm.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Jerome Glisse <jglisse@redhat.com>,
	Mike Kravetz <mike.kravetz@oracle.com>,
	"Kirill A . Shutemov" <kirill@shutemov.name>,
	Andrea Arcangeli <aarcange@redhat.com>
Subject: [PATCH v7 05/23] mm/shmem: Take care of UFFDIO_COPY_MODE_WP
Date: Fri,  4 Mar 2022 13:16:50 +0800	[thread overview]
Message-ID: <20220304051708.86193-6-peterx@redhat.com> (raw)
In-Reply-To: <20220304051708.86193-1-peterx@redhat.com>

Pass wp_copy into shmem_mfill_atomic_pte() through the stack, then apply the
UFFD_WP bit properly when the UFFDIO_COPY on shmem is with UFFDIO_COPY_MODE_WP.
wp_copy lands mfill_atomic_install_pte() finally.

Note: we must do pte_wrprotect() if !writable in mfill_atomic_install_pte(), as
mk_pte() could return a writable pte (e.g., when VM_SHARED on a shmem file).

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 include/linux/shmem_fs.h |  4 ++--
 mm/shmem.c               |  4 ++--
 mm/userfaultfd.c         | 23 ++++++++++++++++++-----
 3 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index ab51d3cd39bd..02d23ce5f979 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -145,11 +145,11 @@ extern int shmem_mfill_atomic_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd,
 				  struct vm_area_struct *dst_vma,
 				  unsigned long dst_addr,
 				  unsigned long src_addr,
-				  bool zeropage,
+				  bool zeropage, bool wp_copy,
 				  struct page **pagep);
 #else /* !CONFIG_SHMEM */
 #define shmem_mfill_atomic_pte(dst_mm, dst_pmd, dst_vma, dst_addr, \
-			       src_addr, zeropage, pagep)       ({ BUG(); 0; })
+			       src_addr, zeropage, wp_copy, pagep) ({ BUG(); 0; })
 #endif /* CONFIG_SHMEM */
 #endif /* CONFIG_USERFAULTFD */
 
diff --git a/mm/shmem.c b/mm/shmem.c
index 81a69bd247b4..3f0332c1c1e9 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2317,7 +2317,7 @@ int shmem_mfill_atomic_pte(struct mm_struct *dst_mm,
 			   struct vm_area_struct *dst_vma,
 			   unsigned long dst_addr,
 			   unsigned long src_addr,
-			   bool zeropage,
+			   bool zeropage, bool wp_copy,
 			   struct page **pagep)
 {
 	struct inode *inode = file_inode(dst_vma->vm_file);
@@ -2390,7 +2390,7 @@ int shmem_mfill_atomic_pte(struct mm_struct *dst_mm,
 		goto out_release;
 
 	ret = mfill_atomic_install_pte(dst_mm, dst_pmd, dst_vma, dst_addr,
-				       page, true, false);
+				       page, true, wp_copy);
 	if (ret)
 		goto out_delete_from_cache;
 
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index e9bb6db002aa..ef418a48b121 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -77,10 +77,19 @@ int mfill_atomic_install_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd,
 	 * Always mark a PTE as write-protected when needed, regardless of
 	 * VM_WRITE, which the user might change.
 	 */
-	if (wp_copy)
+	if (wp_copy) {
 		_dst_pte = pte_mkuffd_wp(_dst_pte);
-	else if (writable)
+		writable = false;
+	}
+
+	if (writable)
 		_dst_pte = pte_mkwrite(_dst_pte);
+	else
+		/*
+		 * We need this to make sure write bit removed; as mk_pte()
+		 * could return a pte with write bit set.
+		 */
+		_dst_pte = pte_wrprotect(_dst_pte);
 
 	dst_pte = pte_offset_map_lock(dst_mm, dst_pmd, dst_addr, &ptl);
 
@@ -95,7 +104,12 @@ int mfill_atomic_install_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd,
 	}
 
 	ret = -EEXIST;
-	if (!pte_none(*dst_pte))
+	/*
+	 * We allow to overwrite a pte marker: consider when both MISSING|WP
+	 * registered, we firstly wr-protect a none pte which has no page cache
+	 * page backing it, then access the page.
+	 */
+	if (!pte_none_mostly(*dst_pte))
 		goto out_unlock;
 
 	if (page_in_cache) {
@@ -479,11 +493,10 @@ static __always_inline ssize_t mfill_atomic_pte(struct mm_struct *dst_mm,
 			err = mfill_zeropage_pte(dst_mm, dst_pmd,
 						 dst_vma, dst_addr);
 	} else {
-		VM_WARN_ON_ONCE(wp_copy);
 		err = shmem_mfill_atomic_pte(dst_mm, dst_pmd, dst_vma,
 					     dst_addr, src_addr,
 					     mode != MCOPY_ATOMIC_NORMAL,
-					     page);
+					     wp_copy, page);
 	}
 
 	return err;
-- 
2.32.0


  parent reply	other threads:[~2022-03-04  5:18 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-04  5:16 [PATCH v7 00/23] userfaultfd-wp: Support shmem and hugetlbfs Peter Xu
2022-03-04  5:16 ` [PATCH v7 01/23] mm: Introduce PTE_MARKER swap entry Peter Xu
2022-03-04  5:16 ` [PATCH v7 02/23] mm: Teach core mm about pte markers Peter Xu
2022-03-04  5:16 ` [PATCH v7 03/23] mm: Check against orig_pte for finish_fault() Peter Xu
2022-03-04  5:16 ` [PATCH v7 04/23] mm/uffd: PTE_MARKER_UFFD_WP Peter Xu
2022-03-04  5:16 ` Peter Xu [this message]
2022-03-04  5:16 ` [PATCH v7 06/23] mm/shmem: Handle uffd-wp special pte in page fault handler Peter Xu
2022-03-04  5:16 ` [PATCH v7 07/23] mm/shmem: Persist uffd-wp bit across zapping for file-backed Peter Xu
2022-03-04  5:16 ` [PATCH v7 08/23] mm/shmem: Allow uffd wr-protect none pte for file-backed mem Peter Xu
2022-03-04  5:16 ` [PATCH v7 09/23] mm/shmem: Allows file-back mem to be uffd wr-protected on thps Peter Xu
2022-03-04  5:16 ` [PATCH v7 10/23] mm/shmem: Handle uffd-wp during fork() Peter Xu
2022-03-04  5:16 ` [PATCH v7 11/23] mm/hugetlb: Introduce huge pte version of uffd-wp helpers Peter Xu
2022-03-04  5:16 ` [PATCH v7 12/23] mm/hugetlb: Hook page faults for uffd write protection Peter Xu
2022-03-04  5:16 ` [PATCH v7 13/23] mm/hugetlb: Take care of UFFDIO_COPY_MODE_WP Peter Xu
2022-03-04  5:16 ` [PATCH v7 14/23] mm/hugetlb: Handle UFFDIO_WRITEPROTECT Peter Xu
2022-03-04  5:17 ` [PATCH v7 15/23] mm/hugetlb: Handle pte markers in page faults Peter Xu
2022-03-04  5:17 ` [PATCH v7 16/23] mm/hugetlb: Allow uffd wr-protect none ptes Peter Xu
2022-03-04  5:17 ` [PATCH v7 17/23] mm/hugetlb: Only drop uffd-wp special pte if required Peter Xu
2022-03-04  5:17 ` [PATCH v7 18/23] mm/hugetlb: Handle uffd-wp during fork() Peter Xu
2022-03-04  5:17 ` [PATCH v7 19/23] mm/khugepaged: Don't recycle vma pgtable if uffd-wp registered Peter Xu
2022-03-04  5:17 ` [PATCH v7 20/23] mm/pagemap: Recognize uffd-wp bit for shmem/hugetlbfs Peter Xu
2022-03-04  5:17 ` [PATCH v7 21/23] mm/uffd: Enable write protection for shmem & hugetlbfs Peter Xu
2022-03-04  5:17 ` [PATCH v7 22/23] mm: Enable PTE markers by default Peter Xu
2022-03-04  5:17 ` [PATCH v7 23/23] selftests/uffd: Enable uffd-wp for shmem/hugetlbfs Peter Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220304051708.86193-6-peterx@redhat.com \
    --to=peterx@redhat.com \
    --cc=aarcange@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=apopple@nvidia.com \
    --cc=axelrasmussen@google.com \
    --cc=david@redhat.com \
    --cc=hughd@google.com \
    --cc=jglisse@redhat.com \
    --cc=kirill@shutemov.name \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mike.kravetz@oracle.com \
    --cc=nadav.amit@gmail.com \
    --cc=rppt@linux.vnet.ibm.com \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.