]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/mmap: Introduce dup_vma_anon() helper
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Wed, 10 Aug 2022 22:11:48 +0000 (18:11 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Thu, 11 Aug 2022 21:49:18 +0000 (17:49 -0400)
Create a helper for duplicating the anon vma when adjusting the vma.
This simplifies the logic of __vma_adjust().

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

index a6e0dcbe7d2e57e657662267ffe0e8644c1ca26f..45f5b8552ea92659e81369b330e8d0a1667f82ee 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -646,6 +646,29 @@ again:
                uprobe_mmap(vl->insert);
 }
 
+/*
+ * dup_anon_vma() - Helper function to duplicate anon_vma
+ * @dst: The destination VMA
+ * @src: The source VMA
+ *
+ * Returns: 0 on success.
+ */
+static inline int dup_anon_vma(struct vm_area_struct *dst,
+                              struct vm_area_struct *src)
+{
+       /*
+        * Easily overlooked: when mprotect shifts the boundary, make sure the
+        * expanding vma has anon_vma set if the shrinking vma had, to cover any
+        * anon pages imported.
+        */
+       if (src->anon_vma && !dst->anon_vma) {
+               dst->anon_vma = src->anon_vma;
+               return anon_vma_clone(dst, src);
+       }
+
+       return 0;
+}
+
 /*
  * vma_expand - Expand an existing VMA
  *
@@ -672,15 +695,12 @@ int vma_expand(struct ma_state *mas, struct vm_area_struct *vma,
        struct vma_locking vma_lock;
 
        if (next && (vma != next) && (end == next->vm_end)) {
-               remove_next = true;
-               if (next->anon_vma && !vma->anon_vma) {
-                       int error;
+               int ret = 0;
 
-                       vma->anon_vma = next->anon_vma;
-                       error = anon_vma_clone(vma, next);
-                       if (error)
-                               return error;
-               }
+               remove_next = true;
+               ret = dup_anon_vma(vma, next);
+               if (ret)
+                       return ret;
        }
 
        init_multi_vma_lock(&vma_lock, vma, NULL, remove_next ? next : NULL,
@@ -767,10 +787,11 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
        bool vma_changed = false;
        long adjust_next = 0;
        MA_STATE(mas, &mm->mm_mt, 0, 0);
-       struct vm_area_struct *exporter = NULL, *importer = NULL;
        struct vma_locking vma_lock;
 
        if (next) {
+               int error = 0;
+
                if (end >= next->vm_end) {
                        /*
                         * vma expands, overlapping all the next, and
@@ -806,15 +827,14 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
                                           end != remove2->vm_end);
                        }
 
-                       exporter = next;
-                       importer = vma;
-
                        /*
                         * If next doesn't have anon_vma, import from vma after
                         * next, if the vma overlaps with it.
                         */
-                       if (remove2 != NULL && !next->anon_vma)
-                               exporter = remove2;
+                       if (remove != NULL && !next->anon_vma)
+                               error = dup_anon_vma(vma, remove2);
+                       else
+                               error = dup_anon_vma(vma, remove);
 
                } else if (end > next->vm_start) {
                        /*
@@ -822,9 +842,8 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
                         * mprotect case 5 shifting the boundary up.
                         */
                        adjust_next = (end - next->vm_start);
-                       exporter = next;
-                       importer = vma;
-                       VM_WARN_ON(expand != importer);
+                       VM_WARN_ON(expand != vma);
+                       error = dup_anon_vma(vma, next);
                } else if (end < vma->vm_end) {
                        /*
                         * vma shrinks, and !insert tells it's not
@@ -832,24 +851,11 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
                         * mprotect case 4 shifting the boundary down.
                         */
                        adjust_next = -(vma->vm_end - end);
-                       exporter = vma;
-                       importer = next;
-                       VM_WARN_ON(expand != importer);
-               }
-
-               /*
-                * Easily overlooked: when mprotect shifts the boundary,
-                * make sure the expanding vma has anon_vma set if the
-                * shrinking vma had, to cover any anon pages imported.
-                */
-               if (exporter && exporter->anon_vma && !importer->anon_vma) {
-                       int error;
-
-                       importer->anon_vma = exporter->anon_vma;
-                       error = anon_vma_clone(importer, exporter);
-                       if (error)
-                               return error;
+                       VM_WARN_ON(expand != next);
+                       error = dup_anon_vma(next, vma);
                }
+               if (error)
+                       return error;
        }
 
        if (mas_preallocate(&mas, vma, GFP_KERNEL))