* [PATCH v2 0/4] initial work on making VMA flags a bitmap
@ 2025-11-14 13:26 Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 1/4] mm: declare VMA flags by bit Lorenzo Stoakes
` (4 more replies)
0 siblings, 5 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-14 13:26 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
We are in the rather silly situation that we are running out of VMA flags
as they are currently limited to a system word in size.
This leads to absurd situations where we limit features to 64-bit
architectures only because we simply do not have the ability to add a flag
for 32-bit ones.
This is very constraining and leads to hacks or, in the worst case, simply
an inability to implement features we want for entirely arbitrary reasons.
This also of course gives us something of a Y2K type situation in mm where
we might eventually exhaust all of the VMA flags even on 64-bit systems.
This series lays the groundwork for getting away from this limitation by
establishing VMA flags as a bitmap whose size we can increase in future
beyond 64 bits if required.
This is necessarily a highly iterative process given the extensive use of
VMA flags throughout the kernel, so we start by performing basic steps.
Firstly, we declare VMA flags by bit number rather than by value, retaining
the VM_xxx fields but in terms of these newly introduced VMA_xxx_BIT
fields.
While we are here, we use sparse annotations to ensure that, when dealing
with VMA bit number parameters, we cannot be passed values which are not
declared as such - providing some useful type safety.
We then introduce an opaque VMA flag type, much like the opaque mm_struct
flag type introduced in commit bb6525f2f8c4 ("mm: add bitmap mm->flags
field"), which we establish in union with vma->vm_flags (but still set at
system word size meaning there is no functional or data type size change).
We update the vm_flags_xxx() helpers to use this new bitmap, introducing
sensible helpers to do so.
This series lays the foundation for further work to expand the use of
bitmap VMA flags and eventually eliminate these arbitrary restrictions.
v2:
* Corrected kdoc for vma_flag_t.
* Introduced DECLARE_VMA_BIT() as per Jason. We can't also declare the VMA
flags in the enum as this breaks assumptions in the kernel, resulting in
errors like 'enum constant in boolean context
[-Werror=int-in-bool-context]'.
* Dropped the conversion patch - To make life simpler this cycle, let's just
fixup the flag declarations and introduce the new field type and introduce
vm_flags_*() changes. We can do more later.
* Split out VMA testing vma->__vm_flags change.
* Fixed vma_flag_*_atomic() helper functions for sparse purposes to work
with vma_flag_t.
* Fixed rust breakages as reported by Nico and help provided by Alice. For
now we are doing a minimal fix, we can do a more substantial one once the
VMA flag helper functions are introduced in an upcoming series.
v1:
https://lore.kernel.org/all/cover.1761757731.git.lorenzo.stoakes@oracle.com/
Lorenzo Stoakes (4):
mm: declare VMA flags by bit
mm: simplify and rename mm flags function for clarity
tools/testing/vma: eliminate dependency on vma->__vm_flags
mm: introduce VMA flags bitmap type
fs/proc/task_mmu.c | 4 +-
include/linux/mm.h | 400 +++++++++++++++------------
include/linux/mm_types.h | 78 +++++-
kernel/fork.c | 4 +-
mm/khugepaged.c | 2 +-
mm/madvise.c | 2 +-
rust/bindings/bindings_helper.h | 25 ++
rust/kernel/mm/virt.rs | 2 +-
tools/testing/vma/vma.c | 20 +-
tools/testing/vma/vma_internal.h | 446 ++++++++++++++++++++++++++-----
10 files changed, 716 insertions(+), 267 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 1/4] mm: declare VMA flags by bit
2025-11-14 13:26 [PATCH v2 0/4] initial work on making VMA flags a bitmap Lorenzo Stoakes
@ 2025-11-14 13:26 ` Lorenzo Stoakes
2025-11-14 13:50 ` Alice Ryhl
` (3 more replies)
2025-11-14 13:26 ` [PATCH v2 2/4] mm: simplify and rename mm flags function for clarity Lorenzo Stoakes
` (3 subsequent siblings)
4 siblings, 4 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-14 13:26 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
In order to lay the groundwork for VMA flags being a bitmap rather than a
system word in size, we need to be able to consistently refer to VMA flags
by bit number rather than value.
Take this opportunity to do so in an enum which we which is additionally
useful for tooling to extract metadata from.
This additionally makes it very clear which bits are being used for what at
a glance.
We use the VMA_ prefix for the bit values as it is logical to do so since
these reference VMAs. We consistently suffix with _BIT to make it clear
what the values refer to.
We declare bit values even when the flags that use them would not be enabled by
config options as this is simply clearer and clearly defines what bit
numbers are used for what, at no additional cost.
We declare a sparse-bitwise type vma_flag_t which ensures that users can't
pass around invalid VMA flags by accident and prepares for future work
towards VMA flags being a bitmap where we want to ensure bit values are
type safe.
To make life easier, we declare some macro helpers - DECLARE_VMA_BIT()
allows us to avoid duplication in the enum bit number declarations (and
maintaining the sparse __bitwise attribute), and INIT_VM_FLAG() is used to
assist with declaration of flags.
Unfortunately we can't declare both in the enum, as we run into issue with
logic in the kernel requiring that flags are preprocessor definitions, and
additionally we cannot have a macro which declares another macro so we must
define each flag macro directly.
Additionally, update the VMA userland testing vma_internal.h header to
include these changes.
We also have to fix the parameters to the vma_flag_*_atomic() functions
since VMA_MAYBE_GUARD_BIT is now of type vma_flag_t and sparse will
complain otherwise.
We have to update some rather silly if-deffery found in mm/task_mmu.c which
would otherwise break.
Finally, we update the rust binding helper as now it cannot auto-detect the
flags at all.
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
fs/proc/task_mmu.c | 4 +-
include/linux/mm.h | 384 +++++++++++++++++--------------
mm/khugepaged.c | 2 +-
mm/madvise.c | 2 +-
rust/bindings/bindings_helper.h | 25 ++
tools/testing/vma/vma_internal.h | 303 ++++++++++++++++++++----
6 files changed, 504 insertions(+), 216 deletions(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 41b062ce6ad8..720d70623209 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -1183,10 +1183,10 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
[ilog2(VM_PKEY_BIT0)] = "",
[ilog2(VM_PKEY_BIT1)] = "",
[ilog2(VM_PKEY_BIT2)] = "",
-#if VM_PKEY_BIT3
+#if CONFIG_ARCH_PKEY_BITS > 3
[ilog2(VM_PKEY_BIT3)] = "",
#endif
-#if VM_PKEY_BIT4
+#if CONFIG_ARCH_PKEY_BITS > 4
[ilog2(VM_PKEY_BIT4)] = "",
#endif
#endif /* CONFIG_ARCH_HAS_PKEYS */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 43eec43da66a..ad000c472bd5 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -271,185 +271,238 @@ extern struct rw_semaphore nommu_region_sem;
extern unsigned int kobjsize(const void *objp);
#endif
-#define VM_MAYBE_GUARD_BIT 11
-
/*
* vm_flags in vm_area_struct, see mm_types.h.
* When changing, update also include/trace/events/mmflags.h
*/
-#define VM_NONE 0x00000000
-#define VM_READ 0x00000001 /* currently active flags */
-#define VM_WRITE 0x00000002
-#define VM_EXEC 0x00000004
-#define VM_SHARED 0x00000008
+#define VM_NONE 0x00000000
-/* mprotect() hardcodes VM_MAYREAD >> 4 == VM_READ, and so for r/w/x bits. */
-#define VM_MAYREAD 0x00000010 /* limits for mprotect() etc */
-#define VM_MAYWRITE 0x00000020
-#define VM_MAYEXEC 0x00000040
-#define VM_MAYSHARE 0x00000080
+/**
+ * typedef vma_flag_t - specifies an individual VMA flag by bit number.
+ *
+ * This value is made type safe by sparse to avoid passing invalid flag values
+ * around.
+ */
+typedef int __bitwise vma_flag_t;
-#define VM_GROWSDOWN 0x00000100 /* general info on the segment */
+#define DECLARE_VMA_BIT(name, bitnum) \
+ VMA_ ## name ## _BIT = ((__force vma_flag_t)bitnum)
+#define DECLARE_VMA_BIT_ALIAS(name, aliased) \
+ VMA_ ## name ## _BIT = (VMA_ ## aliased ## _BIT)
+enum {
+ DECLARE_VMA_BIT(READ, 0),
+ DECLARE_VMA_BIT(WRITE, 1),
+ DECLARE_VMA_BIT(EXEC, 2),
+ DECLARE_VMA_BIT(SHARED, 3),
+ /* mprotect() hardcodes VM_MAYREAD >> 4 == VM_READ, and so for r/w/x bits. */
+ DECLARE_VMA_BIT(MAYREAD, 4), /* limits for mprotect() etc. */
+ DECLARE_VMA_BIT(MAYWRITE, 5),
+ DECLARE_VMA_BIT(MAYEXEC, 6),
+ DECLARE_VMA_BIT(MAYSHARE, 7),
+ DECLARE_VMA_BIT(GROWSDOWN, 8), /* general info on the segment */
#ifdef CONFIG_MMU
-#define VM_UFFD_MISSING 0x00000200 /* missing pages tracking */
-#else /* CONFIG_MMU */
-#define VM_MAYOVERLAY 0x00000200 /* nommu: R/O MAP_PRIVATE mapping that might overlay a file mapping */
-#define VM_UFFD_MISSING 0
+ DECLARE_VMA_BIT(UFFD_MISSING, 9),/* missing pages tracking */
+#else
+ /* nommu: R/O MAP_PRIVATE mapping that might overlay a file mapping */
+ DECLARE_VMA_BIT(MAYOVERLAY, 9),
#endif /* CONFIG_MMU */
-#define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */
-#define VM_MAYBE_GUARD BIT(VM_MAYBE_GUARD_BIT) /* The VMA maybe contains guard regions. */
-#define VM_UFFD_WP 0x00001000 /* wrprotect pages tracking */
-
-#define VM_LOCKED 0x00002000
-#define VM_IO 0x00004000 /* Memory mapped I/O or similar */
-
- /* Used by sys_madvise() */
-#define VM_SEQ_READ 0x00008000 /* App will access data sequentially */
-#define VM_RAND_READ 0x00010000 /* App will not benefit from clustered reads */
-
-#define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
-#define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
-#define VM_LOCKONFAULT 0x00080000 /* Lock the pages covered when they are faulted in */
-#define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */
-#define VM_NORESERVE 0x00200000 /* should the VM suppress accounting */
-#define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */
-#define VM_SYNC 0x00800000 /* Synchronous page faults */
-#define VM_ARCH_1 0x01000000 /* Architecture-specific flag */
-#define VM_WIPEONFORK 0x02000000 /* Wipe VMA contents in child. */
-#define VM_DONTDUMP 0x04000000 /* Do not include in the core dump */
-
+ /* Page-ranges managed without "struct page", just pure PFN */
+ DECLARE_VMA_BIT(PFNMAP, 10),
+ DECLARE_VMA_BIT(MAYBE_GUARD, 11),
+ DECLARE_VMA_BIT(UFFD_WP, 12), /* wrprotect pages tracking */
+ DECLARE_VMA_BIT(LOCKED, 13),
+ DECLARE_VMA_BIT(IO, 14), /* Memory mapped I/O or similar */
+ DECLARE_VMA_BIT(SEQ_READ, 15), /* App will access data sequentially */
+ DECLARE_VMA_BIT(RAND_READ, 16), /* App will not benefit from clustered reads */
+ DECLARE_VMA_BIT(DONTCOPY, 17), /* Do not copy this vma on fork */
+ DECLARE_VMA_BIT(DONTEXPAND, 18),/* Cannot expand with mremap() */
+ DECLARE_VMA_BIT(LOCKONFAULT, 19),/* Lock pages covered when faulted in */
+ DECLARE_VMA_BIT(ACCOUNT, 20), /* Is a VM accounted object */
+ DECLARE_VMA_BIT(NORESERVE, 21), /* should the VM suppress accounting */
+ DECLARE_VMA_BIT(HUGETLB, 22), /* Huge TLB Page VM */
+ DECLARE_VMA_BIT(SYNC, 23), /* Synchronous page faults */
+ DECLARE_VMA_BIT(ARCH_1, 24), /* Architecture-specific flag */
+ DECLARE_VMA_BIT(WIPEONFORK, 25),/* Wipe VMA contents in child. */
+ DECLARE_VMA_BIT(DONTDUMP, 26), /* Do not include in the core dump */
+ DECLARE_VMA_BIT(SOFTDIRTY, 27), /* NOT soft dirty clean area */
+ DECLARE_VMA_BIT(MIXEDMAP, 28), /* Can contain struct page and pure PFN pages */
+ DECLARE_VMA_BIT(HUGEPAGE, 29), /* MADV_HUGEPAGE marked this vma */
+ DECLARE_VMA_BIT(NOHUGEPAGE, 30),/* MADV_NOHUGEPAGE marked this vma */
+ DECLARE_VMA_BIT(MERGEABLE, 31), /* KSM may merge identical pages */
+ /* These bits are reused, we define specific uses below. */
+ DECLARE_VMA_BIT(HIGH_ARCH_0, 32),
+ DECLARE_VMA_BIT(HIGH_ARCH_1, 33),
+ DECLARE_VMA_BIT(HIGH_ARCH_2, 34),
+ DECLARE_VMA_BIT(HIGH_ARCH_3, 35),
+ DECLARE_VMA_BIT(HIGH_ARCH_4, 36),
+ DECLARE_VMA_BIT(HIGH_ARCH_5, 37),
+ DECLARE_VMA_BIT(HIGH_ARCH_6, 38),
+ /*
+ * This flag is used to connect VFIO to arch specific KVM code. It
+ * indicates that the memory under this VMA is safe for use with any
+ * non-cachable memory type inside KVM. Some VFIO devices, on some
+ * platforms, are thought to be unsafe and can cause machine crashes
+ * if KVM does not lock down the memory type.
+ */
+ DECLARE_VMA_BIT(ALLOW_ANY_UNCACHED, 39),
+#ifdef CONFIG_PPC32
+ DECLARE_VMA_BIT_ALIAS(DROPPABLE, ARCH_1),
+#else
+ DECLARE_VMA_BIT(DROPPABLE, 40),
+#endif
+ DECLARE_VMA_BIT(UFFD_MINOR, 41),
+ DECLARE_VMA_BIT(SEALED, 42),
+ /* Flags that reuse flags above. */
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT0, HIGH_ARCH_0),
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT1, HIGH_ARCH_1),
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT2, HIGH_ARCH_2),
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT3, HIGH_ARCH_3),
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT4, HIGH_ARCH_4),
+#if defined(CONFIG_X86_USER_SHADOW_STACK)
+ /*
+ * VM_SHADOW_STACK should not be set with VM_SHARED because of lack of
+ * support core mm.
+ *
+ * These VMAs will get a single end guard page. This helps userspace
+ * protect itself from attacks. A single page is enough for current
+ * shadow stack archs (x86). See the comments near alloc_shstk() in
+ * arch/x86/kernel/shstk.c for more details on the guard size.
+ */
+ DECLARE_VMA_BIT_ALIAS(SHADOW_STACK, HIGH_ARCH_5),
+#elif defined(CONFIG_ARM64_GCS)
+ /*
+ * arm64's Guarded Control Stack implements similar functionality and
+ * has similar constraints to shadow stacks.
+ */
+ DECLARE_VMA_BIT_ALIAS(SHADOW_STACK, HIGH_ARCH_6),
+#endif
+ DECLARE_VMA_BIT_ALIAS(SAO, ARCH_1), /* Strong Access Ordering (powerpc) */
+ DECLARE_VMA_BIT_ALIAS(GROWSUP, ARCH_1), /* parisc */
+ DECLARE_VMA_BIT_ALIAS(SPARC_ADI, ARCH_1), /* sparc64 */
+ DECLARE_VMA_BIT_ALIAS(ARM64_BTI, ARCH_1), /* arm64 */
+ DECLARE_VMA_BIT_ALIAS(ARCH_CLEAR, ARCH_1), /* sparc64, arm64 */
+ DECLARE_VMA_BIT_ALIAS(MAPPED_COPY, ARCH_1), /* !CONFIG_MMU */
+ DECLARE_VMA_BIT_ALIAS(MTE, HIGH_ARCH_4), /* arm64 */
+ DECLARE_VMA_BIT_ALIAS(MTE_ALLOWED, HIGH_ARCH_5),/* arm64 */
+#ifdef CONFIG_STACK_GROWSUP
+ DECLARE_VMA_BIT_ALIAS(STACK, GROWSUP),
+ DECLARE_VMA_BIT_ALIAS(STACK_EARLY, GROWSDOWN),
+#else
+ DECLARE_VMA_BIT_ALIAS(STACK, GROWSDOWN),
+#endif
+};
+#undef DECLARE_VMA_BIT
+#undef DECLARE_VMA_BIT_ALIAS
+
+#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
+#define VM_READ INIT_VM_FLAG(READ)
+#define VM_WRITE INIT_VM_FLAG(WRITE)
+#define VM_EXEC INIT_VM_FLAG(EXEC)
+#define VM_SHARED INIT_VM_FLAG(SHARED)
+#define VM_MAYREAD INIT_VM_FLAG(MAYREAD)
+#define VM_MAYWRITE INIT_VM_FLAG(MAYWRITE)
+#define VM_MAYEXEC INIT_VM_FLAG(MAYEXEC)
+#define VM_MAYSHARE INIT_VM_FLAG(MAYSHARE)
+#define VM_GROWSDOWN INIT_VM_FLAG(GROWSDOWN)
+#ifdef CONFIG_MMU
+#define VM_UFFD_MISSING INIT_VM_FLAG(UFFD_MISSING)
+#else
+#define VM_UFFD_MISSING VM_NONE
+#endif
+#define VM_PFNMAP INIT_VM_FLAG(PFNMAP)
+#define VM_MAYBE_GUARD INIT_VM_FLAG(MAYBE_GUARD)
+#define VM_UFFD_WP INIT_VM_FLAG(UFFD_WP)
+#define VM_LOCKED INIT_VM_FLAG(LOCKED)
+#define VM_IO INIT_VM_FLAG(IO)
+#define VM_SEQ_READ INIT_VM_FLAG(SEQ_READ)
+#define VM_RAND_READ INIT_VM_FLAG(RAND_READ)
+#define VM_DONTCOPY INIT_VM_FLAG(DONTCOPY)
+#define VM_DONTEXPAND INIT_VM_FLAG(DONTEXPAND)
+#define VM_LOCKONFAULT INIT_VM_FLAG(LOCKONFAULT)
+#define VM_ACCOUNT INIT_VM_FLAG(ACCOUNT)
+#define VM_NORESERVE INIT_VM_FLAG(NORESERVE)
+#define VM_HUGETLB INIT_VM_FLAG(HUGETLB)
+#define VM_SYNC INIT_VM_FLAG(SYNC)
+#define VM_ARCH_1 INIT_VM_FLAG(ARCH_1)
+#define VM_WIPEONFORK INIT_VM_FLAG(WIPEONFORK)
+#define VM_DONTDUMP INIT_VM_FLAG(DONTDUMP)
#ifdef CONFIG_MEM_SOFT_DIRTY
-# define VM_SOFTDIRTY 0x08000000 /* Not soft dirty clean area */
+#define VM_SOFTDIRTY INIT_VM_FLAG(SOFTDIRTY)
#else
-# define VM_SOFTDIRTY 0
+#define VM_SOFTDIRTY VM_NONE
+#endif
+#define VM_MIXEDMAP INIT_VM_FLAG(MIXEDMAP)
+#define VM_HUGEPAGE INIT_VM_FLAG(HUGEPAGE)
+#define VM_NOHUGEPAGE INIT_VM_FLAG(NOHUGEPAGE)
+#define VM_MERGEABLE INIT_VM_FLAG(MERGEABLE)
+#define VM_STACK INIT_VM_FLAG(STACK)
+#ifdef CONFIG_STACK_GROWS_UP
+#define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY)
+#else
+#define VM_STACK_EARLY VM_NONE
#endif
-
-#define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
-#define VM_HUGEPAGE 0x20000000 /* MADV_HUGEPAGE marked this vma */
-#define VM_NOHUGEPAGE 0x40000000 /* MADV_NOHUGEPAGE marked this vma */
-#define VM_MERGEABLE BIT(31) /* KSM may merge identical pages */
-
-#ifdef CONFIG_ARCH_USES_HIGH_VMA_FLAGS
-#define VM_HIGH_ARCH_BIT_0 32 /* bit only usable on 64-bit architectures */
-#define VM_HIGH_ARCH_BIT_1 33 /* bit only usable on 64-bit architectures */
-#define VM_HIGH_ARCH_BIT_2 34 /* bit only usable on 64-bit architectures */
-#define VM_HIGH_ARCH_BIT_3 35 /* bit only usable on 64-bit architectures */
-#define VM_HIGH_ARCH_BIT_4 36 /* bit only usable on 64-bit architectures */
-#define VM_HIGH_ARCH_BIT_5 37 /* bit only usable on 64-bit architectures */
-#define VM_HIGH_ARCH_BIT_6 38 /* bit only usable on 64-bit architectures */
-#define VM_HIGH_ARCH_0 BIT(VM_HIGH_ARCH_BIT_0)
-#define VM_HIGH_ARCH_1 BIT(VM_HIGH_ARCH_BIT_1)
-#define VM_HIGH_ARCH_2 BIT(VM_HIGH_ARCH_BIT_2)
-#define VM_HIGH_ARCH_3 BIT(VM_HIGH_ARCH_BIT_3)
-#define VM_HIGH_ARCH_4 BIT(VM_HIGH_ARCH_BIT_4)
-#define VM_HIGH_ARCH_5 BIT(VM_HIGH_ARCH_BIT_5)
-#define VM_HIGH_ARCH_6 BIT(VM_HIGH_ARCH_BIT_6)
-#endif /* CONFIG_ARCH_USES_HIGH_VMA_FLAGS */
-
#ifdef CONFIG_ARCH_HAS_PKEYS
-# define VM_PKEY_SHIFT VM_HIGH_ARCH_BIT_0
-# define VM_PKEY_BIT0 VM_HIGH_ARCH_0
-# define VM_PKEY_BIT1 VM_HIGH_ARCH_1
-# define VM_PKEY_BIT2 VM_HIGH_ARCH_2
+#define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT)
+/* Despite the naming, these are FLAGS not bits. */
+#define VM_PKEY_BIT0 INIT_VM_FLAG(PKEY_BIT0)
+#define VM_PKEY_BIT1 INIT_VM_FLAG(PKEY_BIT1)
+#define VM_PKEY_BIT2 INIT_VM_FLAG(PKEY_BIT2)
#if CONFIG_ARCH_PKEY_BITS > 3
-# define VM_PKEY_BIT3 VM_HIGH_ARCH_3
+#define VM_PKEY_BIT3 INIT_VM_FLAG(PKEY_BIT3)
#else
-# define VM_PKEY_BIT3 0
-#endif
+#define VM_PKEY_BIT3 VM_NONE
+#endif /* CONFIG_ARCH_PKEY_BITS > 3 */
#if CONFIG_ARCH_PKEY_BITS > 4
-# define VM_PKEY_BIT4 VM_HIGH_ARCH_4
+#define VM_PKEY_BIT4 INIT_VM_FLAG(PKEY_BIT4)
#else
-# define VM_PKEY_BIT4 0
-#endif
+#define VM_PKEY_BIT4 VM_NONE
+#endif /* CONFIG_ARCH_PKEY_BITS > 4 */
#endif /* CONFIG_ARCH_HAS_PKEYS */
-
-#ifdef CONFIG_X86_USER_SHADOW_STACK
-/*
- * VM_SHADOW_STACK should not be set with VM_SHARED because of lack of
- * support core mm.
- *
- * These VMAs will get a single end guard page. This helps userspace protect
- * itself from attacks. A single page is enough for current shadow stack archs
- * (x86). See the comments near alloc_shstk() in arch/x86/kernel/shstk.c
- * for more details on the guard size.
- */
-# define VM_SHADOW_STACK VM_HIGH_ARCH_5
-#endif
-
-#if defined(CONFIG_ARM64_GCS)
-/*
- * arm64's Guarded Control Stack implements similar functionality and
- * has similar constraints to shadow stacks.
- */
-# define VM_SHADOW_STACK VM_HIGH_ARCH_6
-#endif
-
-#ifndef VM_SHADOW_STACK
-# define VM_SHADOW_STACK VM_NONE
+#if defined(CONFIG_X86_USER_SHADOW_STACK) || defined(CONFIG_ARM64_GCS)
+#define VM_SHADOW_STACK INIT_VM_FLAG(SHADOW_STACK)
+#else
+#define VM_SHADOW_STACK VM_NONE
#endif
-
#if defined(CONFIG_PPC64)
-# define VM_SAO VM_ARCH_1 /* Strong Access Ordering (powerpc) */
+#define VM_SAO INIT_VM_FLAG(SAO)
#elif defined(CONFIG_PARISC)
-# define VM_GROWSUP VM_ARCH_1
+#define VM_GROWSUP INIT_VM_FLAG(GROWSUP)
#elif defined(CONFIG_SPARC64)
-# define VM_SPARC_ADI VM_ARCH_1 /* Uses ADI tag for access control */
-# define VM_ARCH_CLEAR VM_SPARC_ADI
+#define VM_SPARC_ADI INIT_VM_FLAG(SPARC_ADI)
+#define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR)
#elif defined(CONFIG_ARM64)
-# define VM_ARM64_BTI VM_ARCH_1 /* BTI guarded page, a.k.a. GP bit */
-# define VM_ARCH_CLEAR VM_ARM64_BTI
+#define VM_ARM64_BTI INIT_VM_FLAG(ARM64_BTI)
+#define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR)
#elif !defined(CONFIG_MMU)
-# define VM_MAPPED_COPY VM_ARCH_1 /* T if mapped copy of data (nommu mmap) */
+#define VM_MAPPED_COPY INIT_VM_FLAG(MAPPED_COPY)
#endif
-
-#if defined(CONFIG_ARM64_MTE)
-# define VM_MTE VM_HIGH_ARCH_4 /* Use Tagged memory for access control */
-# define VM_MTE_ALLOWED VM_HIGH_ARCH_5 /* Tagged memory permitted */
-#else
-# define VM_MTE VM_NONE
-# define VM_MTE_ALLOWED VM_NONE
-#endif
-
#ifndef VM_GROWSUP
-# define VM_GROWSUP VM_NONE
+#define VM_GROWSUP VM_NONE
+#endif
+#ifdef CONFIG_ARM64_MTE
+#define VM_MTE INIT_VM_FLAG(MTE)
+#define VM_MTE_ALLOWED INIT_VM_FLAG(MTE_ALLOWED)
+#else
+#define VM_MTE VM_NONE
+#define VM_MTE_ALLOWED VM_NONE
#endif
-
#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR
-# define VM_UFFD_MINOR_BIT 41
-# define VM_UFFD_MINOR BIT(VM_UFFD_MINOR_BIT) /* UFFD minor faults */
-#else /* !CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
-# define VM_UFFD_MINOR VM_NONE
-#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
-
-/*
- * This flag is used to connect VFIO to arch specific KVM code. It
- * indicates that the memory under this VMA is safe for use with any
- * non-cachable memory type inside KVM. Some VFIO devices, on some
- * platforms, are thought to be unsafe and can cause machine crashes
- * if KVM does not lock down the memory type.
- */
-#ifdef CONFIG_64BIT
-#define VM_ALLOW_ANY_UNCACHED_BIT 39
-#define VM_ALLOW_ANY_UNCACHED BIT(VM_ALLOW_ANY_UNCACHED_BIT)
+#define VM_UFFD_MINOR INIT_VM_FLAG(UFFD_MINOR)
#else
-#define VM_ALLOW_ANY_UNCACHED VM_NONE
+#define VM_UFFD_MINOR VM_NONE
#endif
-
#ifdef CONFIG_64BIT
-#define VM_DROPPABLE_BIT 40
-#define VM_DROPPABLE BIT(VM_DROPPABLE_BIT)
-#elif defined(CONFIG_PPC32)
-#define VM_DROPPABLE VM_ARCH_1
+#define VM_ALLOW_ANY_UNCACHED INIT_VM_FLAG(ALLOW_ANY_UNCACHED)
+#define VM_SEALED INIT_VM_FLAG(SEALED)
#else
-#define VM_DROPPABLE VM_NONE
+#define VM_ALLOW_ANY_UNCACHED VM_NONE
+#define VM_SEALED VM_NONE
#endif
-
-#ifdef CONFIG_64BIT
-#define VM_SEALED_BIT 42
-#define VM_SEALED BIT(VM_SEALED_BIT)
+#if defined(CONFIG_64BIT) || defined(CONFIG_PPC32)
+#define VM_DROPPABLE INIT_VM_FLAG(DROPPABLE)
#else
-#define VM_SEALED VM_NONE
+#define VM_DROPPABLE VM_NONE
#endif
/* Bits set in the VMA until the stack is in its final location */
@@ -475,12 +528,18 @@ extern unsigned int kobjsize(const void *objp);
#define VM_STARTGAP_FLAGS (VM_GROWSDOWN | VM_SHADOW_STACK)
+
+
#ifdef CONFIG_STACK_GROWSUP
-#define VM_STACK VM_GROWSUP
-#define VM_STACK_EARLY VM_GROWSDOWN
+#define VM_STACK_EARLY VMA_BIT(VMA_STACK_EARLY_BIT)
+#else
+#define VM_STACK_EARLY VM_NONE
+#endif
+
+#ifdef CONFIG_MSEAL_SYSTEM_MAPPINGS
+#define VM_SEALED_SYSMAP VM_SEALED
#else
-#define VM_STACK VM_GROWSDOWN
-#define VM_STACK_EARLY 0
+#define VM_SEALED_SYSMAP VM_NONE
#endif
#define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
@@ -488,7 +547,6 @@ extern unsigned int kobjsize(const void *objp);
/* VMA basic access permission flags */
#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC)
-
/*
* Special vmas that are non-mergable, non-mlock()able.
*/
@@ -523,7 +581,7 @@ extern unsigned int kobjsize(const void *objp);
/* Arch-specific flags to clear when updating VM flags on protection change */
#ifndef VM_ARCH_CLEAR
-# define VM_ARCH_CLEAR VM_NONE
+#define VM_ARCH_CLEAR VM_NONE
#endif
#define VM_FLAGS_CLEAR (ARCH_VM_PKEY_FLAGS | VM_ARCH_CLEAR)
@@ -919,9 +977,9 @@ static inline void vm_flags_mod(struct vm_area_struct *vma,
}
static inline bool __vma_flag_atomic_valid(struct vm_area_struct *vma,
- int bit)
+ vma_flag_t bit)
{
- const vm_flags_t mask = BIT(bit);
+ const vm_flags_t mask = BIT((__force int)bit);
/* Only specific flags are permitted */
if (WARN_ON_ONCE(!(mask & VM_ATOMIC_SET_ALLOWED)))
@@ -934,14 +992,15 @@ static inline bool __vma_flag_atomic_valid(struct vm_area_struct *vma,
* Set VMA flag atomically. Requires only VMA/mmap read lock. Only specific
* valid flags are allowed to do this.
*/
-static inline void vma_flag_set_atomic(struct vm_area_struct *vma, int bit)
+static inline void vma_flag_set_atomic(struct vm_area_struct *vma,
+ vma_flag_t bit)
{
/* mmap read lock/VMA read lock must be held. */
if (!rwsem_is_locked(&vma->vm_mm->mmap_lock))
vma_assert_locked(vma);
if (__vma_flag_atomic_valid(vma, bit))
- set_bit(bit, &ACCESS_PRIVATE(vma, __vm_flags));
+ set_bit((__force int)bit, &ACCESS_PRIVATE(vma, __vm_flags));
}
/*
@@ -951,10 +1010,11 @@ static inline void vma_flag_set_atomic(struct vm_area_struct *vma, int bit)
* This is necessarily racey, so callers must ensure that serialisation is
* achieved through some other means, or that races are permissible.
*/
-static inline bool vma_flag_test_atomic(struct vm_area_struct *vma, int bit)
+static inline bool vma_flag_test_atomic(struct vm_area_struct *vma,
+ vma_flag_t bit)
{
if (__vma_flag_atomic_valid(vma, bit))
- return test_bit(bit, &vma->vm_flags);
+ return test_bit((__force int)bit, &vma->vm_flags);
return false;
}
@@ -4515,16 +4575,6 @@ int arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *st
int arch_set_shadow_stack_status(struct task_struct *t, unsigned long status);
int arch_lock_shadow_stack_status(struct task_struct *t, unsigned long status);
-
-/*
- * mseal of userspace process's system mappings.
- */
-#ifdef CONFIG_MSEAL_SYSTEM_MAPPINGS
-#define VM_SEALED_SYSMAP VM_SEALED
-#else
-#define VM_SEALED_SYSMAP VM_NONE
-#endif
-
/*
* DMA mapping IDs for page_pool
*
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 7e8cb181d5bd..746cb16f6466 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1742,7 +1742,7 @@ static bool file_backed_vma_is_retractable(struct vm_area_struct *vma)
* obtained on guard region installation after the flag is set, so this
* check being performed under this lock excludes races.
*/
- if (vma_flag_test_atomic(vma, VM_MAYBE_GUARD_BIT))
+ if (vma_flag_test_atomic(vma, VMA_MAYBE_GUARD_BIT))
return false;
return true;
diff --git a/mm/madvise.c b/mm/madvise.c
index 52a10ed80c07..84fc0e63011f 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -1142,7 +1142,7 @@ static long madvise_guard_install(struct madvise_behavior *madv_behavior)
* acquire an mmap/VMA write lock to read it. All remaining readers may
* or may not see the flag set, but we don't care.
*/
- vma_flag_set_atomic(vma, VM_MAYBE_GUARD_BIT);
+ vma_flag_set_atomic(vma, VMA_MAYBE_GUARD_BIT);
/*
* If anonymous and we are establishing page tables the VMA ought to
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 2e43c66635a2..4c327db01ca0 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -108,7 +108,32 @@ const xa_mark_t RUST_CONST_HELPER_XA_PRESENT = XA_PRESENT;
const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC = XA_FLAGS_ALLOC;
const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC1 = XA_FLAGS_ALLOC1;
+
const vm_flags_t RUST_CONST_HELPER_VM_MERGEABLE = VM_MERGEABLE;
+const vm_flags_t RUST_CONST_HELPER_VM_READ = VM_READ;
+const vm_flags_t RUST_CONST_HELPER_VM_WRITE = VM_WRITE;
+const vm_flags_t RUST_CONST_HELPER_VM_EXEC = VM_EXEC;
+const vm_flags_t RUST_CONST_HELPER_VM_SHARED = VM_SHARED;
+const vm_flags_t RUST_CONST_HELPER_VM_MAYREAD = VM_MAYREAD;
+const vm_flags_t RUST_CONST_HELPER_VM_MAYWRITE = VM_MAYWRITE;
+const vm_flags_t RUST_CONST_HELPER_VM_MAYEXEC = VM_MAYEXEC;
+const vm_flags_t RUST_CONST_HELPER_VM_MAYSHARE = VM_MAYEXEC;
+const vm_flags_t RUST_CONST_HELPER_VM_PFNMAP = VM_PFNMAP;
+const vm_flags_t RUST_CONST_HELPER_VM_IO = VM_IO;
+const vm_flags_t RUST_CONST_HELPER_VM_DONTCOPY = VM_DONTCOPY;
+const vm_flags_t RUST_CONST_HELPER_VM_DONTEXPAND = VM_DONTEXPAND;
+const vm_flags_t RUST_CONST_HELPER_VM_LOCKONFAULT = VM_LOCKONFAULT;
+const vm_flags_t RUST_CONST_HELPER_VM_ACCOUNT = VM_ACCOUNT;
+const vm_flags_t RUST_CONST_HELPER_VM_NORESERVE = VM_NORESERVE;
+const vm_flags_t RUST_CONST_HELPER_VM_HUGETLB = VM_HUGETLB;
+const vm_flags_t RUST_CONST_HELPER_VM_SYNC = VM_SYNC;
+const vm_flags_t RUST_CONST_HELPER_VM_ARCH_1 = VM_ARCH_1;
+const vm_flags_t RUST_CONST_HELPER_VM_WIPEONFORK = VM_WIPEONFORK;
+const vm_flags_t RUST_CONST_HELPER_VM_DONTDUMP = VM_DONTDUMP;
+const vm_flags_t RUST_CONST_HELPER_VM_SOFTDIRTY = VM_SOFTDIRTY;
+const vm_flags_t RUST_CONST_HELPER_VM_MIXEDMAP = VM_MIXEDMAP;
+const vm_flags_t RUST_CONST_HELPER_VM_HUGEPAGE = VM_HUGEPAGE;
+const vm_flags_t RUST_CONST_HELPER_VM_NOHUGEPAGE = VM_NOHUGEPAGE;
#if IS_ENABLED(CONFIG_ANDROID_BINDER_IPC_RUST)
#include "../../drivers/android/binder/rust_binder.h"
diff --git a/tools/testing/vma/vma_internal.h b/tools/testing/vma/vma_internal.h
index bd6352a5f24d..18659214e262 100644
--- a/tools/testing/vma/vma_internal.h
+++ b/tools/testing/vma/vma_internal.h
@@ -46,42 +46,270 @@ extern unsigned long dac_mmap_min_addr;
#define MMF_HAS_MDWE 28
+/*
+ * vm_flags in vm_area_struct, see mm_types.h.
+ * When changing, update also include/trace/events/mmflags.h
+ */
+
#define VM_NONE 0x00000000
-#define VM_READ 0x00000001
-#define VM_WRITE 0x00000002
-#define VM_EXEC 0x00000004
-#define VM_SHARED 0x00000008
-#define VM_MAYREAD 0x00000010
-#define VM_MAYWRITE 0x00000020
-#define VM_MAYEXEC 0x00000040
-#define VM_GROWSDOWN 0x00000100
-#define VM_PFNMAP 0x00000400
-#define VM_MAYBE_GUARD 0x00000800
-#define VM_LOCKED 0x00002000
-#define VM_IO 0x00004000
-#define VM_SEQ_READ 0x00008000 /* App will access data sequentially */
-#define VM_RAND_READ 0x00010000 /* App will not benefit from clustered reads */
-#define VM_DONTEXPAND 0x00040000
-#define VM_LOCKONFAULT 0x00080000
-#define VM_ACCOUNT 0x00100000
-#define VM_NORESERVE 0x00200000
-#define VM_MIXEDMAP 0x10000000
-#define VM_STACK VM_GROWSDOWN
-#define VM_SHADOW_STACK VM_NONE
-#define VM_SOFTDIRTY 0
-#define VM_ARCH_1 0x01000000 /* Architecture-specific flag */
-#define VM_GROWSUP VM_NONE
-#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC)
-#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP)
+/**
+ * typedef vma_flag_t - specifies an individual VMA flag by bit number.
+ *
+ * This value is made type safe by sparse to avoid passing invalid flag values
+ * around.
+ */
+typedef int __bitwise vma_flag_t;
+#define DECLARE_VMA_BIT(name, bitnum) \
+ VMA_ ## name ## _BIT = ((__force vma_flag_t)bitnum)
+#define DECLARE_VMA_BIT_ALIAS(name, aliased) \
+ VMA_ ## name ## _BIT = VMA_ ## aliased ## _BIT
+enum {
+ DECLARE_VMA_BIT(READ, 0),
+ DECLARE_VMA_BIT(WRITE, 1),
+ DECLARE_VMA_BIT(EXEC, 2),
+ DECLARE_VMA_BIT(SHARED, 3),
+ /* mprotect() hardcodes VM_MAYREAD >> 4 == VM_READ, and so for r/w/x bits. */
+ DECLARE_VMA_BIT(MAYREAD, 4), /* limits for mprotect() etc. */
+ DECLARE_VMA_BIT(MAYWRITE, 5),
+ DECLARE_VMA_BIT(MAYEXEC, 6),
+ DECLARE_VMA_BIT(MAYSHARE, 7),
+ DECLARE_VMA_BIT(GROWSDOWN, 8), /* general info on the segment */
+#ifdef CONFIG_MMU
+ DECLARE_VMA_BIT(UFFD_MISSING, 9),/* missing pages tracking */
+#else
+ /* nommu: R/O MAP_PRIVATE mapping that might overlay a file mapping */
+ DECLARE_VMA_BIT(MAYOVERLAY, 9),
+#endif /* CONFIG_MMU */
+ /* Page-ranges managed without "struct page", just pure PFN */
+ DECLARE_VMA_BIT(PFNMAP, 10),
+ DECLARE_VMA_BIT(MAYBE_GUARD, 11),
+ DECLARE_VMA_BIT(UFFD_WP, 12), /* wrprotect pages tracking */
+ DECLARE_VMA_BIT(LOCKED, 13),
+ DECLARE_VMA_BIT(IO, 14), /* Memory mapped I/O or similar */
+ DECLARE_VMA_BIT(SEQ_READ, 15), /* App will access data sequentially */
+ DECLARE_VMA_BIT(RAND_READ, 16), /* App will not benefit from clustered reads */
+ DECLARE_VMA_BIT(DONTCOPY, 17), /* Do not copy this vma on fork */
+ DECLARE_VMA_BIT(DONTEXPAND, 18),/* Cannot expand with mremap() */
+ DECLARE_VMA_BIT(LOCKONFAULT, 19),/* Lock pages covered when faulted in */
+ DECLARE_VMA_BIT(ACCOUNT, 20), /* Is a VM accounted object */
+ DECLARE_VMA_BIT(NORESERVE, 21), /* should the VM suppress accounting */
+ DECLARE_VMA_BIT(HUGETLB, 22), /* Huge TLB Page VM */
+ DECLARE_VMA_BIT(SYNC, 23), /* Synchronous page faults */
+ DECLARE_VMA_BIT(ARCH_1, 24), /* Architecture-specific flag */
+ DECLARE_VMA_BIT(WIPEONFORK, 25),/* Wipe VMA contents in child. */
+ DECLARE_VMA_BIT(DONTDUMP, 26), /* Do not include in the core dump */
+ DECLARE_VMA_BIT(SOFTDIRTY, 27), /* NOT soft dirty clean area */
+ DECLARE_VMA_BIT(MIXEDMAP, 28), /* Can contain struct page and pure PFN pages */
+ DECLARE_VMA_BIT(HUGEPAGE, 29), /* MADV_HUGEPAGE marked this vma */
+ DECLARE_VMA_BIT(NOHUGEPAGE, 30),/* MADV_NOHUGEPAGE marked this vma */
+ DECLARE_VMA_BIT(MERGEABLE, 31), /* KSM may merge identical pages */
+ /* These bits are reused, we define specific uses below. */
+ DECLARE_VMA_BIT(HIGH_ARCH_0, 32),
+ DECLARE_VMA_BIT(HIGH_ARCH_1, 33),
+ DECLARE_VMA_BIT(HIGH_ARCH_2, 34),
+ DECLARE_VMA_BIT(HIGH_ARCH_3, 35),
+ DECLARE_VMA_BIT(HIGH_ARCH_4, 36),
+ DECLARE_VMA_BIT(HIGH_ARCH_5, 37),
+ DECLARE_VMA_BIT(HIGH_ARCH_6, 38),
+ /*
+ * This flag is used to connect VFIO to arch specific KVM code. It
+ * indicates that the memory under this VMA is safe for use with any
+ * non-cachable memory type inside KVM. Some VFIO devices, on some
+ * platforms, are thought to be unsafe and can cause machine crashes
+ * if KVM does not lock down the memory type.
+ */
+ DECLARE_VMA_BIT(ALLOW_ANY_UNCACHED, 39),
+#ifdef CONFIG_PPC32
+ DECLARE_VMA_BIT_ALIAS(DROPPABLE, ARCH_1),
+#else
+ DECLARE_VMA_BIT(DROPPABLE, 40),
+#endif
+ DECLARE_VMA_BIT(UFFD_MINOR, 41),
+ DECLARE_VMA_BIT(SEALED, 42),
+ /* Flags that reuse flags above. */
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT0, HIGH_ARCH_0),
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT1, HIGH_ARCH_1),
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT2, HIGH_ARCH_2),
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT3, HIGH_ARCH_3),
+ DECLARE_VMA_BIT_ALIAS(PKEY_BIT4, HIGH_ARCH_4),
+#if defined(CONFIG_X86_USER_SHADOW_STACK)
+ /*
+ * VM_SHADOW_STACK should not be set with VM_SHARED because of lack of
+ * support core mm.
+ *
+ * These VMAs will get a single end guard page. This helps userspace
+ * protect itself from attacks. A single page is enough for current
+ * shadow stack archs (x86). See the comments near alloc_shstk() in
+ * arch/x86/kernel/shstk.c for more details on the guard size.
+ */
+ DECLARE_VMA_BIT_ALIAS(SHADOW_STACK, HIGH_ARCH_5),
+#elif defined(CONFIG_ARM64_GCS)
+ /*
+ * arm64's Guarded Control Stack implements similar functionality and
+ * has similar constraints to shadow stacks.
+ */
+ DECLARE_VMA_BIT_ALIAS(SHADOW_STACK, HIGH_ARCH_6),
+#endif
+ DECLARE_VMA_BIT_ALIAS(SAO, ARCH_1), /* Strong Access Ordering (powerpc) */
+ DECLARE_VMA_BIT_ALIAS(GROWSUP, ARCH_1), /* parisc */
+ DECLARE_VMA_BIT_ALIAS(SPARC_ADI, ARCH_1), /* sparc64 */
+ DECLARE_VMA_BIT_ALIAS(ARM64_BTI, ARCH_1), /* arm64 */
+ DECLARE_VMA_BIT_ALIAS(ARCH_CLEAR, ARCH_1), /* sparc64, arm64 */
+ DECLARE_VMA_BIT_ALIAS(MAPPED_COPY, ARCH_1), /* !CONFIG_MMU */
+ DECLARE_VMA_BIT_ALIAS(MTE, HIGH_ARCH_4), /* arm64 */
+ DECLARE_VMA_BIT_ALIAS(MTE_ALLOWED, HIGH_ARCH_5),/* arm64 */
#ifdef CONFIG_STACK_GROWSUP
-#define VM_STACK VM_GROWSUP
-#define VM_STACK_EARLY VM_GROWSDOWN
+ DECLARE_VMA_BIT_ALIAS(STACK, GROWSUP),
+ DECLARE_VMA_BIT_ALIAS(STACK_EARLY, GROWSDOWN),
#else
-#define VM_STACK VM_GROWSDOWN
-#define VM_STACK_EARLY 0
+ DECLARE_VMA_BIT_ALIAS(STACK, GROWSDOWN),
#endif
+};
+
+#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
+#define VM_READ INIT_VM_FLAG(READ)
+#define VM_WRITE INIT_VM_FLAG(WRITE)
+#define VM_EXEC INIT_VM_FLAG(EXEC)
+#define VM_SHARED INIT_VM_FLAG(SHARED)
+#define VM_MAYREAD INIT_VM_FLAG(MAYREAD)
+#define VM_MAYWRITE INIT_VM_FLAG(MAYWRITE)
+#define VM_MAYEXEC INIT_VM_FLAG(MAYEXEC)
+#define VM_MAYSHARE INIT_VM_FLAG(MAYSHARE)
+#define VM_GROWSDOWN INIT_VM_FLAG(GROWSDOWN)
+#ifdef CONFIG_MMU
+#define VM_UFFD_MISSING INIT_VM_FLAG(UFFD_MISSING)
+#else
+#define VM_UFFD_MISSING VM_NONE
+#endif
+#define VM_PFNMAP INIT_VM_FLAG(PFNMAP)
+#define VM_MAYBE_GUARD INIT_VM_FLAG(MAYBE_GUARD)
+#define VM_UFFD_WP INIT_VM_FLAG(UFFD_WP)
+#define VM_LOCKED INIT_VM_FLAG(LOCKED)
+#define VM_IO INIT_VM_FLAG(IO)
+#define VM_SEQ_READ INIT_VM_FLAG(SEQ_READ)
+#define VM_RAND_READ INIT_VM_FLAG(RAND_READ)
+#define VM_DONTCOPY INIT_VM_FLAG(DONTCOPY)
+#define VM_DONTEXPAND INIT_VM_FLAG(DONTEXPAND)
+#define VM_LOCKONFAULT INIT_VM_FLAG(LOCKONFAULT)
+#define VM_ACCOUNT INIT_VM_FLAG(ACCOUNT)
+#define VM_NORESERVE INIT_VM_FLAG(NORESERVE)
+#define VM_HUGETLB INIT_VM_FLAG(HUGETLB)
+#define VM_SYNC INIT_VM_FLAG(SYNC)
+#define VM_ARCH_1 INIT_VM_FLAG(ARCH_1)
+#define VM_WIPEONFORK INIT_VM_FLAG(WIPEONFORK)
+#define VM_DONTDUMP INIT_VM_FLAG(DONTDUMP)
+#ifdef CONFIG_MEM_SOFT_DIRTY
+#define VM_SOFTDIRTY INIT_VM_FLAG(SOFTDIRTY)
+#else
+#define VM_SOFTDIRTY VM_NONE
+#endif
+#define VM_MIXEDMAP INIT_VM_FLAG(MIXEDMAP)
+#define VM_HUGEPAGE INIT_VM_FLAG(HUGEPAGE)
+#define VM_NOHUGEPAGE INIT_VM_FLAG(NOHUGEPAGE)
+#define VM_MERGEABLE INIT_VM_FLAG(MERGEABLE)
+#define VM_STACK INIT_VM_FLAG(STACK)
+#ifdef CONFIG_STACK_GROWS_UP
+#define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY)
+#else
+#define VM_STACK_EARLY VM_NONE
+#endif
+#ifdef CONFIG_ARCH_HAS_PKEYS
+#define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT)
+/* Despite the naming, these are FLAGS not bits. */
+#define VM_PKEY_BIT0 INIT_VM_FLAG(PKEY_BIT0)
+#define VM_PKEY_BIT1 INIT_VM_FLAG(PKEY_BIT1)
+#define VM_PKEY_BIT2 INIT_VM_FLAG(PKEY_BIT2)
+#if CONFIG_ARCH_PKEY_BITS > 3
+#define VM_PKEY_BIT3 INIT_VM_FLAG(PKEY_BIT3)
+#else
+#define VM_PKEY_BIT3 VM_NONE
+#endif /* CONFIG_ARCH_PKEY_BITS > 3 */
+#if CONFIG_ARCH_PKEY_BITS > 4
+#define VM_PKEY_BIT4 INIT_VM_FLAG(PKEY_BIT4)
+#else
+#define VM_PKEY_BIT4 VM_NONE
+#endif /* CONFIG_ARCH_PKEY_BITS > 4 */
+#endif /* CONFIG_ARCH_HAS_PKEYS */
+#if defined(CONFIG_X86_USER_SHADOW_STACK) || defined(CONFIG_ARM64_GCS)
+#define VM_SHADOW_STACK INIT_VM_FLAG(SHADOW_STACK)
+#else
+#define VM_SHADOW_STACK VM_NONE
+#endif
+#if defined(CONFIG_PPC64)
+#define VM_SAO INIT_VM_FLAG(SAO)
+#elif defined(CONFIG_PARISC)
+#define VM_GROWSUP INIT_VM_FLAG(GROWSUP)
+#elif defined(CONFIG_SPARC64)
+#define VM_SPARC_ADI INIT_VM_FLAG(SPARC_ADI)
+#define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR)
+#elif defined(CONFIG_ARM64)
+#define VM_ARM64_BTI INIT_VM_FLAG(ARM64_BTI)
+#define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR)
+#elif !defined(CONFIG_MMU)
+#define VM_MAPPED_COPY INIT_VM_FLAG(MAPPED_COPY)
+#endif
+#ifndef VM_GROWSUP
+#define VM_GROWSUP VM_NONE
+#endif
+#ifdef CONFIG_ARM64_MTE
+#define VM_MTE INIT_VM_FLAG(MTE)
+#define VM_MTE_ALLOWED INIT_VM_FLAG(MTE_ALLOWED)
+#else
+#define VM_MTE VM_NONE
+#define VM_MTE_ALLOWED VM_NONE
+#endif
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR
+#define VM_UFFD_MINOR INIT_VM_FLAG(UFFD_MINOR)
+#else
+#define VM_UFFD_MINOR VM_NONE
+#endif
+#ifdef CONFIG_64BIT
+#define VM_ALLOW_ANY_UNCACHED INIT_VM_FLAG(ALLOW_ANY_UNCACHED)
+#define VM_SEALED INIT_VM_FLAG(SEALED)
+#else
+#define VM_ALLOW_ANY_UNCACHED VM_NONE
+#define VM_SEALED VM_NONE
+#endif
+#if defined(CONFIG_64BIT) || defined(CONFIG_PPC32)
+#define VM_DROPPABLE INIT_VM_FLAG(DROPPABLE)
+#else
+#define VM_DROPPABLE VM_NONE
+#endif
+
+/* Bits set in the VMA until the stack is in its final location */
+#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
+
+#define TASK_EXEC ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0)
+
+/* Common data flag combinations */
+#define VM_DATA_FLAGS_TSK_EXEC (VM_READ | VM_WRITE | TASK_EXEC | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+#define VM_DATA_FLAGS_NON_EXEC (VM_READ | VM_WRITE | VM_MAYREAD | \
+ VM_MAYWRITE | VM_MAYEXEC)
+#define VM_DATA_FLAGS_EXEC (VM_READ | VM_WRITE | VM_EXEC | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#ifndef VM_DATA_DEFAULT_FLAGS /* arch can override this */
+#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_EXEC
+#endif
+
+#ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
+#define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
+#endif
+
+#define VM_STARTGAP_FLAGS (VM_GROWSDOWN | VM_SHADOW_STACK)
+
+#define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
+
+/* VMA basic access permission flags */
+#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC)
+
+/*
+ * Special vmas that are non-mergable, non-mlock()able.
+ */
+#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP)
#define DEFAULT_MAP_WINDOW ((1UL << 47) - PAGE_SIZE)
#define TASK_SIZE_LOW DEFAULT_MAP_WINDOW
@@ -97,26 +325,11 @@ extern unsigned long dac_mmap_min_addr;
#define VM_DATA_FLAGS_TSK_EXEC (VM_READ | VM_WRITE | TASK_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC
-
-#define VM_STARTGAP_FLAGS (VM_GROWSDOWN | VM_SHADOW_STACK)
-
-#define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
-#define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
-#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
-
#define RLIMIT_STACK 3 /* max stack size */
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define CAP_IPC_LOCK 14
-#ifdef CONFIG_64BIT
-#define VM_SEALED_BIT 42
-#define VM_SEALED BIT(VM_SEALED_BIT)
-#else
-#define VM_SEALED VM_NONE
-#endif
-
/*
* Flags which should be 'sticky' on merge - that is, flags which, when one VMA
* possesses it but the other does not, the merged VMA should nonetheless have
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 2/4] mm: simplify and rename mm flags function for clarity
2025-11-14 13:26 [PATCH v2 0/4] initial work on making VMA flags a bitmap Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 1/4] mm: declare VMA flags by bit Lorenzo Stoakes
@ 2025-11-14 13:26 ` Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 3/4] tools/testing/vma: eliminate dependency on vma->__vm_flags Lorenzo Stoakes
` (2 subsequent siblings)
4 siblings, 0 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-14 13:26 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
The __mm_flags_set_word() function is slightly ambiguous - we use 'set' to
refer to setting individual bits (such as in mm_flags_set()) but here we
use it to refer to overwriting the value altogether.
Rename it to __mm_flags_overwrite_word() to eliminate this ambiguity.
We additionally simplify the functions, eliminating unnecessary
bitmap_xxx() operations (the compiler would have optimised these out but
it's worth being as clear as we can be here).
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
include/linux/mm_types.h | 14 +++++---------
kernel/fork.c | 4 ++--
2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 4f66a3206a63..3550672e0f9e 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1314,15 +1314,13 @@ struct mm_struct {
unsigned long cpu_bitmap[];
};
-/* Set the first system word of mm flags, non-atomically. */
-static inline void __mm_flags_set_word(struct mm_struct *mm, unsigned long value)
+/* Copy value to the first system word of mm flags, non-atomically. */
+static inline void __mm_flags_overwrite_word(struct mm_struct *mm, unsigned long value)
{
- unsigned long *bitmap = ACCESS_PRIVATE(&mm->flags, __mm_flags);
-
- bitmap_copy(bitmap, &value, BITS_PER_LONG);
+ *ACCESS_PRIVATE(&mm->flags, __mm_flags) = value;
}
-/* Obtain a read-only view of the bitmap. */
+/* Obtain a read-only view of the mm flags bitmap. */
static inline const unsigned long *__mm_flags_get_bitmap(const struct mm_struct *mm)
{
return (const unsigned long *)ACCESS_PRIVATE(&mm->flags, __mm_flags);
@@ -1331,9 +1329,7 @@ static inline const unsigned long *__mm_flags_get_bitmap(const struct mm_struct
/* Read the first system word of mm flags, non-atomically. */
static inline unsigned long __mm_flags_get_word(const struct mm_struct *mm)
{
- const unsigned long *bitmap = __mm_flags_get_bitmap(mm);
-
- return bitmap_read(bitmap, 0, BITS_PER_LONG);
+ return *__mm_flags_get_bitmap(mm);
}
/*
diff --git a/kernel/fork.c b/kernel/fork.c
index dd0bb5fe4305..5e3309a2332c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1061,10 +1061,10 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
if (current->mm) {
unsigned long flags = __mm_flags_get_word(current->mm);
- __mm_flags_set_word(mm, mmf_init_legacy_flags(flags));
+ __mm_flags_overwrite_word(mm, mmf_init_legacy_flags(flags));
mm->def_flags = current->mm->def_flags & VM_INIT_DEF_MASK;
} else {
- __mm_flags_set_word(mm, default_dump_filter);
+ __mm_flags_overwrite_word(mm, default_dump_filter);
mm->def_flags = 0;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 3/4] tools/testing/vma: eliminate dependency on vma->__vm_flags
2025-11-14 13:26 [PATCH v2 0/4] initial work on making VMA flags a bitmap Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 1/4] mm: declare VMA flags by bit Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 2/4] mm: simplify and rename mm flags function for clarity Lorenzo Stoakes
@ 2025-11-14 13:26 ` Lorenzo Stoakes
2025-11-21 17:28 ` Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 4/4] mm: introduce VMA flags bitmap type Lorenzo Stoakes
2025-11-21 14:50 ` [PATCH v2 0/4] initial work on making VMA flags a bitmap Vlastimil Babka
4 siblings, 1 reply; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-14 13:26 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
The userland VMA test code relied on an internal implementation detail -
the existence of vma->__vm_flags to directly access VMA flags. There is no
need to do so when we have the vm_flags_*() helper functions available.
This is both ugly, but also a subsequent commit will eliminate this field
altogether so this will shortly become broken.
This patch has us utilise the helper functions instead.
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
tools/testing/vma/vma.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/tools/testing/vma/vma.c b/tools/testing/vma/vma.c
index ee9d3547c421..fc77fa3f66f0 100644
--- a/tools/testing/vma/vma.c
+++ b/tools/testing/vma/vma.c
@@ -69,18 +69,18 @@ static struct vm_area_struct *alloc_vma(struct mm_struct *mm,
pgoff_t pgoff,
vm_flags_t vm_flags)
{
- struct vm_area_struct *ret = vm_area_alloc(mm);
+ struct vm_area_struct *vma = vm_area_alloc(mm);
- if (ret == NULL)
+ if (vma == NULL)
return NULL;
- ret->vm_start = start;
- ret->vm_end = end;
- ret->vm_pgoff = pgoff;
- ret->__vm_flags = vm_flags;
- vma_assert_detached(ret);
+ vma->vm_start = start;
+ vma->vm_end = end;
+ vma->vm_pgoff = pgoff;
+ vm_flags_reset(vma, vm_flags);
+ vma_assert_detached(vma);
- return ret;
+ return vma;
}
/* Helper function to allocate a VMA and link it to the tree. */
@@ -713,7 +713,7 @@ static bool test_vma_merge_special_flags(void)
for (i = 0; i < ARRAY_SIZE(special_flags); i++) {
vm_flags_t special_flag = special_flags[i];
- vma_left->__vm_flags = vm_flags | special_flag;
+ vm_flags_reset(vma_left, vm_flags | special_flag);
vmg.vm_flags = vm_flags | special_flag;
vma = merge_new(&vmg);
ASSERT_EQ(vma, NULL);
@@ -735,7 +735,7 @@ static bool test_vma_merge_special_flags(void)
for (i = 0; i < ARRAY_SIZE(special_flags); i++) {
vm_flags_t special_flag = special_flags[i];
- vma_left->__vm_flags = vm_flags | special_flag;
+ vm_flags_reset(vma_left, vm_flags | special_flag);
vmg.vm_flags = vm_flags | special_flag;
vma = merge_existing(&vmg);
ASSERT_EQ(vma, NULL);
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 4/4] mm: introduce VMA flags bitmap type
2025-11-14 13:26 [PATCH v2 0/4] initial work on making VMA flags a bitmap Lorenzo Stoakes
` (2 preceding siblings ...)
2025-11-14 13:26 ` [PATCH v2 3/4] tools/testing/vma: eliminate dependency on vma->__vm_flags Lorenzo Stoakes
@ 2025-11-14 13:26 ` Lorenzo Stoakes
2025-11-21 17:44 ` Lorenzo Stoakes
2025-11-21 14:50 ` [PATCH v2 0/4] initial work on making VMA flags a bitmap Vlastimil Babka
4 siblings, 1 reply; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-14 13:26 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
It is useful to transition to using a bitmap for VMA flags so we can avoid
running out of flags, especially for 32-bit kernels which are constrained
to 32 flags, necessitating some features to be limited to 64-bit kernels
only.
By doing so, we remove any constraint on the number of VMA flags moving
forwards no matter the platform and can decide in future to extend beyond
64 if required.
We start by declaring an opaque types, vma_flags_t (which resembles
mm_struct flags of type mm_flags_t), setting it to precisely the same size
as vm_flags_t, and place it in union with vm_flags in the VMA declaration.
We additionally update struct vm_area_desc equivalently placing the new
opaque type in union with vm_flags.
This change therefore does not impact the size of struct vm_area_struct or
struct vm_area_desc.
In order for the change to be iterative and to avoid impacting performance,
we designate VM_xxx declared bitmap flag values as those which must exist
in the first system word of the VMA flags bitmap.
We therefore declare vma_flags_clear_all(), vma_flags_overwrite_word(),
vma_flags_overwrite_word(), vma_flags_overwrite_word_once(),
vma_flags_set_word() and vma_flags_clear_word() in order to allow us to
update the existing vm_flags_*() functions to utilise these helpers.
This is a stepping stone towards converting users to the VMA flags bitmap
and behaves precisely as before.
By doing this, we can eliminate the existing private vma->__vm_flags field
in the vma->vm_flags union and replace it with the newly introduced opaque
type vma_flags, which we call flags so we refer to the new bitmap field as
vma->flags.
We update vma_flag_[test, set]_atomic() to account for the change also.
We additionally update the VMA userland test declarations to implement the
same changes there.
Finally, we update the rust code to reference vma->vm_flags on update
rather than vma->__vm_flags which has been removed. This is safe for now,
albeit it is implicitly performing a const cast.
Once we introduce flag helpers we can improve this more.
No functional change intended.
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
include/linux/mm.h | 18 ++--
include/linux/mm_types.h | 64 +++++++++++++-
rust/kernel/mm/virt.rs | 2 +-
tools/testing/vma/vma_internal.h | 143 ++++++++++++++++++++++++++-----
4 files changed, 196 insertions(+), 31 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index ad000c472bd5..79345c44a350 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -919,7 +919,8 @@ static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
static inline void vm_flags_init(struct vm_area_struct *vma,
vm_flags_t flags)
{
- ACCESS_PRIVATE(vma, __vm_flags) = flags;
+ vma_flags_clear_all(&vma->flags);
+ vma_flags_overwrite_word(&vma->flags, flags);
}
/*
@@ -938,21 +939,26 @@ static inline void vm_flags_reset_once(struct vm_area_struct *vma,
vm_flags_t flags)
{
vma_assert_write_locked(vma);
- WRITE_ONCE(ACCESS_PRIVATE(vma, __vm_flags), flags);
+ /*
+ * The user should only be interested in avoiding reordering of
+ * assignment to the first word.
+ */
+ vma_flags_clear_all(&vma->flags);
+ vma_flags_overwrite_word_once(&vma->flags, flags);
}
static inline void vm_flags_set(struct vm_area_struct *vma,
vm_flags_t flags)
{
vma_start_write(vma);
- ACCESS_PRIVATE(vma, __vm_flags) |= flags;
+ vma_flags_set_word(&vma->flags, flags);
}
static inline void vm_flags_clear(struct vm_area_struct *vma,
vm_flags_t flags)
{
vma_start_write(vma);
- ACCESS_PRIVATE(vma, __vm_flags) &= ~flags;
+ vma_flags_clear_word(&vma->flags, flags);
}
/*
@@ -995,12 +1001,14 @@ static inline bool __vma_flag_atomic_valid(struct vm_area_struct *vma,
static inline void vma_flag_set_atomic(struct vm_area_struct *vma,
vma_flag_t bit)
{
+ unsigned long *bitmap = ACCESS_PRIVATE(&vma->flags, __vma_flags);
+
/* mmap read lock/VMA read lock must be held. */
if (!rwsem_is_locked(&vma->vm_mm->mmap_lock))
vma_assert_locked(vma);
if (__vma_flag_atomic_valid(vma, bit))
- set_bit((__force int)bit, &ACCESS_PRIVATE(vma, __vm_flags));
+ set_bit((__force int)bit, bitmap);
}
/*
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 3550672e0f9e..b71625378ce3 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -848,6 +848,15 @@ struct mmap_action {
bool hide_from_rmap_until_complete :1;
};
+/*
+ * Opaque type representing current VMA (vm_area_struct) flag state. Must be
+ * accessed via vma_flags_xxx() helper functions.
+ */
+#define NUM_VMA_FLAG_BITS BITS_PER_LONG
+typedef struct {
+ DECLARE_BITMAP(__vma_flags, NUM_VMA_FLAG_BITS);
+} __private vma_flags_t;
+
/*
* Describes a VMA that is about to be mmap()'ed. Drivers may choose to
* manipulate mutable fields which will cause those fields to be updated in the
@@ -865,7 +874,10 @@ struct vm_area_desc {
/* Mutable fields. Populated with initial state. */
pgoff_t pgoff;
struct file *vm_file;
- vm_flags_t vm_flags;
+ union {
+ vm_flags_t vm_flags;
+ vma_flags_t vma_flags;
+ };
pgprot_t page_prot;
/* Write-only fields. */
@@ -910,10 +922,12 @@ struct vm_area_struct {
/*
* Flags, see mm.h.
* To modify use vm_flags_{init|reset|set|clear|mod} functions.
+ * Preferably, use vma_flags_xxx() functions.
*/
union {
+ /* Temporary while VMA flags are being converted. */
const vm_flags_t vm_flags;
- vm_flags_t __private __vm_flags;
+ vma_flags_t flags;
};
#ifdef CONFIG_PER_VMA_LOCK
@@ -994,6 +1008,52 @@ struct vm_area_struct {
#endif
} __randomize_layout;
+/* Clears all bits in the VMA flags bitmap, non-atomically. */
+static inline void vma_flags_clear_all(vma_flags_t *flags)
+{
+ bitmap_zero(ACCESS_PRIVATE(flags, __vma_flags), NUM_VMA_FLAG_BITS);
+}
+
+/*
+ * Copy value to the first system word of VMA flags, non-atomically.
+ *
+ * IMPORTANT: This does not overwrite bytes past the first system word. The
+ * caller must account for this.
+ */
+static inline void vma_flags_overwrite_word(vma_flags_t *flags, unsigned long value)
+{
+ *ACCESS_PRIVATE(flags, __vma_flags) = value;
+}
+
+/*
+ * Copy value to the first system word of VMA flags ONCE, non-atomically.
+ *
+ * IMPORTANT: This does not overwrite bytes past the first system word. The
+ * caller must account for this.
+ */
+static inline void vma_flags_overwrite_word_once(vma_flags_t *flags, unsigned long value)
+{
+ unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
+
+ WRITE_ONCE(*bitmap, value);
+}
+
+/* Update the first system word of VMA flags setting bits, non-atomically. */
+static inline void vma_flags_set_word(vma_flags_t *flags, unsigned long value)
+{
+ unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
+
+ *bitmap |= value;
+}
+
+/* Update the first system word of VMA flags clearing bits, non-atomically. */
+static inline void vma_flags_clear_word(vma_flags_t *flags, unsigned long value)
+{
+ unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
+
+ *bitmap &= ~value;
+}
+
#ifdef CONFIG_NUMA
#define vma_policy(vma) ((vma)->vm_policy)
#else
diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs
index a1bfa4e19293..da21d65ccd20 100644
--- a/rust/kernel/mm/virt.rs
+++ b/rust/kernel/mm/virt.rs
@@ -250,7 +250,7 @@ unsafe fn update_flags(&self, set: vm_flags_t, unset: vm_flags_t) {
// SAFETY: This is not a data race: the vma is undergoing initial setup, so it's not yet
// shared. Additionally, `VmaNew` is `!Sync`, so it cannot be used to write in parallel.
// The caller promises that this does not set the flags to an invalid value.
- unsafe { (*self.as_ptr()).__bindgen_anon_2.__vm_flags = flags };
+ unsafe { (*self.as_ptr()).__bindgen_anon_2.vm_flags = flags };
}
/// Set the `VM_MIXEDMAP` flag on this vma.
diff --git a/tools/testing/vma/vma_internal.h b/tools/testing/vma/vma_internal.h
index 18659214e262..13ee825bdfcf 100644
--- a/tools/testing/vma/vma_internal.h
+++ b/tools/testing/vma/vma_internal.h
@@ -528,6 +528,15 @@ typedef struct {
__private DECLARE_BITMAP(__mm_flags, NUM_MM_FLAG_BITS);
} mm_flags_t;
+/*
+ * Opaque type representing current VMA (vm_area_struct) flag state. Must be
+ * accessed via vma_flags_xxx() helper functions.
+ */
+#define NUM_VMA_FLAG_BITS BITS_PER_LONG
+typedef struct {
+ DECLARE_BITMAP(__vma_flags, NUM_VMA_FLAG_BITS);
+} __private vma_flags_t;
+
struct mm_struct {
struct maple_tree mm_mt;
int map_count; /* number of VMAs */
@@ -612,7 +621,10 @@ struct vm_area_desc {
/* Mutable fields. Populated with initial state. */
pgoff_t pgoff;
struct file *vm_file;
- vm_flags_t vm_flags;
+ union {
+ vm_flags_t vm_flags;
+ vma_flags_t vma_flags;
+ };
pgprot_t page_prot;
/* Write-only fields. */
@@ -658,7 +670,7 @@ struct vm_area_struct {
*/
union {
const vm_flags_t vm_flags;
- vm_flags_t __private __vm_flags;
+ vma_flags_t flags;
};
#ifdef CONFIG_PER_VMA_LOCK
@@ -1372,26 +1384,6 @@ static inline bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags,
return true;
}
-static inline void vm_flags_init(struct vm_area_struct *vma,
- vm_flags_t flags)
-{
- vma->__vm_flags = flags;
-}
-
-static inline void vm_flags_set(struct vm_area_struct *vma,
- vm_flags_t flags)
-{
- vma_start_write(vma);
- vma->__vm_flags |= flags;
-}
-
-static inline void vm_flags_clear(struct vm_area_struct *vma,
- vm_flags_t flags)
-{
- vma_start_write(vma);
- vma->__vm_flags &= ~flags;
-}
-
static inline int shmem_zero_setup(struct vm_area_struct *vma)
{
return 0;
@@ -1548,13 +1540,118 @@ static inline void userfaultfd_unmap_complete(struct mm_struct *mm,
{
}
-# define ACCESS_PRIVATE(p, member) ((p)->member)
+#define ACCESS_PRIVATE(p, member) ((p)->member)
+
+#define bitmap_size(nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE)
+
+static __always_inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
+{
+ unsigned int len = bitmap_size(nbits);
+
+ if (small_const_nbits(nbits))
+ *dst = 0;
+ else
+ memset(dst, 0, len);
+}
static inline bool mm_flags_test(int flag, const struct mm_struct *mm)
{
return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
}
+/* Clears all bits in the VMA flags bitmap, non-atomically. */
+static inline void vma_flags_clear_all(vma_flags_t *flags)
+{
+ bitmap_zero(ACCESS_PRIVATE(flags, __vma_flags), NUM_VMA_FLAG_BITS);
+}
+
+/*
+ * Copy value to the first system word of VMA flags, non-atomically.
+ *
+ * IMPORTANT: This does not overwrite bytes past the first system word. The
+ * caller must account for this.
+ */
+static inline void vma_flags_overwrite_word(vma_flags_t *flags, unsigned long value)
+{
+ *ACCESS_PRIVATE(flags, __vma_flags) = value;
+}
+
+/*
+ * Copy value to the first system word of VMA flags ONCE, non-atomically.
+ *
+ * IMPORTANT: This does not overwrite bytes past the first system word. The
+ * caller must account for this.
+ */
+static inline void vma_flags_overwrite_word_once(vma_flags_t *flags, unsigned long value)
+{
+ unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
+
+ WRITE_ONCE(*bitmap, value);
+}
+
+/* Update the first system word of VMA flags setting bits, non-atomically. */
+static inline void vma_flags_set_word(vma_flags_t *flags, unsigned long value)
+{
+ unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
+
+ *bitmap |= value;
+}
+
+/* Update the first system word of VMA flags clearing bits, non-atomically. */
+static inline void vma_flags_clear_word(vma_flags_t *flags, unsigned long value)
+{
+ unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
+
+ *bitmap &= ~value;
+}
+
+
+/* Use when VMA is not part of the VMA tree and needs no locking */
+static inline void vm_flags_init(struct vm_area_struct *vma,
+ vm_flags_t flags)
+{
+ vma_flags_clear_all(&vma->flags);
+ vma_flags_overwrite_word(&vma->flags, flags);
+}
+
+/*
+ * Use when VMA is part of the VMA tree and modifications need coordination
+ * Note: vm_flags_reset and vm_flags_reset_once do not lock the vma and
+ * it should be locked explicitly beforehand.
+ */
+static inline void vm_flags_reset(struct vm_area_struct *vma,
+ vm_flags_t flags)
+{
+ vma_assert_write_locked(vma);
+ vm_flags_init(vma, flags);
+}
+
+static inline void vm_flags_reset_once(struct vm_area_struct *vma,
+ vm_flags_t flags)
+{
+ vma_assert_write_locked(vma);
+ /*
+ * The user should only be interested in avoiding reordering of
+ * assignment to the first word.
+ */
+ vma_flags_clear_all(&vma->flags);
+ vma_flags_overwrite_word_once(&vma->flags, flags);
+}
+
+static inline void vm_flags_set(struct vm_area_struct *vma,
+ vm_flags_t flags)
+{
+ vma_start_write(vma);
+ vma_flags_set_word(&vma->flags, flags);
+}
+
+static inline void vm_flags_clear(struct vm_area_struct *vma,
+ vm_flags_t flags)
+{
+ vma_start_write(vma);
+ vma_flags_clear_word(&vma->flags, flags);
+}
+
/*
* Denies creating a writable executable mapping or gaining executable permissions.
*
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] mm: declare VMA flags by bit
2025-11-14 13:26 ` [PATCH v2 1/4] mm: declare VMA flags by bit Lorenzo Stoakes
@ 2025-11-14 13:50 ` Alice Ryhl
2025-11-14 13:55 ` Lorenzo Stoakes
2025-11-14 14:22 ` Lorenzo Stoakes
` (2 subsequent siblings)
3 siblings, 1 reply; 18+ messages in thread
From: Alice Ryhl @ 2025-11-14 13:50 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, Muchun Song, Oscar Salvador, David Hildenbrand,
Liam R . Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
Wei Xu, Peter Xu, Ingo Molnar, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Kees Cook, Matthew Wilcox,
Jason Gunthorpe, John Hubbard, Leon Romanovsky, Zi Yan,
Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Xu Xin, Chengming Zhou, Jann Horn, Matthew Brost,
Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang,
Alistair Popple, Pedro Falcato, Shakeel Butt, David Rientjes,
Rik van Riel, Harry Yoo, Kemeng Shi, Kairui Song, Nhat Pham,
Baoquan He, Chris Li, Johannes Weiner, Qi Zheng, linux-kernel,
linux-fsdevel, linux-mm, Miguel Ojeda, Alex Gaynor, Boqun Feng,
Gary Guo, Bjorn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux
On Fri, Nov 14, 2025 at 01:26:08PM +0000, Lorenzo Stoakes wrote:
> diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
> index 2e43c66635a2..4c327db01ca0 100644
> --- a/rust/bindings/bindings_helper.h
> +++ b/rust/bindings/bindings_helper.h
> @@ -108,7 +108,32 @@ const xa_mark_t RUST_CONST_HELPER_XA_PRESENT = XA_PRESENT;
>
> const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC = XA_FLAGS_ALLOC;
> const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC1 = XA_FLAGS_ALLOC1;
> +
> const vm_flags_t RUST_CONST_HELPER_VM_MERGEABLE = VM_MERGEABLE;
> +const vm_flags_t RUST_CONST_HELPER_VM_READ = VM_READ;
> +const vm_flags_t RUST_CONST_HELPER_VM_WRITE = VM_WRITE;
> +const vm_flags_t RUST_CONST_HELPER_VM_EXEC = VM_EXEC;
> +const vm_flags_t RUST_CONST_HELPER_VM_SHARED = VM_SHARED;
> +const vm_flags_t RUST_CONST_HELPER_VM_MAYREAD = VM_MAYREAD;
> +const vm_flags_t RUST_CONST_HELPER_VM_MAYWRITE = VM_MAYWRITE;
> +const vm_flags_t RUST_CONST_HELPER_VM_MAYEXEC = VM_MAYEXEC;
> +const vm_flags_t RUST_CONST_HELPER_VM_MAYSHARE = VM_MAYEXEC;
> +const vm_flags_t RUST_CONST_HELPER_VM_PFNMAP = VM_PFNMAP;
> +const vm_flags_t RUST_CONST_HELPER_VM_IO = VM_IO;
> +const vm_flags_t RUST_CONST_HELPER_VM_DONTCOPY = VM_DONTCOPY;
> +const vm_flags_t RUST_CONST_HELPER_VM_DONTEXPAND = VM_DONTEXPAND;
> +const vm_flags_t RUST_CONST_HELPER_VM_LOCKONFAULT = VM_LOCKONFAULT;
> +const vm_flags_t RUST_CONST_HELPER_VM_ACCOUNT = VM_ACCOUNT;
> +const vm_flags_t RUST_CONST_HELPER_VM_NORESERVE = VM_NORESERVE;
> +const vm_flags_t RUST_CONST_HELPER_VM_HUGETLB = VM_HUGETLB;
> +const vm_flags_t RUST_CONST_HELPER_VM_SYNC = VM_SYNC;
> +const vm_flags_t RUST_CONST_HELPER_VM_ARCH_1 = VM_ARCH_1;
> +const vm_flags_t RUST_CONST_HELPER_VM_WIPEONFORK = VM_WIPEONFORK;
> +const vm_flags_t RUST_CONST_HELPER_VM_DONTDUMP = VM_DONTDUMP;
> +const vm_flags_t RUST_CONST_HELPER_VM_SOFTDIRTY = VM_SOFTDIRTY;
> +const vm_flags_t RUST_CONST_HELPER_VM_MIXEDMAP = VM_MIXEDMAP;
> +const vm_flags_t RUST_CONST_HELPER_VM_HUGEPAGE = VM_HUGEPAGE;
> +const vm_flags_t RUST_CONST_HELPER_VM_NOHUGEPAGE = VM_NOHUGEPAGE;
I got this error:
error[E0428]: the name `VM_SOFTDIRTY` is defined multiple times
--> rust/bindings/bindings_generated.rs:115967:1
|
13440 | pub const VM_SOFTDIRTY: u32 = 0;
| -------------------------------- previous definition of the value `VM_SOFTDIRTY` here
...
115967 | pub const VM_SOFTDIRTY: vm_flags_t = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `VM_SOFTDIRTY` redefined here
|
= note: `VM_SOFTDIRTY` must be defined only once in the value namespace of this module
Please add the constants in rust/bindgen_parameters next to
ARCH_KMALLOC_MINALIGN to avoid this error. This ensures that only the
version from bindings_helper.h is generated.
Alice
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] mm: declare VMA flags by bit
2025-11-14 13:50 ` Alice Ryhl
@ 2025-11-14 13:55 ` Lorenzo Stoakes
2025-11-14 14:08 ` Alice Ryhl
0 siblings, 1 reply; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-14 13:55 UTC (permalink / raw)
To: Alice Ryhl
Cc: Andrew Morton, Muchun Song, Oscar Salvador, David Hildenbrand,
Liam R . Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
Wei Xu, Peter Xu, Ingo Molnar, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Kees Cook, Matthew Wilcox,
Jason Gunthorpe, John Hubbard, Leon Romanovsky, Zi Yan,
Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Xu Xin, Chengming Zhou, Jann Horn, Matthew Brost,
Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang,
Alistair Popple, Pedro Falcato, Shakeel Butt, David Rientjes,
Rik van Riel, Harry Yoo, Kemeng Shi, Kairui Song, Nhat Pham,
Baoquan He, Chris Li, Johannes Weiner, Qi Zheng, linux-kernel,
linux-fsdevel, linux-mm, Miguel Ojeda, Alex Gaynor, Boqun Feng,
Gary Guo, Bjorn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux
On Fri, Nov 14, 2025 at 01:50:45PM +0000, Alice Ryhl wrote:
> On Fri, Nov 14, 2025 at 01:26:08PM +0000, Lorenzo Stoakes wrote:
> > diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
> > index 2e43c66635a2..4c327db01ca0 100644
> > --- a/rust/bindings/bindings_helper.h
> > +++ b/rust/bindings/bindings_helper.h
> > @@ -108,7 +108,32 @@ const xa_mark_t RUST_CONST_HELPER_XA_PRESENT = XA_PRESENT;
> >
> > const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC = XA_FLAGS_ALLOC;
> > const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC1 = XA_FLAGS_ALLOC1;
> > +
> > const vm_flags_t RUST_CONST_HELPER_VM_MERGEABLE = VM_MERGEABLE;
> > +const vm_flags_t RUST_CONST_HELPER_VM_READ = VM_READ;
> > +const vm_flags_t RUST_CONST_HELPER_VM_WRITE = VM_WRITE;
> > +const vm_flags_t RUST_CONST_HELPER_VM_EXEC = VM_EXEC;
> > +const vm_flags_t RUST_CONST_HELPER_VM_SHARED = VM_SHARED;
> > +const vm_flags_t RUST_CONST_HELPER_VM_MAYREAD = VM_MAYREAD;
> > +const vm_flags_t RUST_CONST_HELPER_VM_MAYWRITE = VM_MAYWRITE;
> > +const vm_flags_t RUST_CONST_HELPER_VM_MAYEXEC = VM_MAYEXEC;
> > +const vm_flags_t RUST_CONST_HELPER_VM_MAYSHARE = VM_MAYEXEC;
> > +const vm_flags_t RUST_CONST_HELPER_VM_PFNMAP = VM_PFNMAP;
> > +const vm_flags_t RUST_CONST_HELPER_VM_IO = VM_IO;
> > +const vm_flags_t RUST_CONST_HELPER_VM_DONTCOPY = VM_DONTCOPY;
> > +const vm_flags_t RUST_CONST_HELPER_VM_DONTEXPAND = VM_DONTEXPAND;
> > +const vm_flags_t RUST_CONST_HELPER_VM_LOCKONFAULT = VM_LOCKONFAULT;
> > +const vm_flags_t RUST_CONST_HELPER_VM_ACCOUNT = VM_ACCOUNT;
> > +const vm_flags_t RUST_CONST_HELPER_VM_NORESERVE = VM_NORESERVE;
> > +const vm_flags_t RUST_CONST_HELPER_VM_HUGETLB = VM_HUGETLB;
> > +const vm_flags_t RUST_CONST_HELPER_VM_SYNC = VM_SYNC;
> > +const vm_flags_t RUST_CONST_HELPER_VM_ARCH_1 = VM_ARCH_1;
> > +const vm_flags_t RUST_CONST_HELPER_VM_WIPEONFORK = VM_WIPEONFORK;
> > +const vm_flags_t RUST_CONST_HELPER_VM_DONTDUMP = VM_DONTDUMP;
> > +const vm_flags_t RUST_CONST_HELPER_VM_SOFTDIRTY = VM_SOFTDIRTY;
> > +const vm_flags_t RUST_CONST_HELPER_VM_MIXEDMAP = VM_MIXEDMAP;
> > +const vm_flags_t RUST_CONST_HELPER_VM_HUGEPAGE = VM_HUGEPAGE;
> > +const vm_flags_t RUST_CONST_HELPER_VM_NOHUGEPAGE = VM_NOHUGEPAGE;
>
> I got this error:
>
> error[E0428]: the name `VM_SOFTDIRTY` is defined multiple times
> --> rust/bindings/bindings_generated.rs:115967:1
> |
> 13440 | pub const VM_SOFTDIRTY: u32 = 0;
> | -------------------------------- previous definition of the value `VM_SOFTDIRTY` here
> ...
> 115967 | pub const VM_SOFTDIRTY: vm_flags_t = 0;
> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `VM_SOFTDIRTY` redefined here
> |
> = note: `VM_SOFTDIRTY` must be defined only once in the value namespace of this module
>
That's odd, obviously I build tested this and didn't get the same error.
Be good to know what config options to enable for testing for rust. I repro'd
the previously reported issues, and new ones since I'm now declaring these
values consistently using BIT().
But in my build locally, no errors with LLVM=1 and CONFIG_RUST=y.
> Please add the constants in rust/bindgen_parameters next to
> ARCH_KMALLOC_MINALIGN to avoid this error. This ensures that only the
> version from bindings_helper.h is generated.
As in
--block-list-item <VM_blah> for every flag?
>
> Alice
Thanks, Lorenzo
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] mm: declare VMA flags by bit
2025-11-14 13:55 ` Lorenzo Stoakes
@ 2025-11-14 14:08 ` Alice Ryhl
2025-11-14 14:11 ` Lorenzo Stoakes
0 siblings, 1 reply; 18+ messages in thread
From: Alice Ryhl @ 2025-11-14 14:08 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, Muchun Song, Oscar Salvador, David Hildenbrand,
Liam R . Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
Wei Xu, Peter Xu, Ingo Molnar, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Kees Cook, Matthew Wilcox,
Jason Gunthorpe, John Hubbard, Leon Romanovsky, Zi Yan,
Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Xu Xin, Chengming Zhou, Jann Horn, Matthew Brost,
Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang,
Alistair Popple, Pedro Falcato, Shakeel Butt, David Rientjes,
Rik van Riel, Harry Yoo, Kemeng Shi, Kairui Song, Nhat Pham,
Baoquan He, Chris Li, Johannes Weiner, Qi Zheng, linux-kernel,
linux-fsdevel, linux-mm, Miguel Ojeda, Alex Gaynor, Boqun Feng,
Gary Guo, Bjorn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux
On Fri, Nov 14, 2025 at 3:02 PM Lorenzo Stoakes
<lorenzo.stoakes@oracle.com> wrote:
>
> On Fri, Nov 14, 2025 at 01:50:45PM +0000, Alice Ryhl wrote:
> > On Fri, Nov 14, 2025 at 01:26:08PM +0000, Lorenzo Stoakes wrote:
> > > diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
> > > index 2e43c66635a2..4c327db01ca0 100644
> > > --- a/rust/bindings/bindings_helper.h
> > > +++ b/rust/bindings/bindings_helper.h
> > > @@ -108,7 +108,32 @@ const xa_mark_t RUST_CONST_HELPER_XA_PRESENT = XA_PRESENT;
> > >
> > > const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC = XA_FLAGS_ALLOC;
> > > const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC1 = XA_FLAGS_ALLOC1;
> > > +
> > > const vm_flags_t RUST_CONST_HELPER_VM_MERGEABLE = VM_MERGEABLE;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_READ = VM_READ;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_WRITE = VM_WRITE;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_EXEC = VM_EXEC;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_SHARED = VM_SHARED;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_MAYREAD = VM_MAYREAD;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_MAYWRITE = VM_MAYWRITE;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_MAYEXEC = VM_MAYEXEC;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_MAYSHARE = VM_MAYEXEC;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_PFNMAP = VM_PFNMAP;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_IO = VM_IO;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_DONTCOPY = VM_DONTCOPY;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_DONTEXPAND = VM_DONTEXPAND;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_LOCKONFAULT = VM_LOCKONFAULT;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_ACCOUNT = VM_ACCOUNT;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_NORESERVE = VM_NORESERVE;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_HUGETLB = VM_HUGETLB;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_SYNC = VM_SYNC;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_ARCH_1 = VM_ARCH_1;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_WIPEONFORK = VM_WIPEONFORK;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_DONTDUMP = VM_DONTDUMP;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_SOFTDIRTY = VM_SOFTDIRTY;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_MIXEDMAP = VM_MIXEDMAP;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_HUGEPAGE = VM_HUGEPAGE;
> > > +const vm_flags_t RUST_CONST_HELPER_VM_NOHUGEPAGE = VM_NOHUGEPAGE;
> >
> > I got this error:
> >
> > error[E0428]: the name `VM_SOFTDIRTY` is defined multiple times
> > --> rust/bindings/bindings_generated.rs:115967:1
> > |
> > 13440 | pub const VM_SOFTDIRTY: u32 = 0;
> > | -------------------------------- previous definition of the value `VM_SOFTDIRTY` here
> > ...
> > 115967 | pub const VM_SOFTDIRTY: vm_flags_t = 0;
> > | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `VM_SOFTDIRTY` redefined here
> > |
> > = note: `VM_SOFTDIRTY` must be defined only once in the value namespace of this module
> >
>
> That's odd, obviously I build tested this and didn't get the same error.
>
> Be good to know what config options to enable for testing for rust. I repro'd
> the previously reported issues, and new ones since I'm now declaring these
> values consistently using BIT().
>
> But in my build locally, no errors with LLVM=1 and CONFIG_RUST=y.
I got this error because my config defines VM_SOFTDIRTY as VM_NONE,
which bindgen can resolve to zero. You probably have a config where
it's defined using a function-like macro, so bindgen did not generate
a duplicate for you.
> > Please add the constants in rust/bindgen_parameters next to
> > ARCH_KMALLOC_MINALIGN to avoid this error. This ensures that only the
> > version from bindings_helper.h is generated.
>
> As in
>
> --block-list-item <VM_blah> for every flag?
Yes.
Alice
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] mm: declare VMA flags by bit
2025-11-14 14:08 ` Alice Ryhl
@ 2025-11-14 14:11 ` Lorenzo Stoakes
0 siblings, 0 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-14 14:11 UTC (permalink / raw)
To: Alice Ryhl
Cc: Andrew Morton, Muchun Song, Oscar Salvador, David Hildenbrand,
Liam R . Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
Wei Xu, Peter Xu, Ingo Molnar, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Kees Cook, Matthew Wilcox,
Jason Gunthorpe, John Hubbard, Leon Romanovsky, Zi Yan,
Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Xu Xin, Chengming Zhou, Jann Horn, Matthew Brost,
Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang,
Alistair Popple, Pedro Falcato, Shakeel Butt, David Rientjes,
Rik van Riel, Harry Yoo, Kemeng Shi, Kairui Song, Nhat Pham,
Baoquan He, Chris Li, Johannes Weiner, Qi Zheng, linux-kernel,
linux-fsdevel, linux-mm, Miguel Ojeda, Alex Gaynor, Boqun Feng,
Gary Guo, Bjorn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux
On Fri, Nov 14, 2025 at 03:08:21PM +0100, Alice Ryhl wrote:
> On Fri, Nov 14, 2025 at 3:02 PM Lorenzo Stoakes
> <lorenzo.stoakes@oracle.com> wrote:
> >
> > On Fri, Nov 14, 2025 at 01:50:45PM +0000, Alice Ryhl wrote:
> > > On Fri, Nov 14, 2025 at 01:26:08PM +0000, Lorenzo Stoakes wrote:
> > > > diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
> > > > index 2e43c66635a2..4c327db01ca0 100644
> > > > --- a/rust/bindings/bindings_helper.h
> > > > +++ b/rust/bindings/bindings_helper.h
> > > > @@ -108,7 +108,32 @@ const xa_mark_t RUST_CONST_HELPER_XA_PRESENT = XA_PRESENT;
> > > >
> > > > const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC = XA_FLAGS_ALLOC;
> > > > const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC1 = XA_FLAGS_ALLOC1;
> > > > +
> > > > const vm_flags_t RUST_CONST_HELPER_VM_MERGEABLE = VM_MERGEABLE;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_READ = VM_READ;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_WRITE = VM_WRITE;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_EXEC = VM_EXEC;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_SHARED = VM_SHARED;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_MAYREAD = VM_MAYREAD;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_MAYWRITE = VM_MAYWRITE;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_MAYEXEC = VM_MAYEXEC;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_MAYSHARE = VM_MAYEXEC;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_PFNMAP = VM_PFNMAP;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_IO = VM_IO;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_DONTCOPY = VM_DONTCOPY;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_DONTEXPAND = VM_DONTEXPAND;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_LOCKONFAULT = VM_LOCKONFAULT;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_ACCOUNT = VM_ACCOUNT;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_NORESERVE = VM_NORESERVE;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_HUGETLB = VM_HUGETLB;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_SYNC = VM_SYNC;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_ARCH_1 = VM_ARCH_1;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_WIPEONFORK = VM_WIPEONFORK;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_DONTDUMP = VM_DONTDUMP;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_SOFTDIRTY = VM_SOFTDIRTY;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_MIXEDMAP = VM_MIXEDMAP;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_HUGEPAGE = VM_HUGEPAGE;
> > > > +const vm_flags_t RUST_CONST_HELPER_VM_NOHUGEPAGE = VM_NOHUGEPAGE;
> > >
> > > I got this error:
> > >
> > > error[E0428]: the name `VM_SOFTDIRTY` is defined multiple times
> > > --> rust/bindings/bindings_generated.rs:115967:1
> > > |
> > > 13440 | pub const VM_SOFTDIRTY: u32 = 0;
> > > | -------------------------------- previous definition of the value `VM_SOFTDIRTY` here
> > > ...
> > > 115967 | pub const VM_SOFTDIRTY: vm_flags_t = 0;
> > > | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `VM_SOFTDIRTY` redefined here
> > > |
> > > = note: `VM_SOFTDIRTY` must be defined only once in the value namespace of this module
> > >
> >
> > That's odd, obviously I build tested this and didn't get the same error.
> >
> > Be good to know what config options to enable for testing for rust. I repro'd
> > the previously reported issues, and new ones since I'm now declaring these
> > values consistently using BIT().
> >
> > But in my build locally, no errors with LLVM=1 and CONFIG_RUST=y.
>
> I got this error because my config defines VM_SOFTDIRTY as VM_NONE,
> which bindgen can resolve to zero. You probably have a config where
> it's defined using a function-like macro, so bindgen did not generate
> a duplicate for you.
Ugh yeah of course, damn.
>
> > > Please add the constants in rust/bindgen_parameters next to
> > > ARCH_KMALLOC_MINALIGN to avoid this error. This ensures that only the
> > > version from bindings_helper.h is generated.
> >
> > As in
> >
> > --block-list-item <VM_blah> for every flag?
>
> Yes.
OK will send a fixpatch, better to add them all to be safe.
Bit ugly but we can fix this up later when I add in the actual accessor
helpers.
>
> Alice
>
Thanks, Lorenzo
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] mm: declare VMA flags by bit
2025-11-14 13:26 ` [PATCH v2 1/4] mm: declare VMA flags by bit Lorenzo Stoakes
2025-11-14 13:50 ` Alice Ryhl
@ 2025-11-14 14:22 ` Lorenzo Stoakes
2025-11-14 15:35 ` Lorenzo Stoakes
2025-11-20 14:27 ` Lorenzo Stoakes
3 siblings, 0 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-14 14:22 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
Hi Andrew,
Please apply this fix-patch to solve an issue with the patch accidentally
causing duplication in rust bindgen when a VMA flag resolves to something
bindgen can generate itself.
To fix it, we simply blacklist all the VMA flags used by rust from bindgen
auto-generating.
I repro'd the issue locally thanks to Alice for reporting and giving
insight into the issue + explaining how to fix it! :)
Thanks, Lorenzo
----8<----
From f441480340ff608869f3655b2371ca70c77eb82b Mon Sep 17 00:00:00 2001
From: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Date: Fri, 14 Nov 2025 14:19:04 +0000
Subject: [PATCH] fixup
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
rust/bindgen_parameters | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/rust/bindgen_parameters b/rust/bindgen_parameters
index e13c6f9dd17b..fd2fd1c3cb9a 100644
--- a/rust/bindgen_parameters
+++ b/rust/bindgen_parameters
@@ -35,6 +35,31 @@
# recognized, block generation of the non-helper constants.
--blocklist-item ARCH_SLAB_MINALIGN
--blocklist-item ARCH_KMALLOC_MINALIGN
+--blocklist-item VM_MERGEABLE
+--blocklist-item VM_READ
+--blocklist-item VM_WRITE
+--blocklist-item VM_EXEC
+--blocklist-item VM_SHARED
+--blocklist-item VM_MAYREAD
+--blocklist-item VM_MAYWRITE
+--blocklist-item VM_MAYEXEC
+--blocklist-item VM_MAYEXEC
+--blocklist-item VM_PFNMAP
+--blocklist-item VM_IO
+--blocklist-item VM_DONTCOPY
+--blocklist-item VM_DONTEXPAND
+--blocklist-item VM_LOCKONFAULT
+--blocklist-item VM_ACCOUNT
+--blocklist-item VM_NORESERVE
+--blocklist-item VM_HUGETLB
+--blocklist-item VM_SYNC
+--blocklist-item VM_ARCH_1
+--blocklist-item VM_WIPEONFORK
+--blocklist-item VM_DONTDUMP
+--blocklist-item VM_SOFTDIRTY
+--blocklist-item VM_MIXEDMAP
+--blocklist-item VM_HUGEPAGE
+--blocklist-item VM_NOHUGEPAGE
# Structs should implement `Zeroable` when all of their fields do.
--with-derive-custom-struct .*=MaybeZeroable
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] mm: declare VMA flags by bit
2025-11-14 13:26 ` [PATCH v2 1/4] mm: declare VMA flags by bit Lorenzo Stoakes
2025-11-14 13:50 ` Alice Ryhl
2025-11-14 14:22 ` Lorenzo Stoakes
@ 2025-11-14 15:35 ` Lorenzo Stoakes
2025-11-20 14:27 ` Lorenzo Stoakes
3 siblings, 0 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-14 15:35 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
Hi Andrew,
In typical fashion nommu has caused a problem. Sorry to send a couple in
quick succession here, but nommu will nommu... :)
Thanks, Lorenzo
----8<----
From b14b98a2e78a06c6a3ff790bc2c188be94202e30 Mon Sep 17 00:00:00 2001
From: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Date: Fri, 14 Nov 2025 15:32:14 +0000
Subject: [PATCH] nommu fixup
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
include/linux/mm.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index ad000c472bd5..9824211d3d8e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -409,6 +409,7 @@ enum {
#define VM_UFFD_MISSING INIT_VM_FLAG(UFFD_MISSING)
#else
#define VM_UFFD_MISSING VM_NONE
+#define VM_MAYOVERLAY INIT_VM_FLAG(MAYOVERLAY)
#endif
#define VM_PFNMAP INIT_VM_FLAG(PFNMAP)
#define VM_MAYBE_GUARD INIT_VM_FLAG(MAYBE_GUARD)
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] mm: declare VMA flags by bit
2025-11-14 13:26 ` [PATCH v2 1/4] mm: declare VMA flags by bit Lorenzo Stoakes
` (2 preceding siblings ...)
2025-11-14 15:35 ` Lorenzo Stoakes
@ 2025-11-20 14:27 ` Lorenzo Stoakes
3 siblings, 0 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-20 14:27 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
Hi Andrew,
Sorry to be a pain, seems build bots are sleeping on parisc32/64 as there was
some accidental duplication of VM_STACK_EARLY when CONFIG_STACK_GROWSUP is
specified (currently only a parisc thing :).
The attached fix-patch fixes this and some broken whitespace.
Many thanks to David H. who noticed this and pinged me off-list!
Cheers, Lorenzo
----8<----
From d706def8a4511b42bc7c7da0a01a3f30cd054e6e Mon Sep 17 00:00:00 2001
From: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Date: Thu, 20 Nov 2025 14:23:13 +0000
Subject: [PATCH] fixup
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
include/linux/mm.h | 8 --------
1 file changed, 8 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 3148be546e11..5f7f4aad1d26 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -529,14 +529,6 @@ enum {
#define VM_STARTGAP_FLAGS (VM_GROWSDOWN | VM_SHADOW_STACK)
-
-
-#ifdef CONFIG_STACK_GROWSUP
-#define VM_STACK_EARLY VMA_BIT(VMA_STACK_EARLY_BIT)
-#else
-#define VM_STACK_EARLY VM_NONE
-#endif
-
#ifdef CONFIG_MSEAL_SYSTEM_MAPPINGS
#define VM_SEALED_SYSMAP VM_SEALED
#else
--
2.51.2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 0/4] initial work on making VMA flags a bitmap
2025-11-14 13:26 [PATCH v2 0/4] initial work on making VMA flags a bitmap Lorenzo Stoakes
` (3 preceding siblings ...)
2025-11-14 13:26 ` [PATCH v2 4/4] mm: introduce VMA flags bitmap type Lorenzo Stoakes
@ 2025-11-21 14:50 ` Vlastimil Babka
2025-11-21 17:20 ` Lorenzo Stoakes
4 siblings, 1 reply; 18+ messages in thread
From: Vlastimil Babka @ 2025-11-21 14:50 UTC (permalink / raw)
To: Lorenzo Stoakes, Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Axel Rasmussen,
Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar, Peter Zijlstra,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
Ben Segall, Mel Gorman, Valentin Schneider, Kees Cook,
Matthew Wilcox, Jason Gunthorpe, John Hubbard, Leon Romanovsky,
Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Xu Xin, Chengming Zhou, Jann Horn,
Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
On 11/14/25 14:26, Lorenzo Stoakes wrote:
> We are in the rather silly situation that we are running out of VMA flags
> as they are currently limited to a system word in size.
>
> This leads to absurd situations where we limit features to 64-bit
> architectures only because we simply do not have the ability to add a flag
> for 32-bit ones.
>
> This is very constraining and leads to hacks or, in the worst case, simply
> an inability to implement features we want for entirely arbitrary reasons.
>
> This also of course gives us something of a Y2K type situation in mm where
> we might eventually exhaust all of the VMA flags even on 64-bit systems.
>
> This series lays the groundwork for getting away from this limitation by
> establishing VMA flags as a bitmap whose size we can increase in future
> beyond 64 bits if required.
>
> This is necessarily a highly iterative process given the extensive use of
> VMA flags throughout the kernel, so we start by performing basic steps.
>
> Firstly, we declare VMA flags by bit number rather than by value, retaining
> the VM_xxx fields but in terms of these newly introduced VMA_xxx_BIT
> fields.
>
> While we are here, we use sparse annotations to ensure that, when dealing
> with VMA bit number parameters, we cannot be passed values which are not
> declared as such - providing some useful type safety.
>
> We then introduce an opaque VMA flag type, much like the opaque mm_struct
> flag type introduced in commit bb6525f2f8c4 ("mm: add bitmap mm->flags
> field"), which we establish in union with vma->vm_flags (but still set at
> system word size meaning there is no functional or data type size change).
>
> We update the vm_flags_xxx() helpers to use this new bitmap, introducing
> sensible helpers to do so.
>
> This series lays the foundation for further work to expand the use of
> bitmap VMA flags and eventually eliminate these arbitrary restrictions.
>
>
> v2:
> * Corrected kdoc for vma_flag_t.
> * Introduced DECLARE_VMA_BIT() as per Jason. We can't also declare the VMA
> flags in the enum as this breaks assumptions in the kernel, resulting in
> errors like 'enum constant in boolean context
> [-Werror=int-in-bool-context]'.
> * Dropped the conversion patch - To make life simpler this cycle, let's just
> fixup the flag declarations and introduce the new field type and introduce
> vm_flags_*() changes. We can do more later.
> * Split out VMA testing vma->__vm_flags change.
> * Fixed vma_flag_*_atomic() helper functions for sparse purposes to work
> with vma_flag_t.
> * Fixed rust breakages as reported by Nico and help provided by Alice. For
> now we are doing a minimal fix, we can do a more substantial one once the
> VMA flag helper functions are introduced in an upcoming series.
>
> v1:
> https://lore.kernel.org/all/cover.1761757731.git.lorenzo.stoakes@oracle.com/
>
> Lorenzo Stoakes (4):
> mm: declare VMA flags by bit
> mm: simplify and rename mm flags function for clarity
> tools/testing/vma: eliminate dependency on vma->__vm_flags
> mm: introduce VMA flags bitmap type
Acked-by: Vlastimil Babka <vbabka@suse.cz>
However something has happened to patch 4/4 in git, it has a very different
tools/testing/vma/vma_internal.h:
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?h=mm-stable&id=c3f7c506e8f122a31b9cc01d234e7fcda46b0eca
>
> fs/proc/task_mmu.c | 4 +-
> include/linux/mm.h | 400 +++++++++++++++------------
> include/linux/mm_types.h | 78 +++++-
> kernel/fork.c | 4 +-
> mm/khugepaged.c | 2 +-
> mm/madvise.c | 2 +-
> rust/bindings/bindings_helper.h | 25 ++
> rust/kernel/mm/virt.rs | 2 +-
> tools/testing/vma/vma.c | 20 +-
> tools/testing/vma/vma_internal.h | 446 ++++++++++++++++++++++++++-----
> 10 files changed, 716 insertions(+), 267 deletions(-)
>
> --
> 2.51.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 0/4] initial work on making VMA flags a bitmap
2025-11-21 14:50 ` [PATCH v2 0/4] initial work on making VMA flags a bitmap Vlastimil Babka
@ 2025-11-21 17:20 ` Lorenzo Stoakes
0 siblings, 0 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-21 17:20 UTC (permalink / raw)
To: Vlastimil Babka
Cc: Andrew Morton, Muchun Song, Oscar Salvador, David Hildenbrand,
Liam R . Howlett, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
On Fri, Nov 21, 2025 at 03:50:53PM +0100, Vlastimil Babka wrote:
> On 11/14/25 14:26, Lorenzo Stoakes wrote:
> > We are in the rather silly situation that we are running out of VMA flags
> > as they are currently limited to a system word in size.
> >
> > This leads to absurd situations where we limit features to 64-bit
> > architectures only because we simply do not have the ability to add a flag
> > for 32-bit ones.
> >
> > This is very constraining and leads to hacks or, in the worst case, simply
> > an inability to implement features we want for entirely arbitrary reasons.
> >
> > This also of course gives us something of a Y2K type situation in mm where
> > we might eventually exhaust all of the VMA flags even on 64-bit systems.
> >
> > This series lays the groundwork for getting away from this limitation by
> > establishing VMA flags as a bitmap whose size we can increase in future
> > beyond 64 bits if required.
> >
> > This is necessarily a highly iterative process given the extensive use of
> > VMA flags throughout the kernel, so we start by performing basic steps.
> >
> > Firstly, we declare VMA flags by bit number rather than by value, retaining
> > the VM_xxx fields but in terms of these newly introduced VMA_xxx_BIT
> > fields.
> >
> > While we are here, we use sparse annotations to ensure that, when dealing
> > with VMA bit number parameters, we cannot be passed values which are not
> > declared as such - providing some useful type safety.
> >
> > We then introduce an opaque VMA flag type, much like the opaque mm_struct
> > flag type introduced in commit bb6525f2f8c4 ("mm: add bitmap mm->flags
> > field"), which we establish in union with vma->vm_flags (but still set at
> > system word size meaning there is no functional or data type size change).
> >
> > We update the vm_flags_xxx() helpers to use this new bitmap, introducing
> > sensible helpers to do so.
> >
> > This series lays the foundation for further work to expand the use of
> > bitmap VMA flags and eventually eliminate these arbitrary restrictions.
> >
> >
> > v2:
> > * Corrected kdoc for vma_flag_t.
> > * Introduced DECLARE_VMA_BIT() as per Jason. We can't also declare the VMA
> > flags in the enum as this breaks assumptions in the kernel, resulting in
> > errors like 'enum constant in boolean context
> > [-Werror=int-in-bool-context]'.
> > * Dropped the conversion patch - To make life simpler this cycle, let's just
> > fixup the flag declarations and introduce the new field type and introduce
> > vm_flags_*() changes. We can do more later.
> > * Split out VMA testing vma->__vm_flags change.
> > * Fixed vma_flag_*_atomic() helper functions for sparse purposes to work
> > with vma_flag_t.
> > * Fixed rust breakages as reported by Nico and help provided by Alice. For
> > now we are doing a minimal fix, we can do a more substantial one once the
> > VMA flag helper functions are introduced in an upcoming series.
> >
> > v1:
> > https://lore.kernel.org/all/cover.1761757731.git.lorenzo.stoakes@oracle.com/
> >
> > Lorenzo Stoakes (4):
> > mm: declare VMA flags by bit
> > mm: simplify and rename mm flags function for clarity
> > tools/testing/vma: eliminate dependency on vma->__vm_flags
> > mm: introduce VMA flags bitmap type
>
> Acked-by: Vlastimil Babka <vbabka@suse.cz>
Thanks!
>
> However something has happened to patch 4/4 in git, it has a very different
> tools/testing/vma/vma_internal.h:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?h=mm-stable&id=c3f7c506e8f122a31b9cc01d234e7fcda46b0eca
Yeah something has gone very wrong here :)
3/4 also has an issue annoyingly, I tested it locally with no issues but
now it seems to have issues... but also it seems like it should _always_
have.
Anyway let me address each at a time I guess... :)
>
> >
> > fs/proc/task_mmu.c | 4 +-
> > include/linux/mm.h | 400 +++++++++++++++------------
> > include/linux/mm_types.h | 78 +++++-
> > kernel/fork.c | 4 +-
> > mm/khugepaged.c | 2 +-
> > mm/madvise.c | 2 +-
> > rust/bindings/bindings_helper.h | 25 ++
> > rust/kernel/mm/virt.rs | 2 +-
> > tools/testing/vma/vma.c | 20 +-
> > tools/testing/vma/vma_internal.h | 446 ++++++++++++++++++++++++++-----
> > 10 files changed, 716 insertions(+), 267 deletions(-)
> >
> > --
> > 2.51.0
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 3/4] tools/testing/vma: eliminate dependency on vma->__vm_flags
2025-11-14 13:26 ` [PATCH v2 3/4] tools/testing/vma: eliminate dependency on vma->__vm_flags Lorenzo Stoakes
@ 2025-11-21 17:28 ` Lorenzo Stoakes
0 siblings, 0 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-21 17:28 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
Hi Andrew,
Some small silly issue here, for some reason I seemed to have vm_flags_reset()
available from the VMA tests when I tested but err, that doesn't seem to be the
case at all.
Again I realise this is in mm-stable so this might be fiddly so we might have to
live with minor bisect pain :(
Cheers, Lorenzo
----8<----
From afe5af105e7d64e39a4280c7fc8b34ad67cf0db0 Mon Sep 17 00:00:00 2001
From: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Date: Fri, 21 Nov 2025 17:25:18 +0000
Subject: [PATCH] tools/testing/vma: add missing stub
The vm_flags_reset() function is not available in the userland VMA tests,
so add a stub which const-casts vma->vm_flags and avoids the upcoming
removal of the vma->__vm_flags field.
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
tools/testing/vma/vma_internal.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tools/testing/vma/vma_internal.h b/tools/testing/vma/vma_internal.h
index 37fd479d49ce..f90a9b3c1880 100644
--- a/tools/testing/vma/vma_internal.h
+++ b/tools/testing/vma/vma_internal.h
@@ -1760,4 +1760,11 @@ static inline int do_munmap(struct mm_struct *, unsigned long, size_t,
return 0;
}
+static inline void vm_flags_reset(struct vm_area_struct *vma, vm_flags_t flags)
+{
+ vm_flags_t *dst = (vm_flags_t *)(&vma->vm_flags);
+
+ *dst = flags;
+}
+
#endif /* __MM_VMA_INTERNAL_H */
--
2.51.2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 4/4] mm: introduce VMA flags bitmap type
2025-11-14 13:26 ` [PATCH v2 4/4] mm: introduce VMA flags bitmap type Lorenzo Stoakes
@ 2025-11-21 17:44 ` Lorenzo Stoakes
2025-11-21 18:51 ` Andrew Morton
0 siblings, 1 reply; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-21 17:44 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
As Vlastimil noticed, something has gone fairly horribly wrong here in the
actual commit [0] vs. the patch here for tools/testing/vma/vma_internal.h.
We should only have the delta shown here, let me know if I need to help with a
conflict resolution! :)
Thanks, Lorenzo
[0]: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?h=mm-stable&id=c3f7c506e8f122a31b9cc01d234e7fcda46b0eca
On Fri, Nov 14, 2025 at 01:26:11PM +0000, Lorenzo Stoakes wrote:
> It is useful to transition to using a bitmap for VMA flags so we can avoid
> running out of flags, especially for 32-bit kernels which are constrained
> to 32 flags, necessitating some features to be limited to 64-bit kernels
> only.
>
> By doing so, we remove any constraint on the number of VMA flags moving
> forwards no matter the platform and can decide in future to extend beyond
> 64 if required.
>
> We start by declaring an opaque types, vma_flags_t (which resembles
> mm_struct flags of type mm_flags_t), setting it to precisely the same size
> as vm_flags_t, and place it in union with vm_flags in the VMA declaration.
>
> We additionally update struct vm_area_desc equivalently placing the new
> opaque type in union with vm_flags.
>
> This change therefore does not impact the size of struct vm_area_struct or
> struct vm_area_desc.
>
> In order for the change to be iterative and to avoid impacting performance,
> we designate VM_xxx declared bitmap flag values as those which must exist
> in the first system word of the VMA flags bitmap.
>
> We therefore declare vma_flags_clear_all(), vma_flags_overwrite_word(),
> vma_flags_overwrite_word(), vma_flags_overwrite_word_once(),
> vma_flags_set_word() and vma_flags_clear_word() in order to allow us to
> update the existing vm_flags_*() functions to utilise these helpers.
>
> This is a stepping stone towards converting users to the VMA flags bitmap
> and behaves precisely as before.
>
> By doing this, we can eliminate the existing private vma->__vm_flags field
> in the vma->vm_flags union and replace it with the newly introduced opaque
> type vma_flags, which we call flags so we refer to the new bitmap field as
> vma->flags.
>
> We update vma_flag_[test, set]_atomic() to account for the change also.
>
> We additionally update the VMA userland test declarations to implement the
> same changes there.
>
> Finally, we update the rust code to reference vma->vm_flags on update
> rather than vma->__vm_flags which has been removed. This is safe for now,
> albeit it is implicitly performing a const cast.
>
> Once we introduce flag helpers we can improve this more.
>
> No functional change intended.
>
> Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> ---
> include/linux/mm.h | 18 ++--
> include/linux/mm_types.h | 64 +++++++++++++-
> rust/kernel/mm/virt.rs | 2 +-
> tools/testing/vma/vma_internal.h | 143 ++++++++++++++++++++++++++-----
> 4 files changed, 196 insertions(+), 31 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index ad000c472bd5..79345c44a350 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -919,7 +919,8 @@ static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
> static inline void vm_flags_init(struct vm_area_struct *vma,
> vm_flags_t flags)
> {
> - ACCESS_PRIVATE(vma, __vm_flags) = flags;
> + vma_flags_clear_all(&vma->flags);
> + vma_flags_overwrite_word(&vma->flags, flags);
> }
>
> /*
> @@ -938,21 +939,26 @@ static inline void vm_flags_reset_once(struct vm_area_struct *vma,
> vm_flags_t flags)
> {
> vma_assert_write_locked(vma);
> - WRITE_ONCE(ACCESS_PRIVATE(vma, __vm_flags), flags);
> + /*
> + * The user should only be interested in avoiding reordering of
> + * assignment to the first word.
> + */
> + vma_flags_clear_all(&vma->flags);
> + vma_flags_overwrite_word_once(&vma->flags, flags);
> }
>
> static inline void vm_flags_set(struct vm_area_struct *vma,
> vm_flags_t flags)
> {
> vma_start_write(vma);
> - ACCESS_PRIVATE(vma, __vm_flags) |= flags;
> + vma_flags_set_word(&vma->flags, flags);
> }
>
> static inline void vm_flags_clear(struct vm_area_struct *vma,
> vm_flags_t flags)
> {
> vma_start_write(vma);
> - ACCESS_PRIVATE(vma, __vm_flags) &= ~flags;
> + vma_flags_clear_word(&vma->flags, flags);
> }
>
> /*
> @@ -995,12 +1001,14 @@ static inline bool __vma_flag_atomic_valid(struct vm_area_struct *vma,
> static inline void vma_flag_set_atomic(struct vm_area_struct *vma,
> vma_flag_t bit)
> {
> + unsigned long *bitmap = ACCESS_PRIVATE(&vma->flags, __vma_flags);
> +
> /* mmap read lock/VMA read lock must be held. */
> if (!rwsem_is_locked(&vma->vm_mm->mmap_lock))
> vma_assert_locked(vma);
>
> if (__vma_flag_atomic_valid(vma, bit))
> - set_bit((__force int)bit, &ACCESS_PRIVATE(vma, __vm_flags));
> + set_bit((__force int)bit, bitmap);
> }
>
> /*
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 3550672e0f9e..b71625378ce3 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -848,6 +848,15 @@ struct mmap_action {
> bool hide_from_rmap_until_complete :1;
> };
>
> +/*
> + * Opaque type representing current VMA (vm_area_struct) flag state. Must be
> + * accessed via vma_flags_xxx() helper functions.
> + */
> +#define NUM_VMA_FLAG_BITS BITS_PER_LONG
> +typedef struct {
> + DECLARE_BITMAP(__vma_flags, NUM_VMA_FLAG_BITS);
> +} __private vma_flags_t;
> +
> /*
> * Describes a VMA that is about to be mmap()'ed. Drivers may choose to
> * manipulate mutable fields which will cause those fields to be updated in the
> @@ -865,7 +874,10 @@ struct vm_area_desc {
> /* Mutable fields. Populated with initial state. */
> pgoff_t pgoff;
> struct file *vm_file;
> - vm_flags_t vm_flags;
> + union {
> + vm_flags_t vm_flags;
> + vma_flags_t vma_flags;
> + };
> pgprot_t page_prot;
>
> /* Write-only fields. */
> @@ -910,10 +922,12 @@ struct vm_area_struct {
> /*
> * Flags, see mm.h.
> * To modify use vm_flags_{init|reset|set|clear|mod} functions.
> + * Preferably, use vma_flags_xxx() functions.
> */
> union {
> + /* Temporary while VMA flags are being converted. */
> const vm_flags_t vm_flags;
> - vm_flags_t __private __vm_flags;
> + vma_flags_t flags;
> };
>
> #ifdef CONFIG_PER_VMA_LOCK
> @@ -994,6 +1008,52 @@ struct vm_area_struct {
> #endif
> } __randomize_layout;
>
> +/* Clears all bits in the VMA flags bitmap, non-atomically. */
> +static inline void vma_flags_clear_all(vma_flags_t *flags)
> +{
> + bitmap_zero(ACCESS_PRIVATE(flags, __vma_flags), NUM_VMA_FLAG_BITS);
> +}
> +
> +/*
> + * Copy value to the first system word of VMA flags, non-atomically.
> + *
> + * IMPORTANT: This does not overwrite bytes past the first system word. The
> + * caller must account for this.
> + */
> +static inline void vma_flags_overwrite_word(vma_flags_t *flags, unsigned long value)
> +{
> + *ACCESS_PRIVATE(flags, __vma_flags) = value;
> +}
> +
> +/*
> + * Copy value to the first system word of VMA flags ONCE, non-atomically.
> + *
> + * IMPORTANT: This does not overwrite bytes past the first system word. The
> + * caller must account for this.
> + */
> +static inline void vma_flags_overwrite_word_once(vma_flags_t *flags, unsigned long value)
> +{
> + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
> +
> + WRITE_ONCE(*bitmap, value);
> +}
> +
> +/* Update the first system word of VMA flags setting bits, non-atomically. */
> +static inline void vma_flags_set_word(vma_flags_t *flags, unsigned long value)
> +{
> + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
> +
> + *bitmap |= value;
> +}
> +
> +/* Update the first system word of VMA flags clearing bits, non-atomically. */
> +static inline void vma_flags_clear_word(vma_flags_t *flags, unsigned long value)
> +{
> + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
> +
> + *bitmap &= ~value;
> +}
> +
> #ifdef CONFIG_NUMA
> #define vma_policy(vma) ((vma)->vm_policy)
> #else
> diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs
> index a1bfa4e19293..da21d65ccd20 100644
> --- a/rust/kernel/mm/virt.rs
> +++ b/rust/kernel/mm/virt.rs
> @@ -250,7 +250,7 @@ unsafe fn update_flags(&self, set: vm_flags_t, unset: vm_flags_t) {
> // SAFETY: This is not a data race: the vma is undergoing initial setup, so it's not yet
> // shared. Additionally, `VmaNew` is `!Sync`, so it cannot be used to write in parallel.
> // The caller promises that this does not set the flags to an invalid value.
> - unsafe { (*self.as_ptr()).__bindgen_anon_2.__vm_flags = flags };
> + unsafe { (*self.as_ptr()).__bindgen_anon_2.vm_flags = flags };
> }
>
> /// Set the `VM_MIXEDMAP` flag on this vma.
> diff --git a/tools/testing/vma/vma_internal.h b/tools/testing/vma/vma_internal.h
> index 18659214e262..13ee825bdfcf 100644
> --- a/tools/testing/vma/vma_internal.h
> +++ b/tools/testing/vma/vma_internal.h
> @@ -528,6 +528,15 @@ typedef struct {
> __private DECLARE_BITMAP(__mm_flags, NUM_MM_FLAG_BITS);
> } mm_flags_t;
>
> +/*
> + * Opaque type representing current VMA (vm_area_struct) flag state. Must be
> + * accessed via vma_flags_xxx() helper functions.
> + */
> +#define NUM_VMA_FLAG_BITS BITS_PER_LONG
> +typedef struct {
> + DECLARE_BITMAP(__vma_flags, NUM_VMA_FLAG_BITS);
> +} __private vma_flags_t;
> +
> struct mm_struct {
> struct maple_tree mm_mt;
> int map_count; /* number of VMAs */
> @@ -612,7 +621,10 @@ struct vm_area_desc {
> /* Mutable fields. Populated with initial state. */
> pgoff_t pgoff;
> struct file *vm_file;
> - vm_flags_t vm_flags;
> + union {
> + vm_flags_t vm_flags;
> + vma_flags_t vma_flags;
> + };
> pgprot_t page_prot;
>
> /* Write-only fields. */
> @@ -658,7 +670,7 @@ struct vm_area_struct {
> */
> union {
> const vm_flags_t vm_flags;
> - vm_flags_t __private __vm_flags;
> + vma_flags_t flags;
> };
>
> #ifdef CONFIG_PER_VMA_LOCK
> @@ -1372,26 +1384,6 @@ static inline bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags,
> return true;
> }
>
> -static inline void vm_flags_init(struct vm_area_struct *vma,
> - vm_flags_t flags)
> -{
> - vma->__vm_flags = flags;
> -}
> -
> -static inline void vm_flags_set(struct vm_area_struct *vma,
> - vm_flags_t flags)
> -{
> - vma_start_write(vma);
> - vma->__vm_flags |= flags;
> -}
> -
> -static inline void vm_flags_clear(struct vm_area_struct *vma,
> - vm_flags_t flags)
> -{
> - vma_start_write(vma);
> - vma->__vm_flags &= ~flags;
> -}
> -
> static inline int shmem_zero_setup(struct vm_area_struct *vma)
> {
> return 0;
> @@ -1548,13 +1540,118 @@ static inline void userfaultfd_unmap_complete(struct mm_struct *mm,
> {
> }
>
> -# define ACCESS_PRIVATE(p, member) ((p)->member)
> +#define ACCESS_PRIVATE(p, member) ((p)->member)
> +
> +#define bitmap_size(nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE)
> +
> +static __always_inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
> +{
> + unsigned int len = bitmap_size(nbits);
> +
> + if (small_const_nbits(nbits))
> + *dst = 0;
> + else
> + memset(dst, 0, len);
> +}
>
> static inline bool mm_flags_test(int flag, const struct mm_struct *mm)
> {
> return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
> }
>
> +/* Clears all bits in the VMA flags bitmap, non-atomically. */
> +static inline void vma_flags_clear_all(vma_flags_t *flags)
> +{
> + bitmap_zero(ACCESS_PRIVATE(flags, __vma_flags), NUM_VMA_FLAG_BITS);
> +}
> +
> +/*
> + * Copy value to the first system word of VMA flags, non-atomically.
> + *
> + * IMPORTANT: This does not overwrite bytes past the first system word. The
> + * caller must account for this.
> + */
> +static inline void vma_flags_overwrite_word(vma_flags_t *flags, unsigned long value)
> +{
> + *ACCESS_PRIVATE(flags, __vma_flags) = value;
> +}
> +
> +/*
> + * Copy value to the first system word of VMA flags ONCE, non-atomically.
> + *
> + * IMPORTANT: This does not overwrite bytes past the first system word. The
> + * caller must account for this.
> + */
> +static inline void vma_flags_overwrite_word_once(vma_flags_t *flags, unsigned long value)
> +{
> + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
> +
> + WRITE_ONCE(*bitmap, value);
> +}
> +
> +/* Update the first system word of VMA flags setting bits, non-atomically. */
> +static inline void vma_flags_set_word(vma_flags_t *flags, unsigned long value)
> +{
> + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
> +
> + *bitmap |= value;
> +}
> +
> +/* Update the first system word of VMA flags clearing bits, non-atomically. */
> +static inline void vma_flags_clear_word(vma_flags_t *flags, unsigned long value)
> +{
> + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags);
> +
> + *bitmap &= ~value;
> +}
> +
> +
> +/* Use when VMA is not part of the VMA tree and needs no locking */
> +static inline void vm_flags_init(struct vm_area_struct *vma,
> + vm_flags_t flags)
> +{
> + vma_flags_clear_all(&vma->flags);
> + vma_flags_overwrite_word(&vma->flags, flags);
> +}
> +
> +/*
> + * Use when VMA is part of the VMA tree and modifications need coordination
> + * Note: vm_flags_reset and vm_flags_reset_once do not lock the vma and
> + * it should be locked explicitly beforehand.
> + */
> +static inline void vm_flags_reset(struct vm_area_struct *vma,
> + vm_flags_t flags)
> +{
> + vma_assert_write_locked(vma);
> + vm_flags_init(vma, flags);
> +}
> +
> +static inline void vm_flags_reset_once(struct vm_area_struct *vma,
> + vm_flags_t flags)
> +{
> + vma_assert_write_locked(vma);
> + /*
> + * The user should only be interested in avoiding reordering of
> + * assignment to the first word.
> + */
> + vma_flags_clear_all(&vma->flags);
> + vma_flags_overwrite_word_once(&vma->flags, flags);
> +}
> +
> +static inline void vm_flags_set(struct vm_area_struct *vma,
> + vm_flags_t flags)
> +{
> + vma_start_write(vma);
> + vma_flags_set_word(&vma->flags, flags);
> +}
> +
> +static inline void vm_flags_clear(struct vm_area_struct *vma,
> + vm_flags_t flags)
> +{
> + vma_start_write(vma);
> + vma_flags_clear_word(&vma->flags, flags);
> +}
> +
> /*
> * Denies creating a writable executable mapping or gaining executable permissions.
> *
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 4/4] mm: introduce VMA flags bitmap type
2025-11-21 17:44 ` Lorenzo Stoakes
@ 2025-11-21 18:51 ` Andrew Morton
2025-11-21 19:26 ` Lorenzo Stoakes
0 siblings, 1 reply; 18+ messages in thread
From: Andrew Morton @ 2025-11-21 18:51 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
On Fri, 21 Nov 2025 17:44:43 +0000 Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> As Vlastimil noticed, something has gone fairly horribly wrong here in the
> actual commit [0] vs. the patch here for tools/testing/vma/vma_internal.h.
>
> We should only have the delta shown here, let me know if I need to help with a
> conflict resolution! :)
OK, thanks, easy fix.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 4/4] mm: introduce VMA flags bitmap type
2025-11-21 18:51 ` Andrew Morton
@ 2025-11-21 19:26 ` Lorenzo Stoakes
0 siblings, 0 replies; 18+ messages in thread
From: Lorenzo Stoakes @ 2025-11-21 19:26 UTC (permalink / raw)
To: Andrew Morton
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Peter Xu, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Kees Cook, Matthew Wilcox, Jason Gunthorpe, John Hubbard,
Leon Romanovsky, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, Xu Xin, Chengming Zhou,
Jann Horn, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Pedro Falcato,
Shakeel Butt, David Rientjes, Rik van Riel, Harry Yoo, Kemeng Shi,
Kairui Song, Nhat Pham, Baoquan He, Chris Li, Johannes Weiner,
Qi Zheng, linux-kernel, linux-fsdevel, linux-mm, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux
On Fri, Nov 21, 2025 at 10:51:31AM -0800, Andrew Morton wrote:
> On Fri, 21 Nov 2025 17:44:43 +0000 Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
>
> > As Vlastimil noticed, something has gone fairly horribly wrong here in the
> > actual commit [0] vs. the patch here for tools/testing/vma/vma_internal.h.
> >
> > We should only have the delta shown here, let me know if I need to help with a
> > conflict resolution! :)
>
> OK, thanks, easy fix.
Perfect, thanks! :)
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2025-11-21 19:26 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-14 13:26 [PATCH v2 0/4] initial work on making VMA flags a bitmap Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 1/4] mm: declare VMA flags by bit Lorenzo Stoakes
2025-11-14 13:50 ` Alice Ryhl
2025-11-14 13:55 ` Lorenzo Stoakes
2025-11-14 14:08 ` Alice Ryhl
2025-11-14 14:11 ` Lorenzo Stoakes
2025-11-14 14:22 ` Lorenzo Stoakes
2025-11-14 15:35 ` Lorenzo Stoakes
2025-11-20 14:27 ` Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 2/4] mm: simplify and rename mm flags function for clarity Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 3/4] tools/testing/vma: eliminate dependency on vma->__vm_flags Lorenzo Stoakes
2025-11-21 17:28 ` Lorenzo Stoakes
2025-11-14 13:26 ` [PATCH v2 4/4] mm: introduce VMA flags bitmap type Lorenzo Stoakes
2025-11-21 17:44 ` Lorenzo Stoakes
2025-11-21 18:51 ` Andrew Morton
2025-11-21 19:26 ` Lorenzo Stoakes
2025-11-21 14:50 ` [PATCH v2 0/4] initial work on making VMA flags a bitmap Vlastimil Babka
2025-11-21 17:20 ` Lorenzo Stoakes
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).