| From foo@baz Wed Aug 22 09:16:56 CEST 2018 |
| From: Linus Torvalds <torvalds@linux-foundation.org> |
| Date: Sat, 21 Jul 2018 14:48:45 -0700 |
| Subject: mm: make vm_area_dup() actually copy the old vma data |
| |
| From: Linus Torvalds <torvalds@linux-foundation.org> |
| |
| [ Upstream commit 95faf6992df468f617edb788da8c21c6eed0dfa7 ] |
| |
| .. and re-initialize th eanon_vma_chain head. |
| |
| This removes some boiler-plate from the users, and also makes it clear |
| why it didn't need use the 'zalloc()' version. |
| |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| kernel/fork.c | 10 +++++++--- |
| mm/mmap.c | 7 ------- |
| mm/nommu.c | 1 - |
| 3 files changed, 7 insertions(+), 11 deletions(-) |
| |
| --- a/kernel/fork.c |
| +++ b/kernel/fork.c |
| @@ -315,7 +315,13 @@ struct vm_area_struct *vm_area_alloc(voi |
| |
| struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) |
| { |
| - return kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
| + struct vm_area_struct *new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
| + |
| + if (new) { |
| + *new = *orig; |
| + INIT_LIST_HEAD(&new->anon_vma_chain); |
| + } |
| + return new; |
| } |
| |
| void vm_area_free(struct vm_area_struct *vma) |
| @@ -473,8 +479,6 @@ static __latent_entropy int dup_mmap(str |
| tmp = vm_area_dup(mpnt); |
| if (!tmp) |
| goto fail_nomem; |
| - *tmp = *mpnt; |
| - INIT_LIST_HEAD(&tmp->anon_vma_chain); |
| retval = vma_dup_policy(mpnt, tmp); |
| if (retval) |
| goto fail_nomem_policy; |
| --- a/mm/mmap.c |
| +++ b/mm/mmap.c |
| @@ -2624,11 +2624,6 @@ int __split_vma(struct mm_struct *mm, st |
| if (!new) |
| return -ENOMEM; |
| |
| - /* most fields are the same, copy all, and then fixup */ |
| - *new = *vma; |
| - |
| - INIT_LIST_HEAD(&new->anon_vma_chain); |
| - |
| if (new_below) |
| new->vm_end = addr; |
| else { |
| @@ -3205,13 +3200,11 @@ struct vm_area_struct *copy_vma(struct v |
| new_vma = vm_area_dup(vma); |
| if (!new_vma) |
| goto out; |
| - *new_vma = *vma; |
| new_vma->vm_start = addr; |
| new_vma->vm_end = addr + len; |
| new_vma->vm_pgoff = pgoff; |
| if (vma_dup_policy(vma, new_vma)) |
| goto out_free_vma; |
| - INIT_LIST_HEAD(&new_vma->anon_vma_chain); |
| if (anon_vma_clone(new_vma, vma)) |
| goto out_free_mempol; |
| if (new_vma->vm_file) |
| --- a/mm/nommu.c |
| +++ b/mm/nommu.c |
| @@ -1476,7 +1476,6 @@ int split_vma(struct mm_struct *mm, stru |
| } |
| |
| /* most fields are the same, copy all, and then fixup */ |
| - *new = *vma; |
| *region = *vma->vm_region; |
| new->vm_region = region; |
| |