Skip to content

Commit

Permalink
mm: move sys_mmap_pgoff from util.c
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Hugh Dickins authored and torvalds committed Dec 30, 2009
1 parent 75c85a0 commit 66f0dc4
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 44 deletions.
40 changes: 40 additions & 0 deletions mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,46 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
}
EXPORT_SYMBOL(do_mmap_pgoff);

SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, pgoff)
{
struct file *file = NULL;
unsigned long retval = -EBADF;

if (!(flags & MAP_ANONYMOUS)) {
if (unlikely(flags & MAP_HUGETLB))
return -EINVAL;
file = fget(fd);
if (!file)
goto out;
} else if (flags & MAP_HUGETLB) {
struct user_struct *user = NULL;
/*
* VM_NORESERVE is used because the reservations will be
* taken when vm_ops->mmap() is called
* A dummy user value is used because we are not locking
* memory so no accounting is necessary
*/
len = ALIGN(len, huge_page_size(&default_hstate));
file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE,
&user, HUGETLB_ANONHUGE_INODE);
if (IS_ERR(file))
return PTR_ERR(file);
}

flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);

down_write(&current->mm->mmap_sem);
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&current->mm->mmap_sem);

if (file)
fput(file);
out:
return retval;
}

/*
* Some shared mappigns will want the pages marked read-only
* to track write events. If so, we'll downgrade vm_page_prot
Expand Down
25 changes: 25 additions & 0 deletions mm/nommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,31 @@ unsigned long do_mmap_pgoff(struct file *file,
}
EXPORT_SYMBOL(do_mmap_pgoff);

SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, pgoff)
{
struct file *file = NULL;
unsigned long retval = -EBADF;

if (!(flags & MAP_ANONYMOUS)) {
file = fget(fd);
if (!file)
goto out;
}

flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);

down_write(&current->mm->mmap_sem);
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&current->mm->mmap_sem);

if (file)
fput(file);
out:
return retval;
}

/*
* split a vma into two pieces at address 'addr', a new vma is allocated either
* for the first part or the tail.
Expand Down
44 changes: 0 additions & 44 deletions mm/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/sched.h>
#include <linux/hugetlb.h>
#include <linux/syscalls.h>
#include <linux/mman.h>
#include <linux/file.h>
#include <asm/uaccess.h>

#define CREATE_TRACE_POINTS
Expand Down Expand Up @@ -272,46 +268,6 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start,
}
EXPORT_SYMBOL_GPL(get_user_pages_fast);

SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, pgoff)
{
struct file * file = NULL;
unsigned long retval = -EBADF;

if (!(flags & MAP_ANONYMOUS)) {
if (unlikely(flags & MAP_HUGETLB))
return -EINVAL;
file = fget(fd);
if (!file)
goto out;
} else if (flags & MAP_HUGETLB) {
struct user_struct *user = NULL;
/*
* VM_NORESERVE is used because the reservations will be
* taken when vm_ops->mmap() is called
* A dummy user value is used because we are not locking
* memory so no accounting is necessary
*/
len = ALIGN(len, huge_page_size(&default_hstate));
file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE,
&user, HUGETLB_ANONHUGE_INODE);
if (IS_ERR(file))
return PTR_ERR(file);
}

flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);

down_write(&current->mm->mmap_sem);
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&current->mm->mmap_sem);

if (file)
fput(file);
out:
return retval;
}

/* Tracepoints definitions. */
EXPORT_TRACEPOINT_SYMBOL(kmalloc);
EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc);
Expand Down

0 comments on commit 66f0dc4

Please sign in to comment.