From: Liam R. Howlett Date: Tue, 1 Dec 2020 02:28:44 +0000 (-0500) Subject: mm/mmap: rework do_mas_munmap() and friends X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=0c52c044d10ae3b2442aa35aeebe5f7f12abe404;p=users%2Fjedix%2Flinux-maple.git mm/mmap: rework do_mas_munmap() and friends Pull out alignmnet calculations for functions that have already aligned Signed-off-by: Liam R. Howlett --- diff --git a/mm/mmap.c b/mm/mmap.c index 60aefcc3c4f3..27aa6e9783de 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2420,34 +2420,23 @@ static inline int unlock_range(struct vm_area_struct *start, return count; } -/* Munmap is split into 2 main parts -- this part which finds - * what needs doing, and the areas themselves, which do the - * work. This now handles partial unmappings. - * Jeremy Fitzhardinge +/* do_mas_align_munmap() - munmap the aligned region from @start to @end. + * + * @mas: The maple_state, ideally set up to alter the correct tree location. + * @vma: The starting vm_area_struct + * @mm: The mm_struct + * @start: The aligned start address to munmap. + * @end: The aligned end address to munmap. + * @uf: The userfaultfd list_head + * @downgrade: Set to true to attempt a downwrite of the mmap_sem + * + * */ -int do_mas_munmap(struct ma_state *mas, struct mm_struct *mm, - unsigned long start, size_t len, struct list_head *uf, - bool downgrade) +int do_mas_align_munmap(struct ma_state *mas, struct vm_area_struct *vma, + struct mm_struct *mm, unsigned long start, + unsigned long end, struct list_head *uf, bool downgrade) { - unsigned long end; - struct vm_area_struct *vma, *prev, *last; - - if ((offset_in_page(start)) || start > TASK_SIZE || len > TASK_SIZE-start) - return -EINVAL; - - end = start + PAGE_ALIGN(len); - if (end == start) - return -EINVAL; - - /* arch_unmap() might do unmaps itself. */ - arch_unmap(mm, start, end); - - /* Find the first overlapping VMA */ - vma = mas_find(mas, end - 1); - if (!vma) - return 0; - - mas->last = end - 1; + struct vm_area_struct *prev, *last; /* we have start < vma->vm_end */ /* @@ -2553,6 +2542,51 @@ int do_mas_munmap(struct ma_state *mas, struct mm_struct *mm, return downgrade ? 1 : 0; } +/* + * do_mas_munmap() - munmap a given range. + * @mas: The maple state + * @mm: The mm_struct + * @start: The start address to munmap + * @len: The length of the range to munmap + * @uf: The userfaultfd list_head + * @downgrade: set to true if the user wants to attempt to write_downgrade the + * mmap_sem + * + * This function takes a @mas that is in the correct state to remove the + * mapping(s). The @len will be aligned and any arch_unmap work will be + * preformed. + */ +int do_mas_munmap(struct ma_state *mas, struct mm_struct *mm, + unsigned long start, size_t len, struct list_head *uf, + bool downgrade) +{ + unsigned long end; + struct vm_area_struct *vma; + + if ((offset_in_page(start)) || start > TASK_SIZE || len > TASK_SIZE-start) + return -EINVAL; + + end = start + PAGE_ALIGN(len); + if (end == start) + return -EINVAL; + + /* arch_unmap() might do unmaps itself. */ + arch_unmap(mm, start, end); + + /* Find the first overlapping VMA */ + vma = mas_find(mas, end - 1); + if (!vma) + return 0; + + mas->last = end - 1; + return do_mas_align_munmap(mas, vma, mm, start, end, uf, downgrade); +} +/* do_munmap() - Wrapper function for non-maple tree aware do_munmap() calls. + * @mm: The mm_struct + * @start: The start address to munmap + * @len: The length to be munmapped. + * @uf: The userfaultfd list_head + */ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, struct list_head *uf) {