All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Rapoport <rppt@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,
	Lorenzo Stoakes <ljs@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: Tue, 2 Jun 2026 11:32:54 +0300	[thread overview]
Message-ID: <ah6VNjfXXx-3Nh9l@kernel.org> (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")
> 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>
> Assisted-by: Claude:claude-opus-4-8

Can you ask claude to produce more concise changelogs and better split it
to paragraphs?

Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

> ---
>  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
> 

-- 
Sincerely yours,
Mike.


  parent reply	other threads:[~2026-06-02  8:33 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
2026-06-02  8:32   ` Mike Rapoport [this message]
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=ah6VNjfXXx-3Nh9l@kernel.org \
    --to=rppt@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=ljs@kernel.org \
    --cc=mhocko@suse.com \
    --cc=peterx@redhat.com \
    --cc=pfalcato@suse.de \
    --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.