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 7c800ec..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;
@@ -245,7 +257,7 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name)
 
        if (!name)
                return -EFAULT;
-       if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+       if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
                return -EFAULT;
 
        error = __copy_to_user(&name->sysname, &utsname()->sysname,
@@ -314,8 +326,8 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
  *
  * This is really horribly ugly.
  */
-asmlinkage int sys_ipc (unsigned int call, int first, int second,
-                       unsigned long third, void __user *ptr, long fifth)
+asmlinkage int sys_ipc(unsigned int call, int first, int second,
+                      unsigned long third, void __user *ptr, long fifth)
 {
        int version, ret;
 
@@ -324,26 +336,26 @@ asmlinkage int sys_ipc (unsigned int call, int first, int second,
 
        switch (call) {
        case SEMOP:
-               return sys_semtimedop (first, (struct sembuf __user *)ptr,
-                                      second, NULL);
+               return sys_semtimedop(first, (struct sembuf __user *)ptr,
+                                     second, NULL);
        case SEMTIMEDOP:
-               return sys_semtimedop (first, (struct sembuf __user *)ptr,
-                                      second,
-                                      (const struct timespec __user *)fifth);
+               return sys_semtimedop(first, (struct sembuf __user *)ptr,
+                                     second,
+                                     (const struct timespec __user *)fifth);
        case SEMGET:
-               return sys_semget (first, second, third);
+               return sys_semget(first, second, third);
        case SEMCTL: {
                union semun fourth;
                if (!ptr)
                        return -EINVAL;
                if (get_user(fourth.__pad, (void __user *__user *) ptr))
                        return -EFAULT;
-               return sys_semctl (first, second, third, fourth);
+               return sys_semctl(first, second, third, fourth);
        }
 
        case MSGSND:
-               return sys_msgsnd (first, (struct msgbuf __user *) ptr,
-                                  second, third);
+               return sys_msgsnd(first, (struct msgbuf __user *) ptr,
+                                 second, third);
        case MSGRCV:
                switch (version) {
                case 0: {
@@ -353,45 +365,45 @@ asmlinkage int sys_ipc (unsigned int call, int first, int second,
 
                        if (copy_from_user(&tmp,
                                           (struct ipc_kludge __user *) ptr,
-                                          sizeof (tmp)))
+                                          sizeof(tmp)))
                                return -EFAULT;
-                       return sys_msgrcv (first, tmp.msgp, second,
-                                          tmp.msgtyp, third);
+                       return sys_msgrcv(first, tmp.msgp, second,
+                                         tmp.msgtyp, third);
                }
                default:
-                       return sys_msgrcv (first,
-                                          (struct msgbuf __user *) ptr,
-                                          second, fifth, third);
+                       return sys_msgrcv(first,
+                                         (struct msgbuf __user *) ptr,
+                                         second, fifth, third);
                }
        case MSGGET:
-               return sys_msgget ((key_t) first, second);
+               return sys_msgget((key_t) first, second);
        case MSGCTL:
-               return sys_msgctl (first, second,
-                                  (struct msqid_ds __user *) ptr);
+               return sys_msgctl(first, second,
+                                 (struct msqid_ds __user *) ptr);
 
        case SHMAT:
                switch (version) {
                default: {
                        unsigned long raddr;
-                       ret = do_shmat (first, (char __user *) ptr, second,
-                                       &raddr);
+                       ret = do_shmat(first, (char __user *) ptr, second,
+                                      &raddr);
                        if (ret)
                                return ret;
-                       return put_user (raddr, (unsigned long __user *) third);
+                       return put_user(raddr, (unsigned long __user *) third);
                }
                case 1: /* iBCS2 emulator entry point */
                        if (!segment_eq(get_fs(), get_ds()))
                                return -EINVAL;
-                       return do_shmat (first, (char __user *) ptr, second,
-                                        (unsigned long *) third);
+                       return do_shmat(first, (char __user *) ptr, second,
+                                       (unsigned long *) third);
                }
        case SHMDT:
-               return sys_shmdt ((char __user *)ptr);
+               return sys_shmdt((char __user *)ptr);
        case SHMGET:
-               return sys_shmget (first, second, third);
+               return sys_shmget(first, second, third);
        case SHMCTL:
-               return sys_shmctl (first, second,
-                                  (struct shmid_ds __user *) ptr);
+               return sys_shmctl(first, second,
+                                 (struct shmid_ds __user *) ptr);
        default:
                return -ENOSYS;
        }