aboutsummaryrefslogtreecommitdiffstats
path: root/mm/nommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/nommu.c')
-rw-r--r--mm/nommu.c187
1 files changed, 142 insertions, 45 deletions
diff --git a/mm/nommu.c b/mm/nommu.c
index 9876fa0c3ad3..63fa17d121f0 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -162,7 +162,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
162 } 162 }
163 if (vmas) 163 if (vmas)
164 vmas[i] = vma; 164 vmas[i] = vma;
165 start += PAGE_SIZE; 165 start = (start + PAGE_SIZE) & PAGE_MASK;
166 } 166 }
167 167
168 return i; 168 return i;
@@ -432,6 +432,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
432 /* 432 /*
433 * Ok, looks good - let it rip. 433 * Ok, looks good - let it rip.
434 */ 434 */
435 flush_icache_range(mm->brk, brk);
435 return mm->brk = brk; 436 return mm->brk = brk;
436} 437}
437 438
@@ -551,11 +552,11 @@ static void free_page_series(unsigned long from, unsigned long to)
551static void __put_nommu_region(struct vm_region *region) 552static void __put_nommu_region(struct vm_region *region)
552 __releases(nommu_region_sem) 553 __releases(nommu_region_sem)
553{ 554{
554 kenter("%p{%d}", region, atomic_read(&region->vm_usage)); 555 kenter("%p{%d}", region, region->vm_usage);
555 556
556 BUG_ON(!nommu_region_tree.rb_node); 557 BUG_ON(!nommu_region_tree.rb_node);
557 558
558 if (atomic_dec_and_test(&region->vm_usage)) { 559 if (--region->vm_usage == 0) {
559 if (region->vm_top > region->vm_start) 560 if (region->vm_top > region->vm_start)
560 delete_nommu_region(region); 561 delete_nommu_region(region);
561 up_write(&nommu_region_sem); 562 up_write(&nommu_region_sem);
@@ -1039,10 +1040,9 @@ static int do_mmap_shared_file(struct vm_area_struct *vma)
1039 if (ret != -ENOSYS) 1040 if (ret != -ENOSYS)
1040 return ret; 1041 return ret;
1041 1042
1042 /* getting an ENOSYS error indicates that direct mmap isn't 1043 /* getting -ENOSYS indicates that direct mmap isn't possible (as
1043 * possible (as opposed to tried but failed) so we'll fall 1044 * opposed to tried but failed) so we can only give a suitable error as
1044 * through to making a private copy of the data and mapping 1045 * it's not possible to make a private copy if MAP_SHARED was given */
1045 * that if we can */
1046 return -ENODEV; 1046 return -ENODEV;
1047} 1047}
1048 1048
@@ -1143,9 +1143,6 @@ static int do_mmap_private(struct vm_area_struct *vma,
1143 if (ret < rlen) 1143 if (ret < rlen)
1144 memset(base + ret, 0, rlen - ret); 1144 memset(base + ret, 0, rlen - ret);
1145 1145
1146 } else {
1147 /* if it's an anonymous mapping, then just clear it */
1148 memset(base, 0, rlen);
1149 } 1146 }
1150 1147
1151 return 0; 1148 return 0;
@@ -1207,11 +1204,11 @@ unsigned long do_mmap_pgoff(struct file *file,
1207 if (!vma) 1204 if (!vma)
1208 goto error_getting_vma; 1205 goto error_getting_vma;
1209 1206
1210 atomic_set(&region->vm_usage, 1); 1207 region->vm_usage = 1;
1211 region->vm_flags = vm_flags; 1208 region->vm_flags = vm_flags;
1212 region->vm_pgoff = pgoff; 1209 region->vm_pgoff = pgoff;
1213 1210
1214 INIT_LIST_HEAD(&vma->anon_vma_node); 1211 INIT_LIST_HEAD(&vma->anon_vma_chain);
1215 vma->vm_flags = vm_flags; 1212 vma->vm_flags = vm_flags;
1216 vma->vm_pgoff = pgoff; 1213 vma->vm_pgoff = pgoff;
1217 1214
@@ -1274,7 +1271,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1274 } 1271 }
1275 1272
1276 /* we've found a region we can share */ 1273 /* we've found a region we can share */
1277 atomic_inc(&pregion->vm_usage); 1274 pregion->vm_usage++;
1278 vma->vm_region = pregion; 1275 vma->vm_region = pregion;
1279 start = pregion->vm_start; 1276 start = pregion->vm_start;
1280 start += (pgoff - pregion->vm_pgoff) << PAGE_SHIFT; 1277 start += (pgoff - pregion->vm_pgoff) << PAGE_SHIFT;
@@ -1291,7 +1288,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1291 vma->vm_region = NULL; 1288 vma->vm_region = NULL;
1292 vma->vm_start = 0; 1289 vma->vm_start = 0;
1293 vma->vm_end = 0; 1290 vma->vm_end = 0;
1294 atomic_dec(&pregion->vm_usage); 1291 pregion->vm_usage--;
1295 pregion = NULL; 1292 pregion = NULL;
1296 goto error_just_free; 1293 goto error_just_free;
1297 } 1294 }
@@ -1343,6 +1340,11 @@ unsigned long do_mmap_pgoff(struct file *file,
1343 goto error_just_free; 1340 goto error_just_free;
1344 add_nommu_region(region); 1341 add_nommu_region(region);
1345 1342
1343 /* clear anonymous mappings that don't ask for uninitialized data */
1344 if (!vma->vm_file && !(flags & MAP_UNINITIALIZED))
1345 memset((void *)region->vm_start, 0,
1346 region->vm_end - region->vm_start);
1347
1346 /* okay... we have a mapping; now we have to register it */ 1348 /* okay... we have a mapping; now we have to register it */
1347 result = vma->vm_start; 1349 result = vma->vm_start;
1348 1350
@@ -1351,10 +1353,14 @@ unsigned long do_mmap_pgoff(struct file *file,
1351share: 1353share:
1352 add_vma_to_mm(current->mm, vma); 1354 add_vma_to_mm(current->mm, vma);
1353 1355
1354 up_write(&nommu_region_sem); 1356 /* we flush the region from the icache only when the first executable
1357 * mapping of it is made */
1358 if (vma->vm_flags & VM_EXEC && !region->vm_icache_flushed) {
1359 flush_icache_range(region->vm_start, region->vm_end);
1360 region->vm_icache_flushed = true;
1361 }
1355 1362
1356 if (prot & PROT_EXEC) 1363 up_write(&nommu_region_sem);
1357 flush_icache_range(result, result + len);
1358 1364
1359 kleave(" = %lx", result); 1365 kleave(" = %lx", result);
1360 return result; 1366 return result;
@@ -1396,6 +1402,55 @@ error_getting_region:
1396} 1402}
1397EXPORT_SYMBOL(do_mmap_pgoff); 1403EXPORT_SYMBOL(do_mmap_pgoff);
1398 1404
1405SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
1406 unsigned long, prot, unsigned long, flags,
1407 unsigned long, fd, unsigned long, pgoff)
1408{
1409 struct file *file = NULL;
1410 unsigned long retval = -EBADF;
1411
1412 if (!(flags & MAP_ANONYMOUS)) {
1413 file = fget(fd);
1414 if (!file)
1415 goto out;
1416 }
1417
1418 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1419
1420 down_write(&current->mm->mmap_sem);
1421 retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1422 up_write(&current->mm->mmap_sem);
1423
1424 if (file)
1425 fput(file);
1426out:
1427 return retval;
1428}
1429
1430#ifdef __ARCH_WANT_SYS_OLD_MMAP
1431struct mmap_arg_struct {
1432 unsigned long addr;
1433 unsigned long len;
1434 unsigned long prot;
1435 unsigned long flags;
1436 unsigned long fd;
1437 unsigned long offset;
1438};
1439
1440SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)
1441{
1442 struct mmap_arg_struct a;
1443
1444 if (copy_from_user(&a, arg, sizeof(a)))
1445 return -EFAULT;
1446 if (a.offset & ~PAGE_MASK)
1447 return -EINVAL;
1448
1449 return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
1450 a.offset >> PAGE_SHIFT);
1451}
1452#endif /* __ARCH_WANT_SYS_OLD_MMAP */
1453
1399/* 1454/*
1400 * split a vma into two pieces at address 'addr', a new vma is allocated either 1455 * split a vma into two pieces at address 'addr', a new vma is allocated either
1401 * for the first part or the tail. 1456 * for the first part or the tail.
@@ -1409,10 +1464,9 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
1409 1464
1410 kenter(""); 1465 kenter("");
1411 1466
1412 /* we're only permitted to split anonymous regions that have a single 1467 /* we're only permitted to split anonymous regions (these should have
1413 * owner */ 1468 * only a single usage on the region) */
1414 if (vma->vm_file || 1469 if (vma->vm_file)
1415 atomic_read(&vma->vm_region->vm_usage) != 1)
1416 return -ENOMEM; 1470 return -ENOMEM;
1417 1471
1418 if (mm->map_count >= sysctl_max_map_count) 1472 if (mm->map_count >= sysctl_max_map_count)
@@ -1486,7 +1540,7 @@ static int shrink_vma(struct mm_struct *mm,
1486 1540
1487 /* cut the backing region down to size */ 1541 /* cut the backing region down to size */
1488 region = vma->vm_region; 1542 region = vma->vm_region;
1489 BUG_ON(atomic_read(&region->vm_usage) != 1); 1543 BUG_ON(region->vm_usage != 1);
1490 1544
1491 down_write(&nommu_region_sem); 1545 down_write(&nommu_region_sem);
1492 delete_nommu_region(region); 1546 delete_nommu_region(region);
@@ -1730,27 +1784,6 @@ void unmap_mapping_range(struct address_space *mapping,
1730EXPORT_SYMBOL(unmap_mapping_range); 1784EXPORT_SYMBOL(unmap_mapping_range);
1731 1785
1732/* 1786/*
1733 * ask for an unmapped area at which to create a mapping on a file
1734 */
1735unsigned long get_unmapped_area(struct file *file, unsigned long addr,
1736 unsigned long len, unsigned long pgoff,
1737 unsigned long flags)
1738{
1739 unsigned long (*get_area)(struct file *, unsigned long, unsigned long,
1740 unsigned long, unsigned long);
1741
1742 get_area = current->mm->get_unmapped_area;
1743 if (file && file->f_op && file->f_op->get_unmapped_area)
1744 get_area = file->f_op->get_unmapped_area;
1745
1746 if (!get_area)
1747 return -ENOSYS;
1748
1749 return get_area(file, addr, len, pgoff, flags);
1750}
1751EXPORT_SYMBOL(get_unmapped_area);
1752
1753/*
1754 * Check that a process has enough memory to allocate a new virtual 1787 * Check that a process has enough memory to allocate a new virtual
1755 * mapping. 0 means there is enough memory for the allocation to 1788 * mapping. 0 means there is enough memory for the allocation to
1756 * succeed and -ENOMEM implies there is not. 1789 * succeed and -ENOMEM implies there is not.
@@ -1889,9 +1922,11 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
1889 1922
1890 /* only read or write mappings where it is permitted */ 1923 /* only read or write mappings where it is permitted */
1891 if (write && vma->vm_flags & VM_MAYWRITE) 1924 if (write && vma->vm_flags & VM_MAYWRITE)
1892 len -= copy_to_user((void *) addr, buf, len); 1925 copy_to_user_page(vma, NULL, addr,
1926 (void *) addr, buf, len);
1893 else if (!write && vma->vm_flags & VM_MAYREAD) 1927 else if (!write && vma->vm_flags & VM_MAYREAD)
1894 len -= copy_from_user(buf, (void *) addr, len); 1928 copy_from_user_page(vma, NULL, addr,
1929 buf, (void *) addr, len);
1895 else 1930 else
1896 len = 0; 1931 len = 0;
1897 } else { 1932 } else {
@@ -1902,3 +1937,65 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
1902 mmput(mm); 1937 mmput(mm);
1903 return len; 1938 return len;
1904} 1939}
1940
1941/**
1942 * nommu_shrink_inode_mappings - Shrink the shared mappings on an inode
1943 * @inode: The inode to check
1944 * @size: The current filesize of the inode
1945 * @newsize: The proposed filesize of the inode
1946 *
1947 * Check the shared mappings on an inode on behalf of a shrinking truncate to
1948 * make sure that that any outstanding VMAs aren't broken and then shrink the
1949 * vm_regions that extend that beyond so that do_mmap_pgoff() doesn't
1950 * automatically grant mappings that are too large.
1951 */
1952int nommu_shrink_inode_mappings(struct inode *inode, size_t size,
1953 size_t newsize)
1954{
1955 struct vm_area_struct *vma;
1956 struct prio_tree_iter iter;
1957 struct vm_region *region;
1958 pgoff_t low, high;
1959 size_t r_size, r_top;
1960
1961 low = newsize >> PAGE_SHIFT;
1962 high = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
1963
1964 down_write(&nommu_region_sem);
1965
1966 /* search for VMAs that fall within the dead zone */
1967 vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
1968 low, high) {
1969 /* found one - only interested if it's shared out of the page
1970 * cache */
1971 if (vma->vm_flags & VM_SHARED) {
1972 up_write(&nommu_region_sem);
1973 return -ETXTBSY; /* not quite true, but near enough */
1974 }
1975 }
1976
1977 /* reduce any regions that overlap the dead zone - if in existence,
1978 * these will be pointed to by VMAs that don't overlap the dead zone
1979 *
1980 * we don't check for any regions that start beyond the EOF as there
1981 * shouldn't be any
1982 */
1983 vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
1984 0, ULONG_MAX) {
1985 if (!(vma->vm_flags & VM_SHARED))
1986 continue;
1987
1988 region = vma->vm_region;
1989 r_size = region->vm_top - region->vm_start;
1990 r_top = (region->vm_pgoff << PAGE_SHIFT) + r_size;
1991
1992 if (r_top > newsize) {
1993 region->vm_top -= r_top - newsize;
1994 if (region->vm_end > region->vm_top)
1995 region->vm_end = region->vm_top;
1996 }
1997 }
1998
1999 up_write(&nommu_region_sem);
2000 return 0;
2001}