[PATCH v2] mm: fix VM_SOFTDIRTY propagation on VMA merge

Ahmed Elaidy
2026-04-24T22:11:44Z

During VMA merging, such as through mprotect(), VM_SOFTDIRTY flags could be
lost. This breaks tools relying on soft-dirty tracking, such as CRIU
incremental dump/restore.

Upstream resolved this using a broader VM_STICKY infrastructure (commit
bf14d4a05387 "mm: propagate VM_SOFTDIRTY on merge"). To minimize churn and
risk in the stable 6.18.y tree, this patch skips backporting the entire
VM_STICKY series (9 patches). Instead, it introduces a minimal standalone fix.

VM_SOFTDIRTY is intentionally excluded from normal flag comparison to allow
merging in mprotect. This patch ensures the resulting merged VMA retains
the VM_SOFTDIRTY flag if either of the original VMAs had it.

Suggested-by: Andrei Vagin <avagin@gmail.com>
Cc: stable@vger.kernel.org
Cc: lorenzo.stoakes@oracle.com
Signed-off-by: Ahmed Khalid Elaidy <elaidya225@gmail.com>
---
mm/vma.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/mm/vma.c b/mm/vma.c
index 5815ae9e5770..03728d855684 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -978,6 +978,14 @@ static __must_check struct vm_area_struct *vma_merge_existing_range(
if (err || commit_merge(vmg))
goto abort;

+ /*
+ * VM_SOFTDIRTY is excluded from normal flag comparison to allow
+ * merging in mprotect, but we have to ensure the result is correctly
+ * marked with it if either side had it.
+ */
+ if ((vmg->target->vm_flags ^ vmg->vm_flags) & VM_SOFTDIRTY)
+ vm_flags_set(vmg->target, VM_SOFTDIRTY);
+
khugepaged_enter_vma(vmg->target, vmg->vm_flags);
vmg->state = VMA_MERGE_SUCCESS;
return vmg->target;
--
2.53.0