Linux Framebuffer Layer development
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
Cc: "Liam R. Howlett" <liam@infradead.org>,
	Vlastimil Babka <vbabka@kernel.org>, Jann Horn <jannh@google.com>,
	Pedro Falcato <pfalcato@suse.de>,
	David Hildenbrand <david@kernel.org>,
	Mike Rapoport <rppt@kernel.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>, Jonathan Corbet <corbet@lwn.net>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>,
	Jason Gunthorpe <jgg@ziepe.ca>, Leon Romanovsky <leon@kernel.org>,
	Paul Moore <paul@paul-moore.com>,
	Stephen Smalley <stephen.smalley.work@gmail.com>,
	Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Eduard Zingerman <eddyz87@gmail.com>,
	Kumar Kartikeya Dwivedi <memxor@gmail.com>,
	Zi Yan <ziy@nvidia.com>,
	Baolin Wang <baolin.wang@linux.alibaba.com>,
	Nico Pache <nico.pache@linux.dev>,
	Ryan Roberts <ryan.roberts@arm.com>, Dev Jain <dev.jain@arm.com>,
	Barry Song <baohua@kernel.org>, Lance Yang <lance.yang@linux.dev>,
	Usama Arif <usama.arif@linux.dev>,
	Kiryl Shutsemau <kas@kernel.org>,
	Doug Gilbert <dgilbert@interlog.com>,
	"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
	"Martin K. Petersen" <mkp@kernel.org>,
	Simona Vetter <simona@ffwll.ch>, Helge Deller <deller@gmx.de>,
	Sebastian Reichel <sre@kernel.org>,
	John Hubbard <jhubbard@nvidia.com>, Peter Xu <peterx@redhat.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Oleg Nesterov <oleg@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
	Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	x86@kernel.org, Arnaldo Carvalho de Melo <acme@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Rik van Riel <riel@surriel.com>, Harry Yoo <harry@kernel.org>,
	Juri Lelli <juri.lelli@redhat.com>,
	Vincent Guittot <vincent.guittot@linaro.org>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@gmail.com>, Will Deacon <will@kernel.org>,
	"Aneesh Kumar K.V" <aneesh.kumar@kernel.org>,
	Nick Piggin <npiggin@gmail.com>, Arnd Bergmann <arnd@arndb.de>,
	Muchun Song <muchun.song@linux.dev>,
	Oscar Salvador <osalvador@suse.de>,
	"Matthew Wilcox (Oracle)" <willy@infradead.org>,
	Jan Kara <jack@suse.cz>, Marc Zyngier <maz@kernel.org>,
	Oliver Upton <oupton@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Madhavan Srinivasan <maddy@linux.ibm.com>,
	Anup Patel <anup@brainfault.org>, Paul Walmsley <pjw@kernel.org>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Christian Borntraeger <borntraeger@linux.ibm.com>,
	Janosch Frank <frankja@linux.ibm.com>,
	Claudio Imbrenda <imbrenda@linux.ibm.com>,
	Alexander Gordeev <agordeev@linux.ibm.com>,
	Gerald Schaefer <gerald.schaefer@linux.ibm.com>,
	Heiko Carstens <hca@linux.ibm.com>,
	Vasily Gorbik <gor@linux.ibm.com>,
	"David S. Miller" <davem@davemloft.net>,
	Andreas Larsson <andreas@gaisler.com>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>,
	Matthew Brost <matthew.brost@intel.com>,
	Joshua Hahn <joshua.hahnjy@gmail.com>,
	Rakie Kim <rakie.kim@sk.com>, Byungchul Park <byungchul@sk.com>,
	Gregory Price <gourry@gourry.net>,
	Ying Huang <ying.huang@linux.alibaba.com>,
	Alistair Popple <apopple@nvidia.com>,
	Chris Li <chrisl@kernel.org>, Kairui Song <kasong@tencent.com>,
	Kemeng Shi <shikemeng@huaweicloud.com>,
	Nhat Pham <nphamcs@gmail.com>, Baoquan He <baoquan.he@linux.dev>,
	Youngjun Park <youngjun.park@lge.com>,
	Johannes Weiner <hannes@cmpxchg.org>,
	Qi Zheng <qi.zheng@linux.dev>,
	Shakeel Butt <shakeel.butt@linux.dev>,
	Axel Rasmussen <axelrasmussen@google.com>,
	Yuanchu Xie <yuanchu@google.com>, Wei Xu <weixugc@google.com>,
	Chengming Zhou <chengming.zhou@linux.dev>,
	Michal Hocko <mhocko@kernel.org>,
	Miklos Szeredi <miklos@szeredi.hu>, Xu Xin <xu.xin@linux.dev>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-usb@vger.kernel.org,
	linux-rdma@vger.kernel.org, selinux@vger.kernel.org,
	linux-sound@vger.kernel.org, bpf@vger.kernel.org,
	linux-scsi@vger.kernel.org, linux-fbdev@vger.kernel.org,
	dri-devel@lists.freedesktop.org,
	linux-trace-kernel@vger.kernel.org,
	linux-perf-users@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-fsdevel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
	linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org,
	kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org,
	linux-s390@vger.kernel.org, sparclinux@vger.kernel.org,
	fuse-devel@lists.linux.dev,
	Ihor Solodrai <ihor.solodrai@linux.dev>,
	Bert Karwatzki <spasswolf@web.de>, Takashi Iwai <tiwai@suse.de>,
	Emil Tsalapatis <emil@etsalapatis.com>
