aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 13d16a2b7623..1cec28d20583 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -176,7 +176,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
176 return next; 176 return next;
177} 177}
178 178
179static int do_brk(unsigned long addr, unsigned long len); 179static int do_brk(unsigned long addr, unsigned long len, struct list_head *uf);
180 180
181SYSCALL_DEFINE1(brk, unsigned long, brk) 181SYSCALL_DEFINE1(brk, unsigned long, brk)
182{ 182{
@@ -185,6 +185,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
185 struct mm_struct *mm = current->mm; 185 struct mm_struct *mm = current->mm;
186 unsigned long min_brk; 186 unsigned long min_brk;
187 bool populate; 187 bool populate;
188 LIST_HEAD(uf);
188 189
189 if (down_write_killable(&mm->mmap_sem)) 190 if (down_write_killable(&mm->mmap_sem))
190 return -EINTR; 191 return -EINTR;
@@ -222,7 +223,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
222 223
223 /* Always allow shrinking brk. */ 224 /* Always allow shrinking brk. */
224 if (brk <= mm->brk) { 225 if (brk <= mm->brk) {
225 if (!do_munmap(mm, newbrk, oldbrk-newbrk)) 226 if (!do_munmap(mm, newbrk, oldbrk-newbrk, &uf))
226 goto set_brk; 227 goto set_brk;
227 goto out; 228 goto out;
228 } 229 }
@@ -232,13 +233,14 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
232 goto out; 233 goto out;
233 234
234 /* Ok, looks good - let it rip. */ 235 /* Ok, looks good - let it rip. */
235 if (do_brk(oldbrk, newbrk-oldbrk) < 0) 236 if (do_brk(oldbrk, newbrk-oldbrk, &uf) < 0)
236 goto out; 237 goto out;
237 238
238set_brk: 239set_brk:
239 mm->brk = brk; 240 mm->brk = brk;
240 populate = newbrk > oldbrk && (mm->def_flags & VM_LOCKED) != 0; 241 populate = newbrk > oldbrk && (mm->def_flags & VM_LOCKED) != 0;
241 up_write(&mm->mmap_sem); 242 up_write(&mm->mmap_sem);
243 userfaultfd_unmap_complete(mm, &uf);
242 if (populate) 244 if (populate)
243 mm_populate(oldbrk, newbrk - oldbrk); 245 mm_populate(oldbrk, newbrk - oldbrk);
244 return brk; 246 return brk;
@@ -1304,7 +1306,8 @@ static inline int mlock_future_check(struct mm_struct *mm,
1304unsigned long do_mmap(struct file *file, unsigned long addr, 1306unsigned long do_mmap(struct file *file, unsigned long addr,
1305 unsigned long len, unsigned long prot, 1307 unsigned long len, unsigned long prot,
1306 unsigned long flags, vm_flags_t vm_flags, 1308 unsigned long flags, vm_flags_t vm_flags,
1307 unsigned long pgoff, unsigned long *populate) 1309 unsigned long pgoff, unsigned long *populate,
1310 struct list_head *uf)
1308{ 1311{
1309 struct mm_struct *mm = current->mm; 1312 struct mm_struct *mm = current->mm;
1310 int pkey = 0; 1313 int pkey = 0;
@@ -1447,7 +1450,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
1447 vm_flags |= VM_NORESERVE; 1450 vm_flags |= VM_NORESERVE;
1448 } 1451 }
1449 1452
1450 addr = mmap_region(file, addr, len, vm_flags, pgoff); 1453 addr = mmap_region(file, addr, len, vm_flags, pgoff, uf);
1451 if (!IS_ERR_VALUE(addr) && 1454 if (!IS_ERR_VALUE(addr) &&
1452 ((vm_flags & VM_LOCKED) || 1455 ((vm_flags & VM_LOCKED) ||
1453 (flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE)) 1456 (flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE))
@@ -1583,7 +1586,8 @@ static inline int accountable_mapping(struct file *file, vm_flags_t vm_flags)
1583} 1586}
1584 1587
1585unsigned long mmap_region(struct file *file, unsigned long addr, 1588unsigned long mmap_region(struct file *file, unsigned long addr,
1586 unsigned long len, vm_flags_t vm_flags, unsigned long pgoff) 1589 unsigned long len, vm_flags_t vm_flags, unsigned long pgoff,
1590 struct list_head *uf)
1587{ 1591{
1588 struct mm_struct *mm = current->mm; 1592 struct mm_struct *mm = current->mm;
1589 struct vm_area_struct *vma, *prev; 1593 struct vm_area_struct *vma, *prev;
@@ -1609,7 +1613,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
1609 /* Clear old maps */ 1613 /* Clear old maps */
1610 while (find_vma_links(mm, addr, addr + len, &prev, &rb_link, 1614 while (find_vma_links(mm, addr, addr + len, &prev, &rb_link,
1611 &rb_parent)) { 1615 &rb_parent)) {
1612 if (do_munmap(mm, addr, len)) 1616 if (do_munmap(mm, addr, len, uf))
1613 return -ENOMEM; 1617 return -ENOMEM;
1614 } 1618 }
1615 1619
@@ -2579,7 +2583,8 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
2579 * work. This now handles partial unmappings. 2583 * work. This now handles partial unmappings.
2580 * Jeremy Fitzhardinge <jeremy@goop.org> 2584 * Jeremy Fitzhardinge <jeremy@goop.org>
2581 */ 2585 */
2582int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) 2586int do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
2587 struct list_head *uf)
2583{ 2588{
2584 unsigned long end; 2589 unsigned long end;
2585 struct vm_area_struct *vma, *prev, *last; 2590 struct vm_area_struct *vma, *prev, *last;
@@ -2603,6 +2608,13 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
2603 if (vma->vm_start >= end) 2608 if (vma->vm_start >= end)
2604 return 0; 2609 return 0;
2605 2610
2611 if (uf) {
2612 int error = userfaultfd_unmap_prep(vma, start, end, uf);
2613
2614 if (error)
2615 return error;
2616 }
2617
2606 /* 2618 /*
2607 * If we need to split any vma, do it now to save pain later. 2619 * If we need to split any vma, do it now to save pain later.
2608 * 2620 *
@@ -2668,12 +2680,14 @@ int vm_munmap(unsigned long start, size_t len)
2668{ 2680{
2669 int ret; 2681 int ret;
2670 struct mm_struct *mm = current->mm; 2682 struct mm_struct *mm = current->mm;
2683 LIST_HEAD(uf);
2671 2684
2672 if (down_write_killable(&mm->mmap_sem)) 2685 if (down_write_killable(&mm->mmap_sem))
2673 return -EINTR; 2686 return -EINTR;
2674 2687
2675 ret = do_munmap(mm, start, len); 2688 ret = do_munmap(mm, start, len, &uf);
2676 up_write(&mm->mmap_sem); 2689 up_write(&mm->mmap_sem);
2690 userfaultfd_unmap_complete(mm, &uf);
2677 return ret; 2691 return ret;
2678} 2692}
2679EXPORT_SYMBOL(vm_munmap); 2693EXPORT_SYMBOL(vm_munmap);
@@ -2773,7 +2787,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
2773 2787
2774 file = get_file(vma->vm_file); 2788 file = get_file(vma->vm_file);
2775 ret = do_mmap_pgoff(vma->vm_file, start, size, 2789 ret = do_mmap_pgoff(vma->vm_file, start, size,
2776 prot, flags, pgoff, &populate); 2790 prot, flags, pgoff, &populate, NULL);
2777 fput(file); 2791 fput(file);
2778out: 2792out:
2779 up_write(&mm->mmap_sem); 2793 up_write(&mm->mmap_sem);
@@ -2799,7 +2813,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm)
2799 * anonymous maps. eventually we may be able to do some 2813 * anonymous maps. eventually we may be able to do some
2800 * brk-specific accounting here. 2814 * brk-specific accounting here.
2801 */ 2815 */
2802static int do_brk_flags(unsigned long addr, unsigned long request, unsigned long flags) 2816static int do_brk_flags(unsigned long addr, unsigned long request, unsigned long flags, struct list_head *uf)
2803{ 2817{
2804 struct mm_struct *mm = current->mm; 2818 struct mm_struct *mm = current->mm;
2805 struct vm_area_struct *vma, *prev; 2819 struct vm_area_struct *vma, *prev;
@@ -2838,7 +2852,7 @@ static int do_brk_flags(unsigned long addr, unsigned long request, unsigned long
2838 */ 2852 */
2839 while (find_vma_links(mm, addr, addr + len, &prev, &rb_link, 2853 while (find_vma_links(mm, addr, addr + len, &prev, &rb_link,
2840 &rb_parent)) { 2854 &rb_parent)) {
2841 if (do_munmap(mm, addr, len)) 2855 if (do_munmap(mm, addr, len, uf))
2842 return -ENOMEM; 2856 return -ENOMEM;
2843 } 2857 }
2844 2858
@@ -2885,9 +2899,9 @@ out:
2885 return 0; 2899 return 0;
2886} 2900}
2887 2901
2888static int do_brk(unsigned long addr, unsigned long len) 2902static int do_brk(unsigned long addr, unsigned long len, struct list_head *uf)
2889{ 2903{
2890 return do_brk_flags(addr, len, 0); 2904 return do_brk_flags(addr, len, 0, uf);
2891} 2905}
2892 2906
2893int vm_brk_flags(unsigned long addr, unsigned long len, unsigned long flags) 2907int vm_brk_flags(unsigned long addr, unsigned long len, unsigned long flags)
@@ -2895,13 +2909,15 @@ int vm_brk_flags(unsigned long addr, unsigned long len, unsigned long flags)
2895 struct mm_struct *mm = current->mm; 2909 struct mm_struct *mm = current->mm;
2896 int ret; 2910 int ret;
2897 bool populate; 2911 bool populate;
2912 LIST_HEAD(uf);
2898 2913
2899 if (down_write_killable(&mm->mmap_sem)) 2914 if (down_write_killable(&mm->mmap_sem))
2900 return -EINTR; 2915 return -EINTR;
2901 2916
2902 ret = do_brk_flags(addr, len, flags); 2917 ret = do_brk_flags(addr, len, flags, &uf);
2903 populate = ((mm->def_flags & VM_LOCKED) != 0); 2918 populate = ((mm->def_flags & VM_LOCKED) != 0);
2904 up_write(&mm->mmap_sem); 2919 up_write(&mm->mmap_sem);
2920 userfaultfd_unmap_complete(mm, &uf);
2905 if (populate && !ret) 2921 if (populate && !ret)
2906 mm_populate(addr, len); 2922 mm_populate(addr, len);
2907 return ret; 2923 return ret;