From: Kiryl Shutsemau <kirill@shutemov.name>
To: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Cc: akpm@linux-foundation.org, rppt@kernel.org, peterx@redhat.com,
surenb@google.com, aarcange@redhat.com, david@kernel.org,
ljs@kernel.org, liam@infradead.org, vbabka@kernel.org,
mhocko@suse.com, shuah@kernel.org, linux-mm@kvack.org,
linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: Re: [PATCH v1 1/2] userfaultfd: clear the inherited uffd bit in move_swap_pte()
Date: Wed, 23 Sep 2026 12:18:30 +0100 [thread overview]
Message-ID: <arO0a3CU_idyVsqQ@thinkstation> (raw)
In-Reply-To: <20260919004630.1159895-2-donggeunyoo.kernel@gmail.com>
On Sat, Sep 19, 2026 at 09:46:29AM +0900, Donggeun Yoo wrote:
> UFFDIO_MOVE on a swapped-out page installs the source PTE at the
> destination unchanged, so a uffd bit set on the source lands in a
> destination VMA that was never registered for write protection. It is
> then permanent: the bit is dropped only by change_protection() under
> MM_CP_UFFD_{WP,RWP}_RESOLVE, which uffd_wp_range(), mrwprotect_range()
> and userfaultfd_clear_vma() issue only for a VMA registered in that
> mode. pagemap reports the page as uffd-tracked, and MADV_COLLAPSE
> refuses the range while the bit is set, because collapse_scan_pmd() is
> strict about uffd on swap entries.
>
> move_present_ptes() and move_zeropage_pte() build the destination PTE
> from dst_vma->vm_page_prot and arm RWP only when dst_vma asks for it, so
> the destination's own registration decides the result. move_swap_pte()
> copies the source PTE instead and only ever sets the bit, never clears
> it, so one UFFDIO_MOVE behaves differently depending on whether the page
> happened to be resident.
>
> Clear the uffd bit on the moved swap entry unless the destination is
> RWP-registered, as copy_nonpresent_pte() does where it installs a PTE
> into a destination that may not be armed. A WP-registered destination
> stops inheriting the bit as well, which is already what it gets when the
> moved page is resident.
>
> Fixes: adef440691ba ("userfaultfd: UFFDIO_MOVE uABI")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
> ---
> mm/userfaultfd.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
> index 74f04c323c50..6495666c596b 100644
> --- a/mm/userfaultfd.c
> +++ b/mm/userfaultfd.c
> @@ -1452,6 +1452,8 @@ static int move_swap_pte(struct mm_struct *mm, struct vm_area_struct *dst_vma,
> /* Re-arm RWP on the moved swap entry if dst_vma is RWP-registered. */
> if (userfaultfd_rwp(dst_vma))
> orig_src_pte = pte_swp_mkuffd(orig_src_pte);
> + else
> + orig_src_pte = pte_swp_clear_uffd(orig_src_pte);
Putting it in the 'else' is wrong. Clear uffd on the source
unconditionally and re-arm based on the target VMA:
orig_src_pte = pte_swp_clear_uffd(orig_src_pte);
/* Re-arm RWP on the moved swap entry if dst_vma is RWP-registered. */
if (userfaultfd_rwp(dst_vma))
orig_src_pte = pte_swp_mkuffd(orig_src_pte);
That is what move_pages_huge_pmd() does with clear_uffd_wp_pmd() before
its own re-arm, and it is the logically correct way to do this: the
source's state is gone, the destination decides.
> set_pte_at(mm, dst_addr, dst_pte, orig_src_pte);
> double_pt_unlock(dst_ptl, src_ptl);
>
> --
> 2.53.0
>
--
Kiryl Shutsemau / Kirill A. Shutemov
next prev parent reply other threads:[~2026-09-23 11:18 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-19 0:46 [PATCH v1 0/2] userfaultfd: clear the inherited uffd bit in move_swap_pte() Donggeun Yoo
2026-09-19 0:46 ` [PATCH v1 1/2] " Donggeun Yoo
2026-09-22 6:45 ` Mike Rapoport
2026-09-22 12:47 ` Donggeun Yoo
2026-09-22 11:40 ` David Hildenbrand (Arm)
2026-09-22 12:41 ` Donggeun Yoo
2026-09-22 16:45 ` Mike Rapoport
2026-09-23 11:20 ` Kiryl Shutsemau
2026-09-23 11:18 ` Kiryl Shutsemau [this message]
2026-09-25 4:37 ` Donggeun Yoo
2026-09-25 7:01 ` David Hildenbrand (Arm)
2026-09-25 8:47 ` Kiryl Shutsemau
2026-09-19 0:46 ` [PATCH v1 2/2] selftests/mm: add a test for UFFDIO_MOVE of a write-protected swap entry Donggeun Yoo
2026-09-22 5:58 ` [PATCH v1 0/2] userfaultfd: clear the inherited uffd bit in move_swap_pte() Mike Rapoport
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=arO0a3CU_idyVsqQ@thinkstation \
--to=kirill@shutemov.name \
--cc=aarcange@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=donggeunyoo.kernel@gmail.com \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=peterx@redhat.com \
--cc=rppt@kernel.org \
--cc=shuah@kernel.org \
--cc=stable@vger.kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.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.