diff mbox series

[v3,3/6] mm: userfaultfd: use can_userfault vma operation

Message ID 20250404154352.23078-4-kalyazin@amazon.com
State New
Headers show
Series [v3,1/6] mm: userfaultfd: generic continue for non hugetlbfs | expand

Commit Message

Nikita Kalyazin April 4, 2025, 3:43 p.m. UTC
Signed-off-by: Nikita Kalyazin <kalyazin@amazon.com>
---
 include/linux/userfaultfd_k.h | 13 ++++++-------
 mm/userfaultfd.c              | 10 +++++++---
 2 files changed, 13 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
index 75342022d144..64551e8a55fb 100644
--- a/include/linux/userfaultfd_k.h
+++ b/include/linux/userfaultfd_k.h
@@ -221,8 +221,8 @@  static inline bool vma_can_userfault(struct vm_area_struct *vma,
 	if (vm_flags & VM_DROPPABLE)
 		return false;
 
-	if ((vm_flags & VM_UFFD_MINOR) &&
-	    (!is_vm_hugetlb_page(vma) && !vma_is_shmem(vma)))
+	if (!vma->vm_ops->can_userfault ||
+	    !vma->vm_ops->can_userfault(vma, VM_UFFD_MINOR))
 		return false;
 
 	/*
@@ -235,16 +235,15 @@  static inline bool vma_can_userfault(struct vm_area_struct *vma,
 #ifndef CONFIG_PTE_MARKER_UFFD_WP
 	/*
 	 * If user requested uffd-wp but not enabled pte markers for
-	 * uffd-wp, then shmem & hugetlbfs are not supported but only
-	 * anonymous.
+	 * uffd-wp, then only anonymous is supported.
 	 */
 	if ((vm_flags & VM_UFFD_WP) && !vma_is_anonymous(vma))
 		return false;
 #endif
 
-	/* By default, allow any of anon|shmem|hugetlb */
-	return vma_is_anonymous(vma) || is_vm_hugetlb_page(vma) ||
-	    vma_is_shmem(vma);
+	return vma_is_anonymous(vma) ||
+	    (vma->vm_ops->can_userfault &&
+	     vma->vm_ops->can_userfault(vma, vm_flags));
 }
 
 static inline bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma)
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 4b3dbc7dac64..0aa82c968e16 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -728,6 +728,7 @@  static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx,
 	unsigned long src_addr, dst_addr;
 	long copied;
 	struct folio *folio;
+	bool can_userfault;
 
 	/*
 	 * Sanitize the command parameters:
@@ -787,10 +788,13 @@  static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx,
 		return  mfill_atomic_hugetlb(ctx, dst_vma, dst_start,
 					     src_start, len, flags);
 
-	if (!vma_is_anonymous(dst_vma) && !vma_is_shmem(dst_vma))
+	can_userfault = dst_vma->vm_ops->can_userfault &&
+	    dst_vma->vm_ops->can_userfault(dst_vma, __VM_UFFD_FLAGS);
+
+	if (!vma_is_anonymous(dst_vma) && !can_userfault)
 		goto out_unlock;
-	if (!vma_is_shmem(dst_vma) &&
-	    uffd_flags_mode_is(flags, MFILL_ATOMIC_CONTINUE))
+
+	if (!can_userfault && uffd_flags_mode_is(flags, MFILL_ATOMIC_CONTINUE))
 		goto out_unlock;
 
 	while (src_addr < src_start + len) {