Re: [PATCH 25/46] mm/userfaultfd: wake waiters when registration modes are removed
From: Lorenzo Stoakes (ARM)
Date: Tue Oct 27 2026 - 04:25:20 EST
On Mon, Oct 26, 2026 at 10:10:24PM -0700, Gregory Price wrote:
> From: Gregory Price <gourry@xxxxxxxxxx>
> Subject: [PATCH] mm/userfaultfd: compare exact registration modes before skipping
>
> Changing registration from MISSING|WP to WP returns success but leaves
> MISSING enabled. The no-op check sees that WP is already set and skips
> the update, so later accesses to missing pages still wait for userspace.
>
> Skip the update only when the current and requested UFFD modes match
> exactly.
>
> Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Gregory Price (Meta) <gourry@xxxxxxxxxx>
> ---
> mm/userfaultfd.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
> index 669f71d485d02..0a28130cebc99 100644
> --- a/mm/userfaultfd.c
> +++ b/mm/userfaultfd.c
> @@ -2299,7 +2299,7 @@ static int userfaultfd_register_range(struct userfaultfd_ctx *ctx,
> * userfaultfd and with the right tracking mode too.
> */
> if (vma->vm_userfaultfd_ctx.ctx == ctx &&
> - vma_test_all_mask(vma, vma_flags))
> + (vma->vm_flags & __VM_UFFD_FLAGS) == vm_flags)
Would be better not to regress to the legacy API. I realise we don't use it for
backported fixes in general, but this patch obviously won't apply to older
versions anyway, so we should use the correct API now, and this for older
versions.
I'll add a better predicate probably to do this in one go, but for the fix,
I put the correct patch below.
> goto skip;
>
> /*
>
> --
> Gregory Price <gourry@xxxxxxxxxx>
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 777bf122d32a..c71cb9179913 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -2288,6 +2288,9 @@ static int userfaultfd_register_range(struct userfaultfd_ctx *ctx,
prev = vma;
for_each_vma_range(vmi, vma, end) {
+ const vma_flags_t curr_vma_flags =
+ vma_flags_and_mask(&vma->flags, __VMA_UFFD_FLAGS);
+
cond_resched();
VM_WARN_ON_ONCE(!vma_can_userfault(vma, vm_flags, wp_async));
@@ -2300,7 +2303,7 @@ static int userfaultfd_register_range(struct userfaultfd_ctx *ctx,
* userfaultfd and with the right tracking mode too.
*/
if (vma->vm_userfaultfd_ctx.ctx == ctx &&
- vma_test_all_mask(vma, vma_flags))
+ vma_flags_same_pair(&curr_vma_flags, &vma_flags))
goto skip;
/*
--
Cheers, Lorenzo