Re: [PATCH 25/46] mm/userfaultfd: wake waiters when registration modes are removed
From: David Hildenbrand (Arm)
Date: Tue Oct 27 2026 - 15:32:29 EST
On 10/27/26 09:24, Lorenzo Stoakes (ARM) wrote:
> 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
I now have: