Commit 6be5ceb0 authored by Linus Torvalds's avatar Linus Torvalds

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: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a46ef99d
...@@ -346,12 +346,10 @@ void single_step_once(struct pt_regs *regs) ...@@ -346,12 +346,10 @@ void single_step_once(struct pt_regs *regs)
} }
/* allocate a cache line of writable, executable memory */ /* allocate a cache line of writable, executable memory */
down_write(&current->mm->mmap_sem); buffer = (void __user *) vm_mmap(NULL, 0, 64,
buffer = (void __user *) do_mmap(NULL, 0, 64,
PROT_EXEC | PROT_READ | PROT_WRITE, PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, MAP_PRIVATE | MAP_ANONYMOUS,
0); 0);
up_write(&current->mm->mmap_sem);
if (IS_ERR((void __force *)buffer)) { if (IS_ERR((void __force *)buffer)) {
kfree(state); kfree(state);
......
...@@ -379,26 +379,22 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -379,26 +379,22 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
goto beyond_if; goto beyond_if;
} }
down_write(&current->mm->mmap_sem); error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
PROT_READ | PROT_EXEC, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
MAP_EXECUTABLE | MAP_32BIT, MAP_EXECUTABLE | MAP_32BIT,
fd_offset); fd_offset);
up_write(&current->mm->mmap_sem);
if (error != N_TXTADDR(ex)) { if (error != N_TXTADDR(ex)) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
return error; return error;
} }
down_write(&current->mm->mmap_sem); error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
MAP_EXECUTABLE | MAP_32BIT, MAP_EXECUTABLE | MAP_32BIT,
fd_offset + ex.a_text); fd_offset + ex.a_text);
up_write(&current->mm->mmap_sem);
if (error != N_DATADDR(ex)) { if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
return error; return error;
...@@ -482,12 +478,10 @@ static int load_aout_library(struct file *file) ...@@ -482,12 +478,10 @@ static int load_aout_library(struct file *file)
goto out; goto out;
} }
/* Now use mmap to map the library into memory. */ /* Now use mmap to map the library into memory. */
down_write(&current->mm->mmap_sem); error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT,
N_TXTOFF(ex)); N_TXTOFF(ex));
up_write(&current->mm->mmap_sem);
retval = error; retval = error;
if (error != start_addr) if (error != start_addr)
goto out; goto out;
......
...@@ -6336,13 +6336,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, ...@@ -6336,13 +6336,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
if (npages && !old.rmap) { if (npages && !old.rmap) {
unsigned long userspace_addr; unsigned long userspace_addr;
down_write(&current->mm->mmap_sem); userspace_addr = vm_mmap(NULL, 0,
userspace_addr = do_mmap(NULL, 0,
npages * PAGE_SIZE, npages * PAGE_SIZE,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
map_flags, map_flags,
0); 0);
up_write(&current->mm->mmap_sem);
if (IS_ERR((void *)userspace_addr)) if (IS_ERR((void *)userspace_addr))
return PTR_ERR((void *)userspace_addr); return PTR_ERR((void *)userspace_addr);
......
...@@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data, ...@@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data,
* \param arg pointer to a drm_buf_map structure. * \param arg pointer to a drm_buf_map structure.
* \return zero on success or a negative number on failure. * \return zero on success or a negative number on failure.
* *
* Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information
* about each buffer into user space. For PCI buffers, it calls do_mmap() with * about each buffer into user space. For PCI buffers, it calls vm_mmap() with
* offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
* drm_mmap_dma(). * drm_mmap_dma().
*/ */
...@@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data, ...@@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data,
retcode = -EINVAL; retcode = -EINVAL;
goto done; goto done;
} }
down_write(&current->mm->mmap_sem); virtual = vm_mmap(file_priv->filp, 0, map->size,
virtual = do_mmap(file_priv->filp, 0, map->size,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_SHARED, MAP_SHARED,
token); token);
up_write(&current->mm->mmap_sem);
} else { } else {
down_write(&current->mm->mmap_sem); virtual = vm_mmap(file_priv->filp, 0, dma->byte_count,
virtual = do_mmap(file_priv->filp, 0, dma->byte_count,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_SHARED, 0); MAP_SHARED, 0);
up_write(&current->mm->mmap_sem);
} }
if (virtual > -1024UL) { if (virtual > -1024UL) {
/* Real error */ /* Real error */
......
...@@ -581,10 +581,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, ...@@ -581,10 +581,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
obj->filp->f_op = &exynos_drm_gem_fops; obj->filp->f_op = &exynos_drm_gem_fops;
obj->filp->private_data = obj; obj->filp->private_data = obj;
down_write(&current->mm->mmap_sem); addr = vm_mmap(obj->filp, 0, args->size,
addr = do_mmap(obj->filp, 0, args->size,
PROT_READ | PROT_WRITE, MAP_SHARED, 0); PROT_READ | PROT_WRITE, MAP_SHARED, 0);
up_write(&current->mm->mmap_sem);
drm_gem_object_unreference_unlocked(obj); drm_gem_object_unreference_unlocked(obj);
......
...@@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) ...@@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)
if (buf_priv->currently_mapped == I810_BUF_MAPPED) if (buf_priv->currently_mapped == I810_BUF_MAPPED)
return -EINVAL; return -EINVAL;
/* This is all entirely broken */
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
old_fops = file_priv->filp->f_op; old_fops = file_priv->filp->f_op;
file_priv->filp->f_op = &i810_buffer_fops; file_priv->filp->f_op = &i810_buffer_fops;
......
...@@ -1087,11 +1087,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, ...@@ -1087,11 +1087,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
if (obj == NULL) if (obj == NULL)
return -ENOENT; return -ENOENT;
down_write(&current->mm->mmap_sem); addr = vm_mmap(obj->filp, 0, args->size,
addr = do_mmap(obj->filp, 0, args->size,
PROT_READ | PROT_WRITE, MAP_SHARED, PROT_READ | PROT_WRITE, MAP_SHARED,
args->offset); args->offset);
up_write(&current->mm->mmap_sem);
drm_gem_object_unreference_unlocked(obj); drm_gem_object_unreference_unlocked(obj);
if (IS_ERR((void *)addr)) if (IS_ERR((void *)addr))
return addr; return addr;
......
...@@ -319,24 +319,20 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -319,24 +319,20 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
goto beyond_if; goto beyond_if;
} }
down_write(&current->mm->mmap_sem); error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
PROT_READ | PROT_EXEC, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset); fd_offset);
up_write(&current->mm->mmap_sem);
if (error != N_TXTADDR(ex)) { if (error != N_TXTADDR(ex)) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
return error; return error;
} }
down_write(&current->mm->mmap_sem); error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset + ex.a_text); fd_offset + ex.a_text);
up_write(&current->mm->mmap_sem);
if (error != N_DATADDR(ex)) { if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
return error; return error;
...@@ -417,12 +413,10 @@ static int load_aout_library(struct file *file) ...@@ -417,12 +413,10 @@ static int load_aout_library(struct file *file)
goto out; goto out;
} }
/* Now use mmap to map the library into memory. */ /* Now use mmap to map the library into memory. */
down_write(&current->mm->mmap_sem); error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
N_TXTOFF(ex)); N_TXTOFF(ex));
up_write(&current->mm->mmap_sem);
retval = error; retval = error;
if (error != start_addr) if (error != start_addr)
goto out; goto out;
......
...@@ -958,10 +958,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -958,10 +958,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
and some applications "depend" upon this behavior. and some applications "depend" upon this behavior.
Since we do not have the power to recompile these, we Since we do not have the power to recompile these, we
emulate the SVr4 behavior. Sigh. */ emulate the SVr4 behavior. Sigh. */
down_write(&current->mm->mmap_sem); error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, 0); MAP_FIXED | MAP_PRIVATE, 0);
up_write(&current->mm->mmap_sem);
} }
#ifdef ELF_PLAT_INIT #ifdef ELF_PLAT_INIT
...@@ -1046,8 +1044,7 @@ static int load_elf_library(struct file *file) ...@@ -1046,8 +1044,7 @@ static int load_elf_library(struct file *file)
eppnt++; eppnt++;
/* Now use mmap to map the library into memory. */ /* Now use mmap to map the library into memory. */
down_write(&current->mm->mmap_sem); error = vm_mmap(file,
error = do_mmap(file,
ELF_PAGESTART(eppnt->p_vaddr), ELF_PAGESTART(eppnt->p_vaddr),
(eppnt->p_filesz + (eppnt->p_filesz +
ELF_PAGEOFFSET(eppnt->p_vaddr)), ELF_PAGEOFFSET(eppnt->p_vaddr)),
...@@ -1055,7 +1052,6 @@ static int load_elf_library(struct file *file) ...@@ -1055,7 +1052,6 @@ static int load_elf_library(struct file *file)
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
(eppnt->p_offset - (eppnt->p_offset -
ELF_PAGEOFFSET(eppnt->p_vaddr))); ELF_PAGEOFFSET(eppnt->p_vaddr)));
up_write(&current->mm->mmap_sem);
if (error != ELF_PAGESTART(eppnt->p_vaddr)) if (error != ELF_PAGESTART(eppnt->p_vaddr))
goto out_free_ph; goto out_free_ph;
......
...@@ -390,21 +390,17 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, ...@@ -390,21 +390,17 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
(executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC))
stack_prot |= PROT_EXEC; stack_prot |= PROT_EXEC;
down_write(&current->mm->mmap_sem); current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot,
current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_PRIVATE | MAP_ANONYMOUS |
MAP_UNINITIALIZED | MAP_GROWSDOWN, MAP_UNINITIALIZED | MAP_GROWSDOWN,
0); 0);
if (IS_ERR_VALUE(current->mm->start_brk)) { if (IS_ERR_VALUE(current->mm->start_brk)) {
up_write(&current->mm->mmap_sem);
retval = current->mm->start_brk; retval = current->mm->start_brk;
current->mm->start_brk = 0; current->mm->start_brk = 0;
goto error_kill; goto error_kill;
} }
up_write(&current->mm->mmap_sem);
current->mm->brk = current->mm->start_brk; current->mm->brk = current->mm->start_brk;
current->mm->context.end_brk = current->mm->start_brk; current->mm->context.end_brk = current->mm->start_brk;
current->mm->context.end_brk += current->mm->context.end_brk +=
...@@ -955,10 +951,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( ...@@ -955,10 +951,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE) if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
mflags |= MAP_EXECUTABLE; mflags |= MAP_EXECUTABLE;
down_write(&mm->mmap_sem); maddr = vm_mmap(NULL, load_addr, top - base,
maddr = do_mmap(NULL, load_addr, top - base,
PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0); PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
up_write(&mm->mmap_sem);
if (IS_ERR_VALUE(maddr)) if (IS_ERR_VALUE(maddr))
return (int) maddr; return (int) maddr;
...@@ -1096,10 +1090,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, ...@@ -1096,10 +1090,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
/* create the mapping */ /* create the mapping */
disp = phdr->p_vaddr & ~PAGE_MASK; disp = phdr->p_vaddr & ~PAGE_MASK;
down_write(&mm->mmap_sem); maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
phdr->p_offset - disp); phdr->p_offset - disp);
up_write(&mm->mmap_sem);
kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx", kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
loop, phdr->p_memsz + disp, prot, flags, 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,10 +1135,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
unsigned long xmaddr; unsigned long xmaddr;
flags |= MAP_FIXED | MAP_ANONYMOUS; flags |= MAP_FIXED | MAP_ANONYMOUS;
down_write(&mm->mmap_sem); xmaddr = vm_mmap(NULL, xaddr, excess - excess1,
xmaddr = do_mmap(NULL, xaddr, excess - excess1,
prot, flags, 0); prot, flags, 0);
up_write(&mm->mmap_sem);
kdebug("mmap[%d] <anon>" kdebug("mmap[%d] <anon>"
" ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx", " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
......
...@@ -542,10 +542,8 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -542,10 +542,8 @@ static int load_flat_file(struct linux_binprm * bprm,
*/ */
DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
down_write(&current->mm->mmap_sem); textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_EXECUTABLE, 0); MAP_PRIVATE|MAP_EXECUTABLE, 0);
up_write(&current->mm->mmap_sem);
if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos || IS_ERR_VALUE(textpos)) {
if (!textpos) if (!textpos)
textpos = (unsigned long) -ENOMEM; textpos = (unsigned long) -ENOMEM;
...@@ -556,10 +554,8 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -556,10 +554,8 @@ static int load_flat_file(struct linux_binprm * bprm,
len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
len = PAGE_ALIGN(len); len = PAGE_ALIGN(len);
down_write(&current->mm->mmap_sem); realdatastart = vm_mmap(0, 0, len,
realdatastart = do_mmap(0, 0, len,
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
up_write(&current->mm->mmap_sem);
if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) { if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) {
if (!realdatastart) if (!realdatastart)
...@@ -603,10 +599,8 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -603,10 +599,8 @@ static int load_flat_file(struct linux_binprm * bprm,
len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
len = PAGE_ALIGN(len); len = PAGE_ALIGN(len);
down_write(&current->mm->mmap_sem); textpos = vm_mmap(0, 0, len,
textpos = do_mmap(0, 0, len,
PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
up_write(&current->mm->mmap_sem);
if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos || IS_ERR_VALUE(textpos)) {
if (!textpos) if (!textpos)
......
...@@ -147,10 +147,8 @@ static int map_som_binary(struct file *file, ...@@ -147,10 +147,8 @@ static int map_som_binary(struct file *file,
code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize); code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize);
current->mm->start_code = code_start; current->mm->start_code = code_start;
current->mm->end_code = code_start + code_size; current->mm->end_code = code_start + code_size;
down_write(&current->mm->mmap_sem); retval = vm_mmap(file, code_start, code_size, prot,
retval = do_mmap(file, code_start, code_size, prot,
flags, SOM_PAGESTART(hpuxhdr->exec_tfile)); flags, SOM_PAGESTART(hpuxhdr->exec_tfile));
up_write(&current->mm->mmap_sem);
if (retval < 0 && retval > -1024) if (retval < 0 && retval > -1024)
goto out; goto out;
...@@ -158,20 +156,16 @@ static int map_som_binary(struct file *file, ...@@ -158,20 +156,16 @@ static int map_som_binary(struct file *file,
data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize); data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize);
current->mm->start_data = data_start; current->mm->start_data = data_start;
current->mm->end_data = bss_start = data_start + data_size; current->mm->end_data = bss_start = data_start + data_size;
down_write(&current->mm->mmap_sem); retval = vm_mmap(file, data_start, data_size,
retval = do_mmap(file, data_start, data_size,
prot | PROT_WRITE, flags, prot | PROT_WRITE, flags,
SOM_PAGESTART(hpuxhdr->exec_dfile)); SOM_PAGESTART(hpuxhdr->exec_dfile));
up_write(&current->mm->mmap_sem);
if (retval < 0 && retval > -1024) if (retval < 0 && retval > -1024)
goto out; goto out;
som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize); som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize);
current->mm->start_brk = current->mm->brk = som_brk; current->mm->start_brk = current->mm->brk = som_brk;
down_write(&current->mm->mmap_sem); retval = vm_mmap(NULL, bss_start, som_brk - bss_start,
retval = do_mmap(NULL, bss_start, som_brk - bss_start,
prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0); prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0);
up_write(&current->mm->mmap_sem);
if (retval > 0 || retval < -1024) if (retval > 0 || retval < -1024)
retval = 0; retval = 0;
out: out:
......
...@@ -1393,31 +1393,20 @@ extern int install_special_mapping(struct mm_struct *mm, ...@@ -1393,31 +1393,20 @@ extern int install_special_mapping(struct mm_struct *mm,
extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long pgoff);
extern unsigned long mmap_region(struct file *file, unsigned long addr, extern unsigned long mmap_region(struct file *file, unsigned long addr,
unsigned long len, unsigned long flags, unsigned long len, unsigned long flags,
vm_flags_t vm_flags, unsigned long pgoff); vm_flags_t vm_flags, unsigned long pgoff);
extern unsigned long do_mmap(struct file *, unsigned long,
static inline unsigned long do_mmap(struct file *file, unsigned long addr, unsigned long, unsigned long,
unsigned long len, unsigned long prot, unsigned long, unsigned long);
unsigned long flag, unsigned long offset)
{
unsigned long ret = -EINVAL;
if ((offset + PAGE_ALIGN(len)) < offset)
goto out;
if (!(offset & ~PAGE_MASK))
ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
out:
return ret;
}
extern int do_munmap(struct mm_struct *, unsigned long, size_t); extern int do_munmap(struct mm_struct *, unsigned long, size_t);
/* These take the mm semaphore themselves */ /* These take the mm semaphore themselves */
extern unsigned long vm_brk(unsigned long, unsigned long); extern unsigned long vm_brk(unsigned long, unsigned long);
extern int vm_munmap(struct mm_struct *, unsigned long, size_t); extern int vm_munmap(struct mm_struct *, unsigned long, size_t);
extern unsigned long vm_mmap(struct file *, unsigned long,
unsigned long, unsigned long,
unsigned long, unsigned long);
/* truncate.c */ /* truncate.c */
extern void truncate_inode_pages(struct address_space *, loff_t); extern void truncate_inode_pages(struct address_space *, loff_t);
......
...@@ -953,7 +953,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint) ...@@ -953,7 +953,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint)
* The caller must hold down_write(&current->mm->mmap_sem). * The caller must hold down_write(&current->mm->mmap_sem).
*/ */
unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot, unsigned long len, unsigned long prot,
unsigned long flags, unsigned long pgoff) unsigned long flags, unsigned long pgoff)
{ {
...@@ -1089,7 +1089,32 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, ...@@ -1089,7 +1089,32 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
return mmap_region(file, addr, len, flags, vm_flags, pgoff); return mmap_region(file, addr, len, flags, vm_flags, pgoff);
} }
EXPORT_SYMBOL(do_mmap_pgoff);
unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
{
if (unlikely(offset + PAGE_ALIGN(len) < offset))
return -EINVAL;
if (unlikely(offset & ~PAGE_MASK))
return -EINVAL;
return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
}
EXPORT_SYMBOL(do_mmap);
unsigned long vm_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
{
unsigned long ret;
struct mm_struct *mm = current->mm;
down_write(&mm->mmap_sem);
ret = do_mmap(file, addr, len, prot, flag, offset);
up_write(&mm->mmap_sem);
return ret;
}
EXPORT_SYMBOL(vm_mmap);
SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags, unsigned long, prot, unsigned long, flags,
......
...@@ -1233,7 +1233,7 @@ static int do_mmap_private(struct vm_area_struct *vma, ...@@ -1233,7 +1233,7 @@ static int do_mmap_private(struct vm_area_struct *vma,
/* /*
* handle mapping creation for uClinux * handle mapping creation for uClinux
*/ */
unsigned long do_mmap_pgoff(struct file *file, static unsigned long do_mmap_pgoff(struct file *file,
unsigned long addr, unsigned long addr,
unsigned long len, unsigned long len,
unsigned long prot, unsigned long prot,
...@@ -1470,7 +1470,32 @@ unsigned long do_mmap_pgoff(struct file *file, ...@@ -1470,7 +1470,32 @@ unsigned long do_mmap_pgoff(struct file *file,
show_free_areas(0); show_free_areas(0);
return -ENOMEM; return -ENOMEM;
} }
EXPORT_SYMBOL(do_mmap_pgoff);
unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
{
if (unlikely(offset + PAGE_ALIGN(len) < offset))
return -EINVAL;
if (unlikely(offset & ~PAGE_MASK))
return -EINVAL;
return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
}
EXPORT_SYMBOL(do_mmap);
unsigned long vm_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
{
unsigned long ret;
struct mm_struct *mm = current->mm;
down_write(&mm->mmap_sem);
ret = do_mmap(file, addr, len, prot, flag, offset);
up_write(&mm->mmap_sem);
return ret;
}
EXPORT_SYMBOL(vm_mmap);
SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags, unsigned long, prot, unsigned long, flags,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment