Merge tag 'for-linus-2022111101' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-starfive.git] / ipc / shm.c
index b3048eb..7d86f05 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1721,7 +1721,7 @@ long ksys_shmdt(char __user *shmaddr)
 #ifdef CONFIG_MMU
        loff_t size = 0;
        struct file *file;
-       struct vm_area_struct *next;
+       VMA_ITERATOR(vmi, mm, addr);
 #endif
 
        if (addr & ~PAGE_MASK)
@@ -1751,12 +1751,9 @@ long ksys_shmdt(char __user *shmaddr)
         * match the usual checks anyway. So assume all vma's are
         * above the starting address given.
         */
-       vma = find_vma(mm, addr);
 
 #ifdef CONFIG_MMU
-       while (vma) {
-               next = vma->vm_next;
-
+       for_each_vma(vmi, vma) {
                /*
                 * Check if the starting address would match, i.e. it's
                 * a fragment created by mprotect() and/or munmap(), or it
@@ -1774,6 +1771,7 @@ long ksys_shmdt(char __user *shmaddr)
                        file = vma->vm_file;
                        size = i_size_read(file_inode(vma->vm_file));
                        do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start, NULL);
+                       mas_pause(&vmi.mas);
                        /*
                         * We discovered the size of the shm segment, so
                         * break out of here and fall through to the next
@@ -1781,10 +1779,9 @@ long ksys_shmdt(char __user *shmaddr)
                         * searching for matching vma's.
                         */
                        retval = 0;
-                       vma = next;
+                       vma = vma_next(&vmi);
                        break;
                }
-               vma = next;
        }
 
        /*
@@ -1794,17 +1791,19 @@ long ksys_shmdt(char __user *shmaddr)
         */
        size = PAGE_ALIGN(size);
        while (vma && (loff_t)(vma->vm_end - addr) <= size) {
-               next = vma->vm_next;
-
                /* finding a matching vma now does not alter retval */
                if ((vma->vm_ops == &shm_vm_ops) &&
                    ((vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) &&
-                   (vma->vm_file == file))
+                   (vma->vm_file == file)) {
                        do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start, NULL);
-               vma = next;
+                       mas_pause(&vmi.mas);
+               }
+
+               vma = vma_next(&vmi);
        }
 
 #else  /* CONFIG_MMU */
+       vma = vma_lookup(mm, addr);
        /* under NOMMU conditions, the exact address to be destroyed must be
         * given
         */