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