This commit was manufactured by cvs2svn to create tag 'before-xenU'.
[linux-2.6.git] / arch / x86_64 / ia32 / sys_ia32.c
index ddd20d4..728a023 100644 (file)
 #include <linux/ptrace.h>
 #include <linux/highuid.h>
 #include <linux/vmalloc.h>
+#include <linux/vs_cvirt.h>
 #include <asm/mman.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
-#include <asm/ipc.h>
 #include <asm/atomic.h>
 #include <asm/ldt.h>
 
 #include <net/sock.h>
 #include <asm/ia32.h>
 
-#define A(__x)         ((unsigned long)(__x))
 #define AA(__x)                ((unsigned long)(__x))
-#define ROUND_UP(x,a)  ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
 
 int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
 {
@@ -88,7 +85,7 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
                return -EOVERFLOW;
        if (kbuf->size >= 0x7fffffff)
                return -EOVERFLOW;
-       if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
+       if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
            __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
            __put_user (kbuf->ino, &ubuf->st_ino) ||
            __put_user (kbuf->mode, &ubuf->st_mode) ||
@@ -131,7 +128,7 @@ cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
        typeof(ubuf->st_gid) gid = 0;
        SET_UID(uid, stat->uid);
        SET_GID(gid, stat->gid);
-       if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat64)) ||
+       if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct stat64)) ||
            __put_user(huge_encode_dev(stat->dev), &ubuf->st_dev) ||
            __put_user (stat->ino, &ubuf->__st_ino) ||
            __put_user (stat->ino, &ubuf->st_ino) ||
@@ -265,7 +262,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
        if (act) {
                compat_uptr_t handler, restorer;
 
-               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+               if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
                    __get_user(handler, &act->sa_handler) ||
                    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
                    __get_user(restorer, &act->sa_restorer)||
@@ -304,9 +301,9 @@ sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
                        set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
                        set32.sig[0] = old_ka.sa.sa_mask.sig[0];
                }
-               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
-                   __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
-                   __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+               if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+                   __put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) ||
+                   __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer) ||
                    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
                    __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)))
                        return -EFAULT;
@@ -325,7 +322,7 @@ sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigacti
                compat_old_sigset_t mask;
                compat_uptr_t handler, restorer;
 
-               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+               if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
                    __get_user(handler, &act->sa_handler) ||
                    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
                    __get_user(restorer, &act->sa_restorer) ||
@@ -341,9 +338,9 @@ sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigacti
         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
        if (!ret && oact) {
-               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
-                   __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
-                   __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+               if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+                   __put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) ||
+                   __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer) ||
                    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
                    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
                        return -EFAULT;
@@ -492,26 +489,6 @@ sys32_old_select(struct sel_arg_struct __user *arg)
                                 compat_ptr(a.exp), compat_ptr(a.tvp));
 }
 
-/*
- * sys_time() can be implemented in user-level using
- * sys_gettimeofday().  x86-64 did this but i386 Linux did not
- * so we have to implement this system call here.
- */
-asmlinkage long sys32_time(int __user * tloc)
-{
-       int i;
-       struct timeval tv;
-
-       do_gettimeofday(&tv);
-       i = tv.tv_sec;
-
-       if (tloc) {
-               if (put_user(i,tloc))
-                       i = -EFAULT;
-       }
-       return i;
-}
-
 extern asmlinkage long
 compat_sys_wait4(compat_pid_t pid, compat_uint_t * stat_addr, int options,
                 struct compat_rusage *ru);
@@ -590,7 +567,7 @@ sys32_sysinfo(struct sysinfo32 __user *info)
                s.freehigh >>= bitcount;
        }
 
-       if (verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo32)) ||
+       if (!access_ok(VERIFY_WRITE, info, sizeof(struct sysinfo32)) ||
            __put_user (s.uptime, &info->uptime) ||
            __put_user (s.loads[0], &info->loads[0]) ||
            __put_user (s.loads[1], &info->loads[1]) ||
@@ -648,53 +625,14 @@ sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
        return ret;
 }
 
-
 asmlinkage long
-sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo,
-                     struct compat_timespec __user *uts, compat_size_t sigsetsize)
-{
-       sigset_t s;
-       compat_sigset_t s32;
-       struct timespec t;
-       int ret;
-       mm_segment_t old_fs = get_fs();
-       siginfo_t info;
-               
-       if (copy_from_user (&s32, uthese, sizeof(compat_sigset_t)))
-               return -EFAULT;
-       switch (_NSIG_WORDS) {
-       case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
-       case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
-       case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
-       case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
-       }
-       if (uts && get_compat_timespec(&t, uts))
-               return -EFAULT;
-       if (uinfo) {
-               /* stop data leak to user space in case of structure fill mismatch
-                * between sys_rt_sigtimedwait & ia32_copy_siginfo_to_user.
-                */
-               memset(&info, 0, sizeof(info));
-       }
-       set_fs (KERNEL_DS);
-       ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL,
-                       sigsetsize);
-       set_fs (old_fs);
-       if (ret >= 0 && uinfo) {
-               if (ia32_copy_siginfo_to_user(uinfo, &info))
-                       return -EFAULT;
-       }
-       return ret;
-}
-
-asmlinkage long
-sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo)
+sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
 {
        siginfo_t info;
        int ret;
        mm_segment_t old_fs = get_fs();
        
-       if (ia32_copy_siginfo_from_user(&info, uinfo))
+       if (copy_siginfo_from_user32(&info, uinfo))
                return -EFAULT;
        set_fs (KERNEL_DS);
        ret = sys_rt_sigqueueinfo(pid, sig, &info);
@@ -712,6 +650,7 @@ sys32_pause(void)
 }
 
 
