fedff08667a788e0c6dfbae5c67ed04c4c13fa13
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / ia32 / sys_ia32.c
1 /*
2  * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Derived from sys_sparc32.c.
3  *
4  * Copyright (C) 2000           VA Linux Co
5  * Copyright (C) 2000           Don Dugger <n0ano@valinux.com>
6  * Copyright (C) 1999           Arun Sharma <arun.sharma@intel.com>
7  * Copyright (C) 1997,1998      Jakub Jelinek (jj@sunsite.mff.cuni.cz)
8  * Copyright (C) 1997           David S. Miller (davem@caip.rutgers.edu)
9  * Copyright (C) 2000-2003 Hewlett-Packard Co
10  *      David Mosberger-Tang <davidm@hpl.hp.com>
11  *
12  * These routines maintain argument size conversion between 32bit and 64bit
13  * environment.
14  */
15
16 #include <linux/config.h>
17 #include <linux/kernel.h>
18 #include <linux/sysctl.h>
19 #include <linux/sched.h>
20 #include <linux/fs.h>
21 #include <linux/file.h>
22 #include <linux/signal.h>
23 #include <linux/resource.h>
24 #include <linux/times.h>
25 #include <linux/utsname.h>
26 #include <linux/timex.h>
27 #include <linux/smp.h>
28 #include <linux/smp_lock.h>
29 #include <linux/sem.h>
30 #include <linux/msg.h>
31 #include <linux/mm.h>
32 #include <linux/shm.h>
33 #include <linux/slab.h>
34 #include <linux/uio.h>
35 #include <linux/nfs_fs.h>
36 #include <linux/smb_fs.h>
37 #include <linux/smb_mount.h>
38 #include <linux/ncp_fs.h>
39 #include <linux/quota.h>
40 #include <linux/sunrpc/svc.h>
41 #include <linux/nfsd/nfsd.h>
42 #include <linux/nfsd/cache.h>
43 #include <linux/nfsd/xdr.h>
44 #include <linux/nfsd/syscall.h>
45 #include <linux/poll.h>
46 #include <linux/personality.h>
47 #include <linux/ptrace.h>
48 #include <linux/stat.h>
49 #include <linux/ipc.h>
50 #include <linux/compat.h>
51 #include <linux/vfs.h>
52
53 #include <asm/types.h>
54 #include <asm/uaccess.h>
55 #include <asm/semaphore.h>
56 #include <asm/ia32.h>
57
58 #include <net/scm.h>
59 #include <net/sock.h>
60
61 #define DEBUG   0
62
63 #if DEBUG
64 # define DBG(fmt...)    printk(KERN_DEBUG fmt)
65 #else
66 # define DBG(fmt...)
67 #endif
68
69 #define A(__x)          ((unsigned long)(__x))
70 #define AA(__x)         ((unsigned long)(__x))
71 #define ROUND_UP(x,a)   ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
72 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
73
74 #define OFFSET4K(a)             ((a) & 0xfff)
75 #define PAGE_START(addr)        ((addr) & PAGE_MASK)
76 #define PAGE_OFF(addr)          ((addr) & ~PAGE_MASK)
77
78 #define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid))
79 #define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid))
80
81 extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *);
82 extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long);
83 extern asmlinkage long sys_munmap (unsigned long, size_t);
84 extern unsigned long arch_get_unmapped_area (struct file *, unsigned long, unsigned long,
85                                              unsigned long, unsigned long);
86
87 /* forward declaration: */
88 asmlinkage long sys32_mprotect (unsigned int, unsigned int, int);
89 asmlinkage unsigned long sys_brk(unsigned long);
90
91 /*
92  * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
93  * while doing so.
94  */
95 /* XXX make per-mm: */
96 static DECLARE_MUTEX(ia32_mmap_sem);
97
98 static int
99 nargs (unsigned int arg, char **ap)
100 {
101         unsigned int addr;
102         int n, err;
103
104         if (!arg)
105                 return 0;
106
107         n = 0;
108         do {
109                 err = get_user(addr, (unsigned int *)A(arg));
110                 if (err)
111                         return err;
112                 if (ap)
113                         *ap++ = (char *) A(addr);
114                 arg += sizeof(unsigned int);
115                 n++;
116         } while (addr);
117         return n - 1;
118 }
119
120 asmlinkage long
121 sys32_execve (char *filename, unsigned int argv, unsigned int envp,
122               struct pt_regs *regs)
123 {
124         unsigned long old_map_base, old_task_size, tssd;
125         char **av, **ae;
126         int na, ne, len;
127         long r;
128
129         na = nargs(argv, NULL);
130         if (na < 0)
131                 return na;
132         ne = nargs(envp, NULL);
133         if (ne < 0)
134                 return ne;
135         len = (na + ne + 2) * sizeof(*av);
136         av = kmalloc(len, GFP_KERNEL);
137         if (!av)
138                 return -ENOMEM;
139
140         ae = av + na + 1;
141         av[na] = NULL;
142         ae[ne] = NULL;
143
144         r = nargs(argv, av);
145         if (r < 0)
146                 goto out;
147         r = nargs(envp, ae);
148         if (r < 0)
149                 goto out;
150
151         old_map_base  = current->thread.map_base;
152         old_task_size = current->thread.task_size;
153         tssd = ia64_get_kr(IA64_KR_TSSD);
154
155         /* we may be exec'ing a 64-bit process: reset map base, task-size, and io-base: */
156         current->thread.map_base  = DEFAULT_MAP_BASE;
157         current->thread.task_size = DEFAULT_TASK_SIZE;
158         ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
159         ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
160
161         set_fs(KERNEL_DS);
162         r = sys_execve(filename, av, ae, regs);
163         if (r < 0) {
164                 /* oops, execve failed, switch back to old values... */
165                 ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
166                 ia64_set_kr(IA64_KR_TSSD, tssd);
167                 current->thread.map_base  = old_map_base;
168                 current->thread.task_size = old_task_size;
169                 set_fs(USER_DS);        /* establish new task-size as the address-limit */
170           out:
171                 kfree(av);
172         }
173         return r;
174 }
175
176 int cp_compat_stat(struct kstat *stat, struct compat_stat *ubuf)
177 {
178         int err;
179
180         if ((u64) stat->size > MAX_NON_LFS)
181                 return -EOVERFLOW;
182
183         if (clear_user(ubuf, sizeof(*ubuf)))
184                 return -EFAULT;
185
186         err  = __put_user(stat->dev, &ubuf->st_dev);
187         err |= __put_user(stat->ino, &ubuf->st_ino);
188         err |= __put_user(stat->mode, &ubuf->st_mode);
189         err |= __put_user(stat->nlink, &ubuf->st_nlink);
190         err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
191         err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
192         err |= __put_user(stat->rdev, &ubuf->st_rdev);
193         err |= __put_user(stat->size, &ubuf->st_size);
194         err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
195         err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
196         err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
197         err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
198         err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
199         err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
200         err |= __put_user(stat->blksize, &ubuf->st_blksize);
201         err |= __put_user(stat->blocks, &ubuf->st_blocks);
202         return err;
203 }
204
205 #if PAGE_SHIFT > IA32_PAGE_SHIFT
206
207
208 static int
209 get_page_prot (unsigned long addr)
210 {
211         struct vm_area_struct *vma = find_vma(current->mm, addr);
212         int prot = 0;
213
214         if (!vma || vma->vm_start > addr)
215                 return 0;
216
217         if (vma->vm_flags & VM_READ)
218                 prot |= PROT_READ;
219         if (vma->vm_flags & VM_WRITE)
220                 prot |= PROT_WRITE;
221         if (vma->vm_flags & VM_EXEC)
222                 prot |= PROT_EXEC;
223         return prot;
224 }
225
226 /*
227  * Map a subpage by creating an anonymous page that contains the union of the old page and
228  * the subpage.
229  */
230 static unsigned long
231 mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
232               loff_t off)
233 {
234         void *page = (void *) get_zeroed_page(GFP_KERNEL);
235         struct inode *inode;
236         unsigned long ret;
237         int old_prot = get_page_prot(start);
238
239         DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
240             file, start, end, prot, flags, off);
241
242         if (!page)
243                 return -ENOMEM;
244
245         if (old_prot)
246                 copy_from_user(page, (void *) PAGE_START(start), PAGE_SIZE);
247
248         down_write(&current->mm->mmap_sem);
249         {
250                 ret = do_mmap(0, PAGE_START(start), PAGE_SIZE, prot | PROT_WRITE,
251                               flags | MAP_FIXED | MAP_ANONYMOUS, 0);
252         }
253         up_write(&current->mm->mmap_sem);
254
255         if (IS_ERR((void *) ret))
256                 goto out;
257
258         if (old_prot) {
259                 /* copy back the old page contents.  */
260                 if (PAGE_OFF(start))
261                         copy_to_user((void *) PAGE_START(start), page, PAGE_OFF(start));
262                 if (PAGE_OFF(end))
263                         copy_to_user((void *) end, page + PAGE_OFF(end),
264                                      PAGE_SIZE - PAGE_OFF(end));
265         }
266         if (!(flags & MAP_ANONYMOUS)) {
267                 /* read the file contents */
268                 inode = file->f_dentry->d_inode;
269                 if (!inode->i_fop || !file->f_op->read
270                     || ((*file->f_op->read)(file, (char *) start, end - start, &off) < 0))
271                 {
272                         ret = -EINVAL;
273                         goto out;
274                 }
275         }
276         if (!(prot & PROT_WRITE))
277                 ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
278   out:
279         free_page((unsigned long) page);
280         return ret;
281 }
282
283 static unsigned long
284 emulate_mmap (struct file *file, unsigned long start, unsigned long len, int prot, int flags,
285               loff_t off)
286 {
287         unsigned long tmp, end, pend, pstart, ret, is_congruent, fudge = 0;
288         struct inode *inode;
289         loff_t poff;
290
291         end = start + len;
292         pstart = PAGE_START(start);
293         pend = PAGE_ALIGN(end);
294
295         if (flags & MAP_FIXED) {
296                 if (start > pstart) {
297                         if (flags & MAP_SHARED)
298                                 printk(KERN_INFO
299                                        "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
300                                        current->comm, current->pid, start);
301                         ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
302                                            off);
303                         if (IS_ERR((void *) ret))
304                                 return ret;
305                         pstart += PAGE_SIZE;
306                         if (pstart >= pend)
307                                 return start;   /* done */
308                 }
309                 if (end < pend) {
310                         if (flags & MAP_SHARED)
311                                 printk(KERN_INFO
312                                        "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
313                                        current->comm, current->pid, end);
314                         ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
315                                            (off + len) - PAGE_OFF(end));
316                         if (IS_ERR((void *) ret))
317                                 return ret;
318                         pend -= PAGE_SIZE;
319                         if (pstart >= pend)
320                                 return start;   /* done */
321                 }
322         } else {
323                 /*
324                  * If a start address was specified, use it if the entire rounded out area
325                  * is available.
326                  */
327                 if (start && !pstart)
328                         fudge = 1;      /* handle case of mapping to range (0,PAGE_SIZE) */
329                 tmp = arch_get_unmapped_area(file, pstart - fudge, pend - pstart, 0, flags);
330                 if (tmp != pstart) {
331                         pstart = tmp;
332                         start = pstart + PAGE_OFF(off); /* make start congruent with off */
333                         end = start + len;
334                         pend = PAGE_ALIGN(end);
335                 }
336         }
337
338         poff = off + (pstart - start);  /* note: (pstart - start) may be negative */
339         is_congruent = (flags & MAP_ANONYMOUS) || (PAGE_OFF(poff) == 0);
340
341         if ((flags & MAP_SHARED) && !is_congruent)
342                 printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
343                        "(addr=0x%lx,off=0x%llx)\n", current->comm, current->pid, start, off);
344
345         DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
346             is_congruent ? "congruent" : "not congruent", poff);
347
348         down_write(&current->mm->mmap_sem);
349         {
350                 if (!(flags & MAP_ANONYMOUS) && is_congruent)
351                         ret = do_mmap(file, pstart, pend - pstart, prot, flags | MAP_FIXED, poff);
352                 else
353                         ret = do_mmap(0, pstart, pend - pstart,
354                                       prot | ((flags & MAP_ANONYMOUS) ? 0 : PROT_WRITE),
355                                       flags | MAP_FIXED | MAP_ANONYMOUS, 0);
356         }
357         up_write(&current->mm->mmap_sem);
358
359         if (IS_ERR((void *) ret))
360                 return ret;
361
362         if (!is_congruent) {
363                 /* read the file contents */
364                 inode = file->f_dentry->d_inode;
365                 if (!inode->i_fop || !file->f_op->read
366                     || ((*file->f_op->read)(file, (char *) pstart, pend - pstart, &poff) < 0))
367                 {
368                         sys_munmap(pstart, pend - pstart);
369                         return -EINVAL;
370                 }
371                 if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0)
372                         return -EINVAL;
373         }
374         return start;
375 }
376
377 #endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
378
379 static inline unsigned int
380 get_prot32 (unsigned int prot)
381 {
382         if (prot & PROT_WRITE)
383                 /* on x86, PROT_WRITE implies PROT_READ which implies PROT_EEC */
384                 prot |= PROT_READ | PROT_WRITE | PROT_EXEC;
385         else if (prot & (PROT_READ | PROT_EXEC))
386                 /* on x86, there is no distinction between PROT_READ and PROT_EXEC */
387                 prot |= (PROT_READ | PROT_EXEC);
388
389         return prot;
390 }
391
392 unsigned long
393 ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot, int flags,
394               loff_t offset)
395 {
396         DBG("ia32_do_mmap(file=%p,addr=0x%lx,len=0x%lx,prot=%x,flags=%x,offset=0x%llx)\n",
397             file, addr, len, prot, flags, offset);
398
399         if (file && (!file->f_op || !file->f_op->mmap))
400                 return -ENODEV;
401
402         len = IA32_PAGE_ALIGN(len);
403         if (len == 0)
404                 return addr;
405
406         if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len)
407                 return -EINVAL;
408
409         if (OFFSET4K(offset))
410                 return -EINVAL;
411
412         prot = get_prot32(prot);
413
414 #if PAGE_SHIFT > IA32_PAGE_SHIFT
415         down(&ia32_mmap_sem);
416         {
417                 addr = emulate_mmap(file, addr, len, prot, flags, offset);
418         }
419         up(&ia32_mmap_sem);
420 #else
421         down_write(&current->mm->mmap_sem);
422         {
423                 addr = do_mmap(file, addr, len, prot, flags, offset);
424         }
425         up_write(&current->mm->mmap_sem);
426 #endif
427         DBG("ia32_do_mmap: returning 0x%lx\n", addr);
428         return addr;
429 }
430
431 /*
432  * Linux/i386 didn't use to be able to handle more than 4 system call parameters, so these
433  * system calls used a memory block for parameter passing..
434  */
435
436 struct mmap_arg_struct {
437         unsigned int addr;
438         unsigned int len;
439         unsigned int prot;
440         unsigned int flags;
441         unsigned int fd;
442         unsigned int offset;
443 };
444
445 asmlinkage long
446 sys32_mmap (struct mmap_arg_struct *arg)
447 {
448         struct mmap_arg_struct a;
449         struct file *file = NULL;
450         unsigned long addr;
451         int flags;
452
453         if (copy_from_user(&a, arg, sizeof(a)))
454                 return -EFAULT;
455
456         if (OFFSET4K(a.offset))
457                 return -EINVAL;
458
459         flags = a.flags;
460
461         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
462         if (!(flags & MAP_ANONYMOUS)) {
463                 file = fget(a.fd);
464                 if (!file)
465                         return -EBADF;
466         }
467
468         addr = ia32_do_mmap(file, a.addr, a.len, a.prot, flags, a.offset);
469
470         if (file)
471                 fput(file);
472         return addr;
473 }
474
475 asmlinkage long
476 sys32_mmap2 (unsigned int addr, unsigned int len, unsigned int prot, unsigned int flags,
477              unsigned int fd, unsigned int pgoff)
478 {
479         struct file *file = NULL;
480         unsigned long retval;
481
482         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
483         if (!(flags & MAP_ANONYMOUS)) {
484                 file = fget(fd);
485                 if (!file)
486                         return -EBADF;
487         }
488
489         retval = ia32_do_mmap(file, addr, len, prot, flags,
490                               (unsigned long) pgoff << IA32_PAGE_SHIFT);
491
492         if (file)
493                 fput(file);
494         return retval;
495 }
496
497 asmlinkage long
498 sys32_munmap (unsigned int start, unsigned int len)
499 {
500         unsigned int end = start + len;
501         long ret;
502
503 #if PAGE_SHIFT <= IA32_PAGE_SHIFT
504         ret = sys_munmap(start, end - start);
505 #else
506         if (start > end)
507                 return -EINVAL;
508
509         start = PAGE_ALIGN(start);
510         end = PAGE_START(end);
511
512         if (start >= end)
513                 return 0;
514
515         down(&ia32_mmap_sem);
516         {
517                 ret = sys_munmap(start, end - start);
518         }
519         up(&ia32_mmap_sem);
520 #endif
521         return ret;
522 }
523
524 #if PAGE_SHIFT > IA32_PAGE_SHIFT
525
526 /*
527  * When mprotect()ing a partial page, we set the permission to the union of the old
528  * settings and the new settings.  In other words, it's only possible to make access to a
529  * partial page less restrictive.
530  */
531 static long
532 mprotect_subpage (unsigned long address, int new_prot)
533 {
534         int old_prot;
535
536         if (new_prot == PROT_NONE)
537                 return 0;               /* optimize case where nothing changes... */
538
539         old_prot = get_page_prot(address);
540         return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
541 }
542
543 #endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
544
545 asmlinkage long
546 sys32_mprotect (unsigned int start, unsigned int len, int prot)
547 {
548         unsigned long end = start + len;
549 #if PAGE_SHIFT > IA32_PAGE_SHIFT
550         long retval = 0;
551 #endif
552
553         prot = get_prot32(prot);
554
555 #if PAGE_SHIFT <= IA32_PAGE_SHIFT
556         return sys_mprotect(start, end - start, prot);
557 #else
558         if (OFFSET4K(start))
559                 return -EINVAL;
560
561         end = IA32_PAGE_ALIGN(end);
562         if (end < start)
563                 return -EINVAL;
564
565         down(&ia32_mmap_sem);
566         {
567                 if (PAGE_OFF(start)) {
568                         /* start address is 4KB aligned but not page aligned. */
569                         retval = mprotect_subpage(PAGE_START(start), prot);
570                         if (retval < 0)
571                                 goto out;
572
573                         start = PAGE_ALIGN(start);
574                         if (start >= end)
575                                 goto out;       /* retval is already zero... */
576                 }
577
578                 if (PAGE_OFF(end)) {
579                         /* end address is 4KB aligned but not page aligned. */
580                         retval = mprotect_subpage(PAGE_START(end), prot);
581                         if (retval < 0)
582                                 goto out;
583
584                         end = PAGE_START(end);
585                 }
586                 retval = sys_mprotect(start, end - start, prot);
587         }
588   out:
589         up(&ia32_mmap_sem);
590         return retval;
591 #endif
592 }
593
594 asmlinkage long
595 sys32_pipe (int *fd)
596 {
597         int retval;
598         int fds[2];
599
600         retval = do_pipe(fds);
601         if (retval)
602                 goto out;
603         if (copy_to_user(fd, fds, sizeof(fds)))
604                 retval = -EFAULT;
605   out:
606         return retval;
607 }
608
609 static inline long
610 get_tv32 (struct timeval *o, struct compat_timeval *i)
611 {
612         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
613                 (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec)));
614 }
615
616 static inline long
617 put_tv32 (struct compat_timeval *o, struct timeval *i)
618 {
619         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
620                 (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec)));
621 }
622
623 asmlinkage unsigned long
624 sys32_alarm (unsigned int seconds)
625 {
626         struct itimerval it_new, it_old;
627         unsigned int oldalarm;
628
629         it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
630         it_new.it_value.tv_sec = seconds;
631         it_new.it_value.tv_usec = 0;
632         do_setitimer(ITIMER_REAL, &it_new, &it_old);
633         oldalarm = it_old.it_value.tv_sec;
634         /* ehhh.. We can't return 0 if we have an alarm pending.. */
635         /* And we'd better return too much than too little anyway */
636         if (it_old.it_value.tv_usec)
637                 oldalarm++;
638         return oldalarm;
639 }
640
641 /* Translations due to time_t size differences.  Which affects all
642    sorts of things, like timeval and itimerval.  */
643
644 extern struct timezone sys_tz;
645 extern int do_sys_settimeofday (struct timeval *tv, struct timezone *tz);
646
647 asmlinkage long
648 sys32_gettimeofday (struct compat_timeval *tv, struct timezone *tz)
649 {
650         if (tv) {
651                 struct timeval ktv;
652                 do_gettimeofday(&ktv);
653                 if (put_tv32(tv, &ktv))
654                         return -EFAULT;
655         }
656         if (tz) {
657                 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
658                         return -EFAULT;
659         }
660         return 0;
661 }
662
663 asmlinkage long
664 sys32_settimeofday (struct compat_timeval *tv, struct timezone *tz)
665 {
666         struct timeval ktv;
667         struct timezone ktz;
668
669         if (tv) {
670                 if (get_tv32(&ktv, tv))
671                         return -EFAULT;
672         }
673         if (tz) {
674                 if (copy_from_user(&ktz, tz, sizeof(ktz)))
675                         return -EFAULT;
676         }
677
678         return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
679 }
680
681 struct getdents32_callback {
682         struct linux32_dirent * current_dir;
683         struct linux32_dirent * previous;
684         int count;
685         int error;
686 };
687
688 struct readdir32_callback {
689         struct old_linux32_dirent * dirent;
690         int count;
691 };
692
693 static int
694 filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
695            unsigned int d_type)
696 {
697         struct linux32_dirent * dirent;
698         struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
699         int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
700
701         buf->error = -EINVAL;   /* only used if we fail.. */
702         if (reclen > buf->count)
703                 return -EINVAL;
704         buf->error = -EFAULT;   /* only used if we fail.. */
705         dirent = buf->previous;
706         if (dirent)
707                 if (put_user(offset, &dirent->d_off))
708                         return -EFAULT;
709         dirent = buf->current_dir;
710         buf->previous = dirent;
711         if (put_user(ino, &dirent->d_ino)
712             || put_user(reclen, &dirent->d_reclen)
713             || copy_to_user(dirent->d_name, name, namlen)
714             || put_user(0, dirent->d_name + namlen))
715                 return -EFAULT;
716         ((char *) dirent) += reclen;
717         buf->current_dir = dirent;
718         buf->count -= reclen;
719         return 0;
720 }
721
722 asmlinkage long
723 sys32_getdents (unsigned int fd, struct linux32_dirent *dirent, unsigned int count)
724 {
725         struct file * file;
726         struct linux32_dirent * lastdirent;
727         struct getdents32_callback buf;
728         int error;
729
730         error = -EBADF;
731         file = fget(fd);
732         if (!file)
733                 goto out;
734
735         buf.current_dir = dirent;
736         buf.previous = NULL;
737         buf.count = count;
738         buf.error = 0;
739
740         error = vfs_readdir(file, filldir32, &buf);
741         if (error < 0)
742                 goto out_putf;
743         error = buf.error;
744         lastdirent = buf.previous;
745         if (lastdirent) {
746                 error = -EINVAL;
747                 if (put_user(file->f_pos, &lastdirent->d_off))
748                         goto out_putf;
749                 error = count - buf.count;
750         }
751
752 out_putf:
753         fput(file);
754 out:
755         return error;
756 }
757
758 static int
759 fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
760               unsigned int d_type)
761 {
762         struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
763         struct old_linux32_dirent * dirent;
764
765         if (buf->count)
766                 return -EINVAL;
767         buf->count++;
768         dirent = buf->dirent;
769         if (put_user(ino, &dirent->d_ino)
770             || put_user(offset, &dirent->d_offset)
771             || put_user(namlen, &dirent->d_namlen)
772             || copy_to_user(dirent->d_name, name, namlen)
773             || put_user(0, dirent->d_name + namlen))
774                 return -EFAULT;
775         return 0;
776 }
777
778 asmlinkage long
779 sys32_readdir (unsigned int fd, void *dirent, unsigned int count)
780 {
781         int error;
782         struct file * file;
783         struct readdir32_callback buf;
784
785         error = -EBADF;
786         file = fget(fd);
787         if (!file)
788                 goto out;
789
790         buf.count = 0;
791         buf.dirent = dirent;
792
793         error = vfs_readdir(file, fillonedir32, &buf);
794         if (error >= 0)
795                 error = buf.count;
796         fput(file);
797 out:
798         return error;
799 }
800
801 /*
802  * We can actually return ERESTARTSYS instead of EINTR, but I'd
803  * like to be certain this leads to no problems. So I return
804  * EINTR just for safety.
805  *
806  * Update: ERESTARTSYS breaks at least the xview clock binary, so
807  * I'm trying ERESTARTNOHAND which restart only when you want to.
808  */
809 #define MAX_SELECT_SECONDS \
810         ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
811 #define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y))
812
813 asmlinkage long
814 sys32_select (int n, fd_set *inp, fd_set *outp, fd_set *exp, struct compat_timeval *tvp32)
815 {
816         fd_set_bits fds;
817         char *bits;
818         long timeout;
819         int ret, size;
820
821         timeout = MAX_SCHEDULE_TIMEOUT;
822         if (tvp32) {
823                 time_t sec, usec;
824
825                 ret = -EFAULT;
826                 if (get_user(sec, &tvp32->tv_sec) || get_user(usec, &tvp32->tv_usec))
827                         goto out_nofds;
828
829                 ret = -EINVAL;
830                 if (sec < 0 || usec < 0)
831                         goto out_nofds;
832
833                 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
834                         timeout = ROUND_UP_TIME(usec, 1000000/HZ);
835                         timeout += sec * (unsigned long) HZ;
836                 }
837         }
838
839         size = FDS_BYTES(n);
840         ret = -EINVAL;
841         if (n < 0 || size < n)
842                 goto out_nofds;
843
844         if (n > current->files->max_fdset)
845                 n = current->files->max_fdset;
846
847         /*
848          * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
849          * since we used fdset we need to allocate memory in units of
850          * long-words.
851          */
852         ret = -ENOMEM;
853         bits = kmalloc(6 * size, GFP_KERNEL);
854         if (!bits)
855                 goto out_nofds;
856         fds.in      = (unsigned long *)  bits;
857         fds.out     = (unsigned long *) (bits +   size);
858         fds.ex      = (unsigned long *) (bits + 2*size);
859         fds.res_in  = (unsigned long *) (bits + 3*size);
860         fds.res_out = (unsigned long *) (bits + 4*size);
861         fds.res_ex  = (unsigned long *) (bits + 5*size);
862
863         if ((ret = get_fd_set(n, inp, fds.in)) ||
864             (ret = get_fd_set(n, outp, fds.out)) ||
865             (ret = get_fd_set(n, exp, fds.ex)))
866                 goto out;
867         zero_fd_set(n, fds.res_in);
868         zero_fd_set(n, fds.res_out);
869         zero_fd_set(n, fds.res_ex);
870
871         ret = do_select(n, &fds, &timeout);
872
873         if (tvp32 && !(current->personality & STICKY_TIMEOUTS)) {
874                 time_t sec = 0, usec = 0;
875                 if (timeout) {
876                         sec = timeout / HZ;
877                         usec = timeout % HZ;
878                         usec *= (1000000/HZ);
879                 }
880                 if (put_user(sec, &tvp32->tv_sec) || put_user(usec, &tvp32->tv_usec)) {
881                         ret = -EFAULT;
882                         goto out;
883                 }
884         }
885
886         if (ret < 0)
887                 goto out;
888         if (!ret) {
889                 ret = -ERESTARTNOHAND;
890                 if (signal_pending(current))
891                         goto out;
892                 ret = 0;
893         }
894
895         set_fd_set(n, inp, fds.res_in);
896         set_fd_set(n, outp, fds.res_out);
897         set_fd_set(n, exp, fds.res_ex);
898
899 out:
900         kfree(bits);
901 out_nofds:
902         return ret;
903 }
904
905 struct sel_arg_struct {
906         unsigned int n;
907         unsigned int inp;
908         unsigned int outp;
909         unsigned int exp;
910         unsigned int tvp;
911 };
912
913 asmlinkage long
914 sys32_old_select (struct sel_arg_struct *arg)
915 {
916         struct sel_arg_struct a;
917
918         if (copy_from_user(&a, arg, sizeof(a)))
919                 return -EFAULT;
920         return sys32_select(a.n, (fd_set *) A(a.inp), (fd_set *) A(a.outp), (fd_set *) A(a.exp),
921                             (struct compat_timeval *) A(a.tvp));
922 }
923
924 asmlinkage ssize_t sys_readv (unsigned long,const struct iovec *,unsigned long);
925 asmlinkage ssize_t sys_writev (unsigned long,const struct iovec *,unsigned long);
926
927 static struct iovec *
928 get_compat_iovec (struct compat_iovec *iov32, struct iovec *iov_buf, u32 count, int type)
929 {
930         u32 i, buf, len;
931         struct iovec *ivp, *iov;
932
933         /* Get the "struct iovec" from user memory */
934
935         if (!count)
936                 return 0;
937         if (verify_area(VERIFY_READ, iov32, sizeof(struct compat_iovec)*count))
938                 return NULL;
939         if (count > UIO_MAXIOV)
940                 return NULL;
941         if (count > UIO_FASTIOV) {
942                 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
943                 if (!iov)
944                         return NULL;
945         } else
946                 iov = iov_buf;
947
948         ivp = iov;
949         for (i = 0; i < count; i++) {
950                 if (__get_user(len, &iov32->iov_len) || __get_user(buf, &iov32->iov_base)) {
951                         if (iov != iov_buf)
952                                 kfree(iov);
953                         return NULL;
954                 }
955                 if (verify_area(type, (void *)A(buf), len)) {
956                         if (iov != iov_buf)
957                                 kfree(iov);
958                         return((struct iovec *)0);
959                 }
960                 ivp->iov_base = (void *)A(buf);
961                 ivp->iov_len = (__kernel_size_t) len;
962                 iov32++;
963                 ivp++;
964         }
965         return iov;
966 }
967
968 asmlinkage long
969 sys32_readv (int fd, struct compat_iovec *vector, u32 count)
970 {
971         struct iovec iovstack[UIO_FASTIOV];
972         struct iovec *iov;
973         long ret;
974         mm_segment_t old_fs = get_fs();
975
976         iov = get_compat_iovec(vector, iovstack, count, VERIFY_WRITE);
977         if (!iov)
978                 return -EFAULT;
979         set_fs(KERNEL_DS);
980         ret = sys_readv(fd, iov, count);
981         set_fs(old_fs);
982         if (iov != iovstack)
983                 kfree(iov);
984         return ret;
985 }
986
987 asmlinkage long
988 sys32_writev (int fd, struct compat_iovec *vector, u32 count)
989 {
990         struct iovec iovstack[UIO_FASTIOV];
991         struct iovec *iov;
992         long ret;
993         mm_segment_t old_fs = get_fs();
994
995         iov = get_compat_iovec(vector, iovstack, count, VERIFY_READ);
996         if (!iov)
997                 return -EFAULT;
998         set_fs(KERNEL_DS);
999         ret = sys_writev(fd, iov, count);
1000         set_fs(old_fs);
1001         if (iov != iovstack)
1002                 kfree(iov);
1003         return ret;
1004 }
1005
1006 /*
1007  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
1008  *
1009  * This is really horribly ugly.
1010  */
1011
1012 struct msgbuf32 { s32 mtype; char mtext[1]; };
1013
1014 struct ipc_perm32 {
1015         key_t key;
1016         compat_uid_t uid;
1017         compat_gid_t gid;
1018         compat_uid_t cuid;
1019         compat_gid_t cgid;
1020         compat_mode_t mode;
1021         unsigned short seq;
1022 };
1023
1024 struct ipc64_perm32 {
1025         key_t key;
1026         compat_uid32_t uid;
1027         compat_gid32_t gid;
1028         compat_uid32_t cuid;
1029         compat_gid32_t cgid;
1030         compat_mode_t mode;
1031         unsigned short __pad1;
1032         unsigned short seq;
1033         unsigned short __pad2;
1034         unsigned int unused1;
1035         unsigned int unused2;
1036 };
1037
1038 struct semid_ds32 {
1039         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
1040         compat_time_t   sem_otime;              /* last semop time */
1041         compat_time_t   sem_ctime;              /* last change time */
1042         u32 sem_base;              /* ptr to first semaphore in array */
1043         u32 sem_pending;          /* pending operations to be processed */
1044         u32 sem_pending_last;    /* last pending operation */
1045         u32 undo;                  /* undo requests on this array */
1046         unsigned short  sem_nsems;              /* no. of semaphores in array */
1047 };
1048
1049 struct semid64_ds32 {
1050         struct ipc64_perm32 sem_perm;
1051         compat_time_t   sem_otime;
1052         unsigned int __unused1;
1053         compat_time_t   sem_ctime;
1054         unsigned int __unused2;
1055         unsigned int sem_nsems;
1056         unsigned int __unused3;
1057         unsigned int __unused4;
1058 };
1059
1060 struct msqid_ds32 {
1061         struct ipc_perm32 msg_perm;
1062         u32 msg_first;
1063         u32 msg_last;
1064         compat_time_t   msg_stime;
1065         compat_time_t   msg_rtime;
1066         compat_time_t   msg_ctime;
1067         u32 wwait;
1068         u32 rwait;
1069         unsigned short msg_cbytes;
1070         unsigned short msg_qnum;
1071         unsigned short msg_qbytes;
1072         compat_ipc_pid_t msg_lspid;
1073         compat_ipc_pid_t msg_lrpid;
1074 };
1075
1076 struct msqid64_ds32 {
1077         struct ipc64_perm32 msg_perm;
1078         compat_time_t   msg_stime;
1079         unsigned int __unused1;
1080         compat_time_t   msg_rtime;
1081         unsigned int __unused2;
1082         compat_time_t   msg_ctime;
1083         unsigned int __unused3;
1084         unsigned int msg_cbytes;
1085         unsigned int msg_qnum;
1086         unsigned int msg_qbytes;
1087         compat_pid_t msg_lspid;
1088         compat_pid_t msg_lrpid;
1089         unsigned int __unused4;
1090         unsigned int __unused5;
1091 };
1092
1093 struct shmid_ds32 {
1094         struct ipc_perm32 shm_perm;
1095         int shm_segsz;
1096         compat_time_t   shm_atime;
1097         compat_time_t   shm_dtime;
1098         compat_time_t   shm_ctime;
1099         compat_ipc_pid_t shm_cpid;
1100         compat_ipc_pid_t shm_lpid;
1101         unsigned short shm_nattch;
1102 };
1103
1104 struct shmid64_ds32 {
1105         struct ipc64_perm shm_perm;
1106         compat_size_t shm_segsz;
1107         compat_time_t   shm_atime;
1108         unsigned int __unused1;
1109         compat_time_t   shm_dtime;
1110         unsigned int __unused2;
1111         compat_time_t   shm_ctime;
1112         unsigned int __unused3;
1113         compat_pid_t shm_cpid;
1114         compat_pid_t shm_lpid;
1115         unsigned int shm_nattch;
1116         unsigned int __unused4;
1117         unsigned int __unused5;
1118 };
1119
1120 struct shminfo64_32 {
1121         unsigned int shmmax;
1122         unsigned int shmmin;
1123         unsigned int shmmni;
1124         unsigned int shmseg;
1125         unsigned int shmall;
1126         unsigned int __unused1;
1127         unsigned int __unused2;
1128         unsigned int __unused3;
1129         unsigned int __unused4;
1130 };
1131
1132 struct shm_info32 {
1133         int used_ids;
1134         u32 shm_tot, shm_rss, shm_swp;
1135         u32 swap_attempts, swap_successes;
1136 };
1137
1138 struct ipc_kludge {
1139         u32 msgp;
1140         s32 msgtyp;
1141 };
1142
1143 #define SEMOP            1
1144 #define SEMGET           2
1145 #define SEMCTL           3
1146 #define SEMTIMEDOP       4
1147 #define MSGSND          11
1148 #define MSGRCV          12
1149 #define MSGGET          13
1150 #define MSGCTL          14
1151 #define SHMAT           21
1152 #define SHMDT           22
1153 #define SHMGET          23
1154 #define SHMCTL          24
1155
1156 #define IPCOP_MASK(__x) (1UL << (__x))
1157
1158 static int
1159 ipc_parse_version32 (int *cmd)
1160 {
1161         if (*cmd & IPC_64) {
1162                 *cmd ^= IPC_64;
1163                 return IPC_64;
1164         } else {
1165                 return IPC_OLD;
1166         }
1167 }
1168
1169 static int
1170 semctl32 (int first, int second, int third, void *uptr)
1171 {
1172         union semun fourth;
1173         u32 pad;
1174         int err = 0, err2;
1175         struct semid64_ds s;
1176         mm_segment_t old_fs;
1177         int version = ipc_parse_version32(&third);
1178
1179         if (!uptr)
1180                 return -EINVAL;
1181         if (get_user(pad, (u32 *)uptr))
1182                 return -EFAULT;
1183         if (third == SETVAL)
1184                 fourth.val = (int)pad;
1185         else
1186                 fourth.__pad = (void *)A(pad);
1187         switch (third) {
1188               default:
1189                 err = -EINVAL;
1190                 break;
1191
1192               case IPC_INFO:
1193               case IPC_RMID:
1194               case IPC_SET:
1195               case SEM_INFO:
1196               case GETVAL:
1197               case GETPID:
1198               case GETNCNT:
1199               case GETZCNT:
1200               case GETALL:
1201               case SETVAL:
1202               case SETALL:
1203                 err = sys_semctl(first, second, third, fourth);
1204                 break;
1205
1206               case IPC_STAT:
1207               case SEM_STAT:
1208                 fourth.__pad = &s;
1209                 old_fs = get_fs();
1210                 set_fs(KERNEL_DS);
1211                 err = sys_semctl(first, second, third, fourth);
1212                 set_fs(old_fs);
1213
1214                 if (version == IPC_64) {
1215                         struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad);
1216
1217                         if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
1218                                 err = -EFAULT;
1219                                 break;
1220                         }
1221                         err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
1222                         err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
1223                         err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
1224                         err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
1225                         err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
1226                         err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
1227                         err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
1228                         err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
1229                         err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
1230                         err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
1231                 } else {
1232                         struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad);
1233
1234                         if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
1235                                 err = -EFAULT;
1236                                 break;
1237                         }
1238                         err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
1239                         err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
1240                         err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
1241                         err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
1242                         err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
1243                         err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
1244                         err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
1245                         err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
1246                         err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
1247                         err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
1248                 }
1249                 if (err2)
1250                     err = -EFAULT;
1251                 break;
1252         }
1253         return err;
1254 }
1255
1256 static int
1257 do_sys32_msgsnd (int first, int second, int third, void *uptr)
1258 {
1259         struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
1260         struct msgbuf32 *up = (struct msgbuf32 *)uptr;
1261         mm_segment_t old_fs;
1262         int err;
1263
1264         if (!p)
1265                 return -ENOMEM;
1266         err = get_user(p->mtype, &up->mtype);
1267         err |= copy_from_user(p->mtext, &up->mtext, second);
1268         if (err)
1269                 goto out;
1270         old_fs = get_fs();
1271         set_fs(KERNEL_DS);
1272         err = sys_msgsnd(first, p, second, third);
1273         set_fs(old_fs);
1274   out:
1275         kfree(p);
1276         return err;
1277 }
1278
1279 static int
1280 do_sys32_msgrcv (int first, int second, int msgtyp, int third, int version, void *uptr)
1281 {
1282         struct msgbuf32 *up;
1283         struct msgbuf *p;
1284         mm_segment_t old_fs;
1285         int err;
1286
1287         if (!version) {
1288                 struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
1289                 struct ipc_kludge ipck;
1290
1291                 err = -EINVAL;
1292                 if (!uptr)
1293                         goto out;
1294                 err = -EFAULT;
1295                 if (copy_from_user(&ipck, uipck, sizeof(struct ipc_kludge)))
1296                         goto out;
1297                 uptr = (void *)A(ipck.msgp);
1298                 msgtyp = ipck.msgtyp;
1299         }
1300         err = -ENOMEM;
1301         p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
1302         if (!p)
1303                 goto out;
1304         old_fs = get_fs();
1305         set_fs(KERNEL_DS);
1306         err = sys_msgrcv(first, p, second + 4, msgtyp, third);
1307         set_fs(old_fs);
1308         if (err < 0)
1309                 goto free_then_out;
1310         up = (struct msgbuf32 *)uptr;
1311         if (put_user(p->mtype, &up->mtype) || copy_to_user(&up->mtext, p->mtext, err))
1312                 err = -EFAULT;
1313 free_then_out:
1314         kfree(p);
1315 out:
1316         return err;
1317 }
1318
1319 static int
1320 msgctl32 (int first, int second, void *uptr)
1321 {
1322         int err = -EINVAL, err2;
1323         struct msqid_ds m;
1324         struct msqid64_ds m64;
1325         struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
1326         struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
1327         mm_segment_t old_fs;
1328         int version = ipc_parse_version32(&second);
1329
1330         switch (second) {
1331               case IPC_INFO:
1332               case IPC_RMID:
1333               case MSG_INFO:
1334                 err = sys_msgctl(first, second, (struct msqid_ds *)uptr);
1335                 break;
1336
1337               case IPC_SET:
1338                 if (version == IPC_64) {
1339                         err = get_user(m.msg_perm.uid, &up64->msg_perm.uid);
1340                         err |= get_user(m.msg_perm.gid, &up64->msg_perm.gid);
1341                         err |= get_user(m.msg_perm.mode, &up64->msg_perm.mode);
1342                         err |= get_user(m.msg_qbytes, &up64->msg_qbytes);
1343                 } else {
1344                         err = get_user(m.msg_perm.uid, &up32->msg_perm.uid);
1345                         err |= get_user(m.msg_perm.gid, &up32->msg_perm.gid);
1346                         err |= get_user(m.msg_perm.mode, &up32->msg_perm.mode);
1347                         err |= get_user(m.msg_qbytes, &up32->msg_qbytes);
1348                 }
1349                 if (err)
1350                         break;
1351                 old_fs = get_fs();
1352                 set_fs(KERNEL_DS);
1353                 err = sys_msgctl(first, second, &m);
1354                 set_fs(old_fs);
1355                 break;
1356
1357               case IPC_STAT:
1358               case MSG_STAT:
1359                 old_fs = get_fs();
1360                 set_fs(KERNEL_DS);
1361                 err = sys_msgctl(first, second, (void *) &m64);
1362                 set_fs(old_fs);
1363
1364                 if (version == IPC_64) {
1365                         if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
1366                                 err = -EFAULT;
1367                                 break;
1368                         }
1369                         err2 = __put_user(m64.msg_perm.key, &up64->msg_perm.key);
1370                         err2 |= __put_user(m64.msg_perm.uid, &up64->msg_perm.uid);
1371                         err2 |= __put_user(m64.msg_perm.gid, &up64->msg_perm.gid);
1372                         err2 |= __put_user(m64.msg_perm.cuid, &up64->msg_perm.cuid);
1373                         err2 |= __put_user(m64.msg_perm.cgid, &up64->msg_perm.cgid);
1374                         err2 |= __put_user(m64.msg_perm.mode, &up64->msg_perm.mode);
1375                         err2 |= __put_user(m64.msg_perm.seq, &up64->msg_perm.seq);
1376                         err2 |= __put_user(m64.msg_stime, &up64->msg_stime);
1377                         err2 |= __put_user(m64.msg_rtime, &up64->msg_rtime);
1378                         err2 |= __put_user(m64.msg_ctime, &up64->msg_ctime);
1379                         err2 |= __put_user(m64.msg_cbytes, &up64->msg_cbytes);
1380                         err2 |= __put_user(m64.msg_qnum, &up64->msg_qnum);
1381                         err2 |= __put_user(m64.msg_qbytes, &up64->msg_qbytes);
1382                         err2 |= __put_user(m64.msg_lspid, &up64->msg_lspid);
1383                         err2 |= __put_user(m64.msg_lrpid, &up64->msg_lrpid);
1384                         if (err2)
1385                                 err = -EFAULT;
1386                 } else {
1387                         if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
1388                                 err = -EFAULT;
1389                                 break;
1390                         }
1391                         err2 = __put_user(m64.msg_perm.key, &up32->msg_perm.key);
1392                         err2 |= __put_user(m64.msg_perm.uid, &up32->msg_perm.uid);
1393                         err2 |= __put_user(m64.msg_perm.gid, &up32->msg_perm.gid);
1394                         err2 |= __put_user(m64.msg_perm.cuid, &up32->msg_perm.cuid);
1395                         err2 |= __put_user(m64.msg_perm.cgid, &up32->msg_perm.cgid);
1396                         err2 |= __put_user(m64.msg_perm.mode, &up32->msg_perm.mode);
1397                         err2 |= __put_user(m64.msg_perm.seq, &up32->msg_perm.seq);
1398                         err2 |= __put_user(m64.msg_stime, &up32->msg_stime);
1399                         err2 |= __put_user(m64.msg_rtime, &up32->msg_rtime);
1400                         err2 |= __put_user(m64.msg_ctime, &up32->msg_ctime);
1401                         err2 |= __put_user(m64.msg_cbytes, &up32->msg_cbytes);
1402                         err2 |= __put_user(m64.msg_qnum, &up32->msg_qnum);
1403                         err2 |= __put_user(m64.msg_qbytes, &up32->msg_qbytes);
1404                         err2 |= __put_user(m64.msg_lspid, &up32->msg_lspid);
1405                         err2 |= __put_user(m64.msg_lrpid, &up32->msg_lrpid);
1406                         if (err2)
1407                                 err = -EFAULT;
1408                 }
1409                 break;
1410         }
1411         return err;
1412 }
1413
1414 static int
1415 shmat32 (int first, int second, int third, int version, void *uptr)
1416 {
1417         unsigned long raddr;
1418         u32 *uaddr = (u32 *)A((u32)third);
1419         int err;
1420
1421         if (version == 1)
1422                 return -EINVAL; /* iBCS2 emulator entry point: unsupported */
1423         err = sys_shmat(first, uptr, second, &raddr);
1424         if (err)
1425                 return err;
1426         return put_user(raddr, uaddr);
1427 }
1428
1429 static int
1430 shmctl32 (int first, int second, void *uptr)
1431 {
1432         int err = -EFAULT, err2;
1433         struct shmid_ds s;
1434         struct shmid64_ds s64;
1435         struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
1436         struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
1437         mm_segment_t old_fs;
1438         struct shm_info32 *uip = (struct shm_info32 *)uptr;
1439         struct shm_info si;
1440         int version = ipc_parse_version32(&second);
1441         struct shminfo64 smi;
1442         struct shminfo *usi32 = (struct shminfo *) uptr;
1443         struct shminfo64_32 *usi64 = (struct shminfo64_32 *) uptr;
1444
1445         switch (second) {
1446               case IPC_INFO:
1447                 old_fs = get_fs();
1448                 set_fs(KERNEL_DS);
1449                 err = sys_shmctl(first, second, (struct shmid_ds *)&smi);
1450                 set_fs(old_fs);
1451
1452                 if (version == IPC_64) {
1453                         if (!access_ok(VERIFY_WRITE, usi64, sizeof(*usi64))) {
1454                                 err = -EFAULT;
1455                                 break;
1456                         }
1457                         err2 = __put_user(smi.shmmax, &usi64->shmmax);
1458                         err2 |= __put_user(smi.shmmin, &usi64->shmmin);
1459                         err2 |= __put_user(smi.shmmni, &usi64->shmmni);
1460                         err2 |= __put_user(smi.shmseg, &usi64->shmseg);
1461                         err2 |= __put_user(smi.shmall, &usi64->shmall);
1462                 } else {
1463                         if (!access_ok(VERIFY_WRITE, usi32, sizeof(*usi32))) {
1464                                 err = -EFAULT;
1465                                 break;
1466                         }
1467                         err2 = __put_user(smi.shmmax, &usi32->shmmax);
1468                         err2 |= __put_user(smi.shmmin, &usi32->shmmin);
1469                         err2 |= __put_user(smi.shmmni, &usi32->shmmni);
1470                         err2 |= __put_user(smi.shmseg, &usi32->shmseg);
1471                         err2 |= __put_user(smi.shmall, &usi32->shmall);
1472                 }
1473                 if (err2)
1474                         err = -EFAULT;
1475                 break;
1476
1477               case IPC_RMID:
1478               case SHM_LOCK:
1479               case SHM_UNLOCK:
1480                 err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
1481                 break;
1482
1483               case IPC_SET:
1484                 if (version == IPC_64) {
1485                         err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
1486                         err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
1487                         err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
1488                 } else {
1489                         err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
1490                         err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
1491                         err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
1492                 }
1493                 if (err)
1494                         break;
1495                 old_fs = get_fs();
1496                 set_fs(KERNEL_DS);
1497                 err = sys_shmctl(first, second, &s);
1498                 set_fs(old_fs);
1499                 break;
1500
1501               case IPC_STAT:
1502               case SHM_STAT:
1503                 old_fs = get_fs();
1504                 set_fs(KERNEL_DS);
1505                 err = sys_shmctl(first, second, (void *) &s64);
1506                 set_fs(old_fs);
1507                 if (err < 0)
1508                         break;
1509                 if (version == IPC_64) {
1510                         if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
1511                                 err = -EFAULT;
1512                                 break;
1513                         }
1514                         err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
1515                         err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
1516                         err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
1517                         err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
1518                         err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
1519                         err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
1520                         err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
1521                         err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
1522                         err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
1523                         err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
1524                         err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
1525                         err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
1526                         err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
1527                         err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
1528                 } else {
1529                         if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
1530                                 err = -EFAULT;
1531                                 break;
1532                         }
1533                         err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
1534                         err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
1535                         err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
1536                         err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
1537                         err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
1538                         err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
1539                         err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
1540                         err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
1541                         err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
1542                         err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
1543                         err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
1544                         err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
1545                         err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
1546                         err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
1547                 }
1548                 if (err2)
1549                         err = -EFAULT;
1550                 break;
1551
1552               case SHM_INFO:
1553                 old_fs = get_fs();
1554                 set_fs(KERNEL_DS);
1555                 err = sys_shmctl(first, second, (void *)&si);
1556                 set_fs(old_fs);
1557                 if (err < 0)
1558                         break;
1559
1560                 if (!access_ok(VERIFY_WRITE, uip, sizeof(*uip))) {
1561                         err = -EFAULT;
1562                         break;
1563                 }
1564                 err2 = __put_user(si.used_ids, &uip->used_ids);
1565                 err2 |= __put_user(si.shm_tot, &uip->shm_tot);
1566                 err2 |= __put_user(si.shm_rss, &uip->shm_rss);
1567                 err2 |= __put_user(si.shm_swp, &uip->shm_swp);
1568                 err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
1569                 err2 |= __put_user(si.swap_successes, &uip->swap_successes);
1570                 if (err2)
1571                         err = -EFAULT;
1572                 break;
1573
1574         }
1575         return err;
1576 }
1577
1578 extern int sem_ctls[];
1579 #define sc_semopm       (sem_ctls[2])
1580
1581 static long
1582 semtimedop32(int semid, struct sembuf *tsops, int nsops,
1583              struct compat_timespec *timeout32)
1584 {
1585         struct timespec t;
1586         mm_segment_t oldfs;
1587         long ret;
1588
1589         /* parameter checking precedence should mirror sys_semtimedop() */
1590         if (nsops < 1 || semid < 0)
1591                 return -EINVAL;
1592         if (nsops > sc_semopm)
1593                 return -E2BIG;
1594         if (!access_ok(VERIFY_READ, tsops, nsops * sizeof(struct sembuf)) ||
1595             get_compat_timespec(&t, timeout32))
1596                 return -EFAULT;
1597
1598         oldfs = get_fs();
1599         set_fs(KERNEL_DS);
1600         ret = sys_semtimedop(semid, tsops, nsops, &t);
1601         set_fs(oldfs);
1602         return ret;
1603 }
1604
1605 asmlinkage long
1606 sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
1607 {
1608         int version;
1609
1610         version = call >> 16; /* hack for backward compatibility */
1611         call &= 0xffff;
1612
1613         switch (call) {
1614               case SEMTIMEDOP:
1615                 if (fifth)
1616                         return semtimedop32(first, (struct sembuf *)AA(ptr),
1617                                 second, (struct compat_timespec *)AA(fifth));
1618                 /* else fall through for normal semop() */
1619               case SEMOP:
1620                 /* struct sembuf is the same on 32 and 64bit :)) */
1621                 return sys_semtimedop(first, (struct sembuf *)AA(ptr), second,
1622                                       NULL);
1623               case SEMGET:
1624                 return sys_semget(first, second, third);
1625               case SEMCTL:
1626                 return semctl32(first, second, third, (void *)AA(ptr));
1627
1628               case MSGSND:
1629                 return do_sys32_msgsnd(first, second, third, (void *)AA(ptr));
1630               case MSGRCV:
1631                 return do_sys32_msgrcv(first, second, fifth, third, version, (void *)AA(ptr));
1632               case MSGGET:
1633                 return sys_msgget((key_t) first, second);
1634               case MSGCTL:
1635                 return msgctl32(first, second, (void *)AA(ptr));
1636
1637               case SHMAT:
1638                 return shmat32(first, second, third, version, (void *)AA(ptr));
1639                 break;
1640               case SHMDT:
1641                 return sys_shmdt((char *)AA(ptr));
1642               case SHMGET:
1643                 return sys_shmget(first, second, third);
1644               case SHMCTL:
1645                 return shmctl32(first, second, (void *)AA(ptr));
1646
1647               default:
1648                 return -ENOSYS;
1649         }
1650         return -EINVAL;
1651 }
1652
1653 /*
1654  * sys_time() can be implemented in user-level using
1655  * sys_gettimeofday().  IA64 did this but i386 Linux did not
1656  * so we have to implement this system call here.
1657  */
1658 asmlinkage long
1659 sys32_time (int *tloc)
1660 {
1661         int i;
1662
1663         /* SMP: This is fairly trivial. We grab CURRENT_TIME and
1664            stuff it to user space. No side effects */
1665         i = get_seconds();
1666         if (tloc) {
1667                 if (put_user(i, tloc))
1668                         i = -EFAULT;
1669         }
1670         return i;
1671 }
1672
1673 asmlinkage long
1674 sys32_waitpid (int pid, unsigned int *stat_addr, int options)
1675 {
1676         return compat_sys_wait4(pid, stat_addr, options, NULL);
1677 }
1678
1679 static unsigned int
1680 ia32_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int *val)
1681 {
1682         size_t copied;
1683         unsigned int ret;
1684
1685         copied = access_process_vm(child, addr, val, sizeof(*val), 0);
1686         return (copied != sizeof(ret)) ? -EIO : 0;
1687 }
1688
1689 static unsigned int
1690 ia32_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int val)
1691 {
1692
1693         if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
1694                 return -EIO;
1695         return 0;
1696 }
1697
1698 /*
1699  *  The order in which registers are stored in the ptrace regs structure
1700  */
1701 #define PT_EBX  0
1702 #define PT_ECX  1
1703 #define PT_EDX  2
1704 #define PT_ESI  3
1705 #define PT_EDI  4
1706 #define PT_EBP  5
1707 #define PT_EAX  6
1708 #define PT_DS   7
1709 #define PT_ES   8
1710 #define PT_FS   9
1711 #define PT_GS   10
1712 #define PT_ORIG_EAX 11
1713 #define PT_EIP  12
1714 #define PT_CS   13
1715 #define PT_EFL  14
1716 #define PT_UESP 15
1717 #define PT_SS   16
1718
1719 static unsigned int
1720 getreg (struct task_struct *child, int regno)
1721 {
1722         struct pt_regs *child_regs;
1723
1724         child_regs = ia64_task_regs(child);
1725         switch (regno / sizeof(int)) {
1726               case PT_EBX: return child_regs->r11;
1727               case PT_ECX: return child_regs->r9;
1728               case PT_EDX: return child_regs->r10;
1729               case PT_ESI: return child_regs->r14;
1730               case PT_EDI: return child_regs->r15;
1731               case PT_EBP: return child_regs->r13;
1732               case PT_EAX: return child_regs->r8;
1733               case PT_ORIG_EAX: return child_regs->r1; /* see dispatch_to_ia32_handler() */
1734               case PT_EIP: return child_regs->cr_iip;
1735               case PT_UESP: return child_regs->r12;
1736               case PT_EFL: return child->thread.eflag;
1737               case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
1738                 return __USER_DS;
1739               case PT_CS: return __USER_CS;
1740               default:
1741                 printk(KERN_ERR "ia32.getreg(): unknown register %d\n", regno);
1742                 break;
1743         }
1744         return 0;
1745 }
1746
1747 static void
1748 putreg (struct task_struct *child, int regno, unsigned int value)
1749 {
1750         struct pt_regs *child_regs;
1751
1752         child_regs = ia64_task_regs(child);
1753         switch (regno / sizeof(int)) {
1754               case PT_EBX: child_regs->r11 = value; break;
1755               case PT_ECX: child_regs->r9 = value; break;
1756               case PT_EDX: child_regs->r10 = value; break;
1757               case PT_ESI: child_regs->r14 = value; break;
1758               case PT_EDI: child_regs->r15 = value; break;
1759               case PT_EBP: child_regs->r13 = value; break;
1760               case PT_EAX: child_regs->r8 = value; break;
1761               case PT_ORIG_EAX: child_regs->r1 = value; break;
1762               case PT_EIP: child_regs->cr_iip = value; break;
1763               case PT_UESP: child_regs->r12 = value; break;
1764               case PT_EFL: child->thread.eflag = value; break;
1765               case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
1766                 if (value != __USER_DS)
1767                         printk(KERN_ERR
1768                                "ia32.putreg: attempt to set invalid segment register %d = %x\n",
1769                                regno, value);
1770                 break;
1771               case PT_CS:
1772                 if (value != __USER_CS)
1773                         printk(KERN_ERR
1774                                "ia32.putreg: attempt to to set invalid segment register %d = %x\n",
1775                                regno, value);
1776                 break;
1777               default:
1778                 printk(KERN_ERR "ia32.putreg: unknown register %d\n", regno);
1779                 break;
1780         }
1781 }
1782
1783 static void
1784 put_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp,
1785            int tos)
1786 {
1787         struct _fpreg_ia32 *f;
1788         char buf[32];
1789
1790         f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
1791         if ((regno += tos) >= 8)
1792                 regno -= 8;
1793         switch (regno) {
1794               case 0:
1795                 ia64f2ia32f(f, &ptp->f8);
1796                 break;
1797               case 1:
1798                 ia64f2ia32f(f, &ptp->f9);
1799                 break;
1800               case 2:
1801               case 3:
1802               case 4:
1803               case 5:
1804               case 6:
1805               case 7:
1806                 ia64f2ia32f(f, &swp->f10 + (regno - 2));
1807                 break;
1808         }
1809         copy_to_user(reg, f, sizeof(*reg));
1810 }
1811
1812 static void
1813 get_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp,
1814            int tos)
1815 {
1816
1817         if ((regno += tos) >= 8)
1818                 regno -= 8;
1819         switch (regno) {
1820               case 0:
1821                 copy_from_user(&ptp->f8, reg, sizeof(*reg));
1822                 break;
1823               case 1:
1824                 copy_from_user(&ptp->f9, reg, sizeof(*reg));
1825                 break;
1826               case 2:
1827               case 3:
1828               case 4:
1829               case 5:
1830               case 6:
1831               case 7:
1832                 copy_from_user(&swp->f10 + (regno - 2), reg, sizeof(*reg));
1833                 break;
1834         }
1835         return;
1836 }
1837
1838 static int
1839 save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save)
1840 {
1841         struct switch_stack *swp;
1842         struct pt_regs *ptp;
1843         int i, tos;
1844
1845         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1846                 return -EFAULT;
1847
1848         __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1849         __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1850         __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1851         __put_user(tsk->thread.fir, &save->fip);
1852         __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1853         __put_user(tsk->thread.fdr, &save->foo);
1854         __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1855
1856         /*
1857          *  Stack frames start with 16-bytes of temp space
1858          */
1859         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1860         ptp = ia64_task_regs(tsk);
1861         tos = (tsk->thread.fsr >> 11) & 7;
1862         for (i = 0; i < 8; i++)
1863                 put_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
1864         return 0;
1865 }
1866
1867 static int
1868 restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save)
1869 {
1870         struct switch_stack *swp;
1871         struct pt_regs *ptp;
1872         int i, tos;
1873         unsigned int fsrlo, fsrhi, num32;
1874
1875         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1876                 return(-EFAULT);
1877
1878         __get_user(num32, (unsigned int *)&save->cwd);
1879         tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1880         __get_user(fsrlo, (unsigned int *)&save->swd);
1881         __get_user(fsrhi, (unsigned int *)&save->twd);
1882         num32 = (fsrhi << 16) | fsrlo;
1883         tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1884         __get_user(num32, (unsigned int *)&save->fip);
1885         tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1886         __get_user(num32, (unsigned int *)&save->foo);
1887         tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1888
1889         /*
1890          *  Stack frames start with 16-bytes of temp space
1891          */
1892         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1893         ptp = ia64_task_regs(tsk);
1894         tos = (tsk->thread.fsr >> 11) & 7;
1895         for (i = 0; i < 8; i++)
1896                 get_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
1897         return 0;
1898 }
1899
1900 static int
1901 save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save)
1902 {
1903         struct switch_stack *swp;
1904         struct pt_regs *ptp;
1905         int i, tos;
1906         unsigned long mxcsr=0;
1907         unsigned long num128[2];
1908
1909         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1910                 return -EFAULT;
1911
1912         __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1913         __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1914         __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1915         __put_user(tsk->thread.fir, &save->fip);
1916         __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1917         __put_user(tsk->thread.fdr, &save->foo);
1918         __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1919
1920         /*
1921          *  Stack frames start with 16-bytes of temp space
1922          */
1923         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1924         ptp = ia64_task_regs(tsk);
1925         tos = (tsk->thread.fsr >> 11) & 7;
1926         for (i = 0; i < 8; i++)
1927                 put_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
1928
1929         mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f);
1930         __put_user(mxcsr & 0xffff, &save->mxcsr);
1931         for (i = 0; i < 8; i++) {
1932                 memcpy(&(num128[0]), &(swp->f16) + i*2, sizeof(unsigned long));
1933                 memcpy(&(num128[1]), &(swp->f17) + i*2, sizeof(unsigned long));
1934                 copy_to_user(&save->xmm_space[0] + 4*i, num128, sizeof(struct _xmmreg_ia32));
1935         }
1936         return 0;
1937 }
1938
1939 static int
1940 restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save)
1941 {
1942         struct switch_stack *swp;
1943         struct pt_regs *ptp;
1944         int i, tos;
1945         unsigned int fsrlo, fsrhi, num32;
1946         int mxcsr;
1947         unsigned long num64;
1948         unsigned long num128[2];
1949
1950         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1951                 return(-EFAULT);
1952
1953         __get_user(num32, (unsigned int *)&save->cwd);
1954         tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1955         __get_user(fsrlo, (unsigned int *)&save->swd);
1956         __get_user(fsrhi, (unsigned int *)&save->twd);
1957         num32 = (fsrhi << 16) | fsrlo;
1958         tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1959         __get_user(num32, (unsigned int *)&save->fip);
1960         tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1961         __get_user(num32, (unsigned int *)&save->foo);
1962         tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1963
1964         /*
1965          *  Stack frames start with 16-bytes of temp space
1966          */
1967         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1968         ptp = ia64_task_regs(tsk);
1969         tos = (tsk->thread.fsr >> 11) & 7;
1970         for (i = 0; i < 8; i++)
1971         get_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
1972
1973         __get_user(mxcsr, (unsigned int *)&save->mxcsr);
1974         num64 = mxcsr & 0xff10;
1975         tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000)) | (num64<<32);
1976         num64 = mxcsr & 0x3f;
1977         tsk->thread.fsr = (tsk->thread.fsr & (~0x3f00000000)) | (num64<<32);
1978
1979         for (i = 0; i < 8; i++) {
1980                 copy_from_user(num128, &save->xmm_space[0] + 4*i, sizeof(struct _xmmreg_ia32));
1981                 memcpy(&(swp->f16) + i*2, &(num128[0]), sizeof(unsigned long));
1982                 memcpy(&(swp->f17) + i*2, &(num128[1]), sizeof(unsigned long));
1983         }
1984         return 0;
1985 }
1986
1987 extern asmlinkage long sys_ptrace (long, pid_t, unsigned long, unsigned long, long, long, long,
1988                                    long, long);
1989
1990 /*
1991  *  Note that the IA32 version of `ptrace' calls the IA64 routine for
1992  *    many of the requests.  This will only work for requests that do
1993  *    not need access to the calling processes `pt_regs' which is located
1994  *    at the address of `stack'.  Once we call the IA64 `sys_ptrace' then
1995  *    the address of `stack' will not be the address of the `pt_regs'.
1996  */
1997 asmlinkage long
1998 sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
1999               long arg4, long arg5, long arg6, long arg7, long stack)
2000 {
2001         struct pt_regs *regs = (struct pt_regs *) &stack;
2002         struct task_struct *child;
2003         unsigned int value, tmp;
2004         long i, ret;
2005
2006         lock_kernel();
2007         if (request == PTRACE_TRACEME) {
2008                 ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
2009                 goto out;
2010         }
2011
2012         ret = -ESRCH;
2013         read_lock(&tasklist_lock);
2014         child = find_task_by_pid(pid);
2015         if (child)
2016                 get_task_struct(child);
2017         read_unlock(&tasklist_lock);
2018         if (!child)
2019                 goto out;
2020         ret = -EPERM;
2021         if (pid == 1)           /* no messing around with init! */
2022                 goto out_tsk;
2023
2024         if (request == PTRACE_ATTACH) {
2025                 ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
2026                 goto out_tsk;
2027         }
2028
2029         ret = ptrace_check_attach(child, request == PTRACE_KILL);
2030         if (ret < 0)
2031                 goto out_tsk;
2032
2033         switch (request) {
2034               case PTRACE_PEEKTEXT:
2035               case PTRACE_PEEKDATA:     /* read word at location addr */
2036                 ret = ia32_peek(regs, child, addr, &value);
2037                 if (ret == 0)
2038                         ret = put_user(value, (unsigned int *) A(data));
2039                 else
2040                         ret = -EIO;
2041                 goto out_tsk;
2042
2043               case PTRACE_POKETEXT:
2044               case PTRACE_POKEDATA:     /* write the word at location addr */
2045                 ret = ia32_poke(regs, child, addr, data);
2046                 goto out_tsk;
2047
2048               case PTRACE_PEEKUSR:      /* read word at addr in USER area */
2049                 ret = -EIO;
2050                 if ((addr & 3) || addr > 17*sizeof(int))
2051                         break;
2052
2053                 tmp = getreg(child, addr);
2054                 if (!put_user(tmp, (unsigned int *) A(data)))
2055                         ret = 0;
2056                 break;
2057
2058               case PTRACE_POKEUSR:      /* write word at addr in USER area */
2059                 ret = -EIO;
2060                 if ((addr & 3) || addr > 17*sizeof(int))
2061                         break;
2062
2063                 putreg(child, addr, data);
2064                 ret = 0;
2065                 break;
2066
2067               case IA32_PTRACE_GETREGS:
2068                 if (!access_ok(VERIFY_WRITE, (int *) A(data), 17*sizeof(int))) {
2069                         ret = -EIO;
2070                         break;
2071                 }
2072                 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
2073                         put_user(getreg(child, i), (unsigned int *) A(data));
2074                         data += sizeof(int);
2075                 }
2076                 ret = 0;
2077                 break;
2078
2079               case IA32_PTRACE_SETREGS:
2080                 if (!access_ok(VERIFY_READ, (int *) A(data), 17*sizeof(int))) {
2081                         ret = -EIO;
2082                         break;
2083                 }
2084                 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
2085                         get_user(tmp, (unsigned int *) A(data));
2086                         putreg(child, i, tmp);
2087                         data += sizeof(int);
2088                 }
2089                 ret = 0;
2090                 break;
2091
2092               case IA32_PTRACE_GETFPREGS:
2093                 ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct *) A(data));
2094                 break;
2095
2096               case IA32_PTRACE_GETFPXREGS:
2097                 ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct *) A(data));
2098                 break;
2099
2100               case IA32_PTRACE_SETFPREGS:
2101                 ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct *) A(data));
2102                 break;
2103
2104               case IA32_PTRACE_SETFPXREGS:
2105                 ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct *) A(data));
2106                 break;
2107
2108               case PTRACE_SYSCALL:      /* continue, stop after next syscall */
2109               case PTRACE_CONT:         /* restart after signal. */
2110               case PTRACE_KILL:
2111               case PTRACE_SINGLESTEP:   /* execute chile for one instruction */
2112               case PTRACE_DETACH:       /* detach a process */
2113                 ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
2114                 break;
2115
2116               default:
2117                 ret = ptrace_request(child, request, addr, data);
2118                 break;
2119
2120         }
2121   out_tsk:
2122         put_task_struct(child);
2123   out:
2124         unlock_kernel();
2125         return ret;
2126 }
2127
2128 asmlinkage long sys_ni_syscall(void);
2129
2130 asmlinkage long
2131 sys32_ni_syscall (int dummy0, int dummy1, int dummy2, int dummy3, int dummy4, int dummy5,
2132                   int dummy6, int dummy7, int stack)
2133 {
2134         struct pt_regs *regs = (struct pt_regs *)&stack;
2135
2136         printk(KERN_WARNING "IA32 syscall #%d issued, maybe we should implement it\n",
2137                (int)regs->r1);
2138         return(sys_ni_syscall());
2139 }
2140
2141 /*
2142  *  The IA64 maps 4 I/O ports for each 4K page
2143  */
2144 #define IOLEN   ((65536 / 4) * 4096)
2145
2146 asmlinkage long
2147 sys32_iopl (int level)
2148 {
2149         extern unsigned long ia64_iobase;
2150         int fd;
2151         struct file * file;
2152         unsigned int old;
2153         unsigned long addr;
2154         mm_segment_t old_fs = get_fs ();
2155
2156         if (level != 3)
2157                 return(-EINVAL);
2158         /* Trying to gain more privileges? */
2159         asm volatile ("mov %0=ar.eflag ;;" : "=r"(old));
2160         if ((unsigned int) level > ((old >> 12) & 3)) {
2161                 if (!capable(CAP_SYS_RAWIO))
2162                         return -EPERM;
2163         }
2164         set_fs(KERNEL_DS);
2165         fd = sys_open("/dev/mem", O_SYNC | O_RDWR, 0);
2166         set_fs(old_fs);
2167         if (fd < 0)
2168                 return fd;
2169         file = fget(fd);
2170         if (file == NULL) {
2171                 sys_close(fd);
2172                 return(-EFAULT);
2173         }
2174
2175         down_write(&current->mm->mmap_sem);
2176         addr = do_mmap_pgoff(file, IA32_IOBASE,
2177                              IOLEN, PROT_READ|PROT_WRITE, MAP_SHARED,
2178                              (ia64_iobase & ~PAGE_OFFSET) >> PAGE_SHIFT);
2179         up_write(&current->mm->mmap_sem);
2180
2181         if (addr >= 0) {
2182                 old = (old & ~0x3000) | (level << 12);
2183                 asm volatile ("mov ar.eflag=%0;;" :: "r"(old));
2184         }
2185
2186         fput(file);
2187         sys_close(fd);
2188         return 0;
2189 }
2190
2191 asmlinkage long
2192 sys32_ioperm (unsigned int from, unsigned int num, int on)
2193 {
2194
2195         /*
2196          *  Since IA64 doesn't have permission bits we'd have to go to
2197          *    a lot of trouble to simulate them in software.  There's
2198          *    no point, only trusted programs can make this call so we'll
2199          *    just turn it into an iopl call and let the process have
2200          *    access to all I/O ports.
2201          *
2202          * XXX proper ioperm() support should be emulated by
2203          *      manipulating the page protections...
2204          */
2205         return sys32_iopl(3);
2206 }
2207
2208 typedef struct {
2209         unsigned int    ss_sp;
2210         unsigned int    ss_flags;
2211         unsigned int    ss_size;
2212 } ia32_stack_t;
2213
2214 asmlinkage long
2215 sys32_sigaltstack (ia32_stack_t *uss32, ia32_stack_t *uoss32,
2216                    long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long stack)
2217 {
2218         struct pt_regs *pt = (struct pt_regs *) &stack;
2219         stack_t uss, uoss;
2220         ia32_stack_t buf32;
2221         int ret;
2222         mm_segment_t old_fs = get_fs();
2223
2224         if (uss32)
2225                 if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t)))
2226                         return -EFAULT;
2227         uss.ss_sp = (void *) (long) buf32.ss_sp;
2228         uss.ss_flags = buf32.ss_flags;
2229         uss.ss_size = buf32.ss_size;
2230         set_fs(KERNEL_DS);
2231         ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12);
2232         set_fs(old_fs);
2233         if (ret < 0)
2234                 return(ret);
2235         if (uoss32) {
2236                 buf32.ss_sp = (long) uoss.ss_sp;
2237                 buf32.ss_flags = uoss.ss_flags;
2238                 buf32.ss_size = uoss.ss_size;
2239                 if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t)))
2240                         return -EFAULT;
2241         }
2242         return ret;
2243 }
2244
2245 asmlinkage int
2246 sys32_pause (void)
2247 {
2248         current->state = TASK_INTERRUPTIBLE;
2249         schedule();
2250         return -ERESTARTNOHAND;
2251 }
2252
2253 asmlinkage long sys_msync (unsigned long start, size_t len, int flags);
2254
2255 asmlinkage int
2256 sys32_msync (unsigned int start, unsigned int len, int flags)
2257 {
2258         unsigned int addr;
2259
2260         if (OFFSET4K(start))
2261                 return -EINVAL;
2262         addr = PAGE_START(start);
2263         return sys_msync(addr, len + (start - addr), flags);
2264 }
2265
2266 struct sysctl32 {
2267         unsigned int    name;
2268         int             nlen;
2269         unsigned int    oldval;
2270         unsigned int    oldlenp;
2271         unsigned int    newval;
2272         unsigned int    newlen;
2273         unsigned int    __unused[4];
2274 };
2275
2276 extern asmlinkage long sys_sysctl(struct __sysctl_args *args);
2277
2278 asmlinkage long
2279 sys32_sysctl (struct sysctl32 *args)
2280 {
2281 #ifdef CONFIG_SYSCTL
2282         struct sysctl32 a32;
2283         mm_segment_t old_fs = get_fs ();
2284         void *oldvalp, *newvalp;
2285         size_t oldlen;
2286         int *namep;
2287         long ret;
2288
2289         if (copy_from_user(&a32, args, sizeof(a32)))
2290                 return -EFAULT;
2291
2292         /*
2293          * We need to pre-validate these because we have to disable address checking
2294          * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
2295          * user specifying bad addresses here.  Well, since we're dealing with 32 bit
2296          * addresses, we KNOW that access_ok() will always succeed, so this is an
2297          * expensive NOP, but so what...
2298          */
2299         namep = (int *) A(a32.name);
2300         oldvalp = (void *) A(a32.oldval);
2301         newvalp = (void *) A(a32.newval);
2302
2303         if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp)))
2304             || !access_ok(VERIFY_WRITE, namep, 0)
2305             || !access_ok(VERIFY_WRITE, oldvalp, 0)
2306             || !access_ok(VERIFY_WRITE, newvalp, 0))
2307                 return -EFAULT;
2308
2309         set_fs(KERNEL_DS);
2310         lock_kernel();
2311         ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen);
2312         unlock_kernel();
2313         set_fs(old_fs);
2314
2315         if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp)))
2316                 return -EFAULT;
2317
2318         return ret;
2319 #else
2320         return -ENOSYS;
2321 #endif
2322 }
2323
2324 asmlinkage long
2325 sys32_newuname (struct new_utsname *name)
2326 {
2327         extern asmlinkage long sys_newuname(struct new_utsname * name);
2328         int ret = sys_newuname(name);
2329
2330         if (!ret)
2331                 if (copy_to_user(name->machine, "i686\0\0\0", 8))
2332                         ret = -EFAULT;
2333         return ret;
2334 }
2335
2336 extern asmlinkage long sys_getresuid (uid_t *ruid, uid_t *euid, uid_t *suid);
2337
2338 asmlinkage long
2339 sys32_getresuid16 (u16 *ruid, u16 *euid, u16 *suid)
2340 {
2341         uid_t a, b, c;
2342         int ret;
2343         mm_segment_t old_fs = get_fs();
2344
2345         set_fs(KERNEL_DS);
2346         ret = sys_getresuid(&a, &b, &c);
2347         set_fs(old_fs);
2348
2349         if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
2350                 return -EFAULT;
2351         return ret;
2352 }
2353
2354 extern asmlinkage long sys_getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid);
2355
2356 asmlinkage long
2357 sys32_getresgid16 (u16 *rgid, u16 *egid, u16 *sgid)
2358 {
2359         gid_t a, b, c;
2360         int ret;
2361         mm_segment_t old_fs = get_fs();
2362
2363         set_fs(KERNEL_DS);
2364         ret = sys_getresgid(&a, &b, &c);
2365         set_fs(old_fs);
2366
2367         if (ret)
2368                 return ret;
2369
2370         return put_user(a, rgid) | put_user(b, egid) | put_user(c, sgid);
2371 }
2372
2373 asmlinkage long
2374 sys32_lseek (unsigned int fd, int offset, unsigned int whence)
2375 {
2376         extern off_t sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
2377
2378         /* Sign-extension of "offset" is important here... */
2379         return sys_lseek(fd, offset, whence);
2380 }
2381
2382 extern asmlinkage long sys_getgroups (int gidsetsize, gid_t *grouplist);
2383
2384 asmlinkage long
2385 sys32_getgroups16 (int gidsetsize, short *grouplist)
2386 {
2387         mm_segment_t old_fs = get_fs();
2388         gid_t gl[NGROUPS];
2389         int ret, i;
2390
2391         set_fs(KERNEL_DS);
2392         ret = sys_getgroups(gidsetsize, gl);
2393         set_fs(old_fs);
2394
2395         if (gidsetsize && ret > 0 && ret <= NGROUPS)
2396                 for (i = 0; i < ret; i++, grouplist++)
2397                         if (put_user(gl[i], grouplist))
2398                                 return -EFAULT;
2399         return ret;
2400 }
2401
2402 extern asmlinkage long sys_setgroups (int gidsetsize, gid_t *grouplist);
2403
2404 asmlinkage long
2405 sys32_setgroups16 (int gidsetsize, short *grouplist)
2406 {
2407         mm_segment_t old_fs = get_fs();
2408         gid_t gl[NGROUPS];
2409         int ret, i;
2410
2411         if ((unsigned) gidsetsize > NGROUPS)
2412                 return -EINVAL;
2413         for (i = 0; i < gidsetsize; i++, grouplist++)
2414                 if (get_user(gl[i], grouplist))
2415                         return -EFAULT;
2416         set_fs(KERNEL_DS);
2417         ret = sys_setgroups(gidsetsize, gl);
2418         set_fs(old_fs);
2419         return ret;
2420 }
2421
2422 asmlinkage long
2423 sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi)
2424 {
2425         extern asmlinkage long sys_truncate (const char *path, unsigned long length);
2426
2427         return sys_truncate((const char *) A(path), ((unsigned long) len_hi << 32) | len_lo);
2428 }
2429
2430 asmlinkage long
2431 sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi)
2432 {
2433         extern asmlinkage long sys_ftruncate (int fd, unsigned long length);
2434
2435         return sys_ftruncate(fd, ((unsigned long) len_hi << 32) | len_lo);
2436 }
2437
2438 static int
2439 putstat64 (struct stat64 *ubuf, struct kstat *kbuf)
2440 {
2441         int err;
2442
2443         if (clear_user(ubuf, sizeof(*ubuf)))
2444                 return -EFAULT;
2445
2446         err  = __put_user(kbuf->dev, &ubuf->st_dev);
2447         err |= __put_user(kbuf->ino, &ubuf->__st_ino);
2448         err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
2449         err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
2450         err |= __put_user(kbuf->mode, &ubuf->st_mode);
2451         err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
2452         err |= __put_user(kbuf->uid, &ubuf->st_uid);
2453         err |= __put_user(kbuf->gid, &ubuf->st_gid);
2454         err |= __put_user(kbuf->rdev, &ubuf->st_rdev);
2455         err |= __put_user(kbuf->size, &ubuf->st_size_lo);
2456         err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
2457         err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
2458         err |= __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec);
2459         err |= __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime);
2460         err |= __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec);
2461         err |= __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime);
2462         err |= __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec);
2463         err |= __put_user(kbuf->blksize, &ubuf->st_blksize);
2464         err |= __put_user(kbuf->blocks, &ubuf->st_blocks);
2465         return err;
2466 }
2467
2468 asmlinkage long
2469 sys32_stat64 (char *filename, struct stat64 *statbuf)
2470 {
2471         struct kstat s;
2472         long ret = vfs_stat(filename, &s);
2473         if (!ret)
2474                 ret = putstat64(statbuf, &s);
2475         return ret;
2476 }
2477
2478 asmlinkage long
2479 sys32_lstat64 (char *filename, struct stat64 *statbuf)
2480 {
2481         struct kstat s;
2482         long ret = vfs_lstat(filename, &s);
2483         if (!ret)
2484                 ret = putstat64(statbuf, &s);
2485         return ret;
2486 }
2487
2488 asmlinkage long
2489 sys32_fstat64 (unsigned int fd, struct stat64 *statbuf)
2490 {
2491         struct kstat s;
2492         long ret = vfs_fstat(fd, &s);
2493         if (!ret)
2494                 ret = putstat64(statbuf, &s);
2495         return ret;
2496 }
2497
2498 struct sysinfo32 {
2499         s32 uptime;
2500         u32 loads[3];
2501         u32 totalram;
2502         u32 freeram;
2503         u32 sharedram;
2504         u32 bufferram;
2505         u32 totalswap;
2506         u32 freeswap;
2507         u16 procs;
2508         u16 pad;
2509         u32 totalhigh;
2510         u32 freehigh;
2511         u32 mem_unit;
2512         char _f[8];
2513 };
2514
2515 asmlinkage long
2516 sys32_sysinfo (struct sysinfo32 *info)
2517 {
2518         extern asmlinkage long sys_sysinfo (struct sysinfo *);
2519         mm_segment_t old_fs = get_fs();
2520         struct sysinfo s;
2521         long ret, err;
2522
2523         set_fs(KERNEL_DS);
2524         ret = sys_sysinfo(&s);
2525         set_fs(old_fs);
2526
2527         if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
2528                 return -EFAULT;
2529
2530         err  = __put_user(s.uptime, &info->uptime);
2531         err |= __put_user(s.loads[0], &info->loads[0]);
2532         err |= __put_user(s.loads[1], &info->loads[1]);
2533         err |= __put_user(s.loads[2], &info->loads[2]);
2534         err |= __put_user(s.totalram, &info->totalram);
2535         err |= __put_user(s.freeram, &info->freeram);
2536         err |= __put_user(s.sharedram, &info->sharedram);
2537         err |= __put_user(s.bufferram, &info->bufferram);
2538         err |= __put_user(s.totalswap, &info->totalswap);
2539         err |= __put_user(s.freeswap, &info->freeswap);
2540         err |= __put_user(s.procs, &info->procs);
2541         err |= __put_user (s.totalhigh, &info->totalhigh);
2542         err |= __put_user (s.freehigh, &info->freehigh);
2543         err |= __put_user (s.mem_unit, &info->mem_unit);
2544         if (err)
2545                 return -EFAULT;
2546         return ret;
2547 }
2548
2549 asmlinkage long
2550 sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec *interval)
2551 {
2552         extern asmlinkage long sys_sched_rr_get_interval (pid_t, struct timespec *);
2553         mm_segment_t old_fs = get_fs();
2554         struct timespec t;
2555         long ret;
2556
2557         set_fs(KERNEL_DS);
2558         ret = sys_sched_rr_get_interval(pid, &t);
2559         set_fs(old_fs);
2560         if (put_compat_timespec(&t, interval))
2561                 return -EFAULT;
2562         return ret;
2563 }
2564
2565 asmlinkage long
2566 sys32_pread (unsigned int fd, void *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
2567 {
2568         extern asmlinkage long sys_pread64 (unsigned int, char *, size_t, loff_t);
2569         return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
2570 }
2571
2572 asmlinkage long
2573 sys32_pwrite (unsigned int fd, void *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
2574 {
2575         extern asmlinkage long sys_pwrite64 (unsigned int, const char *, size_t, loff_t);
2576         return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
2577 }
2578
2579 asmlinkage long
2580 sys32_sendfile (int out_fd, int in_fd, int *offset, unsigned int count)
2581 {
2582         extern asmlinkage long sys_sendfile (int, int, off_t *, size_t);
2583         mm_segment_t old_fs = get_fs();
2584         long ret;
2585         off_t of;
2586
2587         if (offset && get_user(of, offset))
2588                 return -EFAULT;
2589
2590         set_fs(KERNEL_DS);
2591         ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
2592         set_fs(old_fs);
2593
2594         if (!ret && offset && put_user(of, offset))
2595                 return -EFAULT;
2596
2597         return ret;
2598 }
2599
2600 asmlinkage long
2601 sys32_personality (unsigned int personality)
2602 {
2603         extern asmlinkage long sys_personality (unsigned long);
2604         long ret;
2605
2606         if (current->personality == PER_LINUX32 && personality == PER_LINUX)
2607                 personality = PER_LINUX32;
2608         ret = sys_personality(personality);
2609         if (ret == PER_LINUX32)
2610                 ret = PER_LINUX;
2611         return ret;
2612 }
2613
2614 asmlinkage unsigned long
2615 sys32_brk (unsigned int brk)
2616 {
2617         unsigned long ret, obrk;
2618         struct mm_struct *mm = current->mm;
2619
2620         obrk = mm->brk;
2621         ret = sys_brk(brk);
2622         if (ret < obrk)
2623                 clear_user((void *) ret, PAGE_ALIGN(ret) - ret);
2624         return ret;
2625 }
2626
2627 /*
2628  * Exactly like fs/open.c:sys_open(), except that it doesn't set the O_LARGEFILE flag.
2629  */
2630 asmlinkage long
2631 sys32_open (const char * filename, int flags, int mode)
2632 {
2633         char * tmp;
2634         int fd, error;
2635
2636         tmp = getname(filename);
2637         fd = PTR_ERR(tmp);
2638         if (!IS_ERR(tmp)) {
2639                 fd = get_unused_fd();
2640                 if (fd >= 0) {
2641                         struct file *f = filp_open(tmp, flags, mode);
2642                         error = PTR_ERR(f);
2643                         if (IS_ERR(f))
2644                                 goto out_error;
2645                         fd_install(fd, f);
2646                 }
2647 out:
2648                 putname(tmp);
2649         }
2650         return fd;
2651
2652 out_error:
2653         put_unused_fd(fd);
2654         fd = error;
2655         goto out;
2656 }
2657
2658 #ifdef  NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
2659
2660 struct ncp_mount_data32 {
2661         int version;
2662         unsigned int ncp_fd;
2663         compat_uid_t mounted_uid;
2664         int wdog_pid;
2665         unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
2666         unsigned int time_out;
2667         unsigned int retry_count;
2668         unsigned int flags;
2669         compat_uid_t uid;
2670         compat_gid_t gid;
2671         compat_mode_t file_mode;
2672         compat_mode_t dir_mode;
2673 };
2674
2675 static void *
2676 do_ncp_super_data_conv(void *raw_data)
2677 {
2678         struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
2679         struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
2680
2681         n->dir_mode = n32->dir_mode;
2682         n->file_mode = n32->file_mode;
2683         n->gid = n32->gid;
2684         n->uid = n32->uid;
2685         memmove (n->mounted_vol, n32->mounted_vol,
2686                  (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
2687         n->wdog_pid = n32->wdog_pid;
2688         n->mounted_uid = n32->mounted_uid;
2689         return raw_data;
2690 }
2691
2692 struct smb_mount_data32 {
2693         int version;
2694         compat_uid_t mounted_uid;
2695         compat_uid_t uid;
2696         compat_gid_t gid;
2697         compat_mode_t file_mode;
2698         compat_mode_t dir_mode;
2699 };
2700
2701 static void *
2702 do_smb_super_data_conv(void *raw_data)
2703 {
2704         struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
2705         struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
2706
2707         if (s32->version != SMB_MOUNT_OLDVERSION)
2708                 goto out;
2709         s->version = s32->version;
2710         s->mounted_uid = s32->mounted_uid;
2711         s->uid = s32->uid;
2712         s->gid = s32->gid;
2713         s->file_mode = s32->file_mode;
2714         s->dir_mode = s32->dir_mode;
2715 out:
2716         return raw_data;
2717 }
2718
2719 static int
2720 copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
2721 {
2722         int i;
2723         unsigned long page;
2724         struct vm_area_struct *vma;
2725
2726         *kernel = 0;
2727         if(!user)
2728                 return 0;
2729         vma = find_vma(current->mm, (unsigned long)user);
2730         if(!vma || (unsigned long)user < vma->vm_start)
2731                 return -EFAULT;
2732         if(!(vma->vm_flags & VM_READ))
2733                 return -EFAULT;
2734         i = vma->vm_end - (unsigned long) user;
2735         if(PAGE_SIZE <= (unsigned long) i)
2736                 i = PAGE_SIZE - 1;
2737         if(!(page = __get_free_page(GFP_KERNEL)))
2738                 return -ENOMEM;
2739         if(copy_from_user((void *) page, user, i)) {
2740                 free_page(page);
2741                 return -EFAULT;
2742         }
2743         *kernel = page;
2744         return 0;
2745 }
2746
2747 extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
2748                                 unsigned long new_flags, void *data);
2749
2750 #define SMBFS_NAME      "smbfs"
2751 #define NCPFS_NAME      "ncpfs"
2752
2753 asmlinkage long
2754 sys32_mount(char *dev_name, char *dir_name, char *type,
2755             unsigned long new_flags, u32 data)
2756 {
2757         unsigned long type_page;
2758         int err, is_smb, is_ncp;
2759
2760         if(!capable(CAP_SYS_ADMIN))
2761                 return -EPERM;
2762         is_smb = is_ncp = 0;
2763         err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
2764         if(err)
2765                 return err;
2766         if(type_page) {
2767                 is_smb = !strcmp((char *)type_page, SMBFS_NAME);
2768                 is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
2769         }
2770         if(!is_smb && !is_ncp) {
2771                 if(type_page)
2772                         free_page(type_page);
2773                 return sys_mount(dev_name, dir_name, type, new_flags,
2774                                  (void *)AA(data));
2775         } else {
2776                 unsigned long dev_page, dir_page, data_page;
2777
2778                 err = copy_mount_stuff_to_kernel((const void *)dev_name,
2779                                                  &dev_page);
2780                 if(err)
2781                         goto out;
2782                 err = copy_mount_stuff_to_kernel((const void *)dir_name,
2783                                                  &dir_page);
2784                 if(err)
2785                         goto dev_out;
2786                 err = copy_mount_stuff_to_kernel((const void *)AA(data),
2787                                                  &data_page);
2788                 if(err)
2789                         goto dir_out;
2790                 if(is_ncp)
2791                         do_ncp_super_data_conv((void *)data_page);
2792                 else if(is_smb)
2793                         do_smb_super_data_conv((void *)data_page);
2794                 else
2795                         panic("The problem is here...");
2796                 err = do_mount((char *)dev_page, (char *)dir_page,
2797                                 (char *)type_page, new_flags,
2798                                 (void *)data_page);
2799                 if(data_page)
2800                         free_page(data_page);
2801         dir_out:
2802                 if(dir_page)
2803                         free_page(dir_page);
2804         dev_out:
2805                 if(dev_page)
2806                         free_page(dev_page);
2807         out:
2808                 if(type_page)
2809                         free_page(type_page);
2810                 return err;
2811         }
2812 }
2813
2814 extern asmlinkage long sys_setreuid(uid_t ruid, uid_t euid);
2815
2816 asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid)
2817 {
2818         uid_t sruid, seuid;
2819
2820         sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2821         seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
2822         return sys_setreuid(sruid, seuid);
2823 }
2824
2825 extern asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
2826
2827 asmlinkage long
2828 sys32_setresuid(compat_uid_t ruid, compat_uid_t euid,
2829                 compat_uid_t suid)
2830 {
2831         uid_t sruid, seuid, ssuid;
2832
2833         sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2834         seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
2835         ssuid = (suid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)suid);
2836         return sys_setresuid(sruid, seuid, ssuid);
2837 }
2838
2839 extern asmlinkage long sys_setregid(gid_t rgid, gid_t egid);
2840
2841 asmlinkage long
2842 sys32_setregid(compat_gid_t rgid, compat_gid_t egid)
2843 {
2844         gid_t srgid, segid;
2845
2846         srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2847         segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
2848         return sys_setregid(srgid, segid);
2849 }
2850
2851 extern asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
2852
2853 asmlinkage long
2854 sys32_setresgid(compat_gid_t rgid, compat_gid_t egid,
2855                 compat_gid_t sgid)
2856 {
2857         gid_t srgid, segid, ssgid;
2858
2859         srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2860         segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
2861         ssgid = (sgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)sgid);
2862         return sys_setresgid(srgid, segid, ssgid);
2863 }
2864
2865 /* Stuff for NFS server syscalls... */
2866 struct nfsctl_svc32 {
2867         u16                     svc32_port;
2868         s32                     svc32_nthreads;
2869 };
2870
2871 struct nfsctl_client32 {
2872         s8                      cl32_ident[NFSCLNT_IDMAX+1];
2873         s32                     cl32_naddr;
2874         struct in_addr          cl32_addrlist[NFSCLNT_ADDRMAX];
2875         s32                     cl32_fhkeytype;
2876         s32                     cl32_fhkeylen;
2877         u8                      cl32_fhkey[NFSCLNT_KEYMAX];
2878 };
2879
2880 struct nfsctl_export32 {
2881         s8                      ex32_client[NFSCLNT_IDMAX+1];
2882         s8                      ex32_path[NFS_MAXPATHLEN+1];
2883         compat_dev_t    ex32_dev;
2884         compat_ino_t    ex32_ino;
2885         s32                     ex32_flags;
2886         compat_uid_t    ex32_anon_uid;
2887         compat_gid_t    ex32_anon_gid;
2888 };
2889
2890 struct nfsctl_arg32 {
2891         s32                     ca32_version;   /* safeguard */
2892         union {
2893                 struct nfsctl_svc32     u32_svc;
2894                 struct nfsctl_client32  u32_client;
2895                 struct nfsctl_export32  u32_export;
2896                 u32                     u32_debug;
2897         } u;
2898 #define ca32_svc        u.u32_svc
2899 #define ca32_client     u.u32_client
2900 #define ca32_export     u.u32_export
2901 #define ca32_debug      u.u32_debug
2902 };
2903
2904 union nfsctl_res32 {
2905         struct knfs_fh          cr32_getfh;
2906         u32                     cr32_debug;
2907 };
2908
2909 static int
2910 nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
2911 {
2912         int err;
2913
2914         err = __get_user(karg->ca_version, &arg32->ca32_version);
2915         err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
2916         err |= __get_user(karg->ca_svc.svc_nthreads,
2917                           &arg32->ca32_svc.svc32_nthreads);
2918         return err;
2919 }
2920
2921 static int
2922 nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
2923 {
2924         int err;
2925
2926         err = __get_user(karg->ca_version, &arg32->ca32_version);
2927         err |= copy_from_user(&karg->ca_client.cl_ident[0],
2928                           &arg32->ca32_client.cl32_ident[0],
2929                           NFSCLNT_IDMAX);
2930         err |= __get_user(karg->ca_client.cl_naddr,
2931                           &arg32->ca32_client.cl32_naddr);
2932         err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
2933                           &arg32->ca32_client.cl32_addrlist[0],
2934                           (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
2935         err |= __get_user(karg->ca_client.cl_fhkeytype,
2936                       &arg32->ca32_client.cl32_fhkeytype);
2937         err |= __get_user(karg->ca_client.cl_fhkeylen,
2938                       &arg32->ca32_client.cl32_fhkeylen);
2939         err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
2940                           &arg32->ca32_client.cl32_fhkey[0],
2941                           NFSCLNT_KEYMAX);
2942         return err;
2943 }
2944
2945 static int
2946 nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
2947 {
2948         int err;
2949
2950         err = __get_user(karg->ca_version, &arg32->ca32_version);
2951         err |= copy_from_user(&karg->ca_export.ex_client[0],
2952                           &arg32->ca32_export.ex32_client[0],
2953                           NFSCLNT_IDMAX);
2954         err |= copy_from_user(&karg->ca_export.ex_path[0],
2955                           &arg32->ca32_export.ex32_path[0],
2956                           NFS_MAXPATHLEN);
2957         err |= __get_user(karg->ca_export.ex_dev,
2958                       &arg32->ca32_export.ex32_dev);
2959         err |= __get_user(karg->ca_export.ex_ino,
2960                       &arg32->ca32_export.ex32_ino);
2961         err |= __get_user(karg->ca_export.ex_flags,
2962                       &arg32->ca32_export.ex32_flags);
2963         err |= __get_user(karg->ca_export.ex_anon_uid,
2964                       &arg32->ca32_export.ex32_anon_uid);
2965         err |= __get_user(karg->ca_export.ex_anon_gid,
2966                       &arg32->ca32_export.ex32_anon_gid);
2967         return err;
2968 }
2969
2970 static int
2971 nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
2972 {
2973         int err;
2974
2975         err = copy_to_user(&res32->cr32_getfh,
2976                         &kres->cr_getfh,
2977                         sizeof(res32->cr32_getfh));
2978         err |= __put_user(kres->cr_debug, &res32->cr32_debug);
2979         return err;
2980 }
2981
2982 extern asmlinkage long sys_nfsservctl(int cmd, void *arg, void *resp);
2983
2984 int asmlinkage
2985 sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
2986 {
2987         struct nfsctl_arg *karg = NULL;
2988         union nfsctl_res *kres = NULL;
2989         mm_segment_t oldfs;
2990         int err;
2991
2992         karg = kmalloc(sizeof(*karg), GFP_USER);
2993         if(!karg)
2994                 return -ENOMEM;
2995         if(res32) {
2996                 kres = kmalloc(sizeof(*kres), GFP_USER);
2997                 if(!kres) {
2998                         kfree(karg);
2999                         return -ENOMEM;
3000                 }
3001         }
3002         switch(cmd) {
3003         case NFSCTL_SVC:
3004                 err = nfs_svc32_trans(karg, arg32);
3005                 break;
3006         case NFSCTL_ADDCLIENT:
3007                 err = nfs_clnt32_trans(karg, arg32);
3008                 break;
3009         case NFSCTL_DELCLIENT:
3010                 err = nfs_clnt32_trans(karg, arg32);
3011                 break;
3012         case NFSCTL_EXPORT:
3013                 err = nfs_exp32_trans(karg, arg32);
3014                 break;
3015         default:
3016                 err = -EINVAL;
3017                 break;
3018         }
3019         if(err)
3020                 goto done;
3021         oldfs = get_fs();
3022         set_fs(KERNEL_DS);
3023         err = sys_nfsservctl(cmd, karg, kres);
3024         set_fs(oldfs);
3025
3026         if(!err && cmd == NFSCTL_GETFS)
3027                 err = nfs_getfh32_res_trans(kres, res32);
3028
3029 done:
3030         if(karg)
3031                 kfree(karg);
3032         if(kres)
3033                 kfree(kres);
3034         return err;
3035 }
3036
3037 /* Handle adjtimex compatibility. */
3038
3039 struct timex32 {
3040         u32 modes;
3041         s32 offset, freq, maxerror, esterror;
3042         s32 status, constant, precision, tolerance;
3043         struct compat_timeval time;
3044         s32 tick;
3045         s32 ppsfreq, jitter, shift, stabil;
3046         s32 jitcnt, calcnt, errcnt, stbcnt;
3047         s32  :32; s32  :32; s32  :32; s32  :32;
3048         s32  :32; s32  :32; s32  :32; s32  :32;
3049         s32  :32; s32  :32; s32  :32; s32  :32;
3050 };
3051
3052 extern int do_adjtimex(struct timex *);
3053
3054 asmlinkage long
3055 sys32_adjtimex(struct timex32 *utp)
3056 {
3057         struct timex txc;
3058         int ret;
3059
3060         memset(&txc, 0, sizeof(struct timex));
3061
3062         if(get_user(txc.modes, &utp->modes) ||
3063            __get_user(txc.offset, &utp->offset) ||
3064            __get_user(txc.freq, &utp->freq) ||
3065            __get_user(txc.maxerror, &utp->maxerror) ||
3066            __get_user(txc.esterror, &utp->esterror) ||
3067            __get_user(txc.status, &utp->status) ||
3068            __get_user(txc.constant, &utp->constant) ||
3069            __get_user(txc.precision, &utp->precision) ||
3070            __get_user(txc.tolerance, &utp->tolerance) ||
3071            __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
3072            __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
3073            __get_user(txc.tick, &utp->tick) ||
3074            __get_user(txc.ppsfreq, &utp->ppsfreq) ||
3075            __get_user(txc.jitter, &utp->jitter) ||
3076            __get_user(txc.shift, &utp->shift) ||
3077            __get_user(txc.stabil, &utp->stabil) ||
3078            __get_user(txc.jitcnt, &utp->jitcnt) ||
3079            __get_user(txc.calcnt, &utp->calcnt) ||
3080            __get_user(txc.errcnt, &utp->errcnt) ||
3081            __get_user(txc.stbcnt, &utp->stbcnt))
3082                 return -EFAULT;
3083
3084         ret = do_adjtimex(&txc);
3085
3086         if(put_user(txc.modes, &utp->modes) ||
3087            __put_user(txc.offset, &utp->offset) ||
3088            __put_user(txc.freq, &utp->freq) ||
3089            __put_user(txc.maxerror, &utp->maxerror) ||
3090            __put_user(txc.esterror, &utp->esterror) ||
3091            __put_user(txc.status, &utp->status) ||
3092            __put_user(txc.constant, &utp->constant) ||
3093            __put_user(txc.precision, &utp->precision) ||
3094            __put_user(txc.tolerance, &utp->tolerance) ||
3095            __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
3096            __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
3097            __put_user(txc.tick, &utp->tick) ||
3098            __put_user(txc.ppsfreq, &utp->ppsfreq) ||
3099            __put_user(txc.jitter, &utp->jitter) ||
3100            __put_user(txc.shift, &utp->shift) ||
3101            __put_user(txc.stabil, &utp->stabil) ||
3102            __put_user(txc.jitcnt, &utp->jitcnt) ||
3103            __put_user(txc.calcnt, &utp->calcnt) ||
3104            __put_user(txc.errcnt, &utp->errcnt) ||
3105            __put_user(txc.stbcnt, &utp->stbcnt))
3106                 ret = -EFAULT;
3107
3108         return ret;
3109 }
3110 #endif /* NOTYET */