Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6.git] / arch / ia64 / kernel / sys_ia64.c
index c7b943f..609d500 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 1999-2000, 2002-2003, 2005 Hewlett-Packard Co
  *     David Mosberger-Tang <davidm@hpl.hp.com>
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
@@ -14,7 +13,6 @@
 #include <linux/shm.h>
 #include <linux/file.h>                /* doh, must come after sched.h... */
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/highuid.h>
 #include <linux/hugetlb.h>
@@ -34,6 +32,13 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
        if (len > RGN_MAP_LIMIT)
                return -ENOMEM;
 
+       /* handle fixed mapping: prevent overlap with huge pages */
+       if (flags & MAP_FIXED) {
+               if (is_hugepage_only_range(mm, addr, len))
+                       return -EINVAL;
+               return addr;
+       }
+
 #ifdef CONFIG_HUGETLB_PAGE
        if (REGION_NUMBER(addr) == RGN_HPAGE)
                addr = 0;
@@ -95,51 +100,7 @@ sys_getpagesize (void)
 asmlinkage unsigned long
 ia64_brk (unsigned long brk)
 {
-       unsigned long rlim, retval, newbrk, oldbrk;
-       struct mm_struct *mm = current->mm;
-
-       /*
-        * Most of this replicates the code in sys_brk() except for an additional safety
-        * check and the clearing of r8.  However, we can't call sys_brk() because we need
-        * to acquire the mmap_sem before we can do the test...
-        */
-       down_write(&mm->mmap_sem);
-
-       if (brk < mm->end_code)
-               goto out;
-       newbrk = PAGE_ALIGN(brk);
-       oldbrk = PAGE_ALIGN(mm->brk);
-       if (oldbrk == newbrk)
-               goto set_brk;
-
-       /* Always allow shrinking brk. */
-       if (brk <= mm->brk) {
-               if (!do_munmap(mm, newbrk, oldbrk-newbrk))
-                       goto set_brk;
-               goto out;
-       }
-
-       /* Check against unimplemented/unmapped addresses: */
-       if ((newbrk - oldbrk) > RGN_MAP_LIMIT || REGION_OFFSET(newbrk) > RGN_MAP_LIMIT)
-               goto out;
-
-       /* Check against rlimit.. */
-       rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
-       if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
-               goto out;
-
-       /* Check against existing mmap mappings. */
-       if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
-               goto out;
-
-       /* Ok, looks good - let it rip. */
-       if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
-               goto out;
-set_brk:
-       mm->brk = brk;
-out:
-       retval = mm->brk;
-       up_write(&mm->mmap_sem);
+       unsigned long retval = sys_brk(brk);
        force_successful_syscall_return();
        return retval;
 }
@@ -149,13 +110,13 @@ out:
  * and r9) as this is faster than doing a copy_to_user().
  */
 asmlinkage long
-sys_pipe (void)
+sys_ia64_pipe (void)
 {
        struct pt_regs *regs = task_pt_regs(current);
        int fd[2];
        int retval;
 
-       retval = do_pipe(fd);
+       retval = do_pipe_flags(fd, 0);
        if (retval)
                goto out;
        retval = fd[0];
@@ -164,49 +125,20 @@ sys_pipe (void)
        return retval;
 }
 
-static inline unsigned long
-do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff)
+int ia64_mmap_check(unsigned long addr, unsigned long len,
+               unsigned long flags)
 {
        unsigned long roff;
-       struct file *file = NULL;
-
-       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-       if (!(flags & MAP_ANONYMOUS)) {
-               file = fget(fd);
-               if (!file)
-                       return -EBADF;
-
-               if (!file->f_op || !file->f_op->mmap) {
-                       addr = -ENODEV;
-                       goto out;
-               }
-       }
-
-       /* Careful about overflows.. */
-       len = PAGE_ALIGN(len);
-       if (!len || len > TASK_SIZE) {
-               addr = -EINVAL;
-               goto out;
-       }
 
        /*
-        * Don't permit mappings into unmapped space, the virtual page table of a region,
-        * or across a region boundary.  Note: RGN_MAP_LIMIT is equal to 2^n-PAGE_SIZE
-        * (for some integer n <= 61) and len > 0.
+        * Don't permit mappings into unmapped space, the virtual page table
+        * of a region, or across a region boundary.  Note: RGN_MAP_LIMIT is
+        * equal to 2^n-PAGE_SIZE (for some integer n <= 61) and len > 0.
         */
        roff = REGION_OFFSET(addr);
-       if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) {
-               addr = -EINVAL;
-               goto out;
-       }
-
-       down_write(&current->mm->mmap_sem);
-       addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-       up_write(&current->mm->mmap_sem);
-
-out:   if (file)
-               fput(file);
-       return addr;
+       if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len)))
+               return -EINVAL;
+       return 0;
 }
 
 /*
@@ -217,7 +149,7 @@ out:        if (file)
 asmlinkage unsigned long
 sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
 {
-       addr = do_mmap2(addr, len, prot, flags, fd, pgoff);
+       addr = sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
        if (!IS_ERR((void *) addr))
                force_successful_syscall_return();
        return addr;
@@ -229,7 +161,7 @@ sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, lo
        if (offset_in_page(off) != 0)
                return -EINVAL;
 
-       addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+       addr = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
        if (!IS_ERR((void *) addr))
                force_successful_syscall_return();
        return addr;