[PATCH 25/46] mm/userfaultfd: wake waiters when registration modes are removed

David Hildenbrand (Arm) david at kernel.org
Tue Oct 27 12:31:50 PDT 2026


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 at gourry.net>
>> 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 at vger.kernel.org
>> Signed-off-by: Gregory Price (Meta) <gourry at gourry.net>
>> ---
>>  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 at gourry.net>
> 
> 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:

>From e2cb5867bd46dd6c601dfa5f0415bf7c8e12600a Mon Sep 17 00:00:00 2001
From: Gregory Price <gourry at gourry.net>
Date: Tue, 27 Oct 2026 20:27:52 +0100
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 at vger.kernel.org
Signed-off-by: Gregory Price (Meta) <gourry at gourry.net>
[ david: apply fixup from Lorenzo ]
Signed-off-by: David Hildenbrand (Arm) <david at kernel.org>
---
 mm/userfaultfd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 710e913c73bf..24b7a2612469 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -2291,6 +2291,7 @@ static int userfaultfd_register_range(struct userfaultfd_ctx *ctx,
 
 	for_each_vma_range(vmi, vma, end) {
 		const bool any_mode_removed = vma->vm_flags & __VM_UFFD_FLAGS & ~vm_flags;
+		const vma_flags_t curr_vma_flags = vma_flags_and_mask(&vma->flags, __VMA_UFFD_FLAGS);
 
 		cond_resched();
 
@@ -2304,7 +2305,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;
 
 		/*
-- 
2.43.0


-- 
Cheers,

David



More information about the kexec mailing list