diff options
author | Michel Lespinasse <walken@google.com> | 2012-10-08 19:30:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 03:22:28 -0400 |
commit | ca42b26ab285edc5ee3f9faa48379d258db53c35 (patch) | |
tree | 4a9d68d4d730474dde75b1ffff106d7e3442aef1 /mm/mmap.c | |
parent | 227e4047488d3ee0173a914275a7fd207ad51e5b (diff) |
mm: fix potential anon_vma locking issue in mprotect()
Fix an anon_vma locking issue in the following situation:
- vma has no anon_vma
- next has an anon_vma
- vma is being shrunk / next is being expanded, due to an mprotect call
We need to take next's anon_vma lock to avoid races with rmap users (such
as page migration) while next is being expanded.
Signed-off-by: Michel Lespinasse <walken@google.com>
Reviewed-by: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 6 |
1 files changed, 5 insertions, 1 deletions
@@ -573,8 +573,12 @@ again: remove_next = 1 + (end > next->vm_end); | |||
573 | */ | 573 | */ |
574 | if (vma->anon_vma && (importer || start != vma->vm_start)) { | 574 | if (vma->anon_vma && (importer || start != vma->vm_start)) { |
575 | anon_vma = vma->anon_vma; | 575 | anon_vma = vma->anon_vma; |
576 | VM_BUG_ON(adjust_next && next->anon_vma && | ||
577 | anon_vma != next->anon_vma); | ||
578 | } else if (adjust_next && next->anon_vma) | ||
579 | anon_vma = next->anon_vma; | ||
580 | if (anon_vma) | ||
576 | anon_vma_lock(anon_vma); | 581 | anon_vma_lock(anon_vma); |
577 | } | ||
578 | 582 | ||
579 | if (root) { | 583 | if (root) { |
580 | flush_dcache_mmap_lock(mapping); | 584 | flush_dcache_mmap_lock(mapping); |