diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-20 20:13:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-20 20:29:13 -0400 |
commit | 6be5ceb02e98eaf6cfc4f8b12a896d04023f340d (patch) | |
tree | f34de1392300bbf63549f4eeb20f7606d6f7b1f9 /mm | |
parent | a46ef99d80817a167477ed1c8b4d90ee0c2e726f (diff) |
VM: add "vm_mmap()" helper function
This continues the theme started with vm_brk() and vm_munmap():
vm_mmap() does the same thing as do_mmap(), but additionally does the
required VM locking.
This uninlines (and rewrites it to be clearer) do_mmap(), which sadly
duplicates it in mm/mmap.c and mm/nommu.c. But that way we don't have
to export our internal do_mmap_pgoff() function.
Some day we hopefully don't have to export do_mmap() either, if all
modular users can become the simpler vm_mmap() instead. We're actually
very close to that already, with the notable exception of the (broken)
use in i810, and a couple of stragglers in binfmt_elf.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/mmap.c | 29 | ||||
-rw-r--r-- | mm/nommu.c | 29 |
2 files changed, 54 insertions, 4 deletions
@@ -953,7 +953,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint) | |||
953 | * The caller must hold down_write(¤t->mm->mmap_sem). | 953 | * The caller must hold down_write(¤t->mm->mmap_sem). |
954 | */ | 954 | */ |
955 | 955 | ||
956 | unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | 956 | static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, |
957 | unsigned long len, unsigned long prot, | 957 | unsigned long len, unsigned long prot, |
958 | unsigned long flags, unsigned long pgoff) | 958 | unsigned long flags, unsigned long pgoff) |
959 | { | 959 | { |
@@ -1089,7 +1089,32 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
1089 | 1089 | ||
1090 | return mmap_region(file, addr, len, flags, vm_flags, pgoff); | 1090 | return mmap_region(file, addr, len, flags, vm_flags, pgoff); |
1091 | } | 1091 | } |
1092 | EXPORT_SYMBOL(do_mmap_pgoff); | 1092 | |
1093 | unsigned long do_mmap(struct file *file, unsigned long addr, | ||
1094 | unsigned long len, unsigned long prot, | ||
1095 | unsigned long flag, unsigned long offset) | ||
1096 | { | ||
1097 | if (unlikely(offset + PAGE_ALIGN(len) < offset)) | ||
1098 | return -EINVAL; | ||
1099 | if (unlikely(offset & ~PAGE_MASK)) | ||
1100 | return -EINVAL; | ||
1101 | return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); | ||
1102 | } | ||
1103 | EXPORT_SYMBOL(do_mmap); | ||
1104 | |||
1105 | unsigned long vm_mmap(struct file *file, unsigned long addr, | ||
1106 | unsigned long len, unsigned long prot, | ||
1107 | unsigned long flag, unsigned long offset) | ||
1108 | { | ||
1109 | unsigned long ret; | ||
1110 | struct mm_struct *mm = current->mm; | ||
1111 | |||
1112 | down_write(&mm->mmap_sem); | ||
1113 | ret = do_mmap(file, addr, len, prot, flag, offset); | ||
1114 | up_write(&mm->mmap_sem); | ||
1115 | return ret; | ||
1116 | } | ||
1117 | EXPORT_SYMBOL(vm_mmap); | ||
1093 | 1118 | ||
1094 | SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, | 1119 | SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, |
1095 | unsigned long, prot, unsigned long, flags, | 1120 | unsigned long, prot, unsigned long, flags, |
diff --git a/mm/nommu.c b/mm/nommu.c index 11a69b22bd4b..dd00383be2d9 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -1233,7 +1233,7 @@ enomem: | |||
1233 | /* | 1233 | /* |
1234 | * handle mapping creation for uClinux | 1234 | * handle mapping creation for uClinux |
1235 | */ | 1235 | */ |
1236 | unsigned long do_mmap_pgoff(struct file *file, | 1236 | static unsigned long do_mmap_pgoff(struct file *file, |
1237 | unsigned long addr, | 1237 | unsigned long addr, |
1238 | unsigned long len, | 1238 | unsigned long len, |
1239 | unsigned long prot, | 1239 | unsigned long prot, |
@@ -1470,7 +1470,32 @@ error_getting_region: | |||
1470 | show_free_areas(0); | 1470 | show_free_areas(0); |
1471 | return -ENOMEM; | 1471 | return -ENOMEM; |
1472 | } | 1472 | } |
1473 | EXPORT_SYMBOL(do_mmap_pgoff); | 1473 | |
1474 | unsigned long do_mmap(struct file *file, unsigned long addr, | ||
1475 | unsigned long len, unsigned long prot, | ||
1476 | unsigned long flag, unsigned long offset) | ||
1477 | { | ||
1478 | if (unlikely(offset + PAGE_ALIGN(len) < offset)) | ||
1479 | return -EINVAL; | ||
1480 | if (unlikely(offset & ~PAGE_MASK)) | ||
1481 | return -EINVAL; | ||
1482 | return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); | ||
1483 | } | ||
1484 | EXPORT_SYMBOL(do_mmap); | ||
1485 | |||
1486 | unsigned long vm_mmap(struct file *file, unsigned long addr, | ||
1487 | unsigned long len, unsigned long prot, | ||
1488 | unsigned long flag, unsigned long offset) | ||
1489 | { | ||
1490 | unsigned long ret; | ||
1491 | struct mm_struct *mm = current->mm; | ||
1492 | |||
1493 | down_write(&mm->mmap_sem); | ||
1494 | ret = do_mmap(file, addr, len, prot, flag, offset); | ||
1495 | up_write(&mm->mmap_sem); | ||
1496 | return ret; | ||
1497 | } | ||
1498 | EXPORT_SYMBOL(vm_mmap); | ||
1474 | 1499 | ||
1475 | SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, | 1500 | SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, |
1476 | unsigned long, prot, unsigned long, flags, | 1501 | unsigned long, prot, unsigned long, flags, |