diff options
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/mm/mmap.c b/mm/mmap.c index 51e70fa98450..84c71431a527 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1977,6 +1977,8 @@ static int expand_upwards(struct vm_area_struct *vma, unsigned long address) return -ENOMEM; } + /* Lock the VMA before expanding to prevent concurrent page faults */ + vma_start_write(vma); /* * vma->vm_start/vm_end cannot change under us because the caller * is required to hold the mmap_lock in read mode. We need the @@ -2064,6 +2066,8 @@ int expand_downwards(struct vm_area_struct *vma, unsigned long address) return -ENOMEM; } + /* Lock the VMA before expanding to prevent concurrent page faults */ + vma_start_write(vma); /* * vma->vm_start/vm_end cannot change under us because the caller * is required to hold the mmap_lock in read mode. We need the @@ -2554,11 +2558,10 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, mas_set(&mas_detach, start); remove_mt(mm, &mas_detach); __mt_destroy(&mt_detach); + validate_mm(mm); if (unlock) mmap_read_unlock(mm); - - validate_mm(mm); return 0; clear_tree_failed: @@ -2572,6 +2575,7 @@ end_split_failed: __mt_destroy(&mt_detach); start_split_failed: map_count_exceeded: + validate_mm(mm); return error; } @@ -2808,6 +2812,8 @@ cannot_expand: if (vma->vm_file) i_mmap_lock_write(vma->vm_file->f_mapping); + /* Lock the VMA since it is modified after insertion into VMA tree */ + vma_start_write(vma); vma_iter_store(&vmi, vma); mm->map_count++; if (vma->vm_file) { @@ -3020,12 +3026,9 @@ int do_vma_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, bool unlock) { struct mm_struct *mm = vma->vm_mm; - int ret; arch_unmap(mm, start, end); - ret = do_vmi_align_munmap(vmi, vma, mm, start, end, uf, unlock); - validate_mm(mm); - return ret; + return do_vmi_align_munmap(vmi, vma, mm, start, end, uf, unlock); } /* |