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, and nothing clears it afterwards. Patch 1 clears the bit unless the destination is RWP-registered, which is what the present-page and zeropage move paths already do. Patch 2 adds the test that catches it.
v1: https://lore.kernel.org/all/[email protected]/ Changes in v2: - patch 1: clear the bit unconditionally (Kiryl Shutsemau) - patch 1: rewrite the changelog for readability (Mike Rapoport) - add Assisted-by: LLM (Mike Rapoport) x86_64 defconfig plus USERFAULTFD, TRANSPARENT_HUGEPAGE, GUP_TEST and a swap device, under QEMU, base 17e7b8eacf4c: uffd-unit-tests before after move-swap-wp on anon not ok ok the other 114 unit tests ok ok uffd-wp-mremap, 38 tests ok ok pagemap bit 57 at the destination before after swapped page, dst not armed set clear swapped page, dst WP-armed set clear swapped page, dst RWP-armed set set resident page, dst WP-armed clear clear MADV_COLLAPSE over 2 MB at dst EINVAL 0 Donggeun Yoo (2): userfaultfd: clear the inherited uffd bit in move_swap_pte() selftests/mm: add a test for UFFDIO_MOVE of a write-protected swap entry mm/userfaultfd.c | 1 + tools/testing/selftests/mm/uffd-unit-tests.c | 61 ++++++++++++++++++++ 2 files changed, 62 insertions(+) -- 2.53.0

