On Tue, Aug 06, 2024 at 10:28:03PM GMT, Pedro Falcato wrote: > We were doing an extra mmap tree traversal just to check if the entire > range is modifiable. This can be done when we iterate through the VMAs > instead. > > Note that this removes the arch_unmap() callsites and therefore isn't > quite ready for Proper(tm) upstreaming. If this isn't ready for upstreaming which is it being submitted as a patch series and not an RFC or such? Liam is likely to do some significant rework of this arch_unmap() stuff soon, and is certainly significantly reworking the munmap() logic, so to avoid conflicts it goes doubly that if this isn't meant for upstream then it should be RFC'd. > > Signed-off-by: Pedro Falcato <pedro.falcato@xxxxxxxxx> This patch doesn't apply in the mm-unstable tree. If you want your series to come in through the mm tree you need to rebase on this. I made a major change to file structure which moves a bunch of mm/mmap.c stuff to mm/vma.c (similarly moving things around in headers), which is why. It also means I can't sensibly review it... :) > --- > mm/mmap.c | 36 +++++++++++++----------------------- > 1 file changed, 13 insertions(+), 23 deletions(-) > > diff --git a/mm/mmap.c b/mm/mmap.c > index d0dfc85b209..b88666f618b 100644 > --- a/mm/mmap.c > +++ b/mm/mmap.c > @@ -2660,6 +2660,12 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, > if (end < vma->vm_end && mm->map_count >= sysctl_max_map_count) > goto map_count_exceeded; > > + /* Don't bother splitting the VMA if we can't unmap it anyway */ > + if (!can_modify_vma(vma)) { > + error = -EPERM; > + goto start_split_failed; > + } > + > error = __split_vma(vmi, vma, start, 1); > if (error) > goto start_split_failed; > @@ -2671,6 +2677,11 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, > */ > next = vma; > do { > + if (!can_modify_vma(vma)) { > + error = -EPERM; > + goto modify_vma_failed; > + } > + > /* Does it split the end? */ > if (next->vm_end > end) { > error = __split_vma(vmi, next, end, 0); > @@ -2763,6 +2774,7 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, > __mt_destroy(&mt_detach); > return 0; > > +modify_vma_failed: > clear_tree_failed: > userfaultfd_error: > munmap_gather_failed: > @@ -2808,17 +2820,6 @@ int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm, > if (end == start) > return -EINVAL; > > - /* > - * Check if memory is sealed before arch_unmap. > - * Prevent unmapping a sealed VMA. > - * can_modify_mm assumes we have acquired the lock on MM. > - */ > - if (unlikely(!can_modify_mm(mm, start, end))) > - return -EPERM; > - > - /* arch_unmap() might do unmaps itself. */ > - arch_unmap(mm, start, end); > - > /* Find the first overlapping VMA */ > vma = vma_find(vmi, end); > if (!vma) { > @@ -3229,18 +3230,7 @@ int do_vma_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, > unsigned long start, unsigned long end, struct list_head *uf, > bool unlock) > { > - struct mm_struct *mm = vma->vm_mm; > - > - /* > - * Check if memory is sealed before arch_unmap. > - * Prevent unmapping a sealed VMA. > - * can_modify_mm assumes we have acquired the lock on MM. > - */ > - if (unlikely(!can_modify_mm(mm, start, end))) > - return -EPERM; > - > - arch_unmap(mm, start, end); > - return do_vmi_align_munmap(vmi, vma, mm, start, end, uf, unlock); > + return do_vmi_align_munmap(vmi, vma, vma->vm_mm, start, end, uf, unlock); > } > > /* > -- > 2.46.0 >