From: Lorenzo Stoakes <ljs@kernel.org>
To: "Kiryl Shutsemau (Meta)" <kas@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Mike Rapoport <rppt@kernel.org>,
David Hildenbrand <david@kernel.org>,
stable@vger.kernel.org,
Sashiko AI review <sashiko-bot@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
Vlastimil Babka <vbabka@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>, Peter Xu <peterx@redhat.com>,
Pedro Falcato <pfalcato@suse.de>,
Alice Ryhl <aliceryhl@google.com>
Subject: Re: [PATCH 6/6] userfaultfd: build __VMA_UFFD_FLAGS from config-gated masks
Date: Mon, 1 Jun 2026 19:34:29 +0100 [thread overview]
Message-ID: <ah3LooI6IVQBZ9P1@lucifer> (raw)
In-Reply-To: <20260529172331.356655-7-kas@kernel.org>
On Fri, May 29, 2026 at 06:23:30PM +0100, Kiryl Shutsemau (Meta) wrote:
> The VMA flags bitmap is a single word today: NUM_VMA_FLAG_BITS is
> BITS_PER_LONG, so on 32-bit vma_flags_t holds only 32 bits. (The bitmap
> type exists so this can grow past BITS_PER_LONG later; until it does,
> anything declared above the first word is out of range on 32-bit.) The bit
> enum nevertheless declares some bits unconditionally above BITS_PER_LONG --
> VMA_UFFD_MINOR_BIT is 41, with VM_UFFD_MINOR == VM_NONE on 32-bit so no VMA
> actually carries the bit.
>
> __VMA_UFFD_FLAGS feeds VMA_UFFD_MINOR_BIT to mk_vma_flags() unconditionally.
> On 32-bit that becomes __set_bit(41, &one_long), a write one word past the
> end of the single-word bitmap. The compiler folds the out-of-bounds store
> with wraparound (1UL << (41 % 32) == bit 9) into the first word; bit 9 is
> already in __VMA_UFFD_FLAGS so the mask happens to come out right today, but
> it is an out-of-bounds write all the same, and any high-numbered bit whose
> mod-BITS_PER_LONG position is otherwise unused would silently OR an extra
> bit into the mask.
>
> Rather than feed bit numbers that may not exist on the current build to
> mk_vma_flags(), build the mask from whole per-mode masks that collapse to
> EMPTY_VMA_FLAGS when their feature is unavailable. Add
> mk_vma_flags_from_masks() for that, and define VMA_UFFD_MISSING / _WP /
> _MINOR alongside the VM_UFFD_* flags, gating VMA_UFFD_MINOR on the same
> config as VM_UFFD_MINOR (which implies 64BIT, where bit 41 fits). An
> out-of-range bit is then never materialised, on any arch, and the in-range
> fast path stays a compile-time constant.
>
> Fixes: 9ea35a25d51b ("mm: introduce VMA flags bitmap type")
Hmm, I think commit a06eb2f8279e ("mm/vma: convert
vma_modify_flags[_uffd]() to use vma_flags_t") is more appropriate isn't
it?
As that's the commit that added __VMA_UFFD_FLAGS :)
> Cc: stable@vger.kernel.org
> Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
> Suggested-by: Lorenzo Stoakes <ljs@kernel.org>
> Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
The change LGTM, so:
Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
> Assisted-by: Claude:claude-opus-4-8
> ---
> include/linux/mm.h | 39 +++++++++++++++++++++++++++++++++++
> include/linux/userfaultfd_k.h | 4 ++--
> 2 files changed, 41 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 0f2612a70fb1..485df9c2dbdd 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -496,6 +496,21 @@ enum {
> #else
> #define VM_UFFD_MINOR VM_NONE
> #endif
> +
> +/*
> + * vma_flags_t masks for the userfaultfd VMA flags. VMA_UFFD_MINOR is gated on
> + * the same config as VM_UFFD_MINOR -- which implies 64BIT, where the bit fits
> + * -- so an out-of-range bit is never fed to mk_vma_flags() on a build whose
> + * bitmap cannot hold it.
> + */
> +#define VMA_UFFD_MISSING mk_vma_flags(VMA_UFFD_MISSING_BIT)
> +#define VMA_UFFD_WP mk_vma_flags(VMA_UFFD_WP_BIT)
> +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR
> +#define VMA_UFFD_MINOR mk_vma_flags(VMA_UFFD_MINOR_BIT)
> +#else
> +#define VMA_UFFD_MINOR EMPTY_VMA_FLAGS
> +#endif
> +
> #ifdef CONFIG_64BIT
> #define VM_ALLOW_ANY_UNCACHED INIT_VM_FLAG(ALLOW_ANY_UNCACHED)
> #define VM_SEALED INIT_VM_FLAG(SEALED)
> @@ -1238,6 +1253,30 @@ static __always_inline void vma_flags_set_mask(vma_flags_t *flags,
> #define vma_flags_set(flags, ...) \
> vma_flags_set_mask(flags, mk_vma_flags(__VA_ARGS__))
>
> +static __always_inline vma_flags_t __mk_vma_flags_from_masks(size_t count,
> + const vma_flags_t *masks)
> +{
> + vma_flags_t flags = EMPTY_VMA_FLAGS;
> + size_t i;
> +
> + for (i = 0; i < count; i++)
> + vma_flags_set_mask(&flags, masks[i]);
> + return flags;
> +}
> +
> +/*
> + * Combine pre-computed vma_flags_t masks into one value, e.g.:
> + *
> + * vma_flags_t flags = mk_vma_flags_from_masks(VMA_UFFD_WP, VMA_UFFD_MINOR);
> + *
> + * Unlike mk_vma_flags(), which takes bit numbers, this takes whole masks --
> + * each of which may be EMPTY_VMA_FLAGS when its feature is unavailable -- so a
> + * bit that does not exist on the current build is never materialised.
> + */
> +#define mk_vma_flags_from_masks(...) \
> + __mk_vma_flags_from_masks(COUNT_ARGS(__VA_ARGS__), \
> + (const vma_flags_t []){__VA_ARGS__})
> +
> /* Clear all of the to-clear flags in flags, non-atomically. */
> static __always_inline void vma_flags_clear_mask(vma_flags_t *flags,
> vma_flags_t to_clear)
> diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
> index 3ec8e1071673..68edac4dcd78 100644
> --- a/include/linux/userfaultfd_k.h
> +++ b/include/linux/userfaultfd_k.h
> @@ -23,8 +23,8 @@
> /* The set of all possible UFFD-related VM flags. */
> #define __VM_UFFD_FLAGS (VM_UFFD_MISSING | VM_UFFD_WP | VM_UFFD_MINOR)
>
> -#define __VMA_UFFD_FLAGS mk_vma_flags(VMA_UFFD_MISSING_BIT, VMA_UFFD_WP_BIT, \
> - VMA_UFFD_MINOR_BIT)
> +#define __VMA_UFFD_FLAGS mk_vma_flags_from_masks(VMA_UFFD_MISSING, VMA_UFFD_WP, \
> + VMA_UFFD_MINOR)
>
> /*
> * CAREFUL: Check include/uapi/asm-generic/fcntl.h when defining
> --
> 2.54.0
>
next prev parent reply other threads:[~2026-06-01 18:34 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-29 17:23 [PATCH 0/6] userfaultfd/pagemap: pre-existing fixes Kiryl Shutsemau (Meta)
2026-05-29 17:23 ` [PATCH 1/6] fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race Kiryl Shutsemau (Meta)
2026-06-01 17:55 ` Lorenzo Stoakes
2026-06-01 18:00 ` Lorenzo Stoakes
2026-06-02 6:32 ` Dev Jain
2026-05-29 17:23 ` [PATCH 2/6] fs/proc/task_mmu: use huge_page_size() in pagemap_scan_hugetlb_entry() Kiryl Shutsemau (Meta)
2026-06-01 18:06 ` Lorenzo Stoakes
2026-06-02 6:36 ` Dev Jain
2026-05-29 17:23 ` [PATCH 3/6] fs/proc/task_mmu: fix hugetlb self-deadlock in pagemap_scan_pte_hole() Kiryl Shutsemau (Meta)
2026-05-29 17:23 ` [PATCH 4/6] mm/huge_memory: preserve pmd_swp_uffd_wp on device-private PMD downgrade Kiryl Shutsemau (Meta)
2026-06-01 0:17 ` Balbir Singh
2026-05-29 17:23 ` [PATCH 5/6] userfaultfd: gate must_wait writability check on pte_present() Kiryl Shutsemau (Meta)
2026-06-01 18:11 ` Lorenzo Stoakes
2026-06-02 8:28 ` Mike Rapoport
2026-05-29 17:23 ` [PATCH 6/6] userfaultfd: build __VMA_UFFD_FLAGS from config-gated masks Kiryl Shutsemau (Meta)
2026-06-01 18:34 ` Lorenzo Stoakes [this message]
2026-06-02 8:32 ` Mike Rapoport
2026-06-03 9:17 ` Kiryl Shutsemau
2026-05-30 0:34 ` [PATCH 0/6] userfaultfd/pagemap: pre-existing fixes Andrew Morton
2026-06-01 14:17 ` Kiryl Shutsemau
2026-06-01 15:04 ` David Hildenbrand (Arm)
2026-06-03 9:21 ` Kiryl Shutsemau
2026-06-01 17:38 ` Lorenzo Stoakes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ah3LooI6IVQBZ9P1@lucifer \
--to=ljs@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=aliceryhl@google.com \
--cc=david@kernel.org \
--cc=kas@kernel.org \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@suse.com \
--cc=peterx@redhat.com \
--cc=pfalcato@suse.de \
--cc=rppt@kernel.org \
--cc=sashiko-bot@kernel.org \
--cc=stable@vger.kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.