Subject: Re: [PATCH v6 00/39] mm: make VMA flag semantics explicit, eliminate VM_SPECIAL
Date: Tue, 13 Oct 2026 11:50:40 -0700	[thread overview]
Message-ID: <20261013115040.1583b1d8e85c4b5d65a1ae0e@linux-foundation.org> (raw)
In-Reply-To: <20261013-b4-mmap-prepare-vma-flag-sanify-v6-0-1aa3c9b139f9@kernel.org>

On Tue, 13 Oct 2026 16:04:40 +0100 "Lorenzo Stoakes (ARM)" <ljs@kernel.org> wrote:

> The VM_SPECIAL / VMA_SPECIAL_FLAGS mask conflates several unrelated
> properties:
> 
> * Is this managed by core mm, or by a driver mapping MMIO, kernel-allocated
>   pages, or even ordinary pages itself?
> * Can it be expanded or merged?
> * Is this a 'weird' case like mlock where migration might race and we
>   'have' to set invalid flags to notify?
> * Is it another 'weird' case where we just want to stop GUP from touching
>   it?
> 
> Driver writers have often been confused about this, and who can blame them?
> 
> It also interacts badly with the eternal edgecase known as hugetlb - which
> sets VMA_DONTEXPAND_BIT but doesn't also want to be treated like a
> 'special' flag.
> 
> Another issue is that we cannot make sensible assumptions about flag
> use. It's not possible to assume VMA_IO_BIT means iommu because drivers
> abuse it and mlock abuses it.
> 
> Special is also an overloaded term in mm. VDSO and VVAR mappings are also
> called 'special' but they're special in a... special way.
> 
> Sometimes things are called special that are a subset of
> VMA_SPECIAL_FLAGS (VMA_PFNMAP_BIT and VMA_MIXEDMAP_BIT for instance when it
> comes to zapping or vm_normal_folio()).
> 
> There's a specific kind of special for THP too, which considers
> PFN map, mixed map 'special' but DAX not.
> 
> It's all rather a mess.
> 
> This series brings some order to things by both limiting what drivers can
> do with VMA flags and switching to using predicates that describe
> behaviour, not arbitrary flags.

Thanks, I've updated mm-unstable to this version.

> v6:
> * Applied tags (thanks David!)
> * Added 7/39 to split out the vm_insert_page() / vm_insert_pages()
>   mmap lock assertions and VMA API changes out into their own patch,
>   as per David.
> * Updated 8/39 (was 7/38) to collapse the discontig single page case to
>   a single one and to rename things, as per David.
> * Updated 9/39 (was 8/38) to update the discontig docs to reflect the
>   change.
> * Updated 23/39 (was 22/38) to put expression on single line, as per David.
> * Updated 25/39 (was 24/38) to mention the open-coding in the commit
>   message (fixed in next commit), as per discussion with David.
> * Updated 26/39 (was 25/38) to clarify the commit message around the
>   removal of the VMA_IO_BIT check in vma_flags_is_mm_managed(), as per
>   David.
> * Updated 30/39 (was 30/38) to no longer exclude droppable mappings from
>   vma_flags_is_mm_backed(), as it doesn't quite fit into the broader
>   definition, as per David.
> * Updated 30/39 (was 30/38) to express vma_flags_can_merge() in terms of
>   vma_flags_is_mm_backed() (with an explicit hugetlb exclusion), and to
>   no longer use vma_can_merge() in __thp_vma_allowable_orders().
> * Updated 31/39 (was 29/38) to use vma_is_mm_backed() (with hugetlb
>   exclusion) rather than vma_can_merge(), as guard regions have nothing to
>   do with mergeability.
> * Updated 32/39 (was 31/38) to retain an explicit droppable check in
>   vma_can_userfault(), as per David.
> * Updated 33/39 (was 32/38) to use vma_is_mm_backed() with an explicit
>   hugetlb exclusion, rather than vma_can_merge() which makes no sense here.
> * Updated 34/39 (was 33/38) to retain explicit droppable checks in
>   vma_supports_mlock() and ksm_compatible(), as per David.
> * Updated 34/39 (was 33/38) to use vma_is_mm_backed() in should_skip_vma(),
>   based on discussion with David.
> * Updated 35/39 (was 34/38) to use vma_is_mm_backed() in
>   lru_gen_look_around(), as per David.
> * Updated 36/39 (was 35/38) to use vma_is_mm_backed() with an explicit
>   hugetlb exclusion in migrate_vma_setup(), as per David.

