aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2012-02-23 08:50:35 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-02-24 11:59:04 -0500
commit918e556ec214ed2f584e4cac56d7b29e4bb6bf27 (patch)
treecf2ba7c88f4b349d1120517f09ec4588f12eb285 /mm
parent37e79cbf7d45451fb4d1213184e484723c25c65a (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.c7
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}