v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / arch / ia64 / ia32 / sys_ia32.c
1 /*
2  * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Based on
3  *             sys_sparc32
4  *
5  * Copyright (C) 2000           VA Linux Co
6  * Copyright (C) 2000           Don Dugger <n0ano@valinux.com>
7  * Copyright (C) 1999           Arun Sharma <arun.sharma@intel.com>
8  * Copyright (C) 1997,1998      Jakub Jelinek (jj@sunsite.mff.cuni.cz)
9  * Copyright (C) 1997           David S. Miller (davem@caip.rutgers.edu)
10  * Copyright (C) 2000           Hewlett-Packard Co.
11  * Copyright (C) 2000           David Mosberger-Tang <davidm@hpl.hp.com>
12  *
13  * These routines maintain argument size conversion between 32bit and 64bit
14  * environment.
15  */
16
17 #include <linux/config.h>
18 #include <linux/kernel.h>
19 #include <linux/sysctl.h>
20 #include <linux/sched.h>
21 #include <linux/fs.h>
22 #include <linux/file.h>
23 #include <linux/signal.h>
24 #include <linux/utime.h>
25 #include <linux/resource.h>
26 #include <linux/times.h>
27 #include <linux/utsname.h>
28 #include <linux/timex.h>
29 #include <linux/smp.h>
30 #include <linux/smp_lock.h>
31 #include <linux/sem.h>
32 #include <linux/msg.h>
33 #include <linux/mm.h>
34 #include <linux/shm.h>
35 #include <linux/slab.h>
36 #include <linux/uio.h>
37 #include <linux/nfs_fs.h>
38 #include <linux/smb_fs.h>
39 #include <linux/smb_mount.h>
40 #include <linux/ncp_fs.h>
41 #include <linux/quota.h>
42 #include <linux/module.h>
43 #include <linux/sunrpc/svc.h>
44 #include <linux/nfsd/nfsd.h>
45 #include <linux/nfsd/cache.h>
46 #include <linux/nfsd/xdr.h>
47 #include <linux/nfsd/syscall.h>
48 #include <linux/poll.h>
49 #include <linux/personality.h>
50 #include <linux/stat.h>
51 #include <linux/ipc.h>
52
53 #include <asm/types.h>
54 #include <asm/uaccess.h>
55 #include <asm/semaphore.h>
56 #include <asm/ipc.h>
57
58 #include <net/scm.h>
59 #include <net/sock.h>
60 #include <asm/ia32.h>
61
62 #define A(__x)          ((unsigned long)(__x))
63 #define AA(__x)         ((unsigned long)(__x))
64 #define ROUND_UP(x,a)   ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
65 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
66
67 extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *);
68 extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long);
69
70 static int
71 nargs (unsigned int arg, char **ap)
72 {
73         int n, err, addr;
74
75         if (!arg)
76                 return 0;
77
78         n = 0;
79         do {
80                 err = get_user(addr, (int *)A(arg));
81                 if (err)
82                         return err;
83                 if (ap)
84                         *ap++ = (char *) A(addr);
85                 arg += sizeof(unsigned int);
86                 n++;
87         } while (addr);
88         return n - 1;
89 }
90
91 asmlinkage long
92 sys32_execve (char *filename, unsigned int argv, unsigned int envp,
93               int dummy3, int dummy4, int dummy5, int dummy6, int dummy7,
94               int stack)
95 {
96         struct pt_regs *regs = (struct pt_regs *)&stack;
97         unsigned long old_map_base, old_task_size;
98         char **av, **ae;
99         int na, ne, len;
100         long r;
101
102         na = nargs(argv, NULL);
103         if (na < 0)
104                 return na;
105         ne = nargs(envp, NULL);
106         if (ne < 0)
107                 return ne;
108         len = (na + ne + 2) * sizeof(*av);
109         av = kmalloc(len, GFP_KERNEL);
110         if (!av)
111                 return -ENOMEM;
112
113         ae = av + na + 1;
114         av[na] = NULL;
115         ae[ne] = NULL;
116
117         r = nargs(argv, av);
118         if (r < 0)
119                 goto out;
120         r = nargs(envp, ae);
121         if (r < 0)
122                 goto out;
123
124         old_map_base  = current->thread.map_base;
125         old_task_size = current->thread.task_size;
126
127         /* we may be exec'ing a 64-bit process: reset map base & task-size: */
128         current->thread.map_base  = DEFAULT_MAP_BASE;
129         current->thread.task_size = DEFAULT_TASK_SIZE;
130
131         set_fs(KERNEL_DS);
132         r = sys_execve(filename, av, ae, regs);
133         if (r < 0) {
134                 /* oops, execve failed, switch back to old map base & task-size: */
135                 current->thread.map_base  = old_map_base;
136                 current->thread.task_size = old_task_size;
137                 set_fs(USER_DS);        /* establish new task-size as the address-limit */
138           out:
139                 kfree(av);
140         }
141         return r;
142 }
143
144 static inline int
145 putstat(struct stat32 *ubuf, struct stat *kbuf)
146 {
147         int err;
148
149         err = put_user (kbuf->st_dev, &ubuf->st_dev);
150         err |= __put_user (kbuf->st_ino, &ubuf->st_ino);
151         err |= __put_user (kbuf->st_mode, &ubuf->st_mode);
152         err |= __put_user (kbuf->st_nlink, &ubuf->st_nlink);
153         err |= __put_user (kbuf->st_uid, &ubuf->st_uid);
154         err |= __put_user (kbuf->st_gid, &ubuf->st_gid);
155         err |= __put_user (kbuf->st_rdev, &ubuf->st_rdev);
156         err |= __put_user (kbuf->st_size, &ubuf->st_size);
157         err |= __put_user (kbuf->st_atime, &ubuf->st_atime);
158         err |= __put_user (kbuf->st_mtime, &ubuf->st_mtime);
159         err |= __put_user (kbuf->st_ctime, &ubuf->st_ctime);
160         err |= __put_user (kbuf->st_blksize, &ubuf->st_blksize);
161         err |= __put_user (kbuf->st_blocks, &ubuf->st_blocks);
162         return err;
163 }
164
165 extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
166
167 asmlinkage long
168 sys32_newstat(char * filename, struct stat32 *statbuf)
169 {
170         int ret;
171         struct stat s;
172         mm_segment_t old_fs = get_fs();
173
174         set_fs(KERNEL_DS);
175         ret = sys_newstat(filename, &s);
176         set_fs (old_fs);
177         if (putstat (statbuf, &s))
178                 return -EFAULT;
179         return ret;
180 }
181
182 extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
183
184 asmlinkage long
185 sys32_newlstat(char * filename, struct stat32 *statbuf)
186 {
187         int ret;
188         struct stat s;
189         mm_segment_t old_fs = get_fs();
190
191         set_fs (KERNEL_DS);
192         ret = sys_newlstat(filename, &s);
193         set_fs (old_fs);
194         if (putstat (statbuf, &s))
195                 return -EFAULT;
196         return ret;
197 }
198
199 extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
200
201 asmlinkage long
202 sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
203 {
204         int ret;
205         struct stat s;
206         mm_segment_t old_fs = get_fs();
207
208         set_fs (KERNEL_DS);
209         ret = sys_newfstat(fd, &s);
210         set_fs (old_fs);
211         if (putstat (statbuf, &s))
212                 return -EFAULT;
213         return ret;
214 }
215
216 #define OFFSET4K(a)     ((a) & 0xfff)
217
218 unsigned long
219 do_mmap_fake(struct file *file, unsigned long addr, unsigned long len,
220         unsigned long prot, unsigned long flags, loff_t off)
221 {
222         struct inode *inode;
223         void *front, *back;
224         unsigned long baddr;
225         int r;
226         char c;
227
228         if (OFFSET4K(addr) || OFFSET4K(off))
229                 return -EINVAL;
230         prot |= PROT_WRITE;
231         front = NULL;
232         back = NULL;
233         if ((baddr = (addr & PAGE_MASK)) != addr && get_user(c, (char *)baddr) == 0) {
234                 front = kmalloc(addr - baddr, GFP_KERNEL);
235                 if (!front)
236                         return -ENOMEM;
237                 __copy_user(front, (void *)baddr, addr - baddr);
238         }
239         if (addr && ((addr + len) & ~PAGE_MASK) && get_user(c, (char *)(addr + len)) == 0) {
240                 back = kmalloc(PAGE_SIZE - ((addr + len) & ~PAGE_MASK), GFP_KERNEL);
241                 if (!back) {
242                         if (front)
243                                 kfree(front);
244                         return -ENOMEM;
245                 }
246                 __copy_user(back, (char *)addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
247         }
248         down_write(&current->mm->mmap_sem);
249         r = do_mmap(0, baddr, len + (addr - baddr), prot, flags | MAP_ANONYMOUS, 0);
250         up_write(&current->mm->mmap_sem);
251         if (r < 0)
252                 return(r);
253         if (addr == 0)
254                 addr = r;
255         if (back) {
256                 __copy_user((char *)addr + len, back, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
257                 kfree(back);
258         }
259         if (front) {
260                 __copy_user((void *)baddr, front, addr - baddr);
261                 kfree(front);
262         }
263         if (flags & MAP_ANONYMOUS) {
264                 clear_user((char *)addr, len);
265                 return(addr);
266         }
267         if (!file)
268                 return -EINVAL;
269         inode = file->f_dentry->d_inode;
270         if (!inode->i_fop)
271                 return -EINVAL;
272         if (!file->f_op->read)
273                 return -EINVAL;
274         r = file->f_op->read(file, (char *)addr, len, &off);
275         return (r < 0) ? -EINVAL : addr;
276 }
277
278 long
279 ia32_do_mmap (struct file *file, unsigned int addr, unsigned int len, unsigned int prot,
280               unsigned int flags, unsigned int fd, unsigned int offset)
281 {
282         long error = -EFAULT;
283         unsigned int poff;
284
285         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
286         prot |= PROT_EXEC;
287
288         if ((flags & MAP_FIXED) && ((addr & ~PAGE_MASK) || (offset & ~PAGE_MASK)))
289                 error = do_mmap_fake(file, addr, len, prot, flags, (loff_t)offset);
290         else {
291                 poff = offset & PAGE_MASK;
292                 len += offset - poff;
293
294                 down_write(&current->mm->mmap_sem);
295                 error = do_mmap_pgoff(file, addr, len, prot, flags, poff >> PAGE_SHIFT);
296                 up_write(&current->mm->mmap_sem);
297
298                 if (!IS_ERR((void *) error))
299                         error += offset - poff;
300         }
301         return error;
302 }
303
304 /*
305  * Linux/i386 didn't use to be able to handle more than
306  * 4 system call parameters, so these system calls used a memory
307  * block for parameter passing..
308  */
309
310 struct mmap_arg_struct {
311         unsigned int addr;
312         unsigned int len;
313         unsigned int prot;
314         unsigned int flags;
315         unsigned int fd;
316         unsigned int offset;
317 };
318
319 asmlinkage long
320 sys32_mmap(struct mmap_arg_struct *arg)
321 {
322         struct mmap_arg_struct a;
323         struct file *file = NULL;
324         long retval;
325
326         if (copy_from_user(&a, arg, sizeof(a)))
327                 return -EFAULT;
328
329         if (PAGE_ALIGN(a.len) == 0)
330                 return a.addr;
331
332         if (!(a.flags & MAP_ANONYMOUS)) {
333                 file = fget(a.fd);
334                 if (!file)
335                         return -EBADF;
336         }
337 #ifdef  CONFIG_IA64_PAGE_SIZE_4KB
338         if ((a.offset & ~PAGE_MASK) != 0)
339                 return -EINVAL;
340
341         down_write(&current->mm->mmap_sem);
342         retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset >> PAGE_SHIFT);
343         up_write(&current->mm->mmap_sem);
344 #else
345         retval = ia32_do_mmap(file, a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
346 #endif
347         if (file)
348                 fput(file);
349         return retval;
350 }
351
352 asmlinkage long
353 sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
354 {
355
356 #ifdef  CONFIG_IA64_PAGE_SIZE_4KB
357         return(sys_mprotect(start, len, prot));
358 #else   // CONFIG_IA64_PAGE_SIZE_4KB
359         if (prot == 0)
360                 return(0);
361         len += start & ~PAGE_MASK;
362         if ((start & ~PAGE_MASK) && (prot & PROT_WRITE))
363                 prot |= PROT_EXEC;
364         return(sys_mprotect(start & PAGE_MASK, len & PAGE_MASK, prot));
365 #endif  // CONFIG_IA64_PAGE_SIZE_4KB
366 }
367
368 asmlinkage long
369 sys32_pipe(int *fd)
370 {
371         int retval;
372         int fds[2];
373
374         retval = do_pipe(fds);
375         if (retval)
376                 goto out;
377         if (copy_to_user(fd, fds, sizeof(fds)))
378                 retval = -EFAULT;
379   out:
380         return retval;
381 }
382
383 asmlinkage long
384 sys32_signal (int sig, unsigned int handler)
385 {
386         struct k_sigaction new_sa, old_sa;
387         int ret;
388
389         new_sa.sa.sa_handler = (__sighandler_t) A(handler);
390         new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
391
392         ret = do_sigaction(sig, &new_sa, &old_sa);
393
394         return ret ? ret : (unsigned long)old_sa.sa.sa_handler;
395 }
396
397 asmlinkage long
398 sys32_rt_sigaction(int sig, struct sigaction32 *act,
399                    struct sigaction32 *oact,  unsigned int sigsetsize)
400 {
401         struct k_sigaction new_ka, old_ka;
402         int ret;
403         sigset32_t set32;
404
405         /* XXX: Don't preclude handling different sized sigset_t's.  */
406         if (sigsetsize != sizeof(sigset32_t))
407                 return -EINVAL;
408
409         if (act) {
410                 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
411                 ret |= __copy_from_user(&set32, &act->sa_mask,
412                                         sizeof(sigset32_t));
413                 switch (_NSIG_WORDS) {
414                 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
415                                 | (((long)set32.sig[7]) << 32);
416                 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4]
417                                 | (((long)set32.sig[5]) << 32);
418                 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2]
419                                 | (((long)set32.sig[3]) << 32);
420                 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0]
421                                 | (((long)set32.sig[1]) << 32);
422                 }
423                 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
424
425                 if (ret)
426                         return -EFAULT;
427         }
428
429         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
430
431         if (!ret && oact) {
432                 switch (_NSIG_WORDS) {
433                 case 4:
434                         set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
435                         set32.sig[6] = old_ka.sa.sa_mask.sig[3];
436                 case 3:
437                         set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32);
438                         set32.sig[4] = old_ka.sa.sa_mask.sig[2];
439                 case 2:
440                         set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32);
441                         set32.sig[2] = old_ka.sa.sa_mask.sig[1];
442                 case 1:
443                         set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
444                         set32.sig[0] = old_ka.sa.sa_mask.sig[0];
445                 }
446                 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
447                 ret |= __copy_to_user(&oact->sa_mask, &set32,
448                                       sizeof(sigset32_t));
449                 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
450         }
451
452         return ret;
453 }
454
455
456 extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
457                                           size_t sigsetsize);
458
459 asmlinkage long
460 sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset,
461                      unsigned int sigsetsize)
462 {
463         sigset_t s;
464         sigset32_t s32;
465         int ret;
466         mm_segment_t old_fs = get_fs();
467
468         if (set) {
469                 if (copy_from_user (&s32, set, sizeof(sigset32_t)))
470                         return -EFAULT;
471                 switch (_NSIG_WORDS) {
472                 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
473                 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
474                 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
475                 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
476                 }
477         }
478         set_fs (KERNEL_DS);
479         ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL,
480                                  sigsetsize);
481         set_fs (old_fs);
482         if (ret) return ret;
483         if (oset) {
484                 switch (_NSIG_WORDS) {
485                 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
486                 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
487                 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
488                 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
489                 }
490                 if (copy_to_user (oset, &s32, sizeof(sigset32_t)))
491                         return -EFAULT;
492         }
493         return 0;
494 }
495
496 static inline int
497 put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
498 {
499         int err;
500
501         err = put_user (kbuf->f_type, &ubuf->f_type);
502         err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
503         err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
504         err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
505         err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
506         err |= __put_user (kbuf->f_files, &ubuf->f_files);
507         err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
508         err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
509         err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
510         err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
511         return err;
512 }
513
514 extern asmlinkage long sys_statfs(const char * path, struct statfs * buf);
515
516 asmlinkage long
517 sys32_statfs(const char * path, struct statfs32 *buf)
518 {
519         int ret;
520         struct statfs s;
521         mm_segment_t old_fs = get_fs();
522
523         set_fs (KERNEL_DS);
524         ret = sys_statfs((const char *)path, &s);
525         set_fs (old_fs);
526         if (put_statfs(buf, &s))
527                 return -EFAULT;
528         return ret;
529 }
530
531 extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
532
533 asmlinkage long
534 sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
535 {
536         int ret;
537         struct statfs s;
538         mm_segment_t old_fs = get_fs();
539
540         set_fs (KERNEL_DS);
541         ret = sys_fstatfs(fd, &s);
542         set_fs (old_fs);
543         if (put_statfs(buf, &s))
544                 return -EFAULT;
545         return ret;
546 }
547
548 struct timeval32
549 {
550     int tv_sec, tv_usec;
551 };
552
553 struct itimerval32
554 {
555     struct timeval32 it_interval;
556     struct timeval32 it_value;
557 };
558
559 static inline long
560 get_tv32(struct timeval *o, struct timeval32 *i)
561 {
562         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
563                 (__get_user(o->tv_sec, &i->tv_sec) |
564                  __get_user(o->tv_usec, &i->tv_usec)));
565 }
566
567 static inline long
568 put_tv32(struct timeval32 *o, struct timeval *i)
569 {
570         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
571                 (__put_user(i->tv_sec, &o->tv_sec) |
572                  __put_user(i->tv_usec, &o->tv_usec)));
573 }
574
575 static inline long
576 get_it32(struct itimerval *o, struct itimerval32 *i)
577 {
578         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
579                 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
580                  __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
581                  __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
582                  __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
583 }
584
585 static inline long
586 put_it32(struct itimerval32 *o, struct itimerval *i)
587 {
588         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
589                 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
590                  __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
591                  __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
592                  __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
593 }
594
595 extern int do_getitimer(int which, struct itimerval *value);
596
597 asmlinkage long
598 sys32_getitimer(int which, struct itimerval32 *it)
599 {
600         struct itimerval kit;
601         int error;
602
603         error = do_getitimer(which, &kit);
604         if (!error && put_it32(it, &kit))
605                 error = -EFAULT;
606
607         return error;
608 }
609
610 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
611
612 asmlinkage long
613 sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
614 {
615         struct itimerval kin, kout;
616         int error;
617
618         if (in) {
619                 if (get_it32(&kin, in))
620                         return -EFAULT;
621         } else
622                 memset(&kin, 0, sizeof(kin));
623
624         error = do_setitimer(which, &kin, out ? &kout : NULL);
625         if (error || !out)
626                 return error;
627         if (put_it32(out, &kout))
628                 return -EFAULT;
629
630         return 0;
631
632 }
633 asmlinkage unsigned long
634 sys32_alarm(unsigned int seconds)
635 {
636         struct itimerval it_new, it_old;
637         unsigned int oldalarm;
638
639         it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
640         it_new.it_value.tv_sec = seconds;
641         it_new.it_value.tv_usec = 0;
642         do_setitimer(ITIMER_REAL, &it_new, &it_old);
643         oldalarm = it_old.it_value.tv_sec;
644         /* ehhh.. We can't return 0 if we have an alarm pending.. */
645         /* And we'd better return too much than too little anyway */
646         if (it_old.it_value.tv_usec)
647                 oldalarm++;
648         return oldalarm;
649 }
650
651 /* Translations due to time_t size differences.  Which affects all
652    sorts of things, like timeval and itimerval.  */
653
654 struct utimbuf_32 {
655         int     atime;
656         int     mtime;
657 };
658
659 extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes);
660 extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz);
661
662 asmlinkage long
663 ia32_utime(char * filename, struct utimbuf_32 *times32)
664 {
665         mm_segment_t old_fs = get_fs();
666         struct timeval tv[2], *tvp;
667         long ret;
668
669         if (times32) {
670                 if (get_user(tv[0].tv_sec, &times32->atime))
671                         return -EFAULT;
672                 tv[0].tv_usec = 0;
673                 if (get_user(tv[1].tv_sec, &times32->mtime))
674                         return -EFAULT;
675                 tv[1].tv_usec = 0;
676                 set_fs (KERNEL_DS);
677                 tvp = tv;
678         } else
679                 tvp = NULL;
680         ret = sys_utimes(filename, tvp);
681         set_fs (old_fs);
682         return ret;
683 }
684
685 extern struct timezone sys_tz;
686 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
687
688 asmlinkage long
689 sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
690 {
691         if (tv) {
692                 struct timeval ktv;
693                 do_gettimeofday(&ktv);
694                 if (put_tv32(tv, &ktv))
695                         return -EFAULT;
696         }
697         if (tz) {
698                 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
699                         return -EFAULT;
700         }
701         return 0;
702 }
703
704 asmlinkage long
705 sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
706 {
707         struct timeval ktv;
708         struct timezone ktz;
709
710         if (tv) {
711                 if (get_tv32(&ktv, tv))
712                         return -EFAULT;
713         }
714         if (tz) {
715                 if (copy_from_user(&ktz, tz, sizeof(ktz)))
716                         return -EFAULT;
717         }
718
719         return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
720 }
721
722 struct linux32_dirent {
723         u32     d_ino;
724         u32     d_off;
725         u16     d_reclen;
726         char    d_name[1];
727 };
728
729 struct old_linux32_dirent {
730         u32     d_ino;
731         u32     d_offset;
732         u16     d_namlen;
733         char    d_name[1];
734 };
735
736 struct getdents32_callback {
737         struct linux32_dirent * current_dir;
738         struct linux32_dirent * previous;
739         int count;
740         int error;
741 };
742
743 struct readdir32_callback {
744         struct old_linux32_dirent * dirent;
745         int count;
746 };
747
748 static int
749 filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
750            unsigned int d_type)
751 {
752         struct linux32_dirent * dirent;
753         struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
754         int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
755
756         buf->error = -EINVAL;   /* only used if we fail.. */
757         if (reclen > buf->count)
758                 return -EINVAL;
759         buf->error = -EFAULT;   /* only used if we fail.. */
760         dirent = buf->previous;
761         if (dirent)
762                 if (put_user(offset, &dirent->d_off))
763                         return -EFAULT;
764         dirent = buf->current_dir;
765         buf->previous = dirent;
766         if (put_user(ino, &dirent->d_ino)
767             || put_user(reclen, &dirent->d_reclen)
768             || copy_to_user(dirent->d_name, name, namlen)
769             || put_user(0, dirent->d_name + namlen))
770                 return -EFAULT;
771         ((char *) dirent) += reclen;
772         buf->current_dir = dirent;
773         buf->count -= reclen;
774         return 0;
775 }
776
777 asmlinkage long
778 sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
779 {
780         struct file * file;
781         struct linux32_dirent * lastdirent;
782         struct getdents32_callback buf;
783         int error;
784
785         error = -EBADF;
786         file = fget(fd);
787         if (!file)
788                 goto out;
789
790         buf.current_dir = (struct linux32_dirent *) dirent;
791         buf.previous = NULL;
792         buf.count = count;
793         buf.error = 0;
794
795         error = vfs_readdir(file, filldir32, &buf);
796         if (error < 0)
797                 goto out_putf;
798         error = buf.error;
799         lastdirent = buf.previous;
800         if (lastdirent) {
801                 error = -EINVAL;
802                 if (put_user(file->f_pos, &lastdirent->d_off))
803                         goto out_putf;
804                 error = count - buf.count;
805         }
806
807 out_putf:
808         fput(file);
809 out:
810         return error;
811 }
812
813 static int
814 fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
815               unsigned int d_type)
816 {
817         struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
818         struct old_linux32_dirent * dirent;
819
820         if (buf->count)
821                 return -EINVAL;
822         buf->count++;
823         dirent = buf->dirent;
824         if (put_user(ino, &dirent->d_ino)
825             || put_user(offset, &dirent->d_offset)
826             || put_user(namlen, &dirent->d_namlen)
827             || copy_to_user(dirent->d_name, name, namlen)
828             || put_user(0, dirent->d_name + namlen))
829                 return -EFAULT;
830         return 0;
831 }
832
833 asmlinkage long
834 sys32_readdir (unsigned int fd, void * dirent, unsigned int count)
835 {
836         int error;
837         struct file * file;
838         struct readdir32_callback buf;
839
840         error = -EBADF;
841         file = fget(fd);
842         if (!file)
843                 goto out;
844
845         buf.count = 0;
846         buf.dirent = dirent;
847
848         error = vfs_readdir(file, fillonedir32, &buf);
849         if (error >= 0)
850                 error = buf.count;
851         fput(file);
852 out:
853         return error;
854 }
855
856 /*
857  * We can actually return ERESTARTSYS instead of EINTR, but I'd
858  * like to be certain this leads to no problems. So I return
859  * EINTR just for safety.
860  *
861  * Update: ERESTARTSYS breaks at least the xview clock binary, so
862  * I'm trying ERESTARTNOHAND which restart only when you want to.
863  */
864 #define MAX_SELECT_SECONDS \
865         ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
866 #define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y))
867
868 asmlinkage long
869 sys32_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp32)
870 {
871         fd_set_bits fds;
872         char *bits;
873         long timeout;
874         int ret, size;
875
876         timeout = MAX_SCHEDULE_TIMEOUT;
877         if (tvp32) {
878                 time_t sec, usec;
879
880                 ret = -EFAULT;
881                 if (get_user(sec, &tvp32->tv_sec)
882                     || get_user(usec, &tvp32->tv_usec))
883                         goto out_nofds;
884
885                 ret = -EINVAL;
886                 if (sec < 0 || usec < 0)
887                         goto out_nofds;
888
889                 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
890                         timeout = ROUND_UP_TIME(usec, 1000000/HZ);
891                         timeout += sec * (unsigned long) HZ;
892                 }
893         }
894
895         ret = -EINVAL;
896         if (n < 0)
897                 goto out_nofds;
898
899         if (n > current->files->max_fdset)
900                 n = current->files->max_fdset;
901
902         /*
903          * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
904          * since we used fdset we need to allocate memory in units of
905          * long-words.
906          */
907         ret = -ENOMEM;
908         size = FDS_BYTES(n);
909         bits = kmalloc(6 * size, GFP_KERNEL);
910         if (!bits)
911                 goto out_nofds;
912         fds.in      = (unsigned long *)  bits;
913         fds.out     = (unsigned long *) (bits +   size);
914         fds.ex      = (unsigned long *) (bits + 2*size);
915         fds.res_in  = (unsigned long *) (bits + 3*size);
916         fds.res_out = (unsigned long *) (bits + 4*size);
917         fds.res_ex  = (unsigned long *) (bits + 5*size);
918
919         if ((ret = get_fd_set(n, inp, fds.in)) ||
920             (ret = get_fd_set(n, outp, fds.out)) ||
921             (ret = get_fd_set(n, exp, fds.ex)))
922                 goto out;
923         zero_fd_set(n, fds.res_in);
924         zero_fd_set(n, fds.res_out);
925         zero_fd_set(n, fds.res_ex);
926
927         ret = do_select(n, &fds, &timeout);
928
929         if (tvp32 && !(current->personality & STICKY_TIMEOUTS)) {
930                 time_t sec = 0, usec = 0;
931                 if (timeout) {
932                         sec = timeout / HZ;
933                         usec = timeout % HZ;
934                         usec *= (1000000/HZ);
935                 }
936                 if (put_user(sec, (int *)&tvp32->tv_sec)
937                     || put_user(usec, (int *)&tvp32->tv_usec))
938                 {
939                         ret = -EFAULT;
940                         goto out;
941                 }
942         }
943
944         if (ret < 0)
945                 goto out;
946         if (!ret) {
947                 ret = -ERESTARTNOHAND;
948                 if (signal_pending(current))
949                         goto out;
950                 ret = 0;
951         }
952
953         set_fd_set(n, inp, fds.res_in);
954         set_fd_set(n, outp, fds.res_out);
955         set_fd_set(n, exp, fds.res_ex);
956
957 out:
958         kfree(bits);
959 out_nofds:
960         return ret;
961 }
962
963 struct sel_arg_struct {
964         unsigned int n;
965         unsigned int inp;
966         unsigned int outp;
967         unsigned int exp;
968         unsigned int tvp;
969 };
970
971 asmlinkage long
972 old_select(struct sel_arg_struct *arg)
973 {
974         struct sel_arg_struct a;
975
976         if (copy_from_user(&a, arg, sizeof(a)))
977                 return -EFAULT;
978         return sys32_select(a.n, (fd_set *)A(a.inp), (fd_set *)A(a.outp), (fd_set *)A(a.exp),
979                             (struct timeval32 *)A(a.tvp));
980 }
981
982 struct timespec32 {
983         int     tv_sec;
984         int     tv_nsec;
985 };
986
987 extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
988
989 asmlinkage long
990 sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
991 {
992         struct timespec t;
993         int ret;
994         mm_segment_t old_fs = get_fs ();
995
996         if (get_user (t.tv_sec, &rqtp->tv_sec) ||
997             __get_user (t.tv_nsec, &rqtp->tv_nsec))
998                 return -EFAULT;
999         set_fs (KERNEL_DS);
1000         ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1001         set_fs (old_fs);
1002         if (rmtp && ret == -EINTR) {
1003                 if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1004                     __put_user (t.tv_nsec, &rmtp->tv_nsec))
1005                         return -EFAULT;
1006         }
1007         return ret;
1008 }
1009
1010 struct iovec32 { unsigned int iov_base; int iov_len; };
1011 asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
1012 asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
1013
1014 static struct iovec *
1015 get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type)
1016 {
1017         int i;
1018         u32 buf, len;
1019         struct iovec *ivp, *iov;
1020
1021         /* Get the "struct iovec" from user memory */
1022
1023         if (!count)
1024                 return 0;
1025         if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count))
1026                 return(struct iovec *)0;
1027         if (count > UIO_MAXIOV)
1028                 return(struct iovec *)0;
1029         if (count > UIO_FASTIOV) {
1030                 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1031                 if (!iov)
1032                         return((struct iovec *)0);
1033         } else
1034                 iov = iov_buf;
1035
1036         ivp = iov;
1037         for (i = 0; i < count; i++) {
1038                 if (__get_user(len, &iov32->iov_len) ||
1039                     __get_user(buf, &iov32->iov_base)) {
1040                         if (iov != iov_buf)
1041                                 kfree(iov);
1042                         return((struct iovec *)0);
1043                 }
1044                 if (verify_area(type, (void *)A(buf), len)) {
1045                         if (iov != iov_buf)
1046                                 kfree(iov);
1047                         return((struct iovec *)0);
1048                 }
1049                 ivp->iov_base = (void *)A(buf);
1050                 ivp->iov_len = (__kernel_size_t)len;
1051                 iov32++;
1052                 ivp++;
1053         }
1054         return(iov);
1055 }
1056
1057 asmlinkage long
1058 sys32_readv(int fd, struct iovec32 *vector, u32 count)
1059 {
1060         struct iovec iovstack[UIO_FASTIOV];
1061         struct iovec *iov;
1062         int ret;
1063         mm_segment_t old_fs = get_fs();
1064
1065         if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE)) == (struct iovec *)0)
1066                 return -EFAULT;
1067         set_fs(KERNEL_DS);
1068         ret = sys_readv(fd, iov, count);
1069         set_fs(old_fs);
1070         if (iov != iovstack)
1071                 kfree(iov);
1072         return ret;
1073 }
1074
1075 asmlinkage long
1076 sys32_writev(int fd, struct iovec32 *vector, u32 count)
1077 {
1078         struct iovec iovstack[UIO_FASTIOV];
1079         struct iovec *iov;
1080         int ret;
1081         mm_segment_t old_fs = get_fs();
1082
1083         if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ)) == (struct iovec *)0)
1084                 return -EFAULT;
1085         set_fs(KERNEL_DS);
1086         ret = sys_writev(fd, iov, count);
1087         set_fs(old_fs);
1088         if (iov != iovstack)
1089                 kfree(iov);
1090         return ret;
1091 }
1092
1093 #define RLIM_INFINITY32 0x7fffffff
1094 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
1095
1096 struct rlimit32 {
1097         int     rlim_cur;
1098         int     rlim_max;
1099 };
1100
1101 extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
1102
1103 asmlinkage long
1104 sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
1105 {
1106         struct rlimit r;
1107         int ret;
1108         mm_segment_t old_fs = get_fs ();
1109
1110         set_fs (KERNEL_DS);
1111         ret = sys_getrlimit(resource, &r);
1112         set_fs (old_fs);
1113         if (!ret) {
1114                 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
1115                 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
1116         }
1117         return ret;
1118 }
1119
1120 extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
1121
1122 asmlinkage long
1123 sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
1124 {
1125         struct rlimit r;
1126         int ret;
1127         mm_segment_t old_fs = get_fs ();
1128
1129         if (resource >= RLIM_NLIMITS) return -EINVAL;
1130         if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
1131             __get_user (r.rlim_max, &rlim->rlim_max))
1132                 return -EFAULT;
1133         if (r.rlim_cur == RLIM_INFINITY32)
1134                 r.rlim_cur = RLIM_INFINITY;
1135         if (r.rlim_max == RLIM_INFINITY32)
1136                 r.rlim_max = RLIM_INFINITY;
1137         set_fs (KERNEL_DS);
1138         ret = sys_setrlimit(resource, &r);
1139         set_fs (old_fs);
1140         return ret;
1141 }
1142
1143 /*
1144  *  Declare the IA32 version of the msghdr
1145  */
1146
1147 struct msghdr32 {
1148         unsigned int    msg_name;       /* Socket name                  */
1149         int             msg_namelen;    /* Length of name               */
1150         unsigned int    msg_iov;        /* Data blocks                  */
1151         unsigned int    msg_iovlen;     /* Number of blocks             */
1152         unsigned int    msg_control;    /* Per protocol magic (eg BSD file descriptor passing) */
1153         unsigned int    msg_controllen; /* Length of cmsg list */
1154         unsigned        msg_flags;
1155 };
1156
1157 static inline int
1158 shape_msg(struct msghdr *mp, struct msghdr32 *mp32)
1159 {
1160         int ret;
1161         unsigned int i;
1162
1163         if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32)))
1164                 return(-EFAULT);
1165         ret = __get_user(i, &mp32->msg_name);
1166         mp->msg_name = (void *)A(i);
1167         ret |= __get_user(mp->msg_namelen, &mp32->msg_namelen);
1168         ret |= __get_user(i, &mp32->msg_iov);
1169         mp->msg_iov = (struct iovec *)A(i);
1170         ret |= __get_user(mp->msg_iovlen, &mp32->msg_iovlen);
1171         ret |= __get_user(i, &mp32->msg_control);
1172         mp->msg_control = (void *)A(i);
1173         ret |= __get_user(mp->msg_controllen, &mp32->msg_controllen);
1174         ret |= __get_user(mp->msg_flags, &mp32->msg_flags);
1175         return(ret ? -EFAULT : 0);
1176 }
1177
1178 /*
1179  *      Verify & re-shape IA32 iovec. The caller must ensure that the
1180  *      iovec is big enough to hold the re-shaped message iovec.
1181  *
1182  *      Save time not doing verify_area. copy_*_user will make this work
1183  *      in any case.
1184  *
1185  *      Don't need to check the total size for overflow (cf net/core/iovec.c),
1186  *      32-bit sizes can't overflow a 64-bit count.
1187  */
1188
1189 static inline int
1190 verify_iovec32(struct msghdr *m, struct iovec *iov, char *address, int mode)
1191 {
1192         int size, err, ct;
1193         struct iovec32 *iov32;
1194
1195         if(m->msg_namelen)
1196         {
1197                 if(mode==VERIFY_READ)
1198                 {
1199                         err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address);
1200                         if(err<0)
1201                                 goto out;
1202                 }
1203
1204                 m->msg_name = address;
1205         } else
1206                 m->msg_name = NULL;
1207
1208         err = -EFAULT;
1209         size = m->msg_iovlen * sizeof(struct iovec32);
1210         if (copy_from_user(iov, m->msg_iov, size))
1211                 goto out;
1212         m->msg_iov=iov;
1213
1214         err = 0;
1215         iov32 = (struct iovec32 *)iov;
1216         for (ct = m->msg_iovlen; ct-- > 0; ) {
1217                 iov[ct].iov_len = (__kernel_size_t)iov32[ct].iov_len;
1218                 iov[ct].iov_base = (void *) A(iov32[ct].iov_base);
1219                 err += iov[ct].iov_len;
1220         }
1221 out:
1222         return err;
1223 }
1224
1225 extern __inline__ void
1226 sockfd_put(struct socket *sock)
1227 {
1228         fput(sock->file);
1229 }
1230
1231 /* XXX This really belongs in some header file... -DaveM */
1232 #define MAX_SOCK_ADDR   128             /* 108 for Unix domain -
1233                                            16 for IP, 16 for IPX,
1234                                            24 for IPv6,
1235                                            about 80 for AX.25 */
1236
1237 extern struct socket *sockfd_lookup(int fd, int *err);
1238
1239 /*
1240  *      BSD sendmsg interface
1241  */
1242
1243 int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
1244 {
1245         struct socket *sock;
1246         char address[MAX_SOCK_ADDR];
1247         struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
1248         unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */
1249         unsigned char *ctl_buf = ctl;
1250         struct msghdr msg_sys;
1251         int err, ctl_len, iov_size, total_len;
1252
1253         err = -EFAULT;
1254         if (shape_msg(&msg_sys, msg))
1255                 goto out;
1256
1257         sock = sockfd_lookup(fd, &err);
1258         if (!sock)
1259                 goto out;
1260
1261         /* do not move before msg_sys is valid */
1262         err = -EINVAL;
1263         if (msg_sys.msg_iovlen > UIO_MAXIOV)
1264                 goto out_put;
1265
1266         /* Check whether to allocate the iovec area*/
1267         err = -ENOMEM;
1268         iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32);
1269         if (msg_sys.msg_iovlen > UIO_FASTIOV) {
1270                 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
1271                 if (!iov)
1272                         goto out_put;
1273         }
1274
1275         /* This will also move the address data into kernel space */
1276         err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
1277         if (err < 0)
1278                 goto out_freeiov;
1279         total_len = err;
1280
1281         err = -ENOBUFS;
1282
1283         if (msg_sys.msg_controllen > INT_MAX)
1284                 goto out_freeiov;
1285         ctl_len = msg_sys.msg_controllen;
1286         if (ctl_len)
1287         {
1288                 if (ctl_len > sizeof(ctl))
1289                 {
1290                         err = -ENOBUFS;
1291                         ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
1292                         if (ctl_buf == NULL)
1293                                 goto out_freeiov;
1294                 }
1295                 err = -EFAULT;
1296                 if (copy_from_user(ctl_buf, msg_sys.msg_control, ctl_len))
1297                         goto out_freectl;
1298                 msg_sys.msg_control = ctl_buf;
1299         }
1300         msg_sys.msg_flags = flags;
1301
1302         if (sock->file->f_flags & O_NONBLOCK)
1303                 msg_sys.msg_flags |= MSG_DONTWAIT;
1304         err = sock_sendmsg(sock, &msg_sys, total_len);
1305
1306 out_freectl:
1307         if (ctl_buf != ctl)
1308                 sock_kfree_s(sock->sk, ctl_buf, ctl_len);
1309 out_freeiov:
1310         if (iov != iovstack)
1311                 sock_kfree_s(sock->sk, iov, iov_size);
1312 out_put:
1313         sockfd_put(sock);
1314 out:
1315         return err;
1316 }
1317
1318 /*
1319  *      BSD recvmsg interface
1320  */
1321
1322 int
1323 sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags)
1324 {
1325         struct socket *sock;
1326         struct iovec iovstack[UIO_FASTIOV];
1327         struct iovec *iov=iovstack;
1328         struct msghdr msg_sys;
1329         unsigned long cmsg_ptr;
1330         int err, iov_size, total_len, len;
1331
1332         /* kernel mode address */
1333         char addr[MAX_SOCK_ADDR];
1334
1335         /* user mode address pointers */
1336         struct sockaddr *uaddr;
1337         int *uaddr_len;
1338
1339         err=-EFAULT;
1340         if (shape_msg(&msg_sys, msg))
1341                 goto out;
1342
1343         sock = sockfd_lookup(fd, &err);
1344         if (!sock)
1345                 goto out;
1346
1347         err = -EINVAL;
1348         if (msg_sys.msg_iovlen > UIO_MAXIOV)
1349                 goto out_put;
1350
1351         /* Check whether to allocate the iovec area*/
1352         err = -ENOMEM;
1353         iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
1354         if (msg_sys.msg_iovlen > UIO_FASTIOV) {
1355                 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
1356                 if (!iov)
1357                         goto out_put;
1358         }
1359
1360         /*
1361          *      Save the user-mode address (verify_iovec will change the
1362          *      kernel msghdr to use the kernel address space)
1363          */
1364
1365         uaddr = msg_sys.msg_name;
1366         uaddr_len = &msg->msg_namelen;
1367         err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
1368         if (err < 0)
1369                 goto out_freeiov;
1370         total_len=err;
1371
1372         cmsg_ptr = (unsigned long)msg_sys.msg_control;
1373         msg_sys.msg_flags = 0;
1374
1375         if (sock->file->f_flags & O_NONBLOCK)
1376                 flags |= MSG_DONTWAIT;
1377         err = sock_recvmsg(sock, &msg_sys, total_len, flags);
1378         if (err < 0)
1379                 goto out_freeiov;
1380         len = err;
1381
1382         if (uaddr != NULL) {
1383                 err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
1384                 if (err < 0)
1385                         goto out_freeiov;
1386         }
1387         err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
1388         if (err)
1389                 goto out_freeiov;
1390         err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr,
1391                                                          &msg->msg_controllen);
1392         if (err)
1393                 goto out_freeiov;
1394         err = len;
1395
1396 out_freeiov:
1397         if (iov != iovstack)
1398                 sock_kfree_s(sock->sk, iov, iov_size);
1399 out_put:
1400         sockfd_put(sock);
1401 out:
1402         return err;
1403 }
1404
1405 /* Argument list sizes for sys_socketcall */
1406 #define AL(x) ((x) * sizeof(u32))
1407 static unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
1408                                 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
1409                                 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
1410 #undef AL
1411
1412 extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
1413 extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr,
1414                                   int addrlen);
1415 extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr,
1416                                  int *upeer_addrlen);
1417 extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,
1418                                       int *usockaddr_len);
1419 extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,
1420                                       int *usockaddr_len);
1421 extern asmlinkage long sys_send(int fd, void *buff, size_t len, unsigned flags);
1422 extern asmlinkage long sys_sendto(int fd, u32 buff, __kernel_size_t32 len,
1423                                    unsigned flags, u32 addr, int addr_len);
1424 extern asmlinkage long sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
1425 extern asmlinkage long sys_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
1426                                      unsigned flags, u32 addr, u32 addr_len);
1427 extern asmlinkage long sys_setsockopt(int fd, int level, int optname,
1428                                      char *optval, int optlen);
1429 extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
1430                                        u32 optval, u32 optlen);
1431
1432 extern asmlinkage long sys_socket(int family, int type, int protocol);
1433 extern asmlinkage long sys_socketpair(int family, int type, int protocol,
1434                                      int usockvec[2]);
1435 extern asmlinkage long sys_shutdown(int fd, int how);
1436 extern asmlinkage long sys_listen(int fd, int backlog);
1437
1438 asmlinkage long sys32_socketcall(int call, u32 *args)
1439 {
1440         int ret;
1441         u32 a[6];
1442         u32 a0,a1;
1443
1444         if (call<SYS_SOCKET||call>SYS_RECVMSG)
1445                 return -EINVAL;
1446         if (copy_from_user(a, args, nas[call]))
1447                 return -EFAULT;
1448         a0=a[0];
1449         a1=a[1];
1450
1451         switch(call)
1452         {
1453                 case SYS_SOCKET:
1454                         ret = sys_socket(a0, a1, a[2]);
1455                         break;
1456                 case SYS_BIND:
1457                         ret = sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
1458                         break;
1459                 case SYS_CONNECT:
1460                         ret = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
1461                         break;
1462                 case SYS_LISTEN:
1463                         ret = sys_listen(a0, a1);
1464                         break;
1465                 case SYS_ACCEPT:
1466                         ret = sys_accept(a0, (struct sockaddr *)A(a1),
1467                                           (int *)A(a[2]));
1468                         break;
1469                 case SYS_GETSOCKNAME:
1470                         ret = sys_getsockname(a0, (struct sockaddr *)A(a1),
1471                                                (int *)A(a[2]));
1472                         break;
1473                 case SYS_GETPEERNAME:
1474                         ret = sys_getpeername(a0, (struct sockaddr *)A(a1),
1475                                                (int *)A(a[2]));
1476                         break;
1477                 case SYS_SOCKETPAIR:
1478                         ret = sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
1479                         break;
1480                 case SYS_SEND:
1481                         ret = sys_send(a0, (void *)A(a1), a[2], a[3]);
1482                         break;
1483                 case SYS_SENDTO:
1484                         ret = sys_sendto(a0, a1, a[2], a[3], a[4], a[5]);
1485                         break;
1486                 case SYS_RECV:
1487                         ret = sys_recv(a0, (void *)A(a1), a[2], a[3]);
1488                         break;
1489                 case SYS_RECVFROM:
1490                         ret = sys_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
1491                         break;
1492                 case SYS_SHUTDOWN:
1493                         ret = sys_shutdown(a0,a1);
1494                         break;
1495                 case SYS_SETSOCKOPT:
1496                         ret = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]),
1497                                               a[4]);
1498                         break;
1499                 case SYS_GETSOCKOPT:
1500                         ret = sys_getsockopt(a0, a1, a[2], a[3], a[4]);
1501                         break;
1502                 case SYS_SENDMSG:
1503                         ret = sys32_sendmsg(a0, (struct msghdr32 *)A(a1),
1504                                              a[2]);
1505                         break;
1506                 case SYS_RECVMSG:
1507                         ret = sys32_recvmsg(a0, (struct msghdr32 *)A(a1),
1508                                              a[2]);
1509                         break;
1510                 default:
1511                         ret = EINVAL;
1512                         break;
1513         }
1514         return ret;
1515 }
1516
1517 /*
1518  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
1519  *
1520  * This is really horribly ugly.
1521  */
1522
1523 struct msgbuf32 { s32 mtype; char mtext[1]; };
1524
1525 struct ipc_perm32
1526 {
1527         key_t     key;
1528         __kernel_uid_t32  uid;
1529         __kernel_gid_t32  gid;
1530         __kernel_uid_t32  cuid;
1531         __kernel_gid_t32  cgid;
1532         __kernel_mode_t32 mode;
1533         unsigned short  seq;
1534 };
1535
1536 struct semid_ds32 {
1537         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
1538         __kernel_time_t32 sem_otime;              /* last semop time */
1539         __kernel_time_t32 sem_ctime;              /* last change time */
1540         u32 sem_base;              /* ptr to first semaphore in array */
1541         u32 sem_pending;          /* pending operations to be processed */
1542         u32 sem_pending_last;    /* last pending operation */
1543         u32 undo;                  /* undo requests on this array */
1544         unsigned short  sem_nsems;              /* no. of semaphores in array */
1545 };
1546
1547 struct msqid_ds32
1548 {
1549         struct ipc_perm32 msg_perm;
1550         u32 msg_first;
1551         u32 msg_last;
1552         __kernel_time_t32 msg_stime;
1553         __kernel_time_t32 msg_rtime;
1554         __kernel_time_t32 msg_ctime;
1555         u32 wwait;
1556         u32 rwait;
1557         unsigned short msg_cbytes;
1558         unsigned short msg_qnum;
1559         unsigned short msg_qbytes;
1560         __kernel_ipc_pid_t32 msg_lspid;
1561         __kernel_ipc_pid_t32 msg_lrpid;
1562 };
1563
1564 struct shmid_ds32 {
1565         struct ipc_perm32       shm_perm;
1566         int                     shm_segsz;
1567         __kernel_time_t32       shm_atime;
1568         __kernel_time_t32       shm_dtime;
1569         __kernel_time_t32       shm_ctime;
1570         __kernel_ipc_pid_t32    shm_cpid;
1571         __kernel_ipc_pid_t32    shm_lpid;
1572         unsigned short          shm_nattch;
1573 };
1574
1575 #define IPCOP_MASK(__x) (1UL << (__x))
1576
1577 static int
1578 do_sys32_semctl(int first, int second, int third, void *uptr)
1579 {
1580         union semun fourth;
1581         u32 pad;
1582         int err = 0, err2;
1583         struct semid64_ds s;
1584         struct semid_ds32 *usp;
1585         mm_segment_t old_fs;
1586
1587         if (!uptr)
1588                 return -EINVAL;
1589         if (get_user(pad, (u32 *)uptr))
1590                 return -EFAULT;
1591         if(third == SETVAL)
1592                 fourth.val = (int)pad;
1593         else
1594                 fourth.__pad = (void *)A(pad);
1595         switch (third) {
1596
1597         case IPC_INFO:
1598         case IPC_RMID:
1599         case IPC_SET:
1600         case SEM_INFO:
1601         case GETVAL:
1602         case GETPID:
1603         case GETNCNT:
1604         case GETZCNT:
1605         case GETALL:
1606         case SETVAL:
1607         case SETALL:
1608                 err = sys_semctl (first, second, third, fourth);
1609                 break;
1610
1611         case IPC_STAT:
1612         case SEM_STAT:
1613                 usp = (struct semid_ds32 *)A(pad);
1614                 fourth.__pad = &s;
1615                 old_fs = get_fs ();
1616                 set_fs (KERNEL_DS);
1617                 err = sys_semctl (first, second, third, fourth);
1618                 set_fs (old_fs);
1619                 err2 = put_user(s.sem_perm.key, &usp->sem_perm.key);
1620                 err2 |= __put_user(s.sem_perm.uid, &usp->sem_perm.uid);
1621                 err2 |= __put_user(s.sem_perm.gid, &usp->sem_perm.gid);
1622                 err2 |= __put_user(s.sem_perm.cuid,
1623                                    &usp->sem_perm.cuid);
1624                 err2 |= __put_user (s.sem_perm.cgid,
1625                                     &usp->sem_perm.cgid);
1626                 err2 |= __put_user (s.sem_perm.mode,
1627                                     &usp->sem_perm.mode);
1628                 err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
1629                 err2 |= __put_user (s.sem_otime, &usp->sem_otime);
1630                 err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
1631                 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
1632                 if (err2)
1633                         err = -EFAULT;
1634                 break;
1635
1636         }
1637
1638         return err;
1639 }
1640
1641 static int
1642 do_sys32_msgsnd (int first, int second, int third, void *uptr)
1643 {
1644         struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf)
1645                                     + 4, GFP_USER);
1646         struct msgbuf32 *up = (struct msgbuf32 *)uptr;
1647         mm_segment_t old_fs;
1648         int err;
1649
1650         if (!p)
1651                 return -ENOMEM;
1652         err = get_user (p->mtype, &up->mtype);
1653         err |= __copy_from_user (p->mtext, &up->mtext, second);
1654         if (err)
1655                 goto out;
1656         old_fs = get_fs ();
1657         set_fs (KERNEL_DS);
1658         err = sys_msgsnd (first, p, second, third);
1659         set_fs (old_fs);
1660 out:
1661         kfree (p);
1662         return err;
1663 }
1664
1665 static int
1666 do_sys32_msgrcv (int first, int second, int msgtyp, int third,
1667                  int version, void *uptr)
1668 {
1669         struct msgbuf32 *up;
1670         struct msgbuf *p;
1671         mm_segment_t old_fs;
1672         int err;
1673
1674         if (!version) {
1675                 struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
1676                 struct ipc_kludge ipck;
1677
1678                 err = -EINVAL;
1679                 if (!uptr)
1680                         goto out;
1681                 err = -EFAULT;
1682                 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
1683                         goto out;
1684                 uptr = (void *)A(ipck.msgp);
1685                 msgtyp = ipck.msgtyp;
1686         }
1687         err = -ENOMEM;
1688         p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
1689         if (!p)
1690                 goto out;
1691         old_fs = get_fs ();
1692         set_fs (KERNEL_DS);
1693         err = sys_msgrcv (first, p, second + 4, msgtyp, third);
1694         set_fs (old_fs);
1695         if (err < 0)
1696                 goto free_then_out;
1697         up = (struct msgbuf32 *)uptr;
1698         if (put_user (p->mtype, &up->mtype) ||
1699             __copy_to_user (&up->mtext, p->mtext, err))
1700                 err = -EFAULT;
1701 free_then_out:
1702         kfree (p);
1703 out:
1704         return err;
1705 }
1706
1707 static int
1708 do_sys32_msgctl (int first, int second, void *uptr)
1709 {
1710         int err = -EINVAL, err2;
1711         struct msqid_ds m;
1712         struct msqid64_ds m64;
1713         struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
1714         mm_segment_t old_fs;
1715
1716         switch (second) {
1717
1718         case IPC_INFO:
1719         case IPC_RMID:
1720         case MSG_INFO:
1721                 err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
1722                 break;
1723
1724         case IPC_SET:
1725                 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
1726                 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
1727                 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
1728                 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
1729                 if (err)
1730                         break;
1731                 old_fs = get_fs ();
1732                 set_fs (KERNEL_DS);
1733                 err = sys_msgctl (first, second, &m);
1734                 set_fs (old_fs);
1735                 break;
1736
1737         case IPC_STAT:
1738         case MSG_STAT:
1739                 old_fs = get_fs ();
1740                 set_fs (KERNEL_DS);
1741                 err = sys_msgctl (first, second, (void *) &m64);
1742                 set_fs (old_fs);
1743                 err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);
1744                 err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);
1745                 err2 |= __put_user(m64.msg_perm.gid, &up->msg_perm.gid);
1746                 err2 |= __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid);
1747                 err2 |= __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid);
1748                 err2 |= __put_user(m64.msg_perm.mode, &up->msg_perm.mode);
1749                 err2 |= __put_user(m64.msg_perm.seq, &up->msg_perm.seq);
1750                 err2 |= __put_user(m64.msg_stime, &up->msg_stime);
1751                 err2 |= __put_user(m64.msg_rtime, &up->msg_rtime);
1752                 err2 |= __put_user(m64.msg_ctime, &up->msg_ctime);
1753                 err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes);
1754                 err2 |= __put_user(m64.msg_qnum, &up->msg_qnum);
1755                 err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes);
1756                 err2 |= __put_user(m64.msg_lspid, &up->msg_lspid);
1757                 err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid);
1758                 if (err2)
1759                         err = -EFAULT;
1760                 break;
1761
1762         }
1763
1764         return err;
1765 }
1766
1767 static int
1768 do_sys32_shmat (int first, int second, int third, int version, void *uptr)
1769 {
1770         unsigned long raddr;
1771         u32 *uaddr = (u32 *)A((u32)third);
1772         int err;
1773
1774         if (version == 1)
1775                 return -EINVAL;
1776         err = sys_shmat (first, uptr, second, &raddr);
1777         if (err)
1778                 return err;
1779         return put_user(raddr, uaddr);
1780 }
1781
1782 static int
1783 do_sys32_shmctl (int first, int second, void *uptr)
1784 {
1785         int err = -EFAULT, err2;
1786         struct shmid_ds s;
1787         struct shmid64_ds s64;
1788         struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
1789         mm_segment_t old_fs;
1790         struct shm_info32 {
1791                 int used_ids;
1792                 u32 shm_tot, shm_rss, shm_swp;
1793                 u32 swap_attempts, swap_successes;
1794         } *uip = (struct shm_info32 *)uptr;
1795         struct shm_info si;
1796
1797         switch (second) {
1798
1799         case IPC_INFO:
1800         case IPC_RMID:
1801         case SHM_LOCK:
1802         case SHM_UNLOCK:
1803                 err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
1804                 break;
1805         case IPC_SET:
1806                 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
1807                 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
1808                 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
1809                 if (err)
1810                         break;
1811                 old_fs = get_fs ();
1812                 set_fs (KERNEL_DS);
1813                 err = sys_shmctl (first, second, &s);
1814                 set_fs (old_fs);
1815                 break;
1816
1817         case IPC_STAT:
1818         case SHM_STAT:
1819                 old_fs = get_fs ();
1820                 set_fs (KERNEL_DS);
1821                 err = sys_shmctl (first, second, (void *) &s64);
1822                 set_fs (old_fs);
1823                 if (err < 0)
1824                         break;
1825                 err2 = put_user (s64.shm_perm.key, &up->shm_perm.key);
1826                 err2 |= __put_user (s64.shm_perm.uid, &up->shm_perm.uid);
1827                 err2 |= __put_user (s64.shm_perm.gid, &up->shm_perm.gid);
1828                 err2 |= __put_user (s64.shm_perm.cuid,
1829                                     &up->shm_perm.cuid);
1830                 err2 |= __put_user (s64.shm_perm.cgid,
1831                                     &up->shm_perm.cgid);
1832                 err2 |= __put_user (s64.shm_perm.mode,
1833                                     &up->shm_perm.mode);
1834                 err2 |= __put_user (s64.shm_perm.seq, &up->shm_perm.seq);
1835                 err2 |= __put_user (s64.shm_atime, &up->shm_atime);
1836                 err2 |= __put_user (s64.shm_dtime, &up->shm_dtime);
1837                 err2 |= __put_user (s64.shm_ctime, &up->shm_ctime);
1838                 err2 |= __put_user (s64.shm_segsz, &up->shm_segsz);
1839                 err2 |= __put_user (s64.shm_nattch, &up->shm_nattch);
1840                 err2 |= __put_user (s64.shm_cpid, &up->shm_cpid);
1841                 err2 |= __put_user (s64.shm_lpid, &up->shm_lpid);
1842                 if (err2)
1843                         err = -EFAULT;
1844                 break;
1845
1846         case SHM_INFO:
1847                 old_fs = get_fs ();
1848                 set_fs (KERNEL_DS);
1849                 err = sys_shmctl (first, second, (void *)&si);
1850                 set_fs (old_fs);
1851                 if (err < 0)
1852                         break;
1853                 err2 = put_user (si.used_ids, &uip->used_ids);
1854                 err2 |= __put_user (si.shm_tot, &uip->shm_tot);
1855                 err2 |= __put_user (si.shm_rss, &uip->shm_rss);
1856                 err2 |= __put_user (si.shm_swp, &uip->shm_swp);
1857                 err2 |= __put_user (si.swap_attempts,
1858                                     &uip->swap_attempts);
1859                 err2 |= __put_user (si.swap_successes,
1860                                     &uip->swap_successes);
1861                 if (err2)
1862                         err = -EFAULT;
1863                 break;
1864
1865         }
1866         return err;
1867 }
1868
1869 asmlinkage long
1870 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
1871 {
1872         int version, err;
1873
1874         version = call >> 16; /* hack for backward compatibility */
1875         call &= 0xffff;
1876
1877         switch (call) {
1878
1879         case SEMOP:
1880                 /* struct sembuf is the same on 32 and 64bit :)) */
1881                 err = sys_semop (first, (struct sembuf *)AA(ptr),
1882                                  second);
1883                 break;
1884         case SEMGET:
1885                 err = sys_semget (first, second, third);
1886                 break;
1887         case SEMCTL:
1888                 err = do_sys32_semctl (first, second, third,
1889                                        (void *)AA(ptr));
1890                 break;
1891
1892         case MSGSND:
1893                 err = do_sys32_msgsnd (first, second, third,
1894                                        (void *)AA(ptr));
1895                 break;
1896         case MSGRCV:
1897                 err = do_sys32_msgrcv (first, second, fifth, third,
1898                                        version, (void *)AA(ptr));
1899                 break;
1900         case MSGGET:
1901                 err = sys_msgget ((key_t) first, second);
1902                 break;
1903         case MSGCTL:
1904                 err = do_sys32_msgctl (first, second, (void *)AA(ptr));
1905                 break;
1906
1907         case SHMAT:
1908                 err = do_sys32_shmat (first, second, third, version, (void *)AA(ptr));
1909                 break;
1910         case SHMDT:
1911                 err = sys_shmdt ((char *)AA(ptr));
1912                 break;
1913         case SHMGET:
1914                 err = sys_shmget (first, second, third);
1915                 break;
1916         case SHMCTL:
1917                 err = do_sys32_shmctl (first, second, (void *)AA(ptr));
1918                 break;
1919         default:
1920                 err = -EINVAL;
1921                 break;
1922         }
1923
1924         return err;
1925 }
1926
1927 /*
1928  * sys_time() can be implemented in user-level using
1929  * sys_gettimeofday().  IA64 did this but i386 Linux did not
1930  * so we have to implement this system call here.
1931  */
1932 asmlinkage long sys32_time(int * tloc)
1933 {
1934         int i;
1935
1936         /* SMP: This is fairly trivial. We grab CURRENT_TIME and
1937            stuff it to user space. No side effects */
1938         i = CURRENT_TIME;
1939         if (tloc) {
1940                 if (put_user(i,tloc))
1941                         i = -EFAULT;
1942         }
1943         return i;
1944 }
1945
1946 struct rusage32 {
1947         struct timeval32 ru_utime;
1948         struct timeval32 ru_stime;
1949         int    ru_maxrss;
1950         int    ru_ixrss;
1951         int    ru_idrss;
1952         int    ru_isrss;
1953         int    ru_minflt;
1954         int    ru_majflt;
1955         int    ru_nswap;
1956         int    ru_inblock;
1957         int    ru_oublock;
1958         int    ru_msgsnd;
1959         int    ru_msgrcv;
1960         int    ru_nsignals;
1961         int    ru_nvcsw;
1962         int    ru_nivcsw;
1963 };
1964
1965 static int
1966 put_rusage (struct rusage32 *ru, struct rusage *r)
1967 {
1968         int err;
1969
1970         err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1971         err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1972         err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1973         err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1974         err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1975         err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1976         err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1977         err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1978         err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1979         err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1980         err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1981         err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1982         err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1983         err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1984         err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1985         err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1986         err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1987         err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1988         return err;
1989 }
1990
1991 asmlinkage long
1992 sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
1993             struct rusage32 *ru)
1994 {
1995         if (!ru)
1996                 return sys_wait4(pid, stat_addr, options, NULL);
1997         else {
1998                 struct rusage r;
1999                 int ret;
2000                 unsigned int status;
2001                 mm_segment_t old_fs = get_fs();
2002
2003                 set_fs (KERNEL_DS);
2004                 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
2005                 set_fs (old_fs);
2006                 if (put_rusage (ru, &r)) return -EFAULT;
2007                 if (stat_addr && put_user (status, stat_addr))
2008                         return -EFAULT;
2009                 return ret;
2010         }
2011 }
2012
2013 asmlinkage long
2014 sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
2015 {
2016         return sys32_wait4(pid, stat_addr, options, NULL);
2017 }
2018
2019
2020 extern asmlinkage long
2021 sys_getrusage(int who, struct rusage *ru);
2022
2023 asmlinkage long
2024 sys32_getrusage(int who, struct rusage32 *ru)
2025 {
2026         struct rusage r;
2027         int ret;
2028         mm_segment_t old_fs = get_fs();
2029
2030         set_fs (KERNEL_DS);
2031         ret = sys_getrusage(who, &r);
2032         set_fs (old_fs);
2033         if (put_rusage (ru, &r)) return -EFAULT;
2034         return ret;
2035 }
2036
2037 struct tms32 {
2038         __kernel_clock_t32 tms_utime;
2039         __kernel_clock_t32 tms_stime;
2040         __kernel_clock_t32 tms_cutime;
2041         __kernel_clock_t32 tms_cstime;
2042 };
2043
2044 extern asmlinkage long sys_times(struct tms * tbuf);
2045
2046 asmlinkage long
2047 sys32_times(struct tms32 *tbuf)
2048 {
2049         struct tms t;
2050         long ret;
2051         mm_segment_t old_fs = get_fs ();
2052         int err;
2053
2054         set_fs (KERNEL_DS);
2055         ret = sys_times(tbuf ? &t : NULL);
2056         set_fs (old_fs);
2057         if (tbuf) {
2058                 err = put_user (IA32_TICK(t.tms_utime), &tbuf->tms_utime);
2059                 err |= __put_user (IA32_TICK(t.tms_stime), &tbuf->tms_stime);
2060                 err |= __put_user (IA32_TICK(t.tms_cutime), &tbuf->tms_cutime);
2061                 err |= __put_user (IA32_TICK(t.tms_cstime), &tbuf->tms_cstime);
2062                 if (err)
2063                         ret = -EFAULT;
2064         }
2065         return IA32_TICK(ret);
2066 }
2067
2068 unsigned int
2069 ia32_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int *val)
2070 {
2071         size_t copied;
2072         unsigned int ret;
2073
2074         copied = access_process_vm(child, addr, val, sizeof(*val), 0);
2075         return(copied != sizeof(ret) ? -EIO : 0);
2076 }
2077
2078 unsigned int
2079 ia32_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int val)
2080 {
2081
2082         if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
2083                 return -EIO;
2084         return 0;
2085 }
2086
2087 /*
2088  *  The order in which registers are stored in the ptrace regs structure
2089  */
2090 #define PT_EBX  0
2091 #define PT_ECX  1
2092 #define PT_EDX  2
2093 #define PT_ESI  3
2094 #define PT_EDI  4
2095 #define PT_EBP  5
2096 #define PT_EAX  6
2097 #define PT_DS   7
2098 #define PT_ES   8
2099 #define PT_FS   9
2100 #define PT_GS   10
2101 #define PT_ORIG_EAX 11
2102 #define PT_EIP  12
2103 #define PT_CS   13
2104 #define PT_EFL  14
2105 #define PT_UESP 15
2106 #define PT_SS   16
2107
2108 unsigned int
2109 getreg(struct task_struct *child, int regno)
2110 {
2111         struct pt_regs *child_regs;
2112
2113         child_regs = ia64_task_regs(child);
2114         switch (regno / sizeof(int)) {
2115
2116         case PT_EBX:
2117                 return(child_regs->r11);
2118         case PT_ECX:
2119                 return(child_regs->r9);
2120         case PT_EDX:
2121                 return(child_regs->r10);
2122         case PT_ESI:
2123                 return(child_regs->r14);
2124         case PT_EDI:
2125                 return(child_regs->r15);
2126         case PT_EBP:
2127                 return(child_regs->r13);
2128         case PT_EAX:
2129         case PT_ORIG_EAX:
2130                 return(child_regs->r8);
2131         case PT_EIP:
2132                 return(child_regs->cr_iip);
2133         case PT_UESP:
2134                 return(child_regs->r12);
2135         case PT_EFL:
2136                 return(child->thread.eflag);
2137         case PT_DS:
2138         case PT_ES:
2139         case PT_FS:
2140         case PT_GS:
2141         case PT_SS:
2142                 return((unsigned int)__USER_DS);
2143         case PT_CS:
2144                 return((unsigned int)__USER_CS);
2145         default:
2146                 printk(KERN_ERR "getregs:unknown register %d\n", regno);
2147                 break;
2148
2149         }
2150         return(0);
2151 }
2152
2153 void
2154 putreg(struct task_struct *child, int regno, unsigned int value)
2155 {
2156         struct pt_regs *child_regs;
2157
2158         child_regs = ia64_task_regs(child);
2159         switch (regno / sizeof(int)) {
2160
2161         case PT_EBX:
2162                 child_regs->r11 = value;
2163                 break;
2164         case PT_ECX:
2165                 child_regs->r9 = value;
2166                 break;
2167         case PT_EDX:
2168                 child_regs->r10 = value;
2169                 break;
2170         case PT_ESI:
2171                 child_regs->r14 = value;
2172                 break;
2173         case PT_EDI:
2174                 child_regs->r15 = value;
2175                 break;
2176         case PT_EBP:
2177                 child_regs->r13 = value;
2178                 break;
2179         case PT_EAX:
2180         case PT_ORIG_EAX:
2181                 child_regs->r8 = value;
2182                 break;
2183         case PT_EIP:
2184                 child_regs->cr_iip = value;
2185                 break;
2186         case PT_UESP:
2187                 child_regs->r12 = value;
2188                 break;
2189         case PT_EFL:
2190                 child->thread.eflag = value;
2191                 break;
2192         case PT_DS:
2193         case PT_ES:
2194         case PT_FS:
2195         case PT_GS:
2196         case PT_SS:
2197                 if (value != __USER_DS)
2198                         printk(KERN_ERR "setregs:try to set invalid segment register %d = %x\n",
2199                                regno, value);
2200                 break;
2201         case PT_CS:
2202                 if (value != __USER_CS)
2203                         printk(KERN_ERR "setregs:try to set invalid segment register %d = %x\n",
2204                                regno, value);
2205                 break;
2206         default:
2207                 printk(KERN_ERR "getregs:unknown register %d\n", regno);
2208                 break;
2209
2210         }
2211 }
2212
2213 static inline void
2214 ia32f2ia64f(void *dst, void *src)
2215 {
2216
2217         __asm__ ("ldfe f6=[%1] ;;\n\t"
2218                  "stf.spill [%0]=f6"
2219                 :
2220                 : "r"(dst), "r"(src));
2221         return;
2222 }
2223
2224 static inline void
2225 ia64f2ia32f(void *dst, void *src)
2226 {
2227
2228         __asm__ ("ldf.fill f6=[%1] ;;\n\t"
2229                  "stfe [%0]=f6"
2230                 :
2231                 : "r"(dst),  "r"(src));
2232         return;
2233 }
2234
2235 void
2236 put_fpreg(int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp, int tos)
2237 {
2238         struct _fpreg_ia32 *f;
2239         char buf[32];
2240
2241         f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
2242         if ((regno += tos) >= 8)
2243                 regno -= 8;
2244         switch (regno) {
2245
2246         case 0:
2247                 ia64f2ia32f(f, &ptp->f8);
2248                 break;
2249         case 1:
2250                 ia64f2ia32f(f, &ptp->f9);
2251                 break;
2252         case 2:
2253         case 3:
2254         case 4:
2255         case 5:
2256         case 6:
2257         case 7:
2258                 ia64f2ia32f(f, &swp->f10 + (regno - 2));
2259                 break;
2260
2261         }
2262         __copy_to_user(reg, f, sizeof(*reg));
2263 }
2264
2265 void
2266 get_fpreg(int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp, int tos)
2267 {
2268
2269         if ((regno += tos) >= 8)
2270                 regno -= 8;
2271         switch (regno) {
2272
2273         case 0:
2274                 __copy_from_user(&ptp->f8, reg, sizeof(*reg));
2275                 break;
2276         case 1:
2277                 __copy_from_user(&ptp->f9, reg, sizeof(*reg));
2278                 break;
2279         case 2:
2280         case 3:
2281         case 4:
2282         case 5:
2283         case 6:
2284         case 7:
2285                 __copy_from_user(&swp->f10 + (regno - 2), reg, sizeof(*reg));
2286                 break;
2287
2288         }
2289         return;
2290 }
2291
2292 int
2293 save_ia32_fpstate(struct task_struct *tsk, struct _fpstate_ia32 *save)
2294 {
2295         struct switch_stack *swp;
2296         struct pt_regs *ptp;
2297         int i, tos;
2298
2299         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
2300                 return(-EIO);
2301         __put_user(tsk->thread.fcr, &save->cw);
2302         __put_user(tsk->thread.fsr, &save->sw);
2303         __put_user(tsk->thread.fsr >> 32, &save->tag);
2304         __put_user(tsk->thread.fir, &save->ipoff);
2305         __put_user(__USER_CS, &save->cssel);
2306         __put_user(tsk->thread.fdr, &save->dataoff);
2307         __put_user(__USER_DS, &save->datasel);
2308         /*
2309          *  Stack frames start with 16-bytes of temp space
2310          */
2311         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
2312         ptp = ia64_task_regs(tsk);
2313         tos = (tsk->thread.fsr >> 11) & 3;
2314         for (i = 0; i < 8; i++)
2315                 put_fpreg(i, &save->_st[i], ptp, swp, tos);
2316         return(0);
2317 }
2318
2319 int
2320 restore_ia32_fpstate(struct task_struct *tsk, struct _fpstate_ia32 *save)
2321 {
2322         struct switch_stack *swp;
2323         struct pt_regs *ptp;
2324         int i, tos, ret;
2325         int fsrlo, fsrhi;
2326
2327         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
2328                 return(-EIO);
2329         ret = __get_user(tsk->thread.fcr, (unsigned int *)&save->cw);
2330         ret |= __get_user(fsrlo, (unsigned int *)&save->sw);
2331         ret |= __get_user(fsrhi, (unsigned int *)&save->tag);
2332         tsk->thread.fsr = ((long)fsrhi << 32) | (long)fsrlo;
2333         ret |= __get_user(tsk->thread.fir, (unsigned int *)&save->ipoff);
2334         ret |= __get_user(tsk->thread.fdr, (unsigned int *)&save->dataoff);
2335         /*
2336          *  Stack frames start with 16-bytes of temp space
2337          */
2338         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
2339         ptp = ia64_task_regs(tsk);
2340         tos = (tsk->thread.fsr >> 11) & 3;
2341         for (i = 0; i < 8; i++)
2342                 get_fpreg(i, &save->_st[i], ptp, swp, tos);
2343         return(ret ? -EFAULT : 0);
2344 }
2345
2346 asmlinkage long sys_ptrace(long, pid_t, unsigned long, unsigned long, long, long, long, long, long);
2347
2348 /*
2349  *  Note that the IA32 version of `ptrace' calls the IA64 routine for
2350  *    many of the requests.  This will only work for requests that do
2351  *    not need access to the calling processes `pt_regs' which is located
2352  *    at the address of `stack'.  Once we call the IA64 `sys_ptrace' then
2353  *    the address of `stack' will not be the address of the `pt_regs'.
2354  */
2355 asmlinkage long
2356 sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
2357               long arg4, long arg5, long arg6, long arg7, long stack)
2358 {
2359         struct pt_regs *regs = (struct pt_regs *) &stack;
2360         struct task_struct *child;
2361         long i, ret;
2362         unsigned int value;
2363
2364         lock_kernel();
2365         if (request == PTRACE_TRACEME) {
2366                 ret = sys_ptrace(request, pid, addr, data,
2367                                 arg4, arg5, arg6, arg7, stack);
2368                 goto out;
2369         }
2370
2371         ret = -ESRCH;
2372         read_lock(&tasklist_lock);
2373         child = find_task_by_pid(pid);
2374         read_unlock(&tasklist_lock);
2375         if (!child)
2376                 goto out;
2377         ret = -EPERM;
2378         if (pid == 1)           /* no messing around with init! */
2379                 goto out;
2380
2381         if (request == PTRACE_ATTACH) {
2382                 ret = sys_ptrace(request, pid, addr, data,
2383                                 arg4, arg5, arg6, arg7, stack);
2384                 goto out;
2385         }
2386         ret = -ESRCH;
2387         if (!(child->ptrace & PT_PTRACED))
2388                 goto out;
2389         if (child->state != TASK_STOPPED) {
2390                 if (request != PTRACE_KILL)
2391                         goto out;
2392         }
2393         if (child->p_pptr != current)
2394                 goto out;
2395
2396         switch (request) {
2397               case PTRACE_PEEKTEXT:
2398               case PTRACE_PEEKDATA:     /* read word at location addr */
2399                 ret = ia32_peek(regs, child, addr, &value);
2400                 if (ret == 0)
2401                         ret = put_user(value, (unsigned int *)A(data));
2402                 else
2403                         ret = -EIO;
2404                 goto out;
2405
2406               case PTRACE_POKETEXT:
2407               case PTRACE_POKEDATA:     /* write the word at location addr */
2408                 ret = ia32_poke(regs, child, addr, (unsigned int)data);
2409                 goto out;
2410
2411               case PTRACE_PEEKUSR:      /* read word at addr in USER area */
2412                 ret = 0;
2413                 break;
2414
2415               case PTRACE_POKEUSR:      /* write word at addr in USER area */
2416                 ret = 0;
2417                 break;
2418
2419               case IA32_PTRACE_GETREGS:
2420                 if (!access_ok(VERIFY_WRITE, (int *) A(data), 17*sizeof(int))) {
2421                         ret = -EIO;
2422                         break;
2423                 }
2424                 for ( i = 0; i < 17*sizeof(int); i += sizeof(int) ) {
2425                         __put_user(getreg(child, i), (unsigned int *) A(data));
2426                         data += sizeof(int);
2427                 }
2428                 ret = 0;
2429                 break;
2430
2431               case IA32_PTRACE_SETREGS:
2432               {
2433                 unsigned int tmp;
2434                 if (!access_ok(VERIFY_READ, (int *) A(data), 17*sizeof(int))) {
2435                         ret = -EIO;
2436                         break;
2437                 }
2438                 for ( i = 0; i < 17*sizeof(int); i += sizeof(int) ) {
2439                         __get_user(tmp, (unsigned int *) A(data));
2440                         putreg(child, i, tmp);
2441                         data += sizeof(int);
2442                 }
2443                 ret = 0;
2444                 break;
2445               }
2446
2447               case IA32_PTRACE_GETFPREGS:
2448                 ret = save_ia32_fpstate(child, (struct _fpstate_ia32 *) A(data));
2449                 break;
2450
2451               case IA32_PTRACE_SETFPREGS:
2452                 ret = restore_ia32_fpstate(child, (struct _fpstate_ia32 *) A(data));
2453                 break;
2454
2455               case PTRACE_SYSCALL:      /* continue, stop after next syscall */
2456               case PTRACE_CONT:         /* restart after signal. */
2457               case PTRACE_KILL:
2458               case PTRACE_SINGLESTEP:   /* execute chile for one instruction */
2459               case PTRACE_DETACH:       /* detach a process */
2460                 unlock_kernel();
2461                 ret = sys_ptrace(request, pid, addr, data,
2462                                 arg4, arg5, arg6, arg7, stack);
2463                 return(ret);
2464
2465               default:
2466                 ret = -EIO;
2467                 break;
2468
2469         }
2470   out:
2471         unlock_kernel();
2472         return ret;
2473 }
2474
2475 static inline int
2476 get_flock32(struct flock *kfl, struct flock32 *ufl)
2477 {
2478         int err;
2479
2480         err = get_user(kfl->l_type, &ufl->l_type);
2481         err |= __get_user(kfl->l_whence, &ufl->l_whence);
2482         err |= __get_user(kfl->l_start, &ufl->l_start);
2483         err |= __get_user(kfl->l_len, &ufl->l_len);
2484         err |= __get_user(kfl->l_pid, &ufl->l_pid);
2485         return err;
2486 }
2487
2488 static inline int
2489 put_flock32(struct flock *kfl, struct flock32 *ufl)
2490 {
2491         int err;
2492
2493         err = __put_user(kfl->l_type, &ufl->l_type);
2494         err |= __put_user(kfl->l_whence, &ufl->l_whence);
2495         err |= __put_user(kfl->l_start, &ufl->l_start);
2496         err |= __put_user(kfl->l_len, &ufl->l_len);
2497         err |= __put_user(kfl->l_pid, &ufl->l_pid);
2498         return err;
2499 }
2500
2501 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd,
2502                                  unsigned long arg);
2503
2504 asmlinkage long
2505 sys32_fcntl(unsigned int fd, unsigned int cmd, int arg)
2506 {
2507         struct flock f;
2508         mm_segment_t old_fs;
2509         long ret;
2510
2511         switch (cmd) {
2512         case F_GETLK:
2513         case F_SETLK:
2514         case F_SETLKW:
2515                 if(get_flock32(&f, (struct flock32 *)((long)arg)))
2516                         return -EFAULT;
2517                 old_fs = get_fs();
2518                 set_fs(KERNEL_DS);
2519                 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
2520                 set_fs(old_fs);
2521                 if(cmd == F_GETLK && put_flock32(&f, (struct flock32 *)((long)arg)))
2522                         return -EFAULT;
2523                 return ret;
2524         default:
2525                 /*
2526                  *  `sys_fcntl' lies about arg, for the F_SETOWN
2527                  *  sub-function arg can have a negative value.
2528                  */
2529                 return sys_fcntl(fd, cmd, (unsigned long)((long)arg));
2530         }
2531 }
2532
2533 asmlinkage long
2534 sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
2535 {
2536         struct k_sigaction new_ka, old_ka;
2537         int ret;
2538
2539         if (act) {
2540                 old_sigset32_t mask;
2541
2542                 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2543                 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2544                 ret |= __get_user(mask, &act->sa_mask);
2545                 if (ret)
2546                         return ret;
2547                 siginitset(&new_ka.sa.sa_mask, mask);
2548         }
2549
2550         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2551
2552         if (!ret && oact) {
2553                 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2554                 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2555                 ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
2556         }
2557
2558         return ret;
2559 }
2560
2561 asmlinkage long sys_ni_syscall(void);
2562
2563 asmlinkage long
2564 sys32_ni_syscall(int dummy0, int dummy1, int dummy2, int dummy3,
2565         int dummy4, int dummy5, int dummy6, int dummy7, int stack)
2566 {
2567         struct pt_regs *regs = (struct pt_regs *)&stack;
2568
2569         printk(KERN_WARNING "IA32 syscall #%d issued, maybe we should implement it\n",
2570                (int)regs->r1);
2571         return(sys_ni_syscall());
2572 }
2573
2574 /*
2575  *  The IA64 maps 4 I/O ports for each 4K page
2576  */
2577 #define IOLEN   ((65536 / 4) * 4096)
2578
2579 asmlinkage long
2580 sys_iopl (int level)
2581 {
2582         extern unsigned long ia64_iobase;
2583         int fd;
2584         struct file * file;
2585         unsigned int old;
2586         unsigned long addr;
2587         mm_segment_t old_fs = get_fs ();
2588
2589         if (level != 3)
2590                 return(-EINVAL);
2591         /* Trying to gain more privileges? */
2592         asm volatile ("mov %0=ar.eflag ;;" : "=r"(old));
2593         if (level > ((old >> 12) & 3)) {
2594                 if (!capable(CAP_SYS_RAWIO))
2595                         return -EPERM;
2596         }
2597         set_fs(KERNEL_DS);
2598         fd = sys_open("/dev/mem", O_SYNC | O_RDWR, 0);
2599         set_fs(old_fs);
2600         if (fd < 0)
2601                 return fd;
2602         file = fget(fd);
2603         if (file == NULL) {
2604                 sys_close(fd);
2605                 return(-EFAULT);
2606         }
2607
2608         down_write(&current->mm->mmap_sem);
2609         addr = do_mmap_pgoff(file, IA32_IOBASE,
2610                              IOLEN, PROT_READ|PROT_WRITE, MAP_SHARED,
2611                              (ia64_iobase & ~PAGE_OFFSET) >> PAGE_SHIFT);
2612         up_write(&current->mm->mmap_sem);
2613
2614         if (addr >= 0) {
2615                 ia64_set_kr(IA64_KR_IO_BASE, addr);
2616                 old = (old & ~0x3000) | (level << 12);
2617                 __asm__ __volatile__("mov ar.eflag=%0 ;;" :: "r"(old));
2618         }
2619
2620         fput(file);
2621         sys_close(fd);
2622         return 0;
2623 }
2624
2625 asmlinkage long
2626 sys_ioperm (unsigned int from, unsigned int num, int on)
2627 {
2628
2629         /*
2630          *  Since IA64 doesn't have permission bits we'd have to go to
2631          *    a lot of trouble to simulate them in software.  There's
2632          *    no point, only trusted programs can make this call so we'll
2633          *    just turn it into an iopl call and let the process have
2634          *    access to all I/O ports.
2635          *
2636          * XXX proper ioperm() support should be emulated by
2637          *      manipulating the page protections...
2638          */
2639         return sys_iopl(3);
2640 }
2641
2642 typedef struct {
2643         unsigned int    ss_sp;
2644         unsigned int    ss_flags;
2645         unsigned int    ss_size;
2646 } ia32_stack_t;
2647
2648 asmlinkage long
2649 sys32_sigaltstack (const ia32_stack_t *uss32, ia32_stack_t *uoss32,
2650 long arg2, long arg3, long arg4,
2651 long arg5, long arg6, long arg7,
2652 long stack)
2653 {
2654         struct pt_regs *pt = (struct pt_regs *) &stack;
2655         stack_t uss, uoss;
2656         ia32_stack_t buf32;
2657         int ret;
2658         mm_segment_t old_fs = get_fs();
2659
2660         if (uss32)
2661                 if (copy_from_user(&buf32, (void *)A(uss32), sizeof(ia32_stack_t)))
2662                         return(-EFAULT);
2663         uss.ss_sp = (void *) (long) buf32.ss_sp;
2664         uss.ss_flags = buf32.ss_flags;
2665         uss.ss_size = buf32.ss_size;
2666         set_fs(KERNEL_DS);
2667         ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12);
2668         set_fs(old_fs);
2669         if (ret < 0)
2670                 return(ret);
2671         if (uoss32) {
2672                 buf32.ss_sp = (long) uoss.ss_sp;
2673                 buf32.ss_flags = uoss.ss_flags;
2674                 buf32.ss_size = uoss.ss_size;
2675                 if (copy_to_user((void*)A(uoss32), &buf32, sizeof(ia32_stack_t)))
2676                         return(-EFAULT);
2677         }
2678         return(ret);
2679 }
2680
2681 asmlinkage int
2682 sys_pause (void)
2683 {
2684         current->state = TASK_INTERRUPTIBLE;
2685         schedule();
2686         return -ERESTARTNOHAND;
2687 }
2688
2689 asmlinkage long sys_msync(unsigned long start, size_t len, int flags);
2690
2691 asmlinkage int
2692 sys32_msync(unsigned int start, unsigned int len, int flags)
2693 {
2694         unsigned int addr;
2695
2696         if (OFFSET4K(start))
2697                 return -EINVAL;
2698         addr = start & PAGE_MASK;
2699         return(sys_msync(addr, len + (start - addr), flags));
2700 }
2701
2702 struct sysctl_ia32 {
2703         unsigned int    name;
2704         int             nlen;
2705         unsigned int    oldval;
2706         unsigned int    oldlenp;
2707         unsigned int    newval;
2708         unsigned int    newlen;
2709         unsigned int    __unused[4];
2710 };
2711
2712 extern asmlinkage long sys_sysctl(struct __sysctl_args *args);
2713
2714 asmlinkage long
2715 sys32_sysctl(struct sysctl_ia32 *args32)
2716 {
2717         struct sysctl_ia32 a32;
2718         mm_segment_t old_fs = get_fs ();
2719         void *oldvalp, *newvalp;
2720         size_t oldlen;
2721         int *namep;
2722         long ret;
2723
2724         if (copy_from_user(&a32, args32, sizeof (a32)))
2725                 return -EFAULT;
2726
2727         /*
2728          * We need to pre-validate these because we have to disable address checking
2729          * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
2730          * user specifying bad addresses here.  Well, since we're dealing with 32 bit
2731          * addresses, we KNOW that access_ok() will always succeed, so this is an
2732          * expensive NOP, but so what...
2733          */
2734         namep = (int *) A(a32.name);
2735         oldvalp = (void *) A(a32.oldval);
2736         newvalp = (void *) A(a32.newval);
2737
2738         if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp)))
2739             || !access_ok(VERIFY_WRITE, namep, 0)
2740             || !access_ok(VERIFY_WRITE, oldvalp, 0)
2741             || !access_ok(VERIFY_WRITE, newvalp, 0))
2742                 return -EFAULT;
2743
2744         set_fs(KERNEL_DS);
2745         lock_kernel();
2746         ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen);
2747         unlock_kernel();
2748         set_fs(old_fs);
2749
2750         if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp)))
2751                 return -EFAULT;
2752
2753         return ret;
2754 }
2755
2756 asmlinkage long
2757 sys32_newuname(struct new_utsname * name)
2758 {
2759         extern asmlinkage long sys_newuname(struct new_utsname * name);
2760         int ret = sys_newuname(name);
2761
2762         if (!ret)
2763                 if (copy_to_user(name->machine, "i686\0\0\0", 8))
2764                         ret = -EFAULT;
2765         return ret;
2766 }
2767
2768 extern asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
2769
2770 asmlinkage long
2771 sys32_getresuid (u16 *ruid, u16 *euid, u16 *suid)
2772 {
2773         uid_t a, b, c;
2774         int ret;
2775         mm_segment_t old_fs = get_fs();
2776
2777         set_fs(KERNEL_DS);
2778         ret = sys_getresuid(&a, &b, &c);
2779         set_fs(old_fs);
2780
2781         if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
2782                 return -EFAULT;
2783         return ret;
2784 }
2785
2786 extern asmlinkage long sys_getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid);
2787
2788 asmlinkage long
2789 sys32_getresgid(u16 *rgid, u16 *egid, u16 *sgid)
2790 {
2791         gid_t a, b, c;
2792         int ret;
2793         mm_segment_t old_fs = get_fs();
2794
2795         set_fs(KERNEL_DS);
2796         ret = sys_getresgid(&a, &b, &c);
2797         set_fs(old_fs);
2798
2799         if (!ret) {
2800                 ret  = put_user(a, rgid);
2801                 ret |= put_user(b, egid);
2802                 ret |= put_user(c, sgid);
2803         }
2804         return ret;
2805 }
2806
2807 int
2808 sys32_lseek (unsigned int fd, int offset, unsigned int whence)
2809 {
2810         extern off_t sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
2811
2812         /* Sign-extension of "offset" is important here... */
2813         return sys_lseek(fd, offset, whence);
2814 }
2815
2816 #ifdef  NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
2817
2818 /* In order to reduce some races, while at the same time doing addi