+#ifdef CONFIG_SYSCTL
 struct sysctl_ia32 {
        unsigned int    name;
        int             nlen;
@@ -726,14 +665,11 @@ struct sysctl_ia32 {
 asmlinkage long
 sys32_sysctl(struct sysctl_ia32 __user *args32)
 {
-#ifndef CONFIG_SYSCTL
-       return -ENOSYS; 
-#else
        struct sysctl_ia32 a32;
        mm_segment_t old_fs = get_fs ();
-       void *oldvalp, *newvalp;
+       void __user *oldvalp, *newvalp;
        size_t oldlen;
-       int *namep;
+       int __user *namep;
        long ret;
        extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
                     void *newval, size_t newlen);
@@ -749,9 +685,9 @@ sys32_sysctl(struct sysctl_ia32 __user *args32)
         * addresses, we KNOW that access_ok() will always succeed, so this is an
         * expensive NOP, but so what...
         */
-       namep = (int *) A(a32.name);
-       oldvalp = (void *) A(a32.oldval);
-       newvalp = (void *) A(a32.newval);
+       namep = compat_ptr(a32.name);
+       oldvalp = compat_ptr(a32.oldval);
+       newvalp =  compat_ptr(a32.newval);
 
        if ((oldvalp && get_user(oldlen, (int __user *)compat_ptr(a32.oldlenp)))
            || !access_ok(VERIFY_WRITE, namep, 0)
@@ -769,8 +705,8 @@ sys32_sysctl(struct sysctl_ia32 __user *args32)
                return -EFAULT;
 
        return ret;
-#endif
 }
+#endif
 
 /* warning: next two assume little endian */ 
 asmlinkage long
@@ -846,7 +782,7 @@ sys32_adjtimex(struct timex32 __user *utp)
 
        memset(&txc, 0, sizeof(struct timex));
 
-       if(verify_area(VERIFY_READ, utp, sizeof(struct timex32)) ||
+       if (!access_ok(VERIFY_READ, utp, sizeof(struct timex32)) ||
           __get_user(txc.modes, &utp->modes) ||
           __get_user(txc.offset, &utp->offset) ||
           __get_user(txc.freq, &utp->freq) ||
@@ -871,7 +807,7 @@ sys32_adjtimex(struct timex32 __user *utp)
 
        ret = do_adjtimex(&txc);
 
-       if(verify_area(VERIFY_WRITE, utp, sizeof(struct timex32)) ||
+       if (!access_ok(VERIFY_WRITE, utp, sizeof(struct timex32)) ||
           __put_user(txc.modes, &utp->modes) ||
           __put_user(txc.offset, &utp->offset) ||
           __put_user(txc.freq, &utp->freq) ||
@@ -924,6 +860,7 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
 asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
 {
        int error;
+       struct new_utsname *ptr;
 
        if (!name)
                return -EFAULT;
@@ -932,13 +869,14 @@ asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
   
        down_read(&uts_sem);
        
-       error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
+       ptr = vx_new_utsname();
+       error = __copy_to_user(&name->sysname,ptr->sysname,__OLD_UTS_LEN);
         __put_user(0,name->sysname+__OLD_UTS_LEN);
-        __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+        __copy_to_user(&name->nodename,ptr->nodename,__OLD_UTS_LEN);
         __put_user(0,name->nodename+__OLD_UTS_LEN);
-        __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+        __copy_to_user(&name->release,ptr->release,__OLD_UTS_LEN);
         __put_user(0,name->release+__OLD_UTS_LEN);
-        __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+        __copy_to_user(&name->version,ptr->version,__OLD_UTS_LEN);
         __put_user(0,name->version+__OLD_UTS_LEN);
         { 
                 char *arch = "x86_64";
@@ -961,7 +899,7 @@ long sys32_uname(struct old_utsname __user * name)
        if (!name)
                return -EFAULT;
        down_read(&uts_sem);
-       err=copy_to_user(name, &system_utsname, sizeof (*name));
+       err=copy_to_user(name, vx_new_utsname(), sizeof (*name));
        up_read(&uts_sem);
        if (personality(current->personality) == PER_LINUX32) 
                err |= copy_to_user(&name->machine, "i686", 5);
@@ -1019,32 +957,6 @@ asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp,
         return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
 }
 
-asmlinkage long sys32_waitid(int which, compat_pid_t pid,
-                            siginfo_t32 __user *uinfo, int options,
-                            struct compat_rusage __user *uru)
-{
-       siginfo_t info;
-       struct rusage ru;
-       long ret;
-       mm_segment_t old_fs = get_fs();
-
-       info.si_signo = 0;
-       set_fs (KERNEL_DS);
-       ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
-                        uru ? &ru : NULL);
-       set_fs (old_fs);
-
-       if (ret < 0 || info.si_signo == 0)
-               return ret;
-
-       if (uru && (ret = put_compat_rusage(&ru, uru)))
-               return ret;
-
-       BUG_ON(info.si_code & __SI_MASK);
-       info.si_code |= __SI_CHLD;
-       return ia32_copy_siginfo_to_user(uinfo, &info);
-}
-
 /*
  * Some system calls that need sign extended arguments. This could be done by a generic wrapper.
  */ 
@@ -1083,31 +995,19 @@ asmlinkage long sys32_open(const char __user * filename, int flags, int mode)
        return fd;
 }
 
-struct sigevent32 { 
-       u32 sigev_value;
-       u32 sigev_signo; 
-       u32 sigev_notify; 
-       u32 payload[(64 / 4) - 3]; 
-}; 
-
 extern asmlinkage long
 sys_timer_create(clockid_t which_clock,
                 struct sigevent __user *timer_event_spec,
                 timer_t __user * created_timer_id);
 
 long
-sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
+sys32_timer_create(u32 clock, struct compat_sigevent __user *se32, timer_t __user *timer_id)
 {
        struct sigevent __user *p = NULL;
        if (se32) { 
                struct sigevent se;
                p = compat_alloc_user_space(sizeof(struct sigevent));
-               memset(&se, 0, sizeof(struct sigevent)); 
-               if (get_user(se.sigev_value.sival_int,  &se32->sigev_value) ||
-                   __get_user(se.sigev_signo, &se32->sigev_signo) ||
-                   __get_user(se.sigev_notify, &se32->sigev_notify) ||
-                   __copy_from_user(&se._sigev_un._pad, &se32->payload, 
-                                    sizeof(se32->payload)) ||
+               if (get_compat_sigevent(&se, se32) ||
                    copy_to_user(p, &se, sizeof(se)))
                        return -EFAULT;
        } 
@@ -1141,8 +1041,6 @@ long sys32_lookup_dcookie(u32 addr_low, u32 addr_high,
        return sys_lookup_dcookie(((u64)addr_high << 32) | addr_low, buf, len);
 }
 
-cond_syscall(sys32_ipc)
-
 static int __init ia32_init (void)
 {
        printk("IA32 emulation $Id: sys_ia32.c,v 1.32 2002/03/24 13:02:28 ak Exp $\n");  
@@ -1152,4 +1050,3 @@ static int __init ia32_init (void)
 __initcall(ia32_init);
 
 extern unsigned long ia32_sys_call_table[];
-EXPORT_SYMBOL(ia32_sys_call_table);