Here's how v6 altered mm.git.


 Documentation/filesystems/mmap_prepare.rst |    2 
 include/linux/mm.h                         |  120 +++++++++----------
 include/linux/mm_types.h                   |    6 
 mm/huge_memory.c                           |    7 -
 mm/internal.h                              |    3 
 mm/ksm.c                                   |    3 
 mm/madvise.c                               |   11 +
 mm/memory.c                                |   16 +-
 mm/migrate_device.c                        |    4 
 mm/userfaultfd.c                           |    3 
 mm/vma.c                                   |    4 
 mm/vmscan.c                                |    7 -
 tools/testing/vma/include/dup.h            |   44 +++++-
 13 files changed, 128 insertions(+), 102 deletions(-)

--- a/Documentation/filesystems/mmap_prepare.rst~b
+++ a/Documentation/filesystems/mmap_prepare.rst
@@ -240,7 +240,7 @@ In the ``get`` hook, the user must choos
   compound pages (if the compound page is bigger than the remaining pages in the
   VMA, then only those pages that fit will be mapped). For a compound page, the
   head page must be passed.
-* ``discontig_kernel_map_page_range()`` - Map an array of pages of a specified
+* ``discontig_kernel_map_pages()`` - Map an array of pages of a specified
   size. As with a compound page, if more pages are specified than remain in
   the VMA then only those that fit will be mapped.
 
--- a/include/linux/mm.h~b
+++ a/include/linux/mm.h
@@ -1695,57 +1695,22 @@ static inline bool vma_is_fixed_mapping(
 }
 
 /**
- * vma_flags_can_merge() - Do the specified VMA flags permit the VMA to be
- * merged with another?
- * @flags: The VMA flags to test.
- * Returns: true if the flags permit merging, false otherwise.
- */
-static inline bool vma_flags_can_merge(const vma_flags_t *flags)
-{
-	/*
-	 * VMA merging assumes that a VMA's flags and fields completely describe
-	 * its state.
-	 *
-	 * However, mappings which are not mm-managed may have established state
-	 * upon mapping not embodied in any attribute of the VMA.
-	 *
-	 * Additionally, private (CoW) PFN maps encode the source PFN of the
-	 * range in vma->vm_pgoff, which may otherwise cause spurious merges.
-	 */
-	if (!vma_flags_is_mm_managed(flags))
-		return false;
-	/* VMA explicitly marked as being unmergeable. */
-	if (vma_flags_is_fixed_mapping(flags))
-		return false;
-
-	return true;
-}
-
-/**
- * vma_can_merge() - Do @vma's flags permit it to be merged with another VMA?
- * @vma: The VMA to test.
- * Returns: true if the flags permit merging, otherwise false.
- */
-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:
+ * vma_flags_is_mm_managed()) whose contents are established by core mm's own
+ * fault path rather than a custom ->fault handler.
  *
- * 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.
+ * Mappings not managed by core mm are populated by their owner, and fixed
+ * mappings may be mm-managed but have their contents established by a custom
+ * ->fault handler, so neither are mm-backed. hugetlb mappings are fixed, but
+ * core mm owns them entirely, so they are.
+ *
+ * These are the only mappings which can sensibly be merged, locked, dumped or
+ * be subject to uffd faulting, as all of these assume core mm and core mm
+ * alone manages their contents.
  *
  * Returns: true if the flags imply an mm-backed mapping, otherwise false.
  */
@@ -1761,11 +1726,7 @@ static inline bool vma_flags_is_mm_backe
 	 * 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);
