fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / sparc / kernel / sys_sparc.c
index 925efe9..a954a0c 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
+#include <asm/unistd.h>
 
 /* #define DEBUG_UNIMP_SYSCALL */
 
@@ -136,7 +137,8 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user
                        if (!ptr)
                                goto out;
                        err = -EFAULT;
-                       if(get_user(fourth.__pad, (void __user **)ptr))
+                       if (get_user(fourth.__pad,
+                                    (void __user * __user *)ptr))
                                goto out;
                        err = sys_semctl (first, second, third, fourth);
                        goto out;
@@ -165,7 +167,9 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user
                                goto out;
                                }
                        case 1: default:
-                               err = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
+                               err = sys_msgrcv (first,
+                                                 (struct msgbuf __user *) ptr,
+                                                 second, fifth, third);
                                goto out;
                        }
                case MSGGET:
@@ -194,7 +198,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user
                                goto out;
                                }
                        case 1: /* iBCS2 emulator entry point */
-                               err = do_shmat (first, (char __user *) ptr, second, (ulong __user *) third);
+                               err = -EINVAL;
                                goto out;
                        }
                case SHMDT: 
@@ -216,6 +220,21 @@ out:
        return err;
 }
 
+int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
+{
+       if (ARCH_SUN4C_SUN4 &&
+           (len > 0x20000000 ||
+            ((flags & MAP_FIXED) &&
+             addr < 0xe0000000 && addr + len > 0x20000000)))
+               return -EINVAL;
+
+       /* See asm-sparc/uaccess.h */
+       if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
+               return -EINVAL;
+
+       return 0;
+}
+
 /* Linux version of mmap */
 static unsigned long do_mmap2(unsigned long addr, unsigned long len,
        unsigned long prot, unsigned long flags, unsigned long fd,
@@ -230,25 +249,13 @@ static unsigned long do_mmap2(unsigned long addr, unsigned long len,
                        goto out;
        }
 
-       retval = -EINVAL;
        len = PAGE_ALIGN(len);
-       if (ARCH_SUN4C_SUN4 &&
-           (len > 0x20000000 ||
-            ((flags & MAP_FIXED) &&
-             addr < 0xe0000000 && addr + len > 0x20000000)))
-               goto out_putf;
-
-       /* See asm-sparc/uaccess.h */
-       if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
-               goto out_putf;
-
        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);
 
-out_putf:
        if (file)
                fput(file);
 out:
@@ -371,7 +378,7 @@ sparc_breakpoint (struct pt_regs *regs)
        info.si_signo = SIGTRAP;
        info.si_errno = 0;
        info.si_code = TRAP_BRKPT;
-       info.si_addr = (void *)regs->pc;
+       info.si_addr = (void __user *)regs->pc;
        info.si_trapno = 0;
        force_sig_info(SIGTRAP, &info, current);
 
@@ -396,7 +403,7 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act,
        if (act) {
                unsigned long mask;
 
-               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+               if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
                    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
                        return -EFAULT;
@@ -414,7 +421,7 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act,
                 * deadlock us if we held the signal lock on SMP.  So for
                 * now I take the easy way out and do no locking.
                 */
-               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+               if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
                    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
                        return -EFAULT;
@@ -462,21 +469,45 @@ sys_rt_sigaction(int sig,
 
 asmlinkage int sys_getdomainname(char __user *name, int len)
 {
-       int nlen;
-       int err = -EFAULT;
+       int nlen, err;
        
+       if (len < 0)
+               return -EINVAL;
+
        down_read(&uts_sem);
        
-       nlen = strlen(system_utsname.domainname) + 1;
-
-       if (nlen < len)
-               len = nlen;
-       if (len > __NEW_UTS_LEN)
-               goto done;
-       if (copy_to_user(name, system_utsname.domainname, len))
-               goto done;
-       err = 0;
-done:
+       nlen = strlen(utsname()->domainname) + 1;
+       err = -EINVAL;
+       if (nlen > len)
+               goto out;
+
+       err = -EFAULT;
+       if (!copy_to_user(name, utsname()->domainname, nlen))
+               err = 0;
+
+out:
        up_read(&uts_sem);
        return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       long __res;
+       register long __g1 __asm__ ("g1") = __NR_execve;
+       register long __o0 __asm__ ("o0") = (long)(filename);
+       register long __o1 __asm__ ("o1") = (long)(argv);
+       register long __o2 __asm__ ("o2") = (long)(envp);
+       asm volatile ("t 0x10\n\t"
+                     "bcc 1f\n\t"
+                     "mov %%o0, %0\n\t"
+                     "sub %%g0, %%o0, %0\n\t"
+                     "1:\n\t"
+                     : "=r" (__res), "=&r" (__o0)
+                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+                     : "cc");
+       return __res;
+}