]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/userfaultfd: Add hugetlb_uffd_writeprotect() for hugetlb
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Wed, 29 Oct 2025 08:42:12 +0000 (04:42 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Thu, 30 Oct 2025 16:55:33 +0000 (12:55 -0400)
Remove the special case of hugetlb from writeprotect code by making an
implementation that will only be called for hugetlb.

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

index 72daaf8d06e1ead02a0e8ef6327a87b1a293216e..0cf9c6907468cf0b2469f05a140a326de0e00d65 100644 (file)
@@ -5532,13 +5532,14 @@ static ssize_t hugetlb_failed_do_unlock(struct userfaultfd_ctx *ctx,
 static int hugetlb_mfill_pte_poison(struct uffd_info *info);
 static int hugetlb_mfill_pte_continue(struct uffd_info *info);
 static int hugetlb_mfill_atomic_pte_copy(struct uffd_info *info);
+int hugetlb_uffd_writeprotect(struct uffd_info *info);
 
 static const struct vm_uffd_ops hugetlb_uffd_ops = {
        .copy                   =       hugetlb_mfill_atomic_pte_copy,
        .zeropage               =       NULL,
        .cont                   =       hugetlb_mfill_pte_continue,
        .poison                 =       hugetlb_mfill_pte_poison,
-       .writeprotect           =       uffd_writeprotect,
+       .writeprotect           =       hugetlb_uffd_writeprotect,
        .is_dst_valid           =       hugetlb_is_dst_valid,
        .increment              =       hugetlb_mfill_size,
        .failed_do_unlock       =       hugetlb_failed_do_unlock,
@@ -7147,6 +7148,32 @@ out_release_unlock:
        goto out;
 }
 
+int hugetlb_uffd_writeprotect(struct uffd_info *info)
+{
+       long err;
+       struct vm_area_struct *dst_vma;
+       unsigned long end = info->src_addr + info->len;
+       unsigned long _start, _end;
+       unsigned long page_mask;
+
+       dst_vma = info->dst_vma;
+       if (!userfaultfd_wp(dst_vma)) {
+               return -ENOENT;
+       }
+
+       page_mask = vma_kernel_pagesize(dst_vma) - 1;
+       if ((info->src_addr & page_mask) || (info->len & page_mask))
+               return -EINVAL;
+
+       _start = max(dst_vma->vm_start, info->src_addr);
+       _end = min(dst_vma->vm_end, end);
+
+       err = uffd_wp_range(dst_vma, _start, _end - _start, info->wp);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
 /*
  * Used by userfaultfd UFFDIO_* ioctls. Based on userfaultfd's mfill_atomic_pte
  * with modifications for hugetlb pages.
index f7c5b40f3e0571d6710eb1297e3be730c0de7984..2b77fe81f122380d1b1463ce51a8ea5ae2963c55 100644 (file)
@@ -796,13 +796,6 @@ int uffd_writeprotect(struct uffd_info *info)
        if (!userfaultfd_wp(dst_vma))
                return -ENOENT;
 
-       if (is_vm_hugetlb_page(dst_vma)) {
-               unsigned long page_mask;
-               page_mask = vma_kernel_pagesize(dst_vma) - 1;
-               if ((info->src_addr & page_mask) || (info->len & page_mask))
-                       return -EINVAL;
-       }
-
        _start = max(dst_vma->vm_start, info->src_addr);
        _end = min(dst_vma->vm_end, end);