+	return vma_flags_is_mm_managed(flags) && !vma_flags_is_fixed_mapping(flags);
 }
 
 /**
@@ -1782,6 +1743,43 @@ static inline bool vma_is_mm_backed(cons
 }
 
 /**
+ * vma_flags_can_merge() - Do the specified VMA flags permit the VMA to be
+ * merged with another?
+ * @flags: The VMA flags to test.
+ * Returns: true if the flags permit merging, false otherwise.
+ */
+static inline bool vma_flags_can_merge(const vma_flags_t *flags)
+{
+	/*
+	 * VMA merging assumes that a VMA's flags and fields completely describe
+	 * its state, which is only the case for mm-backed mappings.
+	 *
+	 * Mappings which are not mm-managed may have established state upon
+	 * mapping not embodied in any attribute of the VMA.
+	 *
+	 * Additionally, private (CoW) PFN maps encode the source PFN of the
+	 * range in vma->vm_pgoff, which may otherwise cause spurious merges.
+	 */
+	if (!vma_flags_is_mm_backed(flags))
+		return false;
+	/*
+	 * hugetlb mappings contain per-VMA state, so their flags and fields do
+	 * not completely describe them.
+	 */
+	return !vma_flags_is_hugetlb(flags);
+}
+
+/**
+ * vma_can_merge() - Do @vma's flags permit it to be merged with another VMA?
+ * @vma: The VMA to test.
+ * Returns: true if the flags permit merging, otherwise false.
+ */
+static inline bool vma_can_merge(const struct vm_area_struct *vma)
+{
+	return vma_flags_can_merge(&vma->flags);
+}
+
+/**
  * vma_kernel_pagesize - Default page size granularity for this VMA.
  * @vma: The user mapping.
  *
@@ -4824,28 +4822,26 @@ discontig_kernel_map_abort(struct discon
 
 static inline void
 discontig_kernel_map_page(struct discontig_kernel_page_state *state,
-			  struct page *page)
+		struct page *page)
 {
 	struct folio *folio = page_folio(page);
+	unsigned long nr_pages = 1;
 
 	if (folio_test_large(folio)) {
 		VM_WARN_ON_ONCE(page != folio_page(folio, 0));
-		state->action = DISCONTIG_KERNEL_PAGE_MAP_COMPOUND_PAGE;
-		state->__folio = folio;
-		state->__nr_pages = min(state->nr_pages_remain,
-					folio_nr_pages(folio));
-	} else {
-		state->action = DISCONTIG_KERNEL_PAGE_MAP_PAGE;
-		state->__page = page;
-		state->__nr_pages = 1;
+		nr_pages = folio_nr_pages(folio);
 	}
+
+	state->action = DISCONTIG_KERNEL_PAGE_MAP_CONTIG_PAGES;
+	state->__page = page;
+	state->__nr_pages = min(nr_pages, state->nr_pages_remain);
 }
 
 static inline void
-discontig_kernel_map_page_range(struct discontig_kernel_page_state *state,
-				struct page **page_arr, unsigned long nr_pages)
+discontig_kernel_map_pages(struct discontig_kernel_page_state *state,
+		struct page **page_arr, unsigned long nr_pages)
 {
-	state->action = DISCONTIG_KERNEL_PAGE_MAP_PAGE_RANGE;
+	state->action = DISCONTIG_KERNEL_PAGE_MAP_PAGES;
 	state->__page_arr = page_arr;
 	state->__nr_pages = min(nr_pages, state->nr_pages_remain);
 }
--- a/include/linux/mm_types.h~b
+++ a/include/linux/mm_types.h
@@ -825,9 +825,8 @@ enum mmap_action_type {
 
 enum discontig_kernel_page_action {
 	DISCONTIG_KERNEL_PAGE_ABORT,
-	DISCONTIG_KERNEL_PAGE_MAP_PAGE,
-	DISCONTIG_KERNEL_PAGE_MAP_COMPOUND_PAGE,
-	DISCONTIG_KERNEL_PAGE_MAP_PAGE_RANGE,
+	DISCONTIG_KERNEL_PAGE_MAP_PAGES,	/* Array of individual pages. */
+	DISCONTIG_KERNEL_PAGE_MAP_CONTIG_PAGES,	/* 1..N contiguous pages. */
 };
 
 struct discontig_kernel_page_state {
@@ -847,7 +846,6 @@ struct discontig_kernel_page_state {
 	enum discontig_kernel_page_action action;
 	union {
 		struct page *__page;
-		struct folio *__folio;
 		struct page **__page_arr;
 	};
 	unsigned long __nr_pages;
--- a/mm/huge_memory.c~b
+++ a/mm/huge_memory.c
@@ -207,11 +207,10 @@ unsigned long __thp_vma_allowable_orders
 	 * khugepaged moves data from VMAs once collapsed, after they have been
 	 * faulted in, relying on refaulting for file-backed memory.
 	 *
-	 * Mappings not managed by core mm cannot be reliably reconstructed from
-	 * page faults, and fixed mappings (including hugetlb) may well be
-	 * mm-managed - precisely the mappings which cannot be merged.
+	 * Only mm-backed mappings can be reliably reconstructed from page
+	 * faults, and hugetlb mappings cannot be collapsed.
 	 */
-	if (!in_pf && !smaps && !vma_can_merge(vma))
+	if (!in_pf && !smaps && (!vma_is_mm_backed(vma) || vma_is_hugetlb(vma)))
 		return 0;
 
 	/*
--- a/mm/internal.h~b
+++ a/mm/internal.h
@@ -1114,6 +1114,9 @@ static inline bool vma_supports_mlock(co
 {
 	if (!vma_is_mm_backed(vma))
 		return false;
+	/* Core mm may discard droppable memory at any time. */
+	if (vma_test_single_mask(vma, VMA_DROPPABLE))
+		return false;
 	if (vma_is_dax(vma) || vma_is_hugetlb(vma))
 		return false;
 	return vma != get_gate_vma(current->mm);
--- a/mm/ksm.c~b
+++ a/mm/ksm.c
@@ -749,6 +749,9 @@ static bool ksm_compatible(const struct
 		return false;
 	if (!vma_flags_is_mm_backed(&vma_flags))
 		return false;
+	/* Core mm may discard droppable memory at any time. */
+	if (vma_flags_test_single_mask(&vma_flags, VMA_DROPPABLE))
+		return false;
 	if (file_is_dax(file))
 		return false;
 #ifdef VM_SAO
--- a/mm/madvise.c~b
+++ a/mm/madvise.c
@@ -1069,10 +1069,10 @@ static bool is_valid_guard_vma(const str
 		return false;
 	/*
 	 * Guard regions require a VMA whose page tables are managed solely by
-	 * the core, which is also what merging requires, so disallow any flags
-	 * that would prevent a merge.
+	 * core mm, so the VMA must be mm-backed (excluding hugetlb, in which
+	 * guard markers cannot be installed).
 	 */
-	if (!vma_can_merge(vma))
+	if (!vma_is_mm_backed(vma) || vma_is_hugetlb(vma))
 		return false;
 
 	return true;
@@ -1402,7 +1402,7 @@ static int madvise_vma_behavior(struct m
 		new_flags |= VM_DONTCOPY;
 		break;
 	case MADV_DOFORK:
-		if (!vma_can_merge(vma))
+		if (!vma_is_mm_backed(vma) || vma_is_hugetlb(vma))
 			return -EINVAL;
 		new_flags &= ~VM_DONTCOPY;
 		break;
@@ -1424,6 +1424,9 @@ static int madvise_vma_behavior(struct m
 		/* Only mm-backed memory can be meaningfully dumped. */
 		if (!vma_is_mm_backed(vma))
 			return -EINVAL;
+		/* Core mm may discard droppable memory at any time. */
+		if (new_flags & VM_DROPPABLE)
+			return -EINVAL;
 		new_flags &= ~VM_DONTDUMP;
 		break;
 	case MADV_MERGEABLE:
--- a/mm/memory.c~b
+++ a/mm/memory.c
@@ -2674,26 +2674,24 @@ int map_discontig_kernel_pages_prepare(s
 }
 
 static int apply_discontig_action(struct vm_area_struct *vma,
-				  struct discontig_kernel_page_state *state)
+		struct discontig_kernel_page_state *state)
 {
 	unsigned long nr_pages = state->__nr_pages;
 	unsigned long addr = state->addr;
 	unsigned long i;
 
-	if (state->action == DISCONTIG_KERNEL_PAGE_MAP_PAGE)
-		return insert_page(vma, addr, state->__page,
-				   vma->vm_page_prot, /*mkwrite=*/false);
-	if (state->action == DISCONTIG_KERNEL_PAGE_MAP_PAGE_RANGE)
+	if (state->action == DISCONTIG_KERNEL_PAGE_MAP_PAGES)
 		return insert_pages(vma, addr, state->__page_arr,
-				    &nr_pages, vma->vm_page_prot);
+				&nr_pages, vma->vm_page_prot);
 
-	/* Compound folio - have to iterate through each page. */
+	VM_WARN_ON_ONCE(state->action != DISCONTIG_KERNEL_PAGE_MAP_CONTIG_PAGES);
+	/* Contiguous pages - have to iterate through each one. */
 	for (i = 0; i < nr_pages; i++, addr += PAGE_SIZE) {
-		struct page *page = folio_page(state->__folio, i);
+		struct page *page = state->__page + i;
 		int err;
 
 		err = insert_page(vma, addr, page, vma->vm_page_prot,
-				  /*mkwrite=*/false);
+				/*mkwrite=*/false);
 		if (err)
 			return err;
 	}
--- a/mm/migrate_device.c~b
+++ a/mm/migrate_device.c
@@ -746,8 +746,8 @@ int migrate_vma_setup(struct migrate_vma
 	args->end &= PAGE_MASK;
 	if (!vma)
 		return -EINVAL;
-	if (!vma_is_mm_managed(vma) || vma_is_fixed_mapping(vma) ||
-	    vma_is_dax(vma))
+	/* The migrate_vma page walk has no hugetlb support. */
+	if (!vma_is_mm_backed(vma) || vma_is_hugetlb(vma) || vma_is_dax(vma))
 		return -EINVAL;
 	if (nr_pages <= 0)
 		return -EINVAL;
--- a/mm/userfaultfd.c~b
+++ a/mm/userfaultfd.c
@@ -2156,6 +2156,9 @@ static bool vma_can_userfault(struct vm_
 	/* Only mm-backed memory can have its faults handled by userspace. */
 	if (!vma_is_mm_backed(vma))
 		return false;
+	/* Core mm may discard droppable memory at any time. */
+	if (vma_test_single_mask(vma, VMA_DROPPABLE))
+		return false;
 	/* The shadow stack should not be written to by userspace. */
 	if (vma_test_single_mask(vma, VMA_SHADOW_STACK))
 		return false;
--- a/mm/vma.c~b
+++ a/mm/vma.c
@@ -2654,9 +2654,7 @@ static int __mmap_new_file_vma(struct mm
 	 * VMA_LOCKED_BIT and/or VMA_LOCKONFAULT_BIT flags.
 	 */
 	if (vma_supports_mlock(vma)) {
-		const vma_flags_t mask =
-			vma_flags_and_mask(&map->vma_flags,
-					   VMA_LOCKED_MASK);
+		const vma_flags_t mask = vma_flags_and_mask(&map->vma_flags, VMA_LOCKED_MASK);
 
 		vma_set_flags_mask(vma, mask);
 	}
--- a/mm/vmscan.c~b
+++ a/mm/vmscan.c
@@ -3521,8 +3521,7 @@ static int should_skip_vma(unsigned long
 	if (!vma_has_recency(vma))
 		return true;
 
-	if (vma_test(vma, VMA_LOCKED_BIT) || !vma_is_mm_managed(vma) ||
-	    vma_is_fixed_mapping(vma))
+	if (vma_test(vma, VMA_LOCKED_BIT) || !vma_is_mm_backed(vma))
 		return true;
 
 	if (vma == get_gate_vma(vma->vm_mm))
@@ -4462,8 +4461,8 @@ bool lru_gen_look_around(struct page_vma
 	if (spin_is_contended(pvmw->ptl))
 		return true;
 
-	/* exclude fixed and non-mm-managed VMAs containing anon pages from COW */
-	if (!vma_is_mm_managed(vma) || vma_is_fixed_mapping(vma))
+	/* exclude non-mm-backed VMAs containing anon pages from COW */
+	if (!vma_is_mm_backed(vma))
 		return true;
 
 	/* avoid taking the LRU lock under the PTL when possible */
--- a/tools/testing/vma/include/dup.h~b
+++ a/tools/testing/vma/include/dup.h
@@ -1681,23 +1681,49 @@ static inline bool vma_is_fixed_mapping(
 	return vma_flags_is_fixed_mapping(&vma->flags);
 }
 
+static inline bool vma_flags_is_hugetlb(const vma_flags_t *flags)
+{
+	return IS_ENABLED(CONFIG_HUGETLB_PAGE) &&
+	       vma_flags_test(flags, VMA_HUGETLB_BIT);
+}
+
+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.
+	 */
+	return vma_flags_is_mm_managed(flags) && !vma_flags_is_fixed_mapping(flags);
+}
+
+static inline bool vma_is_mm_backed(const struct vm_area_struct *vma)
+{
+	return vma_flags_is_mm_backed(&vma->flags);
+}
+
 static inline bool vma_flags_can_merge(const vma_flags_t *flags)
 {
 	/*
 	 * VMA merging assumes that a VMA's flags and fields completely describe
-	 * its state.
+	 * its state, which is only the case for mm-backed mappings.
 	 *
-	 * However, mappings which are not mm-managed may have established state
-	 * upon mapping not embodied in any attribute of the VMA.
+	 * Mappings which are not mm-managed may have established state upon
+	 * mapping not embodied in any attribute of the VMA.
 	 *
 	 * Additionally, private (CoW) PFN maps encode the source PFN of the
 	 * range in vma->vm_pgoff, which may otherwise cause spurious merges.
 	 */
-	if (!vma_flags_is_mm_managed(flags))
+	if (!vma_flags_is_mm_backed(flags))
 		return false;
-	/* VMA explicitly marked as being unmergeable. */
-	if (vma_flags_is_fixed_mapping(flags))
-		return false;
-
-	return true;
+	/*
+	 * hugetlb mappings contain per-VMA state, so their flags and fields do
+	 * not completely describe them.
+	 */
+	return !vma_flags_is_hugetlb(flags);
 }
_


      parent reply	other threads:[~2026-10-13 18:50 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13 15:04 [PATCH v6 00/39] mm: make VMA flag semantics explicit, eliminate VM_SPECIAL Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 01/39] mm/vma: fix mmap_prepare file handling, remove file_doesnt_need_get Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 02/39] mm/vma: introduce and use vma_[flags_]can_merge() Lorenzo Stoakes (ARM)
2026-10-13 15:19   ` David Hildenbrand (Arm)
2026-10-13 15:04 ` [PATCH v6 03/39] mm: consistently validate VMA state after mmap[_prepare] hooks Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 04/39] mm/vma: ensure mmap_prepare doesn't set actions on a mergeable vma Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 05/39] mm: make map_kernel_pages_[prepare,complete] internal and unexported Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 06/39] mm/vma: tidy up map kernel pages enum values Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 07/39] mm: assert mmap lock held, use new flags API in vm_insert_page[s] Lorenzo Stoakes (ARM)
2026-10-13 15:20   ` David Hildenbrand (Arm)
2026-10-13 15:04 ` [PATCH v6 08/39] mm: add mmap action for discontiguous kernel page mapping Lorenzo Stoakes (ARM)
2026-10-13 15:24   ` David Hildenbrand (Arm)
2026-10-13 15:04 ` [PATCH v6 09/39] docs: filesystems: update mmap_prepare docs for discontig kernel pgs Lorenzo Stoakes (ARM)
2026-10-13 15:25   ` David Hildenbrand (Arm)
2026-10-13 15:04 ` [PATCH v6 10/39] drivers/usb/mon: update to use mmap_prepare + map kernel pages Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 11/39] infiniband: update hfi1 to use remap_vmalloc_range() Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 12/39] selinux: reject writable opens of policy file, drop mmap shared/write check Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 13/39] ALSA: pcm: use vm_insert_page() to map PCM status page Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 14/39] bpf: arena: mark arena_map_mmap() mappings VM_MIXEDMAP Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 15/39] mm/vma: add vma[_flags]_is_mm_managed() predicates Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 16/39] mm/vma: only allow mmap to clear VMA_MAYWRITE_BIT if not mm-managed Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 17/39] mm/vma: add and use vma_[flags]_is_fixed_mapping Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 18/39] scsi: sg: convert mmap hook to mmap_prepare and rework Lorenzo Stoakes (ARM)
2026-10-13 15:04 ` [PATCH v6 19/39] fbdev: defio: assert FBINFO_VIRTFB, drop VM_IO, add VM_MIXEDMAP Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 20/39] HSI: cmt_speech: convert mmap hook to mmap_prepare, refactor Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 21/39] mm/gup: error out early on !VMA_MAYREAD_BIT VMAs Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 22/39] uprobes: remove VM_IO, set VM_MIXEDMAP for mapped kernel pages Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 23/39] mm/mlock: clear VMA_LOCKED_MASK over mmap callback Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 24/39] mm/mlock: eliminate weird VMA_IO_BIT abuse and simplify Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 25/39] mm/vma: enforce that mm-managed mappings may not set VMA_IO_BIT Lorenzo Stoakes (ARM)
2026-10-13 15:26   ` David Hildenbrand (Arm)
2026-10-13 15:05 ` [PATCH v6 26/39] mm: remove VMA_IO_BIT check in vma[_flags]_is_mm_managed() Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 27/39] mm: remove hugetlb_inline.h Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 28/39] mm: rename is_vm_hugetlb_page() to vma_is_hugetlb() Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 29/39] mm: drop some redundant checks around hugetlb VMAs Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 30/39] mm/vma: introduce vma[_flags]_is_mm_backed() Lorenzo Stoakes (ARM)
2026-10-13 15:31   ` David Hildenbrand (Arm)
2026-10-13 15:05 ` [PATCH v6 31/39] mm/madvise: update is_valid_guard_vma() to use vma_is_mm_backed() Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 32/39] mm/uffd: use predicates for userfaultfd checks Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 33/39] mm/madvise: use predicates for madvise(..., MADV_DOFORK) Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 34/39] mm: eliminate VMA_SPECIAL_FLAGS usage when hugetlb explicitly tested Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 35/39] mm: eliminate VMA_SPECIAL_FLAGS check in lru_gen_look_around() Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 36/39] mm: avoid use of VMA_SPECIAL_FLAGS in migrate_vma_setup() Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 37/39] mm: eliminate VM_SPECIAL, VMA_SPECIAL_FLAGS Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 38/39] fuse: dax: do not set VM_MIXEDMAP Lorenzo Stoakes (ARM)
2026-10-13 15:05 ` [PATCH v6 39/39] mm/huge_memory: remove vma_is_special_huge() Lorenzo Stoakes (ARM)
2026-10-13 18:50 ` Andrew Morton [this message]

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=20261013115040.1583b1d8e85c4b5d65a1ae0e@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=acme@kernel.org \
    --cc=agordeev@linux.ibm.com \
    --cc=airlied@gmail.com \
    --cc=andreas@gaisler.com \
    --cc=andrii@kernel.org \
    --cc=aneesh.kumar@kernel.org \
    --cc=anup@brainfault.org \
    --cc=aou@eecs.berkeley.edu \
    --cc=apopple@nvidia.com \
    --cc=arnd@arndb.de \
    --cc=ast@kernel.org \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=baoquan.he@linux.dev \
    --cc=borntraeger@linux.ibm.com \
    --cc=bp@alien8.de \
    --cc=bpf@vger.kernel.org \
    --cc=brauner@kernel.org \
    --cc=byungchul@sk.com \
    --cc=catalin.marinas@arm.com \
    --cc=chengming.zhou@linux.dev \
    --cc=chrisl@kernel.org \
    --cc=corbet@lwn.net \
    --cc=daniel@iogearbox.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=davem@davemloft.net \
    --cc=david@kernel.org \
    --cc=deller@gmx.de \
    --cc=dennis.dalessandro@cornelisnetworks.com \
    --cc=dev.jain@arm.com \
    --cc=dgilbert@interlog.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=frankja@linux.ibm.com \
    --cc=fuse-devel@lists.linux.dev \
    --cc=gerald.schaefer@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=gourry@gourry.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=hannes@cmpxchg.org \
    --cc=harry@kernel.org \
    --cc=hca@linux.ibm.com \
    --cc=ihor.solodrai@linux.dev \
    --cc=imbrenda@linux.ibm.com \
    --cc=jack@suse.cz \
    --cc=jannh@google.com \
    --cc=jgg@ziepe.ca \
    --cc=jhubbard@nvidia.com \
    --cc=joshua.hahnjy@gmail.com \
    --cc=juri.lelli@redhat.com \
    --cc=kas@kernel.org \
    --cc=kasong@tencent.com \
    --cc=kvm-riscv@lists.infradead.org \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=lance.yang@linux.dev \
    --cc=leon@kernel.org \
    --cc=liam@infradead.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=ljs@kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=maddy@linux.ibm.com \
    --cc=mark.rutland@arm.com \
    --cc=matthew.brost@intel.com \
    --cc=maz@kernel.org \
    --cc=memxor@gmail.com \
    --cc=mhiramat@kernel.org \
    --cc=mhocko@kernel.org \
    --cc=mhocko@suse.com \
    --cc=miklos@szeredi.hu \
    --cc=mingo@redhat.com \
    --cc=mkp@kernel.org \
    --cc=mripard@kernel.org \
    --cc=muchun.song@linux.dev \
    --cc=namhyung@kernel.org \
    --cc=nico.pache@linux.dev \
    --cc=nphamcs@gmail.com \
    --cc=npiggin@gmail.com \
    --cc=oleg@redhat.com \
    --cc=osalvador@suse.de \
    --cc=oupton@kernel.org \
    --cc=palmer@dabbelt.com \
    --cc=paul@paul-moore.com \
    --cc=perex@perex.cz \
    --cc=peterx@redhat.com \
    --cc=peterz@infradead.org \
    --cc=pfalcato@suse.de \
    --cc=pjw@kernel.org \
    --cc=qi.zheng@linux.dev \
    --cc=rakie.kim@sk.com \
    --cc=riel@surriel.com \
    --cc=rppt@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=selinux@vger.kernel.org \
    --cc=shakeel.butt@linux.dev \
    --cc=shikemeng@huaweicloud.com \
    --cc=simona@ffwll.ch \
    --cc=sparclinux@vger.kernel.org \
    --cc=spasswolf@web.de \
    --cc=sre@kernel.org \
    --cc=stephen.smalley.work@gmail.com \
    --cc=surenb@google.com \
    --cc=tglx@kernel.org \
    --cc=tiwai@suse.com \
    --cc=tiwai@suse.de \
    --cc=tzimmermann@suse.de \
    --cc=usama.arif@linux.dev \
    --cc=vbabka@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=weixugc@google.com \
    --cc=will@kernel.org \
    --cc=willy@infradead.org \
    --cc=x86@kernel.org \
    --cc=xu.xin@linux.dev \
    --cc=ying.huang@linux.alibaba.com \
    --cc=youngjun.park@lge.com \
    --cc=yuanchu@google.com \
    --cc=ziy@nvidia.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox