linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / sparc64 / kernel / sys_sparc.c
index 3d6fd1e..60e4483 100644 (file)
@@ -85,6 +85,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
                        return addr;
        }
 
+       if (len <= mm->cached_hole_size) {
+               mm->cached_hole_size = 0;
+               mm->free_area_cache = TASK_UNMAPPED_BASE;
+       }
        start_addr = addr = mm->free_area_cache;
 
        task_size -= len;
@@ -104,6 +108,7 @@ full_search:
                if (task_size < addr) {
                        if (start_addr != TASK_UNMAPPED_BASE) {
                                start_addr = addr = TASK_UNMAPPED_BASE;
+                               mm->cached_hole_size = 0;
                                goto full_search;
                        }
                        return -ENOMEM;
@@ -115,6 +120,9 @@ full_search:
                        mm->free_area_cache = addr + len;
                        return addr;
                }
+               if (addr + mm->cached_hole_size < vma->vm_start)
+                       mm->cached_hole_size = vma->vm_start - addr;
+
                addr = vma->vm_end;
                if (do_color_align)
                        addr = COLOUR_ALIGN(addr, pgoff);
@@ -200,7 +208,8 @@ out:
  * This is really horribly ugly.
  */
 
-asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long third, void __user *ptr, long fifth)
+asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
+                       unsigned long third, void __user *ptr, long fifth)
 {
        int err;
 
@@ -208,14 +217,15 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
        if (call <= SEMCTL) {
                switch (call) {
                case SEMOP:
-                       err = sys_semtimedop(first, ptr, second, NULL);
+                       err = sys_semtimedop(first, ptr,
+                                            (unsigned)second, NULL);
                        goto out;
                case SEMTIMEDOP:
-                       err = sys_semtimedop(first, ptr, second,
+                       err = sys_semtimedop(first, ptr, (unsigned)second,
                                (const struct timespec __user *) fifth);
                        goto out;
                case SEMGET:
-                       err = sys_semget(first, second, (int)third);
+                       err = sys_semget(first, (int)second, (int)third);
                        goto out;
                case SEMCTL: {
                        union semun fourth;
@@ -226,7 +236,7 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
                        if (get_user(fourth.__pad,
                                     (void __user * __user *) ptr))
                                goto out;
-                       err = sys_semctl(first, second | IPC_64,
+                       err = sys_semctl(first, (int)second | IPC_64,
                                         (int)third, fourth);
                        goto out;
                }
@@ -238,17 +248,18 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
        if (call <= MSGCTL) {
                switch (call) {
                case MSGSND:
-                       err = sys_msgsnd(first, ptr, second, (int)third);
+                       err = sys_msgsnd(first, ptr, (size_t)second,
+                                        (int)third);
                        goto out;
                case MSGRCV:
-                       err = sys_msgrcv(first, ptr, second, fifth,
+                       err = sys_msgrcv(first, ptr, (size_t)second, fifth,
                                         (int)third);
                        goto out;
                case MSGGET:
-                       err = sys_msgget((key_t) first, second);
+                       err = sys_msgget((key_t)first, (int)second);
                        goto out;
                case MSGCTL:
-                       err = sys_msgctl(first, second | IPC_64, ptr);
+                       err = sys_msgctl(first, (int)second | IPC_64, ptr);
                        goto out;
                default:
                        err = -ENOSYS;
@@ -259,7 +270,7 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
                switch (call) {
                case SHMAT: {
                        ulong raddr;
-                       err = do_shmat(first, ptr, second, &raddr);
+                       err = do_shmat(first, ptr, (int)second, &raddr);
                        if (!err) {
                                if (put_user(raddr,
                                             (ulong __user *) third))
@@ -271,10 +282,10 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
                        err = sys_shmdt(ptr);
                        goto out;
                case SHMGET:
-                       err = sys_shmget(first, second, (int)third);
+                       err = sys_shmget(first, (size_t)second, (int)third);
                        goto out;
                case SHMCTL:
-                       err = sys_shmctl(first, second | IPC_64, ptr);
+                       err = sys_shmctl(first, (int)second | IPC_64, ptr);
                        goto out;
                default:
                        err = -ENOSYS;
@@ -312,6 +323,23 @@ asmlinkage long sparc64_personality(unsigned long personality)
        return ret;
 }
 
+int sparc64_mmap_check(unsigned long addr, unsigned long len,
+               unsigned long flags)
+{
+       if (test_thread_flag(TIF_32BIT)) {
+               if (len > 0xf0000000UL ||
+                   ((flags & MAP_FIXED) && addr > 0xf0000000UL - len))
+                            return -EINVAL;
+       } else {
+               if (len > -PAGE_OFFSET ||
+                   ((flags & MAP_FIXED) &&
+                        addr < PAGE_OFFSET && addr + len > -PAGE_OFFSET))
+                            return -EINVAL;
+        }
+
+       return 0;
+}
+
 /* Linux version of mmap */
 asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
        unsigned long prot, unsigned long flags, unsigned long fd,
@@ -327,24 +355,11 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
        }
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
        len = PAGE_ALIGN(len);
-       retval = -EINVAL;
-
-       if (test_thread_flag(TIF_32BIT)) {
-               if (len > 0xf0000000UL ||
-                   ((flags & MAP_FIXED) && addr > 0xf0000000UL - len))
-                       goto out_putf;
-       } else {
-               if (len > -PAGE_OFFSET ||
-                   ((flags & MAP_FIXED) &&
-                    addr < PAGE_OFFSET && addr + len > -PAGE_OFFSET))
-                       goto out_putf;
-       }
 
        down_write(&current->mm->mmap_sem);
        retval = do_mmap(file, addr, len, prot, flags, off);
        up_write(&current->mm->mmap_sem);
 
-out_putf:
        if (file)
                fput(file);
 out: