From cc304e8d374998facdfa951897b24c826d02fe18 Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Wed, 22 Oct 2025 21:29:09 -0400 Subject: [PATCH] mm/userfaultfd: Add uffd_ctx_lock_and_validate_dst() to move locking to its own function. Remove the locking from mfill_atomic() into its own function. Signed-off-by: Liam R. Howlett --- mm/userfaultfd.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 00122f42718c..8c3c9692c84c 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -694,6 +694,31 @@ static __always_inline ssize_t mfill_atomic_pte(pmd_t *dst_pmd, return err; } + +static inline ssize_t +uffd_ctx_lock_and_validate_dst(struct userfaultfd_ctx *ctx, + struct vm_area_struct *dst_vma) +{ + /* + * If memory mappings are changing because of non-cooperative + * operation (e.g. mremap) running in parallel, bail out and + * request the user to retry later + */ + down_read(&ctx->map_changing_lock); + if (atomic_read(&ctx->mmap_changing)) + return -EAGAIN; + + /* + * shmem_zero_setup is invoked in mmap for MAP_ANONYMOUS|MAP_SHARED but + * it will overwrite vm_ops, so vma_is_anonymous must return false. + */ + if (WARN_ON_ONCE(vma_is_anonymous(dst_vma) && + dst_vma->vm_flags & VM_SHARED)) + return -EINVAL; + + return 0; +} + static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx, unsigned long dst_start, unsigned long src_start, @@ -733,14 +758,8 @@ retry: goto out; } - /* - * If memory mappings are changing because of non-cooperative - * operation (e.g. mremap) running in parallel, bail out and - * request the user to retry later - */ - down_read(&ctx->map_changing_lock); - err = -EAGAIN; - if (atomic_read(&ctx->mmap_changing)) + err = uffd_ctx_lock_and_validate_dst(ctx, dst_vma); + if (err) goto out_unlock; err = -EINVAL; -- 2.51.0