diff options
author | David Howells <dhowells@redhat.com> | 2012-02-23 08:50:35 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-02-24 11:59:04 -0500 |
commit | 918e556ec214ed2f584e4cac56d7b29e4bb6bf27 (patch) | |
tree | cf2ba7c88f4b349d1120517f09ec4588f12eb285 /mm | |
parent | 37e79cbf7d45451fb4d1213184e484723c25c65a (diff) |
NOMMU: Lock i_mmap_mutex for access to the VMA prio list
Lock i_mmap_mutex for access to the VMA prio list to prevent concurrent
access. Currently, certain parts of the mmap handling are protected by
the region mutex, but not all.
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/nommu.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/mm/nommu.c b/mm/nommu.c index b982290fd962..ee7e57ebef6a 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -696,9 +696,11 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) | |||
696 | if (vma->vm_file) { | 696 | if (vma->vm_file) { |
697 | mapping = vma->vm_file->f_mapping; | 697 | mapping = vma->vm_file->f_mapping; |
698 | 698 | ||
699 | mutex_lock(&mapping->i_mmap_mutex); | ||
699 | flush_dcache_mmap_lock(mapping); | 700 | flush_dcache_mmap_lock(mapping); |
700 | vma_prio_tree_insert(vma, &mapping->i_mmap); | 701 | vma_prio_tree_insert(vma, &mapping->i_mmap); |
701 | flush_dcache_mmap_unlock(mapping); | 702 | flush_dcache_mmap_unlock(mapping); |
703 | mutex_unlock(&mapping->i_mmap_mutex); | ||
702 | } | 704 | } |
703 | 705 | ||
704 | /* add the VMA to the tree */ | 706 | /* add the VMA to the tree */ |
@@ -760,9 +762,11 @@ static void delete_vma_from_mm(struct vm_area_struct *vma) | |||
760 | if (vma->vm_file) { | 762 | if (vma->vm_file) { |
761 | mapping = vma->vm_file->f_mapping; | 763 | mapping = vma->vm_file->f_mapping; |
762 | 764 | ||
765 | mutex_lock(&mapping->i_mmap_mutex); | ||
763 | flush_dcache_mmap_lock(mapping); | 766 | flush_dcache_mmap_lock(mapping); |
764 | vma_prio_tree_remove(vma, &mapping->i_mmap); | 767 | vma_prio_tree_remove(vma, &mapping->i_mmap); |
765 | flush_dcache_mmap_unlock(mapping); | 768 | flush_dcache_mmap_unlock(mapping); |
769 | mutex_unlock(&mapping->i_mmap_mutex); | ||
766 | } | 770 | } |
767 | 771 | ||
768 | /* remove from the MM's tree and list */ | 772 | /* remove from the MM's tree and list */ |
@@ -2052,6 +2056,7 @@ int nommu_shrink_inode_mappings(struct inode *inode, size_t size, | |||
2052 | high = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 2056 | high = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
2053 | 2057 | ||
2054 | down_write(&nommu_region_sem); | 2058 | down_write(&nommu_region_sem); |
2059 | mutex_lock(&inode->i_mapping->i_mmap_mutex); | ||
2055 | 2060 | ||
2056 | /* search for VMAs that fall within the dead zone */ | 2061 | /* search for VMAs that fall within the dead zone */ |
2057 | vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap, | 2062 | vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap, |
@@ -2059,6 +2064,7 @@ int nommu_shrink_inode_mappings(struct inode *inode, size_t size, | |||
2059 | /* found one - only interested if it's shared out of the page | 2064 | /* found one - only interested if it's shared out of the page |
2060 | * cache */ | 2065 | * cache */ |
2061 | if (vma->vm_flags & VM_SHARED) { | 2066 | if (vma->vm_flags & VM_SHARED) { |
2067 | mutex_unlock(&inode->i_mapping->i_mmap_mutex); | ||
2062 | up_write(&nommu_region_sem); | 2068 | up_write(&nommu_region_sem); |
2063 | return -ETXTBSY; /* not quite true, but near enough */ | 2069 | return -ETXTBSY; /* not quite true, but near enough */ |
2064 | } | 2070 | } |
@@ -2086,6 +2092,7 @@ int nommu_shrink_inode_mappings(struct inode *inode, size_t size, | |||
2086 | } | 2092 | } |
2087 | } | 2093 | } |
2088 | 2094 | ||
2095 | mutex_unlock(&inode->i_mapping->i_mmap_mutex); | ||
2089 | up_write(&nommu_region_sem); | 2096 | up_write(&nommu_region_sem); |
2090 | return 0; | 2097 | return 0; |
2091 | } | 2098 | } |