Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[pandora-kernel.git] / arch / mips / kernel / syscall.c
index 17c4374..3523c8d 100644 (file)
 #include <linux/shm.h>
 #include <linux/compiler.h>
 #include <linux/module.h>
+#include <linux/ipc.h>
 
 #include <asm/branch.h>
 #include <asm/cachectl.h>
 #include <asm/cacheflush.h>
-#include <asm/ipc.h>
 #include <asm/asm-offsets.h>
 #include <asm/signal.h>
 #include <asm/sim.h>
 #include <asm/sysmips.h>
 #include <asm/uaccess.h>
 
-asmlinkage int sys_pipe(nabi_no_regargs volatile struct pt_regs regs)
+/*
+ * For historic reasons the pipe(2) syscall on MIPS has an unusual calling
+ * convention.  It returns results in registers $v0 / $v1 which means there
+ * is no need for it to do verify the validity of a userspace pointer
+ * argument.  Historically that used to be expensive in Linux.  These days
+ * the performance advantage is negligible.
+ */
+asmlinkage int sysm_pipe(nabi_no_regargs volatile struct pt_regs regs)
 {
        int fd[2];
        int error, res;
@@ -73,7 +80,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 
        task_size = STACK_TOP;
 
+       if (len > task_size)
+               return -ENOMEM;
+
        if (flags & MAP_FIXED) {
+               /* Even MAP_FIXED mappings must reside within task_size.  */
+               if (task_size - len < addr)
+                       return -EINVAL;
+
                /*
                 * We do not accept a shared mapping if it would violate
                 * cache aliasing constraints.
@@ -83,8 +97,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
                return addr;
        }
 
-       if (len > task_size)
-               return -ENOMEM;
        do_color_align = 0;
        if (filp || (flags & MAP_SHARED))
                do_color_align = 1;