]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/userfaultfd: Move global dst checks to uffd_ctx_lock_and_validate_dst()
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Mon, 27 Oct 2025 19:12:54 +0000 (15:12 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Thu, 30 Oct 2025 16:25:34 +0000 (12:25 -0400)
Reduce mfill_atomic() further by exporting logic checks to the
lock_and_validate_dst().

Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
mm/shmem.c
mm/userfaultfd.c

index a08311bebfa3d01ae36652aa07d89543d19eff02..28c679130f68b406617f98c52646ed422bc71a50 100644 (file)
@@ -3153,14 +3153,6 @@ static inline struct inode *shmem_get_inode(struct mnt_idmap *idmap,
 static ssize_t shmem_is_dst_valid(struct vm_area_struct *dst_vma,
                unsigned long dst_start, unsigned long len)
 {
-       /*
-        * 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;
 }
 
index c64c63a80e0f460e94df656aa176160d66f3d5f6..ca716bef7a50e981d6d8ba800d6ff8f4d799acb2 100644 (file)
@@ -517,10 +517,13 @@ static inline const struct vm_uffd_ops *vma_get_uffd_ops(struct vm_area_struct *
        return &default_uffd_ops;
 }
 
+/*
+ * Global checks live here, specific checks are in the callback.
+ */
 static inline ssize_t
 uffd_ctx_lock_and_validate_dst(struct userfaultfd_ctx *ctx,
                struct vm_area_struct *dst_vma, unsigned long dst_start,
-               unsigned long len)
+               unsigned long len, uffd_flags_t flags)
 {
        const struct vm_uffd_ops *uffd_ops;
 
@@ -533,6 +536,20 @@ uffd_ctx_lock_and_validate_dst(struct userfaultfd_ctx *ctx,
        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;
+       /*
+        * validate 'mode' now that we know the dst_vma: don't allow
+        * a wrprotect copy if the userfaultfd didn't register as WP.
+        */
+       if ((flags & MFILL_ATOMIC_WP) && !(dst_vma->vm_flags & VM_UFFD_WP))
+               return -EINVAL;
+
        uffd_ops = vma_get_uffd_ops(dst_vma);
        WARN_ON_ONCE(!uffd_ops || !uffd_ops->is_dst_valid);
        return uffd_ops->is_dst_valid(dst_vma, dst_start, len);
@@ -600,7 +617,8 @@ retry:
                        goto out;
                }
 
-               err = uffd_ctx_lock_and_validate_dst(ctx, dst_vma, dst_start, len);
+               err = uffd_ctx_lock_and_validate_dst(ctx, dst_vma, dst_start,
+                                                    len, flags);
                if (err)
                        goto out_unlock;
        }
@@ -763,26 +781,11 @@ retry:
                increment = uffd_ops->increment(dst_vma);
        }
 
-       err = uffd_ctx_lock_and_validate_dst(ctx, dst_vma, dst_start, len);
+       err = uffd_ctx_lock_and_validate_dst(ctx, dst_vma, dst_start, len,
+                                            flags);
        if (err)
                goto out_unlock;
 
-       err = -EINVAL;
-       /*
-        * 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))
-               goto out_unlock;
-
-       /*
-        * validate 'mode' now that we know the dst_vma: don't allow
-        * a wrprotect copy if the userfaultfd didn't register as WP.
-        */
-       if ((flags & MFILL_ATOMIC_WP) && !(dst_vma->vm_flags & VM_UFFD_WP))
-               goto out_unlock;
-
        /*
         * If this is a HUGETLB vma, pass off to appropriate routine
         */
@@ -790,6 +793,7 @@ retry:
                return  mfill_atomic_hugetlb(ctx, dst_vma, dst_start,
                                             src_start, len, flags);
 
+       err = -EINVAL;
        if (!vma_is_anonymous(dst_vma) && !vma_is_shmem(dst_vma))
                goto out_unlock;
        if (!vma_is_shmem(dst_vma) &&