* [PATCH v5 01/18] fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race
[not found] <20260526130509.2748441-1-kirill@shutemov.name>
@ 2026-05-26 13:04 ` Kiryl Shutsemau
2026-05-26 13:04 ` [PATCH v5 02/18] mm/huge_memory: preserve pmd_swp_uffd_wp on device-private PMD downgrade Kiryl Shutsemau
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Kiryl Shutsemau @ 2026-05-26 13:04 UTC (permalink / raw)
To: akpm, rppt, peterx, david
Cc: ljs, surenb, vbabka, Liam.Howlett, ziy, corbet, skhan, seanjc,
pbonzini, jthoughton, aarcange, sj, usama.arif, linux-mm,
linux-kernel, linux-doc, linux-kselftest, kvm, kernel-team,
Kiryl Shutsemau (Meta), stable, Sashiko AI review
From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>
make_uffd_wp_huge_pte() arms the UFFD_WP bit on a present HugeTLB PTE by
calling huge_ptep_modify_prot_commit() with a ptent snapshot that was
fetched without the corresponding huge_ptep_modify_prot_start(). The
start helper is what atomically clears the entry so the kernel-owned
snapshot stays consistent until the commit; without it, the hardware
may set Dirty or Accessed in the live PTE between the original read
and the commit, and huge_ptep_modify_prot_commit() (whose generic
implementation just calls set_huge_pte_at()) then writes the stale
snapshot back over the live hardware bits, losing the update.
The non-hugetlb sibling make_uffd_wp_pte() does this correctly via
ptep_modify_prot_start() / ptep_modify_prot_commit(). Mirror that
pattern for the present-PTE branch. The migration case stays as-is --
migration entries are non-present, so there's no hardware update to
race against.
Fixes: 52526ca7fdb9 ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs")
Cc: stable@vger.kernel.org
Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
---
fs/proc/task_mmu.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 1e3a15bf46f4..e21a38ac745b 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -2610,12 +2610,16 @@ static void make_uffd_wp_huge_pte(struct vm_area_struct *vma,
if (softleaf_is_hwpoison(entry) || softleaf_is_marker(entry))
return;
- if (softleaf_is_migration(entry))
+ if (softleaf_is_migration(entry)) {
set_huge_pte_at(vma->vm_mm, addr, ptep,
pte_swp_mkuffd_wp(ptent), psize);
- else
- huge_ptep_modify_prot_commit(vma, addr, ptep, ptent,
- huge_pte_mkuffd_wp(ptent));
+ } else {
+ pte_t old_pte, new_pte;
+
+ old_pte = huge_ptep_modify_prot_start(vma, addr, ptep);
+ new_pte = huge_pte_mkuffd_wp(old_pte);
+ huge_ptep_modify_prot_commit(vma, addr, ptep, old_pte, new_pte);
+ }
}
#endif /* CONFIG_HUGETLB_PAGE */
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 02/18] mm/huge_memory: preserve pmd_swp_uffd_wp on device-private PMD downgrade
[not found] <20260526130509.2748441-1-kirill@shutemov.name>
2026-05-26 13:04 ` [PATCH v5 01/18] fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race Kiryl Shutsemau
@ 2026-05-26 13:04 ` Kiryl Shutsemau
2026-05-26 13:04 ` [PATCH v5 03/18] userfaultfd: gate must_wait writability check on pte_present() Kiryl Shutsemau
2026-05-26 13:04 ` [PATCH v5 04/18] mm: skip out-of-range bits in mk_vma_flags() Kiryl Shutsemau
3 siblings, 0 replies; 6+ messages in thread
From: Kiryl Shutsemau @ 2026-05-26 13:04 UTC (permalink / raw)
To: akpm, rppt, peterx, david
Cc: ljs, surenb, vbabka, Liam.Howlett, ziy, corbet, skhan, seanjc,
pbonzini, jthoughton, aarcange, sj, usama.arif, linux-mm,
linux-kernel, linux-doc, linux-kselftest, kvm, kernel-team,
Kiryl Shutsemau (Meta), stable, Sashiko AI review
From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>
change_non_present_huge_pmd() rewrites a writable device-private PMD
swap entry into a readable one without carrying pmd_swp_uffd_wp()
across. The PTE-level change_softleaf_pte() does this correctly;
mirror that here, matching what copy_huge_pmd() does for the fork
path. Without the carry, a plain mprotect() over a UFFD_WP-marked
device-private THP strips the bit and the trap is bypassed on
swap-in.
Fixes: 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
Cc: stable@vger.kernel.org
Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
---
mm/huge_memory.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 42b86e8ab7c0..b7c895b1d366 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2663,6 +2663,8 @@ static void change_non_present_huge_pmd(struct mm_struct *mm,
} else if (softleaf_is_device_private_write(entry)) {
entry = make_readable_device_private_entry(swp_offset(entry));
newpmd = swp_entry_to_pmd(entry);
+ if (pmd_swp_uffd_wp(*pmd))
+ newpmd = pmd_swp_mkuffd_wp(newpmd);
} else {
newpmd = *pmd;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 03/18] userfaultfd: gate must_wait writability check on pte_present()
[not found] <20260526130509.2748441-1-kirill@shutemov.name>
2026-05-26 13:04 ` [PATCH v5 01/18] fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race Kiryl Shutsemau
2026-05-26 13:04 ` [PATCH v5 02/18] mm/huge_memory: preserve pmd_swp_uffd_wp on device-private PMD downgrade Kiryl Shutsemau
@ 2026-05-26 13:04 ` Kiryl Shutsemau
2026-05-26 13:04 ` [PATCH v5 04/18] mm: skip out-of-range bits in mk_vma_flags() Kiryl Shutsemau
3 siblings, 0 replies; 6+ messages in thread
From: Kiryl Shutsemau @ 2026-05-26 13:04 UTC (permalink / raw)
To: akpm, rppt, peterx, david
Cc: ljs, surenb, vbabka, Liam.Howlett, ziy, corbet, skhan, seanjc,
pbonzini, jthoughton, aarcange, sj, usama.arif, linux-mm,
linux-kernel, linux-doc, linux-kselftest, kvm, kernel-team,
Kiryl Shutsemau (Meta), stable, Sashiko AI review
From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>
userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE
without taking the page table lock and then apply pte_write() /
huge_pte_write() to it. Those accessors decode bits from the present
encoding only; on a swap or migration entry they read the offset bits
that happen to share the same position and return an undefined result.
The intent of the check is "is this fault still WP-blocked?". A
non-marker swap entry means the page is in transit -- the userfault
context the original fault delivered against is no longer the same,
and the swap-in or migration completion path will re-deliver a fresh
fault if userspace still needs to handle it. Worst case under the
current code the garbage write bit says "wait", and the thread stays
asleep until a UFFDIO_WAKE that may never arrive.
Gate the writability check on pte_present() so the lockless re-check
only inspects present-PTE bits when the entry is actually present.
The non-present, non-marker case returns "don't wait" and lets the
fault path retry.
Fixes: 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
Cc: stable@vger.kernel.org
Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
---
mm/userfaultfd.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 35b206cc9aa6..f6d2a1c67019 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -2535,6 +2535,15 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
/* UFFD PTE markers require userspace to resolve the fault. */
if (pte_is_uffd_marker(pte))
return true;
+ /*
+ * Concurrent migration may have replaced the present PTE with a
+ * non-marker swap entry between fault delivery and this lockless
+ * re-check. huge_pte_write() on a swap entry decodes random offset
+ * bits, so gate it on pte_present(). The migration completion path
+ * will re-deliver the fault if it still needs userspace.
+ */
+ if (!pte_present(pte))
+ return false;
/*
* If VMA has UFFD WP faults enabled and WP fault, wait for userspace to
* resolve the fault.
@@ -2621,6 +2630,17 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
/* UFFD PTE markers require userspace to resolve the fault. */
if (pte_is_uffd_marker(ptent))
goto out;
+ /*
+ * Concurrent swap-out / migration may have replaced the present PTE
+ * with a non-marker swap entry between fault delivery and this
+ * lockless re-check. pte_write() on a swap entry decodes random
+ * offset bits, so gate it on pte_present(). The page-in path will
+ * re-deliver the fault if it still needs userspace.
+ */
+ if (!pte_present(ptent)) {
+ ret = false;
+ goto out;
+ }
/*
* If VMA has UFFD WP faults enabled and WP fault, wait for userspace to
* resolve the fault.
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 04/18] mm: skip out-of-range bits in mk_vma_flags()
[not found] <20260526130509.2748441-1-kirill@shutemov.name>
` (2 preceding siblings ...)
2026-05-26 13:04 ` [PATCH v5 03/18] userfaultfd: gate must_wait writability check on pte_present() Kiryl Shutsemau
@ 2026-05-26 13:04 ` Kiryl Shutsemau
2026-05-29 14:00 ` Lorenzo Stoakes
3 siblings, 1 reply; 6+ messages in thread
From: Kiryl Shutsemau @ 2026-05-26 13:04 UTC (permalink / raw)
To: akpm, rppt, peterx, david
Cc: ljs, surenb, vbabka, Liam.Howlett, ziy, corbet, skhan, seanjc,
pbonzini, jthoughton, aarcange, sj, usama.arif, linux-mm,
linux-kernel, linux-doc, linux-kselftest, kvm, kernel-team,
Kiryl Shutsemau (Meta), stable
From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>
vma_flags_t is one unsigned long on 32-bit -- NUM_VMA_FLAG_BITS ==
BITS_PER_LONG by design, so VM_xxx-declared bits sit in the first
word and hit the single-long fast path. But the bit enum declares
some bits unconditionally above BITS_PER_LONG (VMA_UFFD_MINOR_BIT
== 41 today, with VM_UFFD_MINOR == VM_NONE on 32-bit so no VMA
actually carries the bit).
Passing such a bit to mk_vma_flags() goes through __set_bit(41,
&one_long) and writes one word past the end. The compiler folds
the OOB 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 any high-numbered bit whose
mod-BITS_PER_LONG position is otherwise unused would silently OR
an extra bit into the mask.
Add VMA_NO_BIT and have DECLARE_VMA_BIT() resolve any bitnum out
of range to it. vma_flags_set_flag() drops negative bit values.
The ternary collapses at compile time, the runtime check folds
away when the bit is in range, and the common path is unchanged.
Bits declared in the enum are now safe to pass to mk_vma_flags()
regardless of arch.
Fixes: 9ea35a25d51b ("mm: introduce VMA flags bitmap type")
Cc: stable@vger.kernel.org
Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
---
include/linux/mm.h | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 0f2612a70fb1..71b11945e4fc 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -286,8 +286,17 @@ extern unsigned int kobjsize(const void *objp);
*/
typedef int __bitwise vma_flag_t;
-#define DECLARE_VMA_BIT(name, bitnum) \
- VMA_ ## name ## _BIT = ((__force vma_flag_t)bitnum)
+/*
+ * VMA_NO_BIT means "no bit"; mk_vma_flags() skips it. DECLARE_VMA_BIT()
+ * below uses it for any bit number that doesn't fit in the bitmap, so
+ * callers don't need to track which bits are valid on the current build.
+ */
+#define VMA_NO_BIT ((__force vma_flag_t)-1)
+
+#define DECLARE_VMA_BIT(name, bitnum) \
+ VMA_ ## name ## _BIT = (((bitnum) < NUM_VMA_FLAG_BITS) ? \
+ ((__force vma_flag_t)(bitnum)) : \
+ VMA_NO_BIT)
#define DECLARE_VMA_BIT_ALIAS(name, aliased) \
VMA_ ## name ## _BIT = (VMA_ ## aliased ## _BIT)
enum {
@@ -1081,6 +1090,8 @@ static __always_inline void vma_flags_set_flag(vma_flags_t *flags,
{
unsigned long *bitmap = flags->__vma_flags;
+ if ((__force int)bit < 0)
+ return;
__set_bit((__force int)bit, bitmap);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v5 04/18] mm: skip out-of-range bits in mk_vma_flags()
2026-05-26 13:04 ` [PATCH v5 04/18] mm: skip out-of-range bits in mk_vma_flags() Kiryl Shutsemau
@ 2026-05-29 14:00 ` Lorenzo Stoakes
2026-05-29 16:09 ` Kiryl Shutsemau
0 siblings, 1 reply; 6+ messages in thread
From: Lorenzo Stoakes @ 2026-05-29 14:00 UTC (permalink / raw)
To: Kiryl Shutsemau
Cc: akpm, rppt, peterx, david, surenb, vbabka, Liam.Howlett, ziy,
corbet, skhan, seanjc, pbonzini, jthoughton, aarcange, sj,
usama.arif, linux-mm, linux-kernel, linux-doc, linux-kselftest,
kvm, kernel-team, Kiryl Shutsemau (Meta), stable
On Tue, May 26, 2026 at 02:04:52PM +0100, Kiryl Shutsemau wrote:
> From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>
>
> vma_flags_t is one unsigned long on 32-bit -- NUM_VMA_FLAG_BITS ==
> BITS_PER_LONG by design, so VM_xxx-declared bits sit in the first
> word and hit the single-long fast path. But the bit enum declares
> some bits unconditionally above BITS_PER_LONG (VMA_UFFD_MINOR_BIT
> == 41 today, with VM_UFFD_MINOR == VM_NONE on 32-bit so no VMA
> actually carries the bit).
Yeah ugh.
>
> Passing such a bit to mk_vma_flags() goes through __set_bit(41,
> &one_long) and writes one word past the end. The compiler folds
> the OOB 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 any high-numbered bit whose
That is... helpful :) but not great that this is the situation, an
oversight, clearly! How I hate 32-bit kernels :)
> mod-BITS_PER_LONG position is otherwise unused would silently OR
> an extra bit into the mask.
>
> Add VMA_NO_BIT and have DECLARE_VMA_BIT() resolve any bitnum out
> of range to it. vma_flags_set_flag() drops negative bit values.
> The ternary collapses at compile time, the runtime check folds
> away when the bit is in range, and the common path is unchanged.
Hmm are you sure it does?
A key design goal was that mk_vma_flags() generates compile-time constants
the same as if the bitmap were constructed independently.
This surely must generate code? Or at least runs a significant risk of it?
Setting a precedent here would probably lead to VMA_NO_BIT being used more
and therefore generating code in more places I think.
And I'm not sure I really want to bend over backwards here to work around
issues with 32-bit kernels when in the long run the intent is that we move
to making these values 64-bit anyway.
Perhaps it's even wise possibly to just make these values 64-bit already,
ahead of time?
(I did look at this in terms of wanting something like a VMA_NO_BIT so we
could get VM_NONE-like behaviour but nothing I tried failed to generate
code.)
A simple solution that doesn't require change to the core is to just uglify
userfaultfd_k.h a bit with:
#ifdef HAVE_ARCH_USERFAULTFD_MINOR
#define __VMA_UFFD_FLAGS mk_vma_flags(VMA_UFFD_MISSING_BIT, VMA_UFFD_WP_BIT, \
VMA_UFFD_MINOR_BIT)
#else
#define __VMA_UFFD_FLAGS mk_vma_flags(VMA_UFFD_MISSING_BIT, VMA_UFFD_WP_BIT)
#endif
But of course that becomes much more horrible with your changes...
Another alternative, which I used for VMA_DROPPABLE is to add something
like this in mm.h:
#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR
#define VM_UFFD_MINOR INIT_VM_FLAG(UFFD_MINOR)
+define VMA_UFFD_MINOR mk_vma_flags(VMA_UFFD_MINOR_BIT)
#else
#define VM_UFFD_MINOR VM_NONE
+define VMA_UFFD_MINOR EMPTY_VMA_FLAGS
#endif
Then we can do:
#define __VMA_UFFD_FLAGS append_vma_flags(VMA_MINOR, VMA_UFFD_MISSING_BIT, \
VMA_UFFD_WP_BIT)
With you changes in 08/18 on top it'd get hairier, but we could make our
life easier by implementing something like:
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;
int i;
for (i = 0; i < count; i++)
mask = vma_flags_set_mask(&flags, masks[i]);
return flags;
}
#define mk_vma_flags_from_masks(...) __mk_vma_flags_from_masks(, \
COUNT_ARGS(__VA_ARGS__), (const vma_flags_t []){__VA_ARGS__})
(untested code - you would need to ensure it generated equivalent
constants as VM_xxx would now :)
Then you could get VMA_UFFD_RWP with:
#ifdef CONFIG_USERFAULTFD_RWP
#define VMA_UFFD_RWP mk_vma_flags(VMA_UFFD_RWP_BIT)
#else
#define VMA_UFFD_RWP EMPTY_VMA_FLAGS
#endif
And then:
/* Always available if CONFIG_USERFAULTFD set. */
#define __VMA_UFFD_DEFAULT_FLAGS \
mk_vma_flags(VMA_UFFD_MISSING_BIT, VMA_UFFD_WP_BIT)
#define __VMA_UFFD_FLAGS mk_vma_flags_from_masks(__VMA_UFFD_DEFAULT_FLAGS \
VMA_MINOR, VMA_RWP)
Which is kind ok-ish right? I mean it's all a bit fugly obviously.
>
> Bits declared in the enum are now safe to pass to mk_vma_flags()
> regardless of arch.
I mean another issue here is we're then codifying behaviour that's legacy
ahead of time. I really want to avoid that.
>
> Fixes: 9ea35a25d51b ("mm: introduce VMA flags bitmap type")
> Cc: stable@vger.kernel.org
> Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
> ---
> include/linux/mm.h | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 0f2612a70fb1..71b11945e4fc 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -286,8 +286,17 @@ extern unsigned int kobjsize(const void *objp);
> */
> typedef int __bitwise vma_flag_t;
>
> -#define DECLARE_VMA_BIT(name, bitnum) \
> - VMA_ ## name ## _BIT = ((__force vma_flag_t)bitnum)
> +/*
> + * VMA_NO_BIT means "no bit"; mk_vma_flags() skips it. DECLARE_VMA_BIT()
> + * below uses it for any bit number that doesn't fit in the bitmap, so
> + * callers don't need to track which bits are valid on the current build.
> + */
> +#define VMA_NO_BIT ((__force vma_flag_t)-1)
> +
> +#define DECLARE_VMA_BIT(name, bitnum) \
> + VMA_ ## name ## _BIT = (((bitnum) < NUM_VMA_FLAG_BITS) ? \
> + ((__force vma_flag_t)(bitnum)) : \
> + VMA_NO_BIT)
> #define DECLARE_VMA_BIT_ALIAS(name, aliased) \
> VMA_ ## name ## _BIT = (VMA_ ## aliased ## _BIT)
> enum {
> @@ -1081,6 +1090,8 @@ static __always_inline void vma_flags_set_flag(vma_flags_t *flags,
> {
> unsigned long *bitmap = flags->__vma_flags;
>
> + if ((__force int)bit < 0)
> + return;
> __set_bit((__force int)bit, bitmap);
> }
>
> --
> 2.54.0
>
Either way, I think we should break out any fix like this from the series.
Andrew is I think also not a fan of fixes patches in the middle of series
anyway :P
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v5 04/18] mm: skip out-of-range bits in mk_vma_flags()
2026-05-29 14:00 ` Lorenzo Stoakes
@ 2026-05-29 16:09 ` Kiryl Shutsemau
0 siblings, 0 replies; 6+ messages in thread
From: Kiryl Shutsemau @ 2026-05-29 16:09 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: akpm, rppt, peterx, david, surenb, vbabka, Liam.Howlett, ziy,
corbet, skhan, seanjc, pbonzini, jthoughton, aarcange, sj,
usama.arif, linux-mm, linux-kernel, linux-doc, linux-kselftest,
kvm, kernel-team, stable
On Fri, May 29, 2026 at 03:00:14PM +0100, Lorenzo Stoakes wrote:
> > Add VMA_NO_BIT and have DECLARE_VMA_BIT() resolve any bitnum out
> > of range to it. vma_flags_set_flag() drops negative bit values.
> > The ternary collapses at compile time, the runtime check folds
> > away when the bit is in range, and the common path is unchanged.
>
> Hmm are you sure it does?
You were right - I measured it (gcc 15.2, clang 21.1.8, -O2). The
DECLARE_VMA_BIT() ternary is fine, but the "if (bit < 0)" guard does not
reliably fold: with it, clang stops folding __VMA_UFFD_FLAGS to a constant
and gcc keeps a rolled loop; without it, both fold.
So I've dropped VMA_NO_BIT and gone with your config-gated-mask approach
instead: mk_vma_flags_from_masks() plus VMA_UFFD_{MISSING,WP,MINOR,RWP}
masks that collapse to EMPTY_VMA_FLAGS when unavailable, so no out-of-range
bit ever reaches mk_vma_flags(). __VMA_UFFD_FLAGS now folds to a single
constant on both compilers, 32- and 64-bit. Added your Suggested-by.
I also took your "use the new API" hint and added a prep patch converting
the existing userfaultfd_*() helpers to vma_test_any_mask() (Suggested-by
you as well). One deviation: vma_test(vma, VMA_UFFD_RWP_BIT) is itself an
out-of-bounds *read* on 32-bit (test_bit(43, &one_long)), so the helpers
use vma_test_any_mask() with the masks rather than the bit.
> Either way, I think we should break out any fix like this from the series.
Agreed - the OOB fix and the other pre-existing fixes will go as a separate
series with the RWP work rebased on top.
--
Kiryl Shutsemau / Kirill A. Shutemov
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-05-29 16:10 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260526130509.2748441-1-kirill@shutemov.name>
2026-05-26 13:04 ` [PATCH v5 01/18] fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race Kiryl Shutsemau
2026-05-26 13:04 ` [PATCH v5 02/18] mm/huge_memory: preserve pmd_swp_uffd_wp on device-private PMD downgrade Kiryl Shutsemau
2026-05-26 13:04 ` [PATCH v5 03/18] userfaultfd: gate must_wait writability check on pte_present() Kiryl Shutsemau
2026-05-26 13:04 ` [PATCH v5 04/18] mm: skip out-of-range bits in mk_vma_flags() Kiryl Shutsemau
2026-05-29 14:00 ` Lorenzo Stoakes
2026-05-29 16:09 ` Kiryl Shutsemau
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox