aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-04-20 20:13:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-04-20 20:29:13 -0400
commit6be5ceb02e98eaf6cfc4f8b12a896d04023f340d (patch)
treef34de1392300bbf63549f4eeb20f7606d6f7b1f9 /fs
parenta46ef99d80817a167477ed1c8b4d90ee0c2e726f (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 'fs')
-rw-r--r--fs/binfmt_aout.c12
-rw-r--r--fs/binfmt_elf.c8
-rw-r--r--fs/binfmt_elf_fdpic.c18
-rw-r--r--fs/binfmt_flat.c12
-rw-r--r--fs/binfmt_som.c12
5 files changed, 15 insertions, 47 deletions
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index 88527492b917..d146e181d10d 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -319,24 +319,20 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
319 goto beyond_if; 319 goto beyond_if;
320 } 320 }
321 321
322 down_write(&current->mm->mmap_sem); 322 error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
323 error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
324 PROT_READ | PROT_EXEC, 323 PROT_READ | PROT_EXEC,
325 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, 324 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
326 fd_offset); 325 fd_offset);
327 up_write(&current->mm->mmap_sem);
328 326
329 if (error != N_TXTADDR(ex)) { 327 if (error != N_TXTADDR(ex)) {
330 send_sig(SIGKILL, current, 0); 328 send_sig(SIGKILL, current, 0);
331 return error; 329 return error;
332 } 330 }
333 331
334 down_write(&current->mm->mmap_sem); 332 error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
335 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
336 PROT_READ | PROT_WRITE | PROT_EXEC, 333 PROT_READ | PROT_WRITE | PROT_EXEC,
337 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, 334 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
338 fd_offset + ex.a_text); 335 fd_offset + ex.a_text);
339 up_write(&current->mm->mmap_sem);
340 if (error != N_DATADDR(ex)) { 336 if (error != N_DATADDR(ex)) {
341 send_sig(SIGKILL, current, 0); 337 send_sig(SIGKILL, current, 0);
342 return error; 338 return error;
@@ -417,12 +413,10 @@ static int load_aout_library(struct file *file)
417 goto out; 413 goto out;
418 } 414 }
419 /* Now use mmap to map the library into memory. */ 415 /* Now use mmap to map the library into memory. */
420 down_write(&current->mm->mmap_sem); 416 error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
421 error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
422 PROT_READ | PROT_WRITE | PROT_EXEC, 417 PROT_READ | PROT_WRITE | PROT_EXEC,
423 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, 418 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
424 N_TXTOFF(ex)); 419 N_TXTOFF(ex));
425 up_write(&current->mm->mmap_sem);
426 retval = error; 420 retval = error;
427 if (error != start_addr) 421 if (error != start_addr)
428 goto out; 422 goto out;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 0708a0bf0ba9..16f735417072 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -958,10 +958,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
958 and some applications "depend" upon this behavior. 958 and some applications "depend" upon this behavior.
959 Since we do not have the power to recompile these, we 959 Since we do not have the power to recompile these, we
960 emulate the SVr4 behavior. Sigh. */ 960 emulate the SVr4 behavior. Sigh. */
961 down_write(&current->mm->mmap_sem); 961 error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
962 error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
963 MAP_FIXED | MAP_PRIVATE, 0); 962 MAP_FIXED | MAP_PRIVATE, 0);
964 up_write(&current->mm->mmap_sem);
965 } 963 }
966 964
967#ifdef ELF_PLAT_INIT 965#ifdef ELF_PLAT_INIT
@@ -1046,8 +1044,7 @@ static int load_elf_library(struct file *file)
1046 eppnt++; 1044 eppnt++;
1047 1045
1048 /* Now use mmap to map the library into memory. */ 1046 /* Now use mmap to map the library into memory. */
1049 down_write(&current->mm->mmap_sem); 1047 error = vm_mmap(file,
1050 error = do_mmap(file,
1051 ELF_PAGESTART(eppnt->p_vaddr), 1048 ELF_PAGESTART(eppnt->p_vaddr),
1052 (eppnt->p_filesz + 1049 (eppnt->p_filesz +
1053 ELF_PAGEOFFSET(eppnt->p_vaddr)), 1050 ELF_PAGEOFFSET(eppnt->p_vaddr)),
@@ -1055,7 +1052,6 @@ static int load_elf_library(struct file *file)
1055 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, 1052 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
1056 (eppnt->p_offset - 1053 (eppnt->p_offset -
1057 ELF_PAGEOFFSET(eppnt->p_vaddr))); 1054 ELF_PAGEOFFSET(eppnt->p_vaddr)));
1058 up_write(&current->mm->mmap_sem);
1059 if (error != ELF_PAGESTART(eppnt->p_vaddr)) 1055 if (error != ELF_PAGESTART(eppnt->p_vaddr))
1060 goto out_free_ph; 1056 goto out_free_ph;
1061 1057
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 9bd5612a8224..d390a0fffc65 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -390,21 +390,17 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
390 (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) 390 (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC))
391 stack_prot |= PROT_EXEC; 391 stack_prot |= PROT_EXEC;
392 392
393 down_write(&current->mm->mmap_sem); 393 current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot,
394 current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot,
395 MAP_PRIVATE | MAP_ANONYMOUS | 394 MAP_PRIVATE | MAP_ANONYMOUS |
396 MAP_UNINITIALIZED | MAP_GROWSDOWN, 395 MAP_UNINITIALIZED | MAP_GROWSDOWN,
397 0); 396 0);
398 397
399 if (IS_ERR_VALUE(current->mm->start_brk)) { 398 if (IS_ERR_VALUE(current->mm->start_brk)) {
400 up_write(&current->mm->mmap_sem);
401 retval = current->mm->start_brk; 399 retval = current->mm->start_brk;
402 current->mm->start_brk = 0; 400 current->mm->start_brk = 0;
403 goto error_kill; 401 goto error_kill;
404 } 402 }
405 403
406 up_write(&current->mm->mmap_sem);
407
408 current->mm->brk = current->mm->start_brk; 404 current->mm->brk = current->mm->start_brk;
409 current->mm->context.end_brk = current->mm->start_brk; 405 current->mm->context.end_brk = current->mm->start_brk;
410 current->mm->context.end_brk += 406 current->mm->context.end_brk +=
@@ -955,10 +951,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
955 if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE) 951 if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
956 mflags |= MAP_EXECUTABLE; 952 mflags |= MAP_EXECUTABLE;
957 953
958 down_write(&mm->mmap_sem); 954 maddr = vm_mmap(NULL, load_addr, top - base,
959 maddr = do_mmap(NULL, load_addr, top - base,
960 PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0); 955 PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
961 up_write(&mm->mmap_sem);
962 if (IS_ERR_VALUE(maddr)) 956 if (IS_ERR_VALUE(maddr))
963 return (int) maddr; 957 return (int) maddr;
964 958
@@ -1096,10 +1090,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1096 1090
1097 /* create the mapping */ 1091 /* create the mapping */
1098 disp = phdr->p_vaddr & ~PAGE_MASK; 1092 disp = phdr->p_vaddr & ~PAGE_MASK;
1099 down_write(&mm->mmap_sem); 1093 maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
1100 maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
1101 phdr->p_offset - disp); 1094 phdr->p_offset - disp);
1102 up_write(&mm->mmap_sem);
1103 1095
1104 kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx", 1096 kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
1105 loop, phdr->p_memsz + disp, prot, flags, 1097 loop, phdr->p_memsz + disp, prot, flags,
@@ -1143,10 +1135,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1143 unsigned long xmaddr; 1135 unsigned long xmaddr;
1144 1136
1145 flags |= MAP_FIXED | MAP_ANONYMOUS; 1137 flags |= MAP_FIXED | MAP_ANONYMOUS;
1146 down_write(&mm->mmap_sem); 1138 xmaddr = vm_mmap(NULL, xaddr, excess - excess1,
1147 xmaddr = do_mmap(NULL, xaddr, excess - excess1,
1148 prot, flags, 0); 1139 prot, flags, 0);
1149 up_write(&mm->mmap_sem);
1150 1140
1151 kdebug("mmap[%d] <anon>" 1141 kdebug("mmap[%d] <anon>"
1152 " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx", 1142 " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 024d20ee3ca3..6b2daf99fab8 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -542,10 +542,8 @@ static int load_flat_file(struct linux_binprm * bprm,
542 */ 542 */
543 DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); 543 DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
544 544
545 down_write(&current->mm->mmap_sem); 545 textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
546 textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
547 MAP_PRIVATE|MAP_EXECUTABLE, 0); 546 MAP_PRIVATE|MAP_EXECUTABLE, 0);
548 up_write(&current->mm->mmap_sem);
549 if (!textpos || IS_ERR_VALUE(textpos)) { 547 if (!textpos || IS_ERR_VALUE(textpos)) {
550 if (!textpos) 548 if (!textpos)
551 textpos = (unsigned long) -ENOMEM; 549 textpos = (unsigned long) -ENOMEM;
@@ -556,10 +554,8 @@ static int load_flat_file(struct linux_binprm * bprm,
556 554
557 len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); 555 len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
558 len = PAGE_ALIGN(len); 556 len = PAGE_ALIGN(len);
559 down_write(&current->mm->mmap_sem); 557 realdatastart = vm_mmap(0, 0, len,
560 realdatastart = do_mmap(0, 0, len,
561 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); 558 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
562 up_write(&current->mm->mmap_sem);
563 559
564 if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) { 560 if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) {
565 if (!realdatastart) 561 if (!realdatastart)
@@ -603,10 +599,8 @@ static int load_flat_file(struct linux_binprm * bprm,
603 599
604 len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); 600 len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
605 len = PAGE_ALIGN(len); 601 len = PAGE_ALIGN(len);
606 down_write(&current->mm->mmap_sem); 602 textpos = vm_mmap(0, 0, len,
607 textpos = do_mmap(0, 0, len,
608 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); 603 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
609 up_write(&current->mm->mmap_sem);
610 604
611 if (!textpos || IS_ERR_VALUE(textpos)) { 605 if (!textpos || IS_ERR_VALUE(textpos)) {
612 if (!textpos) 606 if (!textpos)
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index e4fc746629a7..4517aaff61b4 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -147,10 +147,8 @@ static int map_som_binary(struct file *file,
147 code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize); 147 code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize);
148 current->mm->start_code = code_start; 148 current->mm->start_code = code_start;
149 current->mm->end_code = code_start + code_size; 149 current->mm->end_code = code_start + code_size;
150 down_write(&current->mm->mmap_sem); 150 retval = vm_mmap(file, code_start, code_size, prot,
151 retval = do_mmap(file, code_start, code_size, prot,
152 flags, SOM_PAGESTART(hpuxhdr->exec_tfile)); 151 flags, SOM_PAGESTART(hpuxhdr->exec_tfile));
153 up_write(&current->mm->mmap_sem);
154 if (retval < 0 && retval > -1024) 152 if (retval < 0 && retval > -1024)
155 goto out; 153 goto out;
156 154
@@ -158,20 +156,16 @@ static int map_som_binary(struct file *file,
158 data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize); 156 data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize);
159 current->mm->start_data = data_start; 157 current->mm->start_data = data_start;
160 current->mm->end_data = bss_start = data_start + data_size; 158 current->mm->end_data = bss_start = data_start + data_size;
161 down_write(&current->mm->mmap_sem); 159 retval = vm_mmap(file, data_start, data_size,
162 retval = do_mmap(file, data_start, data_size,
163 prot | PROT_WRITE, flags, 160 prot | PROT_WRITE, flags,
164 SOM_PAGESTART(hpuxhdr->exec_dfile)); 161 SOM_PAGESTART(hpuxhdr->exec_dfile));
165 up_write(&current->mm->mmap_sem);
166 if (retval < 0 && retval > -1024) 162 if (retval < 0 && retval > -1024)
167 goto out; 163 goto out;
168 164
169 som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize); 165 som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize);
170 current->mm->start_brk = current->mm->brk = som_brk; 166 current->mm->start_brk = current->mm->brk = som_brk;
171 down_write(&current->mm->mmap_sem); 167 retval = vm_mmap(NULL, bss_start, som_brk - bss_start,
172 retval = do_mmap(NULL, bss_start, som_brk - bss_start,
173 prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0); 168 prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0);
174 up_write(&current->mm->mmap_sem);
175 if (retval > 0 || retval < -1024) 169 if (retval > 0 || retval < -1024)
176 retval = 0; 170 retval = 0;
177out: 171out: