mm-rmap-fix-soft-dirty-and-uffd-wp-bit-loss-when-remapping-zero-filled-mthp-subpage-to-shared-zeropage.patch removed from -mm tree
The quilt patch titled
Subject: mm/rmap: fix soft-dirty and uffd-wp bit loss when remapping zero-filled mTHP subpage to shared zeropage
has been removed from the -mm tree. Its filename was
mm-rmap-fix-soft-dirty-and-uffd-wp-bit-loss-when-remapping-zero-filled-mthp-subpage-to-shared-zeropage.patch
This patch was dropped because it was merged into the mm-hotfixes-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Lance Yang <[email protected]>
Subject: mm/rmap: fix soft-dirty and uffd-wp bit loss when remapping zero-filled mTHP subpage to shared zeropage
Date: Tue, 30 Sep 2025 16:10:40 +0800
When splitting an mTHP and replacing a zero-filled subpage with the shared zeropage, try_to_map_unused_to_zeropage() currently drops several important PTE bits.
For userspace tools like CRIU, which rely on the soft-dirty mechanism for incremental snapshots, losing the soft-dirty bit means modified pages are missed, leading to inconsistent memory state after restore.
As pointed out by David, the more critical uffd-wp bit is also dropped. This breaks the userfaultfd write-protection mechanism, causing writes to be silently missed by monitoring applications, which can lead to data corruption.
Preserve both the soft-dirty and uffd-wp bits from the old PTE when creating the new zeropage mapping to ensure they are correctly tracked.
---
mm/migrate.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
mm/migrate.c renamed from mm/migrate.c~mm-rmap-fix-soft-dirty-and-uffd-wp-bit-loss-when-remapping-zero-filled-mthp-subpage-to-shared-zeropage +10 -5
@@ -296,8 +296,7 @@ bool isolate_folio_to_list(struct folio }static bool try_to_map_unused_to_zeropage (struct page_vma_mapped_walk *pvmw, -struct folio *folio, -unsigned long idx) +struct folio *folio,pte_t old_pte,unsigned long idx) {struct page *page =folio_page (folio, idx);pte_t newpte;
@@ -306,7 +305,7 @@ static bool try_to_map_unused_to_zeropagreturn false;VM_BUG_ON_PAGE (!PageAnon (page), page);VM_BUG_ON_PAGE (!PageLocked (page), page); -VM_BUG_ON_PAGE (pte_present (ptep_get (pvmw->pte)), page); +VM_BUG_ON_PAGE (pte_present (old_pte), page);if (folio_test_mlocked (folio) || (pvmw->vma->vm_flags &VM_LOCKED ) ||mm_forbids_zeropage (pvmw->vma->vm_mm))
@@ -322,6 +321,12 @@ static bool try_to_map_unused_to_zeropag newpte =pte_mkspecial (pfn_pte (my_zero_pfn (pvmw->address), pvmw->vma->vm_page_prot)); + +if (pte_swp_soft_dirty (old_pte)) + newpte =pte_mksoft_dirty (newpte); +if (pte_swp_uffd_wp (old_pte)) + newpte =pte_mkuffd_wp (newpte); +set_pte_at (pvmw->vma->vm_mm, pvmw->address, pvmw->pte, newpte);dec_mm_counter (pvmw->vma->vm_mm,mm_counter (folio));
@@ -364,13 +369,13 @@ static bool remove_migration_pte(struct continue; }#endif + old_pte =ptep_get (pvmw.pte);if (rmap_walk_arg->map_unused_to_zeropage && -try_to_map_unused_to_zeropage (&pvmw, folio, idx)) +try_to_map_unused_to_zeropage (&pvmw, folio, old_pte, idx))continue ;folio_get (folio); pte =mk_pte (new,READ_ONCE (vma->vm_page_prot)); - old_pte =ptep_get (pvmw.pte); entry =pte_to_swp_entry (old_pte);if (!is_migration_entry_young (entry))
_
Patches currently in -mm which might be from [email protected] are
hung_task-fix-warnings-caused-by-unaligned-lock-pointers.patch mm-khugepaged-abort-collapse-scan-on-non-swap-entries.patch