[PATCH v4 30/38] mm/vma: introduce vma[_flags]_is_mm_backed()
From: Lorenzo Stoakes (ARM)
Date: Sat Oct 03 2026 - 13:17:32 EST
Introduce vma[_flags]_is_mm_backed() for the purposes of identifying
mappings which are mm-managed and whose contents were placed there by core
mm's own fault path - rather than a custom ->fault handler - and which core
mm has not reserved the right to discard.
Mappings not managed by core mm do not fall into this category, as they are
populated by their owner, and nor of course does memory-mapped I/O.
We exclude fixed mappings as these have a layout core mm cannot assume
ordinary fault semantics over.
hugetlb mappings are fixed mappings, but core mm owns them entirely, so
they are explicitly carved out as mm-backed, as the MADV_DODUMP check
already does.
Droppable mappings are excluded as core mm has promised it may discard them
at any time.
Use this functionality to update the madvise MADV_DODUMP check to test for
this rather than open-coding it.
This replaces the VM_SPECIAL check which means it no longer checks for
VMA_IO_BIT, however this is safe as we have established the invariant that
mm-managed mappings may not set VMA_IO_BIT, so we implicitly include
these.
No functional change intended.
Acked-by: Zi Yan <ziy@xxxxxxxxxx>
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
---
include/linux/mm.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
mm/madvise.c | 4 ++--
2 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 2ce68713e4c3..55320cf2c525 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1738,6 +1738,56 @@ static inline bool vma_can_merge(const struct vm_area_struct *vma)
return vma_flags_can_merge(&vma->flags);
}
+/**
+ * vma_flags_is_mm_backed() - Do the specified VMA flags imply the mapping is
+ * backed by core mm?
+ * @flags: The VMA flags to test.
+ *
+ * An mm-backed mapping is one managed by core mm (see
+ * vma_flags_is_mm_managed()) for which two further things are true:
+ *
+ * 1. Everything mapped was placed there by core mm's fault path (no custom
+ * ->fault).
+ * 2. What is mapped stays there until it is zapped or unmapped by the user.
+ *
+ * These mappings are the only ones which can be sensibly locked, merged, dumped
+ * or be subject to uffd faulting, as all of these assume core mm and core mm
+ * alone manages these, and that the mappings will remain there.
+ *
+ * Returns: true if the flags imply an mm-backed mapping, otherwise false.
+ */
+static inline bool vma_flags_is_mm_backed(const vma_flags_t *flags)
+{
+ /* hugetlb is a fixed mapping, but core mm owns it entirely. */
+ if (vma_flags_is_hugetlb(flags))
+ return true;
+ /*
+ * Mappings not managed by core mm are populated by their owner.
+ *
+ * Fixed mappings may be mm-managed, but their contents are established
+ * by a custom ->fault handler, so core mm cannot assume ordinary fault
+ * semantics over them.
+ */
+ if (!vma_flags_is_mm_managed(flags) ||
+ vma_flags_is_fixed_mapping(flags))
+ return false;
+ /* Core mm may discard droppable memory at any time. */
+ return !vma_flags_test_single_mask(flags, VMA_DROPPABLE);
+}
+
+/**
+ * vma_is_mm_backed() - Is @vma backed by core mm?
+ * @vma: The VMA to test.
+ *
+ * See vma_flags_is_mm_backed() for details.
+ *
+ * Returns: true if the VMA is mm-backed, otherwise false.
+ */
+static inline bool vma_is_mm_backed(const struct vm_area_struct *vma)
+{
+ return vma_flags_is_mm_backed(&vma->flags);
+}
+
/**
* vma_kernel_pagesize - Default page size granularity for this VMA.
* @vma: The user mapping.
diff --git a/mm/madvise.c b/mm/madvise.c
index 0922d5f07a12..9d0cde25da61 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -1584,8 +1584,8 @@ static int madvise_vma_behavior(struct madvise_behavior *madv_behavior)
new_flags |= VM_DONTDUMP;
break;
case MADV_DODUMP:
- if ((!vma_is_hugetlb(vma) && (new_flags & VM_SPECIAL)) ||
- (new_flags & VM_DROPPABLE))
+ /* Only mm-backed memory can be meaningfully dumped. */
+ if (!vma_is_mm_backed(vma))
return -EINVAL;
new_flags &= ~VM_DONTDUMP;
break;
--
2.55.0