diff options
author | Hugh Dickins <hugh.dickins@tiscali.co.uk> | 2009-12-30 15:17:34 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-30 15:23:27 -0500 |
commit | 66f0dc481e5b802ab363b979fc1753410c7d82b5 (patch) | |
tree | 9f8609685f07d410bc6536a0d3e47e366edf93d4 /mm | |
parent | 75c85a0bc13367aabb36e8208d4e373b022b43b3 (diff) |
mm: move sys_mmap_pgoff from util.c
Move sys_mmap_pgoff() from mm/util.c to mm/mmap.c and mm/nommu.c,
where we'd expect to find such code: especially now that it contains
the MAP_HUGETLB handling. Revert mm/util.c to how it was in 2.6.32.
This patch just ignores MAP_HUGETLB in the nommu case, as in 2.6.32,
whereas 2.6.33-rc2 reported -ENOSYS. Perhaps validate_mmap_request()
should reject it with -EINVAL? Add that later if necessary.
Signed-off-by: Hugh Dickins <hugh.dickins@tiscali.co.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/mmap.c | 40 | ||||
-rw-r--r-- | mm/nommu.c | 25 | ||||
-rw-r--r-- | mm/util.c | 44 |
3 files changed, 65 insertions, 44 deletions
@@ -1043,6 +1043,46 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
1043 | } | 1043 | } |
1044 | EXPORT_SYMBOL(do_mmap_pgoff); | 1044 | EXPORT_SYMBOL(do_mmap_pgoff); |
1045 | 1045 | ||
1046 | SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, | ||
1047 | unsigned long, prot, unsigned long, flags, | ||
1048 | unsigned long, fd, unsigned long, pgoff) | ||
1049 | { | ||
1050 | struct file *file = NULL; | ||
1051 | unsigned long retval = -EBADF; | ||
1052 | |||
1053 | if (!(flags & MAP_ANONYMOUS)) { | ||
1054 | if (unlikely(flags & MAP_HUGETLB)) | ||
1055 | return -EINVAL; | ||
1056 | file = fget(fd); | ||
1057 | if (!file) | ||
1058 | goto out; | ||
1059 | } else if (flags & MAP_HUGETLB) { | ||
1060 | struct user_struct *user = NULL; | ||
1061 | /* | ||
1062 | * VM_NORESERVE is used because the reservations will be | ||
1063 | * taken when vm_ops->mmap() is called | ||
1064 | * A dummy user value is used because we are not locking | ||
1065 | * memory so no accounting is necessary | ||
1066 | */ | ||
1067 | len = ALIGN(len, huge_page_size(&default_hstate)); | ||
1068 | file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE, | ||
1069 | &user, HUGETLB_ANONHUGE_INODE); | ||
1070 | if (IS_ERR(file)) | ||
1071 | return PTR_ERR(file); | ||
1072 | } | ||
1073 | |||
1074 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
1075 | |||
1076 | down_write(¤t->mm->mmap_sem); | ||
1077 | retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
1078 | up_write(¤t->mm->mmap_sem); | ||
1079 | |||
1080 | if (file) | ||
1081 | fput(file); | ||
1082 | out: | ||
1083 | return retval; | ||
1084 | } | ||
1085 | |||
1046 | /* | 1086 | /* |
1047 | * Some shared mappigns will want the pages marked read-only | 1087 | * Some shared mappigns will want the pages marked read-only |
1048 | * to track write events. If so, we'll downgrade vm_page_prot | 1088 | * to track write events. If so, we'll downgrade vm_page_prot |
diff --git a/mm/nommu.c b/mm/nommu.c index 8687973462bb..6f9248f89bde 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -1398,6 +1398,31 @@ error_getting_region: | |||
1398 | } | 1398 | } |
1399 | EXPORT_SYMBOL(do_mmap_pgoff); | 1399 | EXPORT_SYMBOL(do_mmap_pgoff); |
1400 | 1400 | ||
1401 | SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, | ||
1402 | unsigned long, prot, unsigned long, flags, | ||
1403 | unsigned long, fd, unsigned long, pgoff) | ||
1404 | { | ||
1405 | struct file *file = NULL; | ||
1406 | unsigned long retval = -EBADF; | ||
1407 | |||
1408 | if (!(flags & MAP_ANONYMOUS)) { | ||
1409 | file = fget(fd); | ||
1410 | if (!file) | ||
1411 | goto out; | ||
1412 | } | ||
1413 | |||
1414 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
1415 | |||
1416 | down_write(¤t->mm->mmap_sem); | ||
1417 | retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
1418 | up_write(¤t->mm->mmap_sem); | ||
1419 | |||
1420 | if (file) | ||
1421 | fput(file); | ||
1422 | out: | ||
1423 | return retval; | ||
1424 | } | ||
1425 | |||
1401 | /* | 1426 | /* |
1402 | * split a vma into two pieces at address 'addr', a new vma is allocated either | 1427 | * split a vma into two pieces at address 'addr', a new vma is allocated either |
1403 | * for the first part or the tail. | 1428 | * for the first part or the tail. |
@@ -4,10 +4,6 @@ | |||
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/err.h> | 5 | #include <linux/err.h> |
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/hugetlb.h> | ||
8 | #include <linux/syscalls.h> | ||
9 | #include <linux/mman.h> | ||
10 | #include <linux/file.h> | ||
11 | #include <asm/uaccess.h> | 7 | #include <asm/uaccess.h> |
12 | 8 | ||
13 | #define CREATE_TRACE_POINTS | 9 | #define CREATE_TRACE_POINTS |
@@ -272,46 +268,6 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start, | |||
272 | } | 268 | } |
273 | EXPORT_SYMBOL_GPL(get_user_pages_fast); | 269 | EXPORT_SYMBOL_GPL(get_user_pages_fast); |
274 | 270 | ||
275 | SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, | ||
276 | unsigned long, prot, unsigned long, flags, | ||
277 | unsigned long, fd, unsigned long, pgoff) | ||
278 | { | ||
279 | struct file * file = NULL; | ||
280 | unsigned long retval = -EBADF; | ||
281 | |||
282 | if (!(flags & MAP_ANONYMOUS)) { | ||
283 | if (unlikely(flags & MAP_HUGETLB)) | ||
284 | return -EINVAL; | ||
285 | file = fget(fd); | ||
286 | if (!file) | ||
287 | goto out; | ||
288 | } else if (flags & MAP_HUGETLB) { | ||
289 | struct user_struct *user = NULL; | ||
290 | /* | ||
291 | * VM_NORESERVE is used because the reservations will be | ||
292 | * taken when vm_ops->mmap() is called | ||
293 | * A dummy user value is used because we are not locking | ||
294 | * memory so no accounting is necessary | ||
295 | */ | ||
296 | len = ALIGN(len, huge_page_size(&default_hstate)); | ||
297 | file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE, | ||
298 | &user, HUGETLB_ANONHUGE_INODE); | ||
299 | if (IS_ERR(file)) | ||
300 | return PTR_ERR(file); | ||
301 | } | ||
302 | |||
303 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
304 | |||
305 | down_write(¤t->mm->mmap_sem); | ||
306 | retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
307 | up_write(¤t->mm->mmap_sem); | ||
308 | |||
309 | if (file) | ||
310 | fput(file); | ||
311 | out: | ||
312 | return retval; | ||
313 | } | ||
314 | |||
315 | /* Tracepoints definitions. */ | 271 | /* Tracepoints definitions. */ |
316 | EXPORT_TRACEPOINT_SYMBOL(kmalloc); | 272 | EXPORT_TRACEPOINT_SYMBOL(kmalloc); |
317 | EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc); | 273 | EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc); |