patch-2_6_7-vs1_9_1_12
[linux-2.6.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/syscalls.h>
19 #include <linux/sysctl.h>
20 #include <linux/sched.h>
21 #include <linux/fs.h>
22 #include <linux/file.h>
23 #include <linux/signal.h>
24 #include <linux/resource.h>
25 #include <linux/times.h>
26 #include <linux/utsname.h>
27 #include <linux/timex.h>
28 #include <linux/smp.h>
29 #include <linux/smp_lock.h>
30 #include <linux/sem.h>
31 #include <linux/msg.h>
32 #include <linux/mm.h>
33 #include <linux/shm.h>
34 #include <linux/slab.h>
35 #include <linux/uio.h>
36 #include <linux/nfs_fs.h>
37 #include <linux/quota.h>
38 #include <linux/sunrpc/svc.h>
39 #include <linux/nfsd/nfsd.h>
40 #include <linux/nfsd/cache.h>
41 #include <linux/nfsd/xdr.h>
42 #include <linux/nfsd/syscall.h>
43 #include <linux/poll.h>
44 #include <linux/eventpoll.h>
45 #include <linux/personality.h>
46 #include <linux/ptrace.h>
47 #include <linux/stat.h>
48 #include <linux/ipc.h>
49 #include <linux/compat.h>
50 #include <linux/vfs.h>
51
52 #include <asm/intrinsics.h>
53 #include <asm/semaphore.h>
54 #include <asm/types.h>
55 #include <asm/uaccess.h>
56 #include <asm/unistd.h>
57
58 #include "ia32priv.h"
59
60 #include <net/scm.h>
61 #include <net/sock.h>
62
63 #define DEBUG   0
64
65 #if DEBUG
66 # define DBG(fmt...)    printk(KERN_DEBUG fmt)
67 #else
68 # define DBG(fmt...)
69 #endif
70
71 #define A(__x)          ((unsigned long)(__x))
72 #define AA(__x)         ((unsigned long)(__x))
73 #define ROUND_UP(x,a)   ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
74 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
75
76 #define OFFSET4K(a)             ((a) & 0xfff)
77 #define PAGE_START(addr)        ((addr) & PAGE_MASK)
78 #define MINSIGSTKSZ_IA32        2048
79
80 #define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid))
81 #define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid))
82
83 extern unsigned long arch_get_unmapped_area (struct file *, unsigned long, unsigned long,
84                                              unsigned long, unsigned long);
85
86 /*
87  * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
88  * while doing so.
89  */
90 /* XXX make per-mm: */
91 static DECLARE_MUTEX(ia32_mmap_sem);
92
93 asmlinkage long
94 sys32_execve (char *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp, struct pt_regs *regs)
95 {
96         long error;
97         char *filename;
98         unsigned long old_map_base, old_task_size, tssd;
99
100         filename = getname(name);
101         error = PTR_ERR(filename);
102         if (IS_ERR(filename))
103                 return error;
104
105         old_map_base  = current->thread.map_base;
106         old_task_size = current->thread.task_size;
107         tssd = ia64_get_kr(IA64_KR_TSSD);
108
109         /* we may be exec'ing a 64-bit process: reset map base, task-size, and io-base: */
110         current->thread.map_base  = DEFAULT_MAP_BASE;
111         current->thread.task_size = DEFAULT_TASK_SIZE;
112         ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
113         ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
114
115         error = compat_do_execve(filename, argv, envp, regs);
116         putname(filename);
117
118         if (error < 0) {
119                 /* oops, execve failed, switch back to old values... */
120                 ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
121                 ia64_set_kr(IA64_KR_TSSD, tssd);
122                 current->thread.map_base  = old_map_base;
123                 current->thread.task_size = old_task_size;
124         }
125
126         return error;
127 }
128
129 int cp_compat_stat(struct kstat *stat, struct compat_stat *ubuf)
130 {
131         int err;
132
133         if ((u64) stat->size > MAX_NON_LFS ||
134             !old_valid_dev(stat->dev) ||
135             !old_valid_dev(stat->rdev))
136                 return -EOVERFLOW;
137
138         if (clear_user(ubuf, sizeof(*ubuf)))
139                 return -EFAULT;
140
141         err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
142         err |= __put_user(stat->ino, &ubuf->st_ino);
143         err |= __put_user(stat->mode, &ubuf->st_mode);
144         err |= __put_user(stat->nlink, &ubuf->st_nlink);
145         err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
146         err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
147         err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
148         err |= __put_user(stat->size, &ubuf->st_size);
149         err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
150         err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
151         err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
152         err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
153         err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
154         err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
155         err |= __put_user(stat->blksize, &ubuf->st_blksize);
156         err |= __put_user(stat->blocks, &ubuf->st_blocks);
157         return err;
158 }
159
160 #if PAGE_SHIFT > IA32_PAGE_SHIFT
161
162
163 static int
164 get_page_prot (struct vm_area_struct *vma, unsigned long addr)
165 {
166         int prot = 0;
167
168         if (!vma || vma->vm_start > addr)
169                 return 0;
170
171         if (vma->vm_flags & VM_READ)
172                 prot |= PROT_READ;
173         if (vma->vm_flags & VM_WRITE)
174                 prot |= PROT_WRITE;
175         if (vma->vm_flags & VM_EXEC)
176                 prot |= PROT_EXEC;
177         return prot;
178 }
179
180 /*
181  * Map a subpage by creating an anonymous page that contains the union of the old page and
182  * the subpage.
183  */
184 static unsigned long
185 mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
186               loff_t off)
187 {
188         void *page = NULL;
189         struct inode *inode;
190         unsigned long ret = 0;
191         struct vm_area_struct *vma = find_vma(current->mm, start);
192         int old_prot = get_page_prot(vma, start);
193
194         DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
195             file, start, end, prot, flags, off);
196
197
198         /* Optimize the case where the old mmap and the new mmap are both anonymous */
199         if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
200                 if (clear_user((void *) start, end - start)) {
201                         ret = -EFAULT;
202                         goto out;
203                 }
204                 goto skip_mmap;
205         }
206
207         page = (void *) get_zeroed_page(GFP_KERNEL);
208         if (!page)
209                 return -ENOMEM;
210
211         if (old_prot)
212                 copy_from_user(page, (void *) PAGE_START(start), PAGE_SIZE);
213
214         down_write(&current->mm->mmap_sem);
215         {
216                 ret = do_mmap(0, PAGE_START(start), PAGE_SIZE, prot | PROT_WRITE,
217                               flags | MAP_FIXED | MAP_ANONYMOUS, 0);
218         }
219         up_write(&current->mm->mmap_sem);
220
221         if (IS_ERR((void *) ret))
222                 goto out;
223
224         if (old_prot) {
225                 /* copy back the old page contents.  */
226                 if (offset_in_page(start))
227                         copy_to_user((void *) PAGE_START(start), page, offset_in_page(start));
228                 if (offset_in_page(end))
229                         copy_to_user((void *) end, page + offset_in_page(end),
230                                      PAGE_SIZE - offset_in_page(end));
231         }
232
233         if (!(flags & MAP_ANONYMOUS)) {
234                 /* read the file contents */
235                 inode = file->f_dentry->d_inode;
236                 if (!inode->i_fop || !file->f_op->read
237                     || ((*file->f_op->read)(file, (char *) start, end - start, &off) < 0))
238                 {
239                         ret = -EINVAL;
240                         goto out;
241                 }
242         }
243
244  skip_mmap:
245         if (!(prot & PROT_WRITE))
246                 ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
247   out:
248         if (page)
249                 free_page((unsigned long) page);
250         return ret;
251 }
252
253 static unsigned long
254 emulate_mmap (struct file *file, unsigned long start, unsigned long len, int prot, int flags,
255               loff_t off)
256 {
257         unsigned long tmp, end, pend, pstart, ret, is_congruent, fudge = 0;
258         struct inode *inode;
259         loff_t poff;
260
261         end = start + len;
262         pstart = PAGE_START(start);
263         pend = PAGE_ALIGN(end);
264
265         if (flags & MAP_FIXED) {
266                 if (start > pstart) {
267                         if (flags & MAP_SHARED)
268                                 printk(KERN_INFO
269                                        "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
270                                        current->comm, current->pid, start);
271                         ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
272                                            off);
273                         if (IS_ERR((void *) ret))
274                                 return ret;
275                         pstart += PAGE_SIZE;
276                         if (pstart >= pend)
277                                 return start;   /* done */
278                 }
279                 if (end < pend) {
280                         if (flags & MAP_SHARED)
281                                 printk(KERN_INFO
282                                        "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
283                                        current->comm, current->pid, end);
284                         ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
285                                            (off + len) - offset_in_page(end));
286                         if (IS_ERR((void *) ret))
287                                 return ret;
288                         pend -= PAGE_SIZE;
289                         if (pstart >= pend)
290                                 return start;   /* done */
291                 }
292         } else {
293                 /*
294                  * If a start address was specified, use it if the entire rounded out area
295                  * is available.
296                  */
297                 if (start && !pstart)
298                         fudge = 1;      /* handle case of mapping to range (0,PAGE_SIZE) */
299                 tmp = arch_get_unmapped_area(file, pstart - fudge, pend - pstart, 0, flags);
300                 if (tmp != pstart) {
301                         pstart = tmp;
302                         start = pstart + offset_in_page(off);   /* make start congruent with off */
303                         end = start + len;
304                         pend = PAGE_ALIGN(end);
305                 }
306         }
307
308         poff = off + (pstart - start);  /* note: (pstart - start) may be negative */
309         is_congruent = (flags & MAP_ANONYMOUS) || (offset_in_page(poff) == 0);
310
311         if ((flags & MAP_SHARED) && !is_congruent)
312                 printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
313                        "(addr=0x%lx,off=0x%llx)\n", current->comm, current->pid, start, off);
314
315         DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
316             is_congruent ? "congruent" : "not congruent", poff);
317
318         down_write(&current->mm->mmap_sem);
319         {
320                 if (!(flags & MAP_ANONYMOUS) && is_congruent)
321                         ret = do_mmap(file, pstart, pend - pstart, prot, flags | MAP_FIXED, poff);
322                 else
323                         ret = do_mmap(0, pstart, pend - pstart,
324                                       prot | ((flags & MAP_ANONYMOUS) ? 0 : PROT_WRITE),
325                                       flags | MAP_FIXED | MAP_ANONYMOUS, 0);
326         }
327         up_write(&current->mm->mmap_sem);
328
329         if (IS_ERR((void *) ret))
330                 return ret;
331
332         if (!is_congruent) {
333                 /* read the file contents */
334                 inode = file->f_dentry->d_inode;
335                 if (!inode->i_fop || !file->f_op->read
336                     || ((*file->f_op->read)(file, (char *) pstart, pend - pstart, &poff) < 0))
337                 {
338                         sys_munmap(pstart, pend - pstart);
339                         return -EINVAL;
340                 }
341                 if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0)
342                         return -EINVAL;
343         }
344         return start;
345 }
346
347 #endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
348
349 static inline unsigned int
350 get_prot32 (unsigned int prot)
351 {
352         if (prot & PROT_WRITE)
353                 /* on x86, PROT_WRITE implies PROT_READ which implies PROT_EEC */
354                 prot |= PROT_READ | PROT_WRITE | PROT_EXEC;
355         else if (prot & (PROT_READ | PROT_EXEC))
356                 /* on x86, there is no distinction between PROT_READ and PROT_EXEC */
357                 prot |= (PROT_READ | PROT_EXEC);
358
359         return prot;
360 }
361
362 unsigned long
363 ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot, int flags,
364               loff_t offset)
365 {
366         DBG("ia32_do_mmap(file=%p,addr=0x%lx,len=0x%lx,prot=%x,flags=%x,offset=0x%llx)\n",
367             file, addr, len, prot, flags, offset);
368
369         if (file && (!file->f_op || !file->f_op->mmap))
370                 return -ENODEV;
371
372         len = IA32_PAGE_ALIGN(len);
373         if (len == 0)
374                 return addr;
375
376         if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len)
377         {
378                 if (flags & MAP_FIXED)
379                         return -ENOMEM;
380                 else
381                 return -EINVAL;
382         }
383
384         if (OFFSET4K(offset))
385                 return -EINVAL;
386
387         prot = get_prot32(prot);
388
389 #if PAGE_SHIFT > IA32_PAGE_SHIFT
390         down(&ia32_mmap_sem);
391         {
392                 addr = emulate_mmap(file, addr, len, prot, flags, offset);
393         }
394         up(&ia32_mmap_sem);
395 #else
396         down_write(&current->mm->mmap_sem);
397         {
398                 addr = do_mmap(file, addr, len, prot, flags, offset);
399         }
400         up_write(&current->mm->mmap_sem);
401 #endif
402         DBG("ia32_do_mmap: returning 0x%lx\n", addr);
403         return addr;
404 }
405
406 /*
407  * Linux/i386 didn't use to be able to handle more than 4 system call parameters, so these
408  * system calls used a memory block for parameter passing..
409  */
410
411 struct mmap_arg_struct {
412         unsigned int addr;
413         unsigned int len;
414         unsigned int prot;
415         unsigned int flags;
416         unsigned int fd;
417         unsigned int offset;
418 };
419
420 asmlinkage long
421 sys32_mmap (struct mmap_arg_struct *arg)
422 {
423         struct mmap_arg_struct a;
424         struct file *file = NULL;
425         unsigned long addr;
426         int flags;
427
428         if (copy_from_user(&a, arg, sizeof(a)))
429                 return -EFAULT;
430
431         if (OFFSET4K(a.offset))
432                 return -EINVAL;
433
434         flags = a.flags;
435
436         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
437         if (!(flags & MAP_ANONYMOUS)) {
438                 file = fget(a.fd);
439                 if (!file)
440                         return -EBADF;
441         }
442
443         addr = ia32_do_mmap(file, a.addr, a.len, a.prot, flags, a.offset);
444
445         if (file)
446                 fput(file);
447         return addr;
448 }
449
450 asmlinkage long
451 sys32_mmap2 (unsigned int addr, unsigned int len, unsigned int prot, unsigned int flags,
452              unsigned int fd, unsigned int pgoff)
453 {
454         struct file *file = NULL;
455         unsigned long retval;
456
457         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
458         if (!(flags & MAP_ANONYMOUS)) {
459                 file = fget(fd);
460                 if (!file)
461                         return -EBADF;
462         }
463
464         retval = ia32_do_mmap(file, addr, len, prot, flags,
465                               (unsigned long) pgoff << IA32_PAGE_SHIFT);
466
467         if (file)
468                 fput(file);
469         return retval;
470 }
471
472 asmlinkage long
473 sys32_munmap (unsigned int start, unsigned int len)
474 {
475         unsigned int end = start + len;
476         long ret;
477
478 #if PAGE_SHIFT <= IA32_PAGE_SHIFT
479         ret = sys_munmap(start, end - start);
480 #else
481         if (start >= end)
482                 return -EINVAL;
483
484         start = PAGE_ALIGN(start);
485         end = PAGE_START(end);
486
487         if (start >= end)
488                 return 0;
489
490         down(&ia32_mmap_sem);
491         {
492                 ret = sys_munmap(start, end - start);
493         }
494         up(&ia32_mmap_sem);
495 #endif
496         return ret;
497 }
498
499 #if PAGE_SHIFT > IA32_PAGE_SHIFT
500
501 /*
502  * When mprotect()ing a partial page, we set the permission to the union of the old
503  * settings and the new settings.  In other words, it's only possible to make access to a
504  * partial page less restrictive.
505  */
506 static long
507 mprotect_subpage (unsigned long address, int new_prot)
508 {
509         int old_prot;
510         struct vm_area_struct *vma;
511
512         if (new_prot == PROT_NONE)
513                 return 0;               /* optimize case where nothing changes... */
514         vma = find_vma(current->mm, address);
515         old_prot = get_page_prot(vma, address);
516         return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
517 }
518
519 #endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
520
521 asmlinkage long
522 sys32_mprotect (unsigned int start, unsigned int len, int prot)
523 {
524         unsigned long end = start + len;
525 #if PAGE_SHIFT > IA32_PAGE_SHIFT
526         long retval = 0;
527 #endif
528
529         prot = get_prot32(prot);
530
531 #if PAGE_SHIFT <= IA32_PAGE_SHIFT
532         return sys_mprotect(start, end - start, prot);
533 #else
534         if (OFFSET4K(start))
535                 return -EINVAL;
536
537         end = IA32_PAGE_ALIGN(end);
538         if (end < start)
539                 return -EINVAL;
540
541         down(&ia32_mmap_sem);
542         {
543                 if (offset_in_page(start)) {
544                         /* start address is 4KB aligned but not page aligned. */
545                         retval = mprotect_subpage(PAGE_START(start), prot);
546                         if (retval < 0)
547                                 goto out;
548
549                         start = PAGE_ALIGN(start);
550                         if (start >= end)
551                                 goto out;       /* retval is already zero... */
552                 }
553
554                 if (offset_in_page(end)) {
555                         /* end address is 4KB aligned but not page aligned. */
556                         retval = mprotect_subpage(PAGE_START(end), prot);
557                         if (retval < 0)
558                                 goto out;
559
560                         end = PAGE_START(end);
561                 }
562                 retval = sys_mprotect(start, end - start, prot);
563         }
564   out:
565         up(&ia32_mmap_sem);
566         return retval;
567 #endif
568 }
569
570 asmlinkage long
571 sys32_pipe (int *fd)
572 {
573         int retval;
574         int fds[2];
575
576         retval = do_pipe(fds);
577         if (retval)
578                 goto out;
579         if (copy_to_user(fd, fds, sizeof(fds)))
580                 retval = -EFAULT;
581   out:
582         return retval;
583 }
584
585 static inline long
586 get_tv32 (struct timeval *o, struct compat_timeval *i)
587 {
588         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
589                 (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec)));
590 }
591
592 static inline long
593 put_tv32 (struct compat_timeval *o, struct timeval *i)
594 {
595         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
596                 (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec)));
597 }
598
599 asmlinkage unsigned long
600 sys32_alarm (unsigned int seconds)
601 {
602         struct itimerval it_new, it_old;
603         unsigned int oldalarm;
604
605         it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
606         it_new.it_value.tv_sec = seconds;
607         it_new.it_value.tv_usec = 0;
608         do_setitimer(ITIMER_REAL, &it_new, &it_old);
609         oldalarm = it_old.it_value.tv_sec;
610         /* ehhh.. We can't return 0 if we have an alarm pending.. */
611         /* And we'd better return too much than too little anyway */
612         if (it_old.it_value.tv_usec)
613                 oldalarm++;
614         return oldalarm;
615 }
616
617 /* Translations due to time_t size differences.  Which affects all
618    sorts of things, like timeval and itimerval.  */
619
620 extern struct timezone sys_tz;
621
622 asmlinkage long
623 sys32_gettimeofday (struct compat_timeval *tv, struct timezone *tz)
624 {
625         if (tv) {
626                 struct timeval ktv;
627                 do_gettimeofday(&ktv);
628                 if (put_tv32(tv, &ktv))
629                         return -EFAULT;
630         }
631         if (tz) {
632                 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
633                         return -EFAULT;
634         }
635         return 0;
636 }
637
638 asmlinkage long
639 sys32_settimeofday (struct compat_timeval *tv, struct timezone *tz)
640 {
641         struct timeval ktv;
642         struct timespec kts;
643         struct timezone ktz;
644
645         if (tv) {
646                 if (get_tv32(&ktv, tv))
647                         return -EFAULT;
648                 kts.tv_sec = ktv.tv_sec;
649                 kts.tv_nsec = ktv.tv_usec * 1000;
650         }
651         if (tz) {
652                 if (copy_from_user(&ktz, tz, sizeof(ktz)))
653                         return -EFAULT;
654         }
655
656         return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
657 }
658
659 struct getdents32_callback {
660         struct compat_dirent * current_dir;
661         struct compat_dirent * previous;
662         int count;
663         int error;
664 };
665
666 struct readdir32_callback {
667         struct old_linux32_dirent * dirent;
668         int count;
669 };
670
671 static int
672 filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
673            unsigned int d_type)
674 {
675         struct compat_dirent * dirent;
676         struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
677         int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
678
679         buf->error = -EINVAL;   /* only used if we fail.. */
680         if (reclen > buf->count)
681                 return -EINVAL;
682         buf->error = -EFAULT;   /* only used if we fail.. */
683         dirent = buf->previous;
684         if (dirent)
685                 if (put_user(offset, &dirent->d_off))
686                         return -EFAULT;
687         dirent = buf->current_dir;
688         buf->previous = dirent;
689         if (put_user(ino, &dirent->d_ino)
690             || put_user(reclen, &dirent->d_reclen)
691             || copy_to_user(dirent->d_name, name, namlen)
692             || put_user(0, dirent->d_name + namlen))
693                 return -EFAULT;
694         dirent = (struct compat_dirent *) ((char *) dirent + reclen);
695         buf->current_dir = dirent;
696         buf->count -= reclen;
697         return 0;
698 }
699
700 asmlinkage long
701 sys32_getdents (unsigned int fd, struct compat_dirent *dirent, unsigned int count)
702 {
703         struct file * file;
704         struct compat_dirent * lastdirent;
705         struct getdents32_callback buf;
706         int error;
707
708         error = -EBADF;
709         file = fget(fd);
710         if (!file)
711                 goto out;
712
713         buf.current_dir = dirent;
714         buf.previous = NULL;
715         buf.count = count;
716         buf.error = 0;
717
718         error = vfs_readdir(file, filldir32, &buf);
719         if (error < 0)
720                 goto out_putf;
721         error = buf.error;
722         lastdirent = buf.previous;
723         if (lastdirent) {
724                 error = -EINVAL;
725                 if (put_user(file->f_pos, &lastdirent->d_off))
726                         goto out_putf;
727                 error = count - buf.count;
728         }
729
730 out_putf:
731         fput(file);
732 out:
733         return error;
734 }
735
736 static int
737 fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
738               unsigned int d_type)
739 {
740         struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
741         struct old_linux32_dirent * dirent;
742
743         if (buf->count)
744                 return -EINVAL;
745         buf->count++;
746         dirent = buf->dirent;
747         if (put_user(ino, &dirent->d_ino)
748             || put_user(offset, &dirent->d_offset)
749             || put_user(namlen, &dirent->d_namlen)
750             || copy_to_user(dirent->d_name, name, namlen)
751             || put_user(0, dirent->d_name + namlen))
752                 return -EFAULT;
753         return 0;
754 }
755
756 asmlinkage long
757 sys32_readdir (unsigned int fd, void *dirent, unsigned int count)
758 {
759         int error;
760         struct file * file;
761         struct readdir32_callback buf;
762
763         error = -EBADF;
764         file = fget(fd);
765         if (!file)
766                 goto out;
767
768         buf.count = 0;
769         buf.dirent = dirent;
770
771         error = vfs_readdir(file, fillonedir32, &buf);
772         if (error >= 0)
773                 error = buf.count;
774         fput(file);
775 out:
776         return error;
777 }
778
779 struct sel_arg_struct {
780         unsigned int n;
781         unsigned int inp;
782         unsigned int outp;
783         unsigned int exp;
784         unsigned int tvp;
785 };
786
787 asmlinkage long
788 sys32_old_select (struct sel_arg_struct *arg)
789 {
790         struct sel_arg_struct a;
791
792         if (copy_from_user(&a, arg, sizeof(a)))
793                 return -EFAULT;
794         return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
795                                  compat_ptr(a.exp), compat_ptr(a.tvp));
796 }
797
798 #define SEMOP            1
799 #define SEMGET           2
800 #define SEMCTL           3
801 #define SEMTIMEDOP       4
802 #define MSGSND          11
803 #define MSGRCV          12
804 #define MSGGET          13
805 #define MSGCTL          14
806 #define SHMAT           21
807 #define SHMDT           22
808 #define SHMGET          23
809 #define SHMCTL          24
810
811 asmlinkage long
812 sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
813 {
814         int version;
815
816         version = call >> 16; /* hack for backward compatibility */
817         call &= 0xffff;
818
819         switch (call) {
820               case SEMTIMEDOP:
821                 if (fifth)
822                         return compat_sys_semtimedop(first, compat_ptr(ptr),
823                                 second, compat_ptr(fifth));
824                 /* else fall through for normal semop() */
825               case SEMOP:
826                 /* struct sembuf is the same on 32 and 64bit :)) */
827                 return sys_semtimedop(first, compat_ptr(ptr), second,
828                                       NULL);
829               case SEMGET:
830                 return sys_semget(first, second, third);
831               case SEMCTL:
832                 return compat_sys_semctl(first, second, third, compat_ptr(ptr));
833
834               case MSGSND:
835                 return compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
836               case MSGRCV:
837                 return compat_sys_msgrcv(first, second, fifth, third, version, compat_ptr(ptr));
838               case MSGGET:
839                 return sys_msgget((key_t) first, second);
840               case MSGCTL:
841                 return compat_sys_msgctl(first, second, compat_ptr(ptr));
842
843               case SHMAT:
844                 return compat_sys_shmat(first, second, third, version, compat_ptr(ptr));
845                 break;
846               case SHMDT:
847                 return sys_shmdt(compat_ptr(ptr));
848               case SHMGET:
849                 return sys_shmget(first, second, third);
850               case SHMCTL:
851                 return compat_sys_shmctl(first, second, compat_ptr(ptr));
852
853               default:
854                 return -ENOSYS;
855         }
856         return -EINVAL;
857 }
858
859 /*
860  * sys_time() can be implemented in user-level using
861  * sys_gettimeofday().  IA64 did this but i386 Linux did not
862  * so we have to implement this system call here.
863  */
864 asmlinkage long
865 sys32_time (int *tloc)
866 {
867         int i;
868         struct timeval tv;
869
870         do_gettimeofday(&tv);
871         i = tv.tv_sec;
872
873         if (tloc) {
874                 if (put_user(i, tloc))
875                         i = -EFAULT;
876         }
877         return i;
878 }
879
880 asmlinkage long
881 compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options,
882                  struct compat_rusage *ru);
883
884 asmlinkage long
885 sys32_waitpid (int pid, unsigned int *stat_addr, int options)
886 {
887         return compat_sys_wait4(pid, stat_addr, options, NULL);
888 }
889
890 static unsigned int
891 ia32_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int *val)
892 {
893         size_t copied;
894         unsigned int ret;
895
896         copied = access_process_vm(child, addr, val, sizeof(*val), 0);
897         return (copied != sizeof(ret)) ? -EIO : 0;
898 }
899
900 static unsigned int
901 ia32_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int val)
902 {
903
904         if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
905                 return -EIO;
906         return 0;
907 }
908
909 /*
910  *  The order in which registers are stored in the ptrace regs structure
911  */
912 #define PT_EBX  0
913 #define PT_ECX  1
914 #define PT_EDX  2
915 #define PT_ESI  3
916 #define PT_EDI  4
917 #define PT_EBP  5
918 #define PT_EAX  6
919 #define PT_DS   7
920 #define PT_ES   8
921 #define PT_FS   9
922 #define PT_GS   10
923 #define PT_ORIG_EAX 11
924 #define PT_EIP  12
925 #define PT_CS   13
926 #define PT_EFL  14
927 #define PT_UESP 15
928 #define PT_SS   16
929
930 static unsigned int
931 getreg (struct task_struct *child, int regno)
932 {
933         struct pt_regs *child_regs;
934
935         child_regs = ia64_task_regs(child);
936         switch (regno / sizeof(int)) {
937               case PT_EBX: return child_regs->r11;
938               case PT_ECX: return child_regs->r9;
939               case PT_EDX: return child_regs->r10;
940               case PT_ESI: return child_regs->r14;
941               case PT_EDI: return child_regs->r15;
942               case PT_EBP: return child_regs->r13;
943               case PT_EAX: return child_regs->r8;
944               case PT_ORIG_EAX: return child_regs->r1; /* see dispatch_to_ia32_handler() */
945               case PT_EIP: return child_regs->cr_iip;
946               case PT_UESP: return child_regs->r12;
947               case PT_EFL: return child->thread.eflag;
948               case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
949                 return __USER_DS;
950               case PT_CS: return __USER_CS;
951               default:
952                 printk(KERN_ERR "ia32.getreg(): unknown register %d\n", regno);
953                 break;
954         }
955         return 0;
956 }
957
958 static void
959 putreg (struct task_struct *child, int regno, unsigned int value)
960 {
961         struct pt_regs *child_regs;
962
963         child_regs = ia64_task_regs(child);
964         switch (regno / sizeof(int)) {
965               case PT_EBX: child_regs->r11 = value; break;
966               case PT_ECX: child_regs->r9 = value; break;
967               case PT_EDX: child_regs->r10 = value; break;
968               case PT_ESI: child_regs->r14 = value; break;
969               case PT_EDI: child_regs->r15 = value; break;
970               case PT_EBP: child_regs->r13 = value; break;
971               case PT_EAX: child_regs->r8 = value; break;
972               case PT_ORIG_EAX: child_regs->r1 = value; break;
973               case PT_EIP: child_regs->cr_iip = value; break;
974               case PT_UESP: child_regs->r12 = value; break;
975               case PT_EFL: child->thread.eflag = value; break;
976               case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
977                 if (value != __USER_DS)
978                         printk(KERN_ERR
979                                "ia32.putreg: attempt to set invalid segment register %d = %x\n",
980                                regno, value);
981                 break;
982               case PT_CS:
983                 if (value != __USER_CS)
984                         printk(KERN_ERR
985                                "ia32.putreg: attempt to to set invalid segment register %d = %x\n",
986                                regno, value);
987                 break;
988               default:
989                 printk(KERN_ERR "ia32.putreg: unknown register %d\n", regno);
990                 break;
991         }
992 }
993
994 static void
995 put_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp,
996            int tos)
997 {
998         struct _fpreg_ia32 *f;
999         char buf[32];
1000
1001         f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
1002         if ((regno += tos) >= 8)
1003                 regno -= 8;
1004         switch (regno) {
1005               case 0:
1006                 ia64f2ia32f(f, &ptp->f8);
1007                 break;
1008               case 1:
1009                 ia64f2ia32f(f, &ptp->f9);
1010                 break;
1011               case 2:
1012                 ia64f2ia32f(f, &ptp->f10);
1013                 break;
1014               case 3:
1015                 ia64f2ia32f(f, &ptp->f11);
1016                 break;
1017               case 4:
1018               case 5:
1019               case 6:
1020               case 7:
1021                 ia64f2ia32f(f, &swp->f12 + (regno - 4));
1022                 break;
1023         }
1024         copy_to_user(reg, f, sizeof(*reg));
1025 }
1026
1027 static void
1028 get_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp,
1029            int tos)
1030 {
1031
1032         if ((regno += tos) >= 8)
1033                 regno -= 8;
1034         switch (regno) {
1035               case 0:
1036                 copy_from_user(&ptp->f8, reg, sizeof(*reg));
1037                 break;
1038               case 1:
1039                 copy_from_user(&ptp->f9, reg, sizeof(*reg));
1040                 break;
1041               case 2:
1042                 copy_from_user(&ptp->f10, reg, sizeof(*reg));
1043                 break;
1044               case 3:
1045                 copy_from_user(&ptp->f11, reg, sizeof(*reg));
1046                 break;
1047               case 4:
1048               case 5:
1049               case 6:
1050               case 7:
1051                 copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg));
1052                 break;
1053         }
1054         return;
1055 }
1056
1057 int
1058 save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save)
1059 {
1060         struct switch_stack *swp;
1061         struct pt_regs *ptp;
1062         int i, tos;
1063
1064         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1065                 return -EFAULT;
1066
1067         __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1068         __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1069         __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1070         __put_user(tsk->thread.fir, &save->fip);
1071         __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1072         __put_user(tsk->thread.fdr, &save->foo);
1073         __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1074
1075         /*
1076          *  Stack frames start with 16-bytes of temp space
1077          */
1078         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1079         ptp = ia64_task_regs(tsk);
1080         tos = (tsk->thread.fsr >> 11) & 7;
1081         for (i = 0; i < 8; i++)
1082                 put_fpreg(i, &save->st_space[i], ptp, swp, tos);
1083         return 0;
1084 }
1085
1086 static int
1087 restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save)
1088 {
1089         struct switch_stack *swp;
1090         struct pt_regs *ptp;
1091         int i, tos;
1092         unsigned int fsrlo, fsrhi, num32;
1093
1094         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1095                 return(-EFAULT);
1096
1097         __get_user(num32, (unsigned int *)&save->cwd);
1098         tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1099         __get_user(fsrlo, (unsigned int *)&save->swd);
1100         __get_user(fsrhi, (unsigned int *)&save->twd);
1101         num32 = (fsrhi << 16) | fsrlo;
1102         tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1103         __get_user(num32, (unsigned int *)&save->fip);
1104         tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1105         __get_user(num32, (unsigned int *)&save->foo);
1106         tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1107
1108         /*
1109          *  Stack frames start with 16-bytes of temp space
1110          */
1111         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1112         ptp = ia64_task_regs(tsk);
1113         tos = (tsk->thread.fsr >> 11) & 7;
1114         for (i = 0; i < 8; i++)
1115                 get_fpreg(i, &save->st_space[i], ptp, swp, tos);
1116         return 0;
1117 }
1118
1119 int
1120 save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save)
1121 {
1122         struct switch_stack *swp;
1123         struct pt_regs *ptp;
1124         int i, tos;
1125         unsigned long mxcsr=0;
1126         unsigned long num128[2];
1127
1128         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1129                 return -EFAULT;
1130
1131         __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1132         __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1133         __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1134         __put_user(tsk->thread.fir, &save->fip);
1135         __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1136         __put_user(tsk->thread.fdr, &save->foo);
1137         __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1138
1139         /*
1140          *  Stack frames start with 16-bytes of temp space
1141          */
1142         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1143         ptp = ia64_task_regs(tsk);
1144         tos = (tsk->thread.fsr >> 11) & 7;
1145         for (i = 0; i < 8; i++)
1146                 put_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
1147
1148         mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f);
1149         __put_user(mxcsr & 0xffff, &save->mxcsr);
1150         for (i = 0; i < 8; i++) {
1151                 memcpy(&(num128[0]), &(swp->f16) + i*2, sizeof(unsigned long));
1152                 memcpy(&(num128[1]), &(swp->f17) + i*2, sizeof(unsigned long));
1153                 copy_to_user(&save->xmm_space[0] + 4*i, num128, sizeof(struct _xmmreg_ia32));
1154         }
1155         return 0;
1156 }
1157
1158 static int
1159 restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save)
1160 {
1161         struct switch_stack *swp;
1162         struct pt_regs *ptp;
1163         int i, tos;
1164         unsigned int fsrlo, fsrhi, num32;
1165         int mxcsr;
1166         unsigned long num64;
1167         unsigned long num128[2];
1168
1169         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1170                 return(-EFAULT);
1171
1172         __get_user(num32, (unsigned int *)&save->cwd);
1173         tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1174         __get_user(fsrlo, (unsigned int *)&save->swd);
1175         __get_user(fsrhi, (unsigned int *)&save->twd);
1176         num32 = (fsrhi << 16) | fsrlo;
1177         tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1178         __get_user(num32, (unsigned int *)&save->fip);
1179         tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1180         __get_user(num32, (unsigned int *)&save->foo);
1181         tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1182
1183         /*
1184          *  Stack frames start with 16-bytes of temp space
1185          */
1186         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1187         ptp = ia64_task_regs(tsk);
1188         tos = (tsk->thread.fsr >> 11) & 7;
1189         for (i = 0; i < 8; i++)
1190         get_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
1191
1192         __get_user(mxcsr, (unsigned int *)&save->mxcsr);
1193         num64 = mxcsr & 0xff10;
1194         tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000)) | (num64<<32);
1195         num64 = mxcsr & 0x3f;
1196         tsk->thread.fsr = (tsk->thread.fsr & (~0x3f00000000)) | (num64<<32);
1197
1198         for (i = 0; i < 8; i++) {
1199                 copy_from_user(num128, &save->xmm_space[0] + 4*i, sizeof(struct _xmmreg_ia32));
1200                 memcpy(&(swp->f16) + i*2, &(num128[0]), sizeof(unsigned long));
1201                 memcpy(&(swp->f17) + i*2, &(num128[1]), sizeof(unsigned long));
1202         }
1203         return 0;
1204 }
1205
1206 /*
1207  *  Note that the IA32 version of `ptrace' calls the IA64 routine for
1208  *    many of the requests.  This will only work for requests that do
1209  *    not need access to the calling processes `pt_regs' which is located
1210  *    at the address of `stack'.  Once we call the IA64 `sys_ptrace' then
1211  *    the address of `stack' will not be the address of the `pt_regs'.
1212  */
1213 asmlinkage long
1214 sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
1215               long arg4, long arg5, long arg6, long arg7, long stack)
1216 {
1217         struct pt_regs *regs = (struct pt_regs *) &stack;
1218         struct task_struct *child;
1219         unsigned int value, tmp;
1220         long i, ret;
1221
1222         lock_kernel();
1223         if (request == PTRACE_TRACEME) {
1224                 ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
1225                 goto out;
1226         }
1227
1228         ret = -ESRCH;
1229         read_lock(&tasklist_lock);
1230         child = find_task_by_pid(pid);
1231         if (child)
1232                 get_task_struct(child);
1233         read_unlock(&tasklist_lock);
1234         if (!child)
1235                 goto out;
1236         ret = -EPERM;
1237         if (pid == 1)           /* no messing around with init! */
1238                 goto out_tsk;
1239
1240         if (request == PTRACE_ATTACH) {
1241                 ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
1242                 goto out_tsk;
1243         }
1244
1245         ret = ptrace_check_attach(child, request == PTRACE_KILL);
1246         if (ret < 0)
1247                 goto out_tsk;
1248
1249         switch (request) {
1250               case PTRACE_PEEKTEXT:
1251               case PTRACE_PEEKDATA:     /* read word at location addr */
1252                 ret = ia32_peek(regs, child, addr, &value);
1253                 if (ret == 0)
1254                         ret = put_user(value, (unsigned int *) A(data));
1255                 else
1256                         ret = -EIO;
1257                 goto out_tsk;
1258
1259               case PTRACE_POKETEXT:
1260               case PTRACE_POKEDATA:     /* write the word at location addr */
1261                 ret = ia32_poke(regs, child, addr, data);
1262                 goto out_tsk;
1263
1264               case PTRACE_PEEKUSR:      /* read word at addr in USER area */
1265                 ret = -EIO;
1266                 if ((addr & 3) || addr > 17*sizeof(int))
1267                         break;
1268
1269                 tmp = getreg(child, addr);
1270                 if (!put_user(tmp, (unsigned int *) A(data)))
1271                         ret = 0;
1272                 break;
1273
1274               case PTRACE_POKEUSR:      /* write word at addr in USER area */
1275                 ret = -EIO;
1276                 if ((addr & 3) || addr > 17*sizeof(int))
1277                         break;
1278
1279                 putreg(child, addr, data);
1280                 ret = 0;
1281                 break;
1282
1283               case IA32_PTRACE_GETREGS:
1284                 if (!access_ok(VERIFY_WRITE, (int *) A(data), 17*sizeof(int))) {
1285                         ret = -EIO;
1286                         break;
1287                 }
1288                 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
1289                         put_user(getreg(child, i), (unsigned int *) A(data));
1290                         data += sizeof(int);
1291                 }
1292                 ret = 0;
1293                 break;
1294
1295               case IA32_PTRACE_SETREGS:
1296                 if (!access_ok(VERIFY_READ, (int *) A(data), 17*sizeof(int))) {
1297                         ret = -EIO;
1298                         break;
1299                 }
1300                 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
1301                         get_user(tmp, (unsigned int *) A(data));
1302                         putreg(child, i, tmp);
1303                         data += sizeof(int);
1304                 }
1305                 ret = 0;
1306                 break;
1307
1308               case IA32_PTRACE_GETFPREGS:
1309                 ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct *) A(data));
1310                 break;
1311
1312               case IA32_PTRACE_GETFPXREGS:
1313                 ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct *) A(data));
1314                 break;
1315
1316               case IA32_PTRACE_SETFPREGS:
1317                 ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct *) A(data));
1318                 break;
1319
1320               case IA32_PTRACE_SETFPXREGS:
1321                 ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct *) A(data));
1322                 break;
1323
1324               case PTRACE_SYSCALL:      /* continue, stop after next syscall */
1325               case PTRACE_CONT:         /* restart after signal. */
1326               case PTRACE_KILL:
1327               case PTRACE_SINGLESTEP:   /* execute chile for one instruction */
1328               case PTRACE_DETACH:       /* detach a process */
1329                 ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
1330                 break;
1331
1332               default:
1333                 ret = ptrace_request(child, request, addr, data);
1334                 break;
1335
1336         }
1337   out_tsk:
1338         put_task_struct(child);
1339   out:
1340         unlock_kernel();
1341         return ret;
1342 }
1343
1344 /*
1345  *  The IA64 maps 4 I/O ports for each 4K page
1346  */
1347 #define IOLEN   ((65536 / 4) * 4096)
1348
1349 asmlinkage long
1350 sys32_iopl (int level)
1351 {
1352         extern unsigned long ia64_iobase;
1353         int fd;
1354         struct file * file;
1355         unsigned int old;
1356         unsigned long addr;
1357         mm_segment_t old_fs = get_fs ();
1358
1359         if (level != 3)
1360                 return(-EINVAL);
1361         /* Trying to gain more privileges? */
1362         old = ia64_getreg(_IA64_REG_AR_EFLAG);
1363         if ((unsigned int) level > ((old >> 12) & 3)) {
1364                 if (!capable(CAP_SYS_RAWIO))
1365                         return -EPERM;
1366         }
1367         set_fs(KERNEL_DS);
1368         fd = sys_open("/dev/mem", O_SYNC | O_RDWR, 0);
1369         set_fs(old_fs);
1370         if (fd < 0)
1371                 return fd;
1372         file = fget(fd);
1373         if (file == NULL) {
1374                 sys_close(fd);
1375                 return(-EFAULT);
1376         }
1377
1378         down_write(&current->mm->mmap_sem);
1379         addr = do_mmap_pgoff(file, IA32_IOBASE,
1380                              IOLEN, PROT_READ|PROT_WRITE, MAP_SHARED,
1381                              (ia64_iobase & ~PAGE_OFFSET) >> PAGE_SHIFT);
1382         up_write(&current->mm->mmap_sem);
1383
1384         if (addr >= 0) {
1385                 old = (old & ~0x3000) | (level << 12);
1386                 ia64_setreg(_IA64_REG_AR_EFLAG, old);
1387         }
1388
1389         fput(file);
1390         sys_close(fd);
1391         return 0;
1392 }
1393
1394 asmlinkage long
1395 sys32_ioperm (unsigned int from, unsigned int num, int on)
1396 {
1397
1398         /*
1399          *  Since IA64 doesn't have permission bits we'd have to go to
1400          *    a lot of trouble to simulate them in software.  There's
1401          *    no point, only trusted programs can make this call so we'll
1402          *    just turn it into an iopl call and let the process have
1403          *    access to all I/O ports.
1404          *
1405          * XXX proper ioperm() support should be emulated by
1406          *      manipulating the page protections...
1407          */
1408         return sys32_iopl(3);
1409 }
1410
1411 typedef struct {
1412         unsigned int    ss_sp;
1413         unsigned int    ss_flags;
1414         unsigned int    ss_size;
1415 } ia32_stack_t;
1416
1417 asmlinkage long
1418 sys32_sigaltstack (ia32_stack_t *uss32, ia32_stack_t *uoss32,
1419                    long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long stack)
1420 {
1421         struct pt_regs *pt = (struct pt_regs *) &stack;
1422         stack_t uss, uoss;
1423         ia32_stack_t buf32;
1424         int ret;
1425         mm_segment_t old_fs = get_fs();
1426
1427         if (uss32)
1428                 if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t)))
1429                         return -EFAULT;
1430         uss.ss_sp = (void *) (long) buf32.ss_sp;
1431         uss.ss_flags = buf32.ss_flags;
1432         /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the 
1433            check and set it to the user requested value later */
1434         if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) {
1435                 ret = -ENOMEM;
1436                 goto out;
1437         }
1438         uss.ss_size = MINSIGSTKSZ;
1439         set_fs(KERNEL_DS);
1440         ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12);
1441         current->sas_ss_size = buf32.ss_size;   
1442         set_fs(old_fs);
1443 out:
1444         if (ret < 0)
1445                 return(ret);
1446         if (uoss32) {
1447                 buf32.ss_sp = (long) uoss.ss_sp;
1448                 buf32.ss_flags = uoss.ss_flags;
1449                 buf32.ss_size = uoss.ss_size;
1450                 if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t)))
1451                         return -EFAULT;
1452         }
1453         return ret;
1454 }
1455
1456 asmlinkage int
1457 sys32_pause (void)
1458 {
1459         current->state = TASK_INTERRUPTIBLE;
1460         schedule();
1461         return -ERESTARTNOHAND;
1462 }
1463
1464 asmlinkage int
1465 sys32_msync (unsigned int start, unsigned int len, int flags)
1466 {
1467         unsigned int addr;
1468
1469         if (OFFSET4K(start))
1470                 return -EINVAL;
1471         addr = PAGE_START(start);
1472         return sys_msync(addr, len + (start - addr), flags);
1473 }
1474
1475 struct sysctl32 {
1476         unsigned int    name;
1477         int             nlen;
1478         unsigned int    oldval;
1479         unsigned int    oldlenp;
1480         unsigned int    newval;
1481         unsigned int    newlen;
1482         unsigned int    __unused[4];
1483 };
1484
1485 asmlinkage long
1486 sys32_sysctl (struct sysctl32 *args)
1487 {
1488 #ifdef CONFIG_SYSCTL
1489         struct sysctl32 a32;
1490         mm_segment_t old_fs = get_fs ();
1491         void *oldvalp, *newvalp;
1492         size_t oldlen;
1493         int *namep;
1494         long ret;
1495
1496         if (copy_from_user(&a32, args, sizeof(a32)))
1497                 return -EFAULT;
1498
1499         /*
1500          * We need to pre-validate these because we have to disable address checking
1501          * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
1502          * user specifying bad addresses here.  Well, since we're dealing with 32 bit
1503          * addresses, we KNOW that access_ok() will always succeed, so this is an
1504          * expensive NOP, but so what...
1505          */
1506         namep = (int *) A(a32.name);
1507         oldvalp = (void *) A(a32.oldval);
1508         newvalp = (void *) A(a32.newval);
1509
1510         if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp)))
1511             || !access_ok(VERIFY_WRITE, namep, 0)
1512             || !access_ok(VERIFY_WRITE, oldvalp, 0)
1513             || !access_ok(VERIFY_WRITE, newvalp, 0))
1514                 return -EFAULT;
1515
1516         set_fs(KERNEL_DS);
1517         lock_kernel();
1518         ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen);
1519         unlock_kernel();
1520         set_fs(old_fs);
1521
1522         if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp)))
1523                 return -EFAULT;
1524
1525         return ret;
1526 #else
1527         return -ENOSYS;
1528 #endif
1529 }
1530
1531 asmlinkage long
1532 sys32_newuname (struct new_utsname *name)
1533 {
1534         int ret = sys_newuname(name);
1535
1536         if (!ret)
1537                 if (copy_to_user(name->machine, "i686\0\0\0", 8))
1538                         ret = -EFAULT;
1539         return ret;
1540 }
1541
1542 asmlinkage long
1543 sys32_getresuid16 (u16 *ruid, u16 *euid, u16 *suid)
1544 {
1545         uid_t a, b, c;
1546         int ret;
1547         mm_segment_t old_fs = get_fs();
1548
1549         set_fs(KERNEL_DS);
1550         ret = sys_getresuid(&a, &b, &c);
1551         set_fs(old_fs);
1552
1553         if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
1554                 return -EFAULT;
1555         return ret;
1556 }
1557
1558 asmlinkage long
1559 sys32_getresgid16 (u16 *rgid, u16 *egid, u16 *sgid)
1560 {
1561         gid_t a, b, c;
1562         int ret;
1563         mm_segment_t old_fs = get_fs();
1564
1565         set_fs(KERNEL_DS);
1566         ret = sys_getresgid(&a, &b, &c);
1567         set_fs(old_fs);
1568
1569         if (ret)
1570                 return ret;
1571
1572         return put_user(a, rgid) | put_user(b, egid) | put_user(c, sgid);
1573 }
1574
1575 asmlinkage long
1576 sys32_lseek (unsigned int fd, int offset, unsigned int whence)
1577 {
1578         /* Sign-extension of "offset" is important here... */
1579         return sys_lseek(fd, offset, whence);
1580 }
1581
1582 static int
1583 groups16_to_user(short *grouplist, struct group_info *group_info)
1584 {
1585         int i;
1586         short group;
1587
1588         for (i = 0; i < group_info->ngroups; i++) {
1589                 group = (short)GROUP_AT(group_info, i);
1590                 if (put_user(group, grouplist+i))
1591                         return -EFAULT;
1592         }
1593
1594         return 0;
1595 }
1596
1597 static int
1598 groups16_from_user(struct group_info *group_info, short *grouplist)
1599 {
1600         int i;
1601         short group;
1602
1603         for (i = 0; i < group_info->ngroups; i++) {
1604                 if (get_user(group, grouplist+i))
1605                         return  -EFAULT;
1606                 GROUP_AT(group_info, i) = (gid_t)group;
1607         }
1608
1609         return 0;
1610 }
1611
1612 asmlinkage long
1613 sys32_getgroups16 (int gidsetsize, short *grouplist)
1614 {
1615         int i;
1616
1617         if (gidsetsize < 0)
1618                 return -EINVAL;
1619
1620         get_group_info(current->group_info);
1621         i = current->group_info->ngroups;
1622         if (gidsetsize) {
1623                 if (i > gidsetsize) {
1624                         i = -EINVAL;
1625                         goto out;
1626                 }
1627                 if (groups16_to_user(grouplist, current->group_info)) {
1628                         i = -EFAULT;
1629                         goto out;
1630                 }
1631         }
1632 out:
1633         put_group_info(current->group_info);
1634         return i;
1635 }
1636
1637 asmlinkage long
1638 sys32_setgroups16 (int gidsetsize, short *grouplist)
1639 {
1640         struct group_info *group_info;
1641         int retval;
1642
1643         if (!capable(CAP_SETGID))
1644                 return -EPERM;
1645         if ((unsigned)gidsetsize > NGROUPS_MAX)
1646                 return -EINVAL;
1647
1648         group_info = groups_alloc(gidsetsize);
1649         if (!group_info)
1650                 return -ENOMEM;
1651         retval = groups16_from_user(group_info, grouplist);
1652         if (retval) {
1653                 put_group_info(group_info);
1654                 return retval;
1655         }
1656
1657         retval = set_current_groups(group_info);
1658         put_group_info(group_info);
1659
1660         return retval;
1661 }
1662
1663 asmlinkage long
1664 sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi)
1665 {
1666         return sys_truncate((const char *) A(path), ((unsigned long) len_hi << 32) | len_lo);
1667 }
1668
1669 asmlinkage long
1670 sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi)
1671 {
1672         return sys_ftruncate(fd, ((unsigned long) len_hi << 32) | len_lo);
1673 }
1674
1675 static int
1676 putstat64 (struct stat64 *ubuf, struct kstat *kbuf)
1677 {
1678         int err;
1679         u64 hdev;
1680
1681         if (clear_user(ubuf, sizeof(*ubuf)))
1682                 return -EFAULT;
1683
1684         hdev = huge_encode_dev(kbuf->dev);
1685         err  = __put_user(hdev, (u32*)&ubuf->st_dev);
1686         err |= __put_user(hdev >> 32, ((u32*)&ubuf->st_dev) + 1);
1687         err |= __put_user(kbuf->ino, &ubuf->__st_ino);
1688         err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
1689         err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
1690         err |= __put_user(kbuf->mode, &ubuf->st_mode);
1691         err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
1692         err |= __put_user(kbuf->uid, &ubuf->st_uid);
1693         err |= __put_user(kbuf->gid, &ubuf->st_gid);
1694         hdev = huge_encode_dev(kbuf->rdev);
1695         err  = __put_user(hdev, (u32*)&ubuf->st_rdev);
1696         err |= __put_user(hdev >> 32, ((u32*)&ubuf->st_rdev) + 1);
1697         err |= __put_user(kbuf->size, &ubuf->st_size_lo);
1698         err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
1699         err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
1700         err |= __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec);
1701         err |= __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime);
1702         err |= __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec);
1703         err |= __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime);
1704         err |= __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec);
1705         err |= __put_user(kbuf->blksize, &ubuf->st_blksize);
1706         err |= __put_user(kbuf->blocks, &ubuf->st_blocks);
1707         return err;
1708 }
1709
1710 asmlinkage long
1711 sys32_stat64 (char *filename, struct stat64 *statbuf)
1712 {
1713         struct kstat s;
1714         long ret = vfs_stat(filename, &s);
1715         if (!ret)
1716                 ret = putstat64(statbuf, &s);
1717         return ret;
1718 }
1719
1720 asmlinkage long
1721 sys32_lstat64 (char *filename, struct stat64 *statbuf)
1722 {
1723         struct kstat s;
1724         long ret = vfs_lstat(filename, &s);
1725         if (!ret)
1726                 ret = putstat64(statbuf, &s);
1727         return ret;
1728 }
1729
1730 asmlinkage long
1731 sys32_fstat64 (unsigned int fd, struct stat64 *statbuf)
1732 {
1733         struct kstat s;
1734         long ret = vfs_fstat(fd, &s);
1735         if (!ret)
1736                 ret = putstat64(statbuf, &s);
1737         return ret;
1738 }
1739
1740 struct sysinfo32 {
1741         s32 uptime;
1742         u32 loads[3];
1743         u32 totalram;
1744         u32 freeram;
1745         u32 sharedram;
1746         u32 bufferram;
1747         u32 totalswap;
1748         u32 freeswap;
1749         u16 procs;
1750         u16 pad;
1751         u32 totalhigh;
1752         u32 freehigh;
1753         u32 mem_unit;
1754         char _f[8];
1755 };
1756
1757 asmlinkage long
1758 sys32_sysinfo (struct sysinfo32 *info)
1759 {
1760         struct sysinfo s;
1761         long ret, err;
1762         int bitcount = 0;
1763         mm_segment_t old_fs = get_fs();
1764
1765         set_fs(KERNEL_DS);
1766         ret = sys_sysinfo(&s);
1767         set_fs(old_fs);
1768         /* Check to see if any memory value is too large for 32-bit and
1769          * scale down if needed.
1770          */
1771         if ((s.totalram >> 32) || (s.totalswap >> 32)) {
1772                 while (s.mem_unit < PAGE_SIZE) {
1773                         s.mem_unit <<= 1;
1774                         bitcount++;
1775                 }
1776                 s.totalram >>= bitcount;
1777                 s.freeram >>= bitcount;
1778                 s.sharedram >>= bitcount;
1779                 s.bufferram >>= bitcount;
1780                 s.totalswap >>= bitcount;
1781                 s.freeswap >>= bitcount;
1782                 s.totalhigh >>= bitcount;
1783                 s.freehigh >>= bitcount;
1784         }
1785
1786         if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
1787                 return -EFAULT;
1788
1789         err  = __put_user(s.uptime, &info->uptime);
1790         err |= __put_user(s.loads[0], &info->loads[0]);
1791         err |= __put_user(s.loads[1], &info->loads[1]);
1792         err |= __put_user(s.loads[2], &info->loads[2]);
1793         err |= __put_user(s.totalram, &info->totalram);
1794         err |= __put_user(s.freeram, &info->freeram);
1795         err |= __put_user(s.sharedram, &info->sharedram);
1796         err |= __put_user(s.bufferram, &info->bufferram);
1797         err |= __put_user(s.totalswap, &info->totalswap);
1798         err |= __put_user(s.freeswap, &info->freeswap);
1799         err |= __put_user(s.procs, &info->procs);
1800         err |= __put_user (s.totalhigh, &info->totalhigh);
1801         err |= __put_user (s.freehigh, &info->freehigh);
1802         err |= __put_user (s.mem_unit, &info->mem_unit);
1803         if (err)
1804                 return -EFAULT;
1805         return ret;
1806 }
1807
1808 asmlinkage long
1809 sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec *interval)
1810 {
1811         mm_segment_t old_fs = get_fs();
1812         struct timespec t;
1813         long ret;
1814
1815         set_fs(KERNEL_DS);
1816         ret = sys_sched_rr_get_interval(pid, &t);
1817         set_fs(old_fs);
1818         if (put_compat_timespec(&t, interval))
1819                 return -EFAULT;
1820         return ret;
1821 }
1822
1823 asmlinkage long
1824 sys32_pread (unsigned int fd, void *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
1825 {
1826         return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
1827 }
1828
1829 asmlinkage long
1830 sys32_pwrite (unsigned int fd, void *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
1831 {
1832         return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
1833 }
1834
1835 asmlinkage long
1836 sys32_sendfile (int out_fd, int in_fd, int *offset, unsigned int count)
1837 {
1838         mm_segment_t old_fs = get_fs();
1839         long ret;
1840         off_t of;
1841
1842         if (offset && get_user(of, offset))
1843                 return -EFAULT;
1844
1845         set_fs(KERNEL_DS);
1846         ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
1847         set_fs(old_fs);
1848
1849         if (!ret && offset && put_user(of, offset))
1850                 return -EFAULT;
1851
1852         return ret;
1853 }
1854
1855 asmlinkage long
1856 sys32_personality (unsigned int personality)
1857 {
1858         long ret;
1859
1860         if (current->personality == PER_LINUX32 && personality == PER_LINUX)
1861                 personality = PER_LINUX32;
1862         ret = sys_personality(personality);
1863         if (ret == PER_LINUX32)
1864                 ret = PER_LINUX;
1865         return ret;
1866 }
1867
1868 asmlinkage unsigned long
1869 sys32_brk (unsigned int brk)
1870 {
1871         unsigned long ret, obrk;
1872         struct mm_struct *mm = current->mm;
1873
1874         obrk = mm->brk;
1875         ret = sys_brk(brk);
1876         if (ret < obrk)
1877                 clear_user((void *) ret, PAGE_ALIGN(ret) - ret);
1878         return ret;
1879 }
1880
1881 /*
1882  * Exactly like fs/open.c:sys_open(), except that it doesn't set the O_LARGEFILE flag.
1883  */
1884 asmlinkage long
1885 sys32_open (const char * filename, int flags, int mode)
1886 {
1887         char * tmp;
1888         int fd, error;
1889
1890         tmp = getname(filename);
1891         fd = PTR_ERR(tmp);
1892         if (!IS_ERR(tmp)) {
1893                 fd = get_unused_fd();
1894                 if (fd >= 0) {
1895                         struct file *f = filp_open(tmp, flags, mode);
1896                         error = PTR_ERR(f);
1897                         if (IS_ERR(f))
1898                                 goto out_error;
1899                         fd_install(fd, f);
1900                 }
1901 out:
1902                 putname(tmp);
1903         }
1904         return fd;
1905
1906 out_error:
1907         put_unused_fd(fd);
1908         fd = error;
1909         goto out;
1910 }
1911
1912 /* Structure for ia32 emulation on ia64 */
1913 struct epoll_event32
1914 {
1915         u32 events;
1916         u32 data[2];
1917 }; 
1918
1919 asmlinkage long
1920 sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 *event)
1921 {
1922         mm_segment_t old_fs = get_fs();
1923         struct epoll_event event64;
1924         int error = -EFAULT;
1925         u32 data_halfword;
1926
1927         if ((error = verify_area(VERIFY_READ, event,
1928                                  sizeof(struct epoll_event32))))
1929                 return error;
1930
1931         __get_user(event64.events, &event->events);
1932         __get_user(data_halfword, &event->data[0]);
1933         event64.data = data_halfword;
1934         __get_user(data_halfword, &event->data[1]);
1935         event64.data |= (u64)data_halfword << 32;
1936
1937         set_fs(KERNEL_DS);
1938         error = sys_epoll_ctl(epfd, op, fd, &event64);
1939         set_fs(old_fs);
1940
1941         return error;
1942 }
1943
1944 asmlinkage long
1945 sys32_epoll_wait(int epfd, struct epoll_event32 *events, int maxevents,
1946                  int timeout)
1947 {
1948         struct epoll_event *events64 = NULL;
1949         mm_segment_t old_fs = get_fs();
1950         int error, numevents, size;
1951         int evt_idx;
1952         int do_free_pages = 0;
1953
1954         if (maxevents <= 0) {
1955                 return -EINVAL;
1956         }
1957
1958         /* Verify that the area passed by the user is writeable */
1959         if ((error = verify_area(VERIFY_WRITE, events,
1960                                  maxevents * sizeof(struct epoll_event32))))
1961                 return error;
1962
1963         /* 
1964          * Allocate space for the intermediate copy.  If the space needed 
1965          * is large enough to cause kmalloc to fail, then try again with
1966          * __get_free_pages.
1967          */
1968         size = maxevents * sizeof(struct epoll_event);
1969         events64 = kmalloc(size, GFP_KERNEL);
1970         if (events64 == NULL) {
1971                 events64 = (struct epoll_event *)
1972                                 __get_free_pages(GFP_KERNEL, get_order(size));
1973                 if (events64 == NULL) 
1974                         return -ENOMEM;
1975                 do_free_pages = 1;
1976         }
1977
1978         /* Do the system call */
1979         set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/
1980         numevents = sys_epoll_wait(epfd, events64, maxevents, timeout);
1981         set_fs(old_fs);
1982
1983         /* Don't modify userspace memory if we're returning an error */
1984         if (numevents > 0) {
1985                 /* Translate the 64-bit structures back into the 32-bit
1986                    structures */
1987                 for (evt_idx = 0; evt_idx < numevents; evt_idx++) {
1988                         __put_user(events64[evt_idx].events,
1989                                    &events[evt_idx].events);
1990                         __put_user((u32)events64[evt_idx].data,
1991                                    &events[evt_idx].data[0]);
1992                         __put_user((u32)(events64[evt_idx].data >> 32),
1993                                    &events[evt_idx].data[1]);
1994                 }
1995         }
1996
1997         if (do_free_pages)
1998                 free_pages((unsigned long) events64, get_order(size));
1999         else
2000                 kfree(events64);
2001         return numevents;
2002 }
2003
2004 /*
2005  * Get a yet unused TLS descriptor index.
2006  */
2007 static int
2008 get_free_idx (void)
2009 {
2010         struct thread_struct *t = &current->thread;
2011         int idx;
2012
2013         for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
2014                 if (desc_empty(t->tls_array + idx))
2015                         return idx + GDT_ENTRY_TLS_MIN;
2016         return -ESRCH;
2017 }
2018
2019 /*
2020  * Set a given TLS descriptor:
2021  */
2022 asmlinkage int
2023 sys32_set_thread_area (struct ia32_user_desc *u_info)
2024 {
2025         struct thread_struct *t = &current->thread;
2026         struct ia32_user_desc info;
2027         struct desc_struct *desc;
2028         int cpu, idx;
2029
2030         if (copy_from_user(&info, u_info, sizeof(info)))
2031                 return -EFAULT;
2032         idx = info.entry_number;
2033
2034         /*
2035          * index -1 means the kernel should try to find and allocate an empty descriptor:
2036          */
2037         if (idx == -1) {
2038                 idx = get_free_idx();
2039                 if (idx < 0)
2040                         return idx;
2041                 if (put_user(idx, &u_info->entry_number))
2042                         return -EFAULT;
2043         }
2044
2045         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2046                 return -EINVAL;
2047
2048         desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
2049
2050         cpu = smp_processor_id();
2051
2052         if (LDT_empty(&info)) {
2053                 desc->a = 0;
2054                 desc->b = 0;
2055         } else {
2056                 desc->a = LDT_entry_a(&info);
2057                 desc->b = LDT_entry_b(&info);
2058         }
2059         load_TLS(t, cpu);
2060         return 0;
2061 }
2062
2063 /*
2064  * Get the current Thread-Local Storage area:
2065  */
2066
2067 #define GET_BASE(desc) (                        \
2068         (((desc)->a >> 16) & 0x0000ffff) |      \
2069         (((desc)->b << 16) & 0x00ff0000) |      \
2070         ( (desc)->b        & 0xff000000)   )
2071
2072 #define GET_LIMIT(desc) (                       \
2073         ((desc)->a & 0x0ffff) |                 \
2074          ((desc)->b & 0xf0000) )
2075
2076 #define GET_32BIT(desc)         (((desc)->b >> 22) & 1)
2077 #define GET_CONTENTS(desc)      (((desc)->b >> 10) & 3)
2078 #define GET_WRITABLE(desc)      (((desc)->b >>  9) & 1)
2079 #define GET_LIMIT_PAGES(desc)   (((desc)->b >> 23) & 1)
2080 #define GET_PRESENT(desc)       (((desc)->b >> 15) & 1)
2081 #define GET_USEABLE(desc)       (((desc)->b >> 20) & 1)
2082
2083 asmlinkage int
2084 sys32_get_thread_area (struct ia32_user_desc *u_info)
2085 {
2086         struct ia32_user_desc info;
2087         struct desc_struct *desc;
2088         int idx;
2089
2090         if (get_user(idx, &u_info->entry_number))
2091                 return -EFAULT;
2092         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2093                 return -EINVAL;
2094
2095         desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
2096
2097         info.entry_number = idx;
2098         info.base_addr = GET_BASE(desc);
2099         info.limit = GET_LIMIT(desc);
2100         info.seg_32bit = GET_32BIT(desc);
2101         info.contents = GET_CONTENTS(desc);
2102         info.read_exec_only = !GET_WRITABLE(desc);
2103         info.limit_in_pages = GET_LIMIT_PAGES(desc);
2104         info.seg_not_present = !GET_PRESENT(desc);
2105         info.useable = GET_USEABLE(desc);
2106
2107         if (copy_to_user(u_info, &info, sizeof(info)))
2108                 return -EFAULT;
2109         return 0;
2110 }
2111
2112 extern asmlinkage long
2113 sys_timer_create(clockid_t which_clock, struct sigevent *timer_event_spec,
2114                  timer_t * created_timer_id);
2115
2116 asmlinkage long
2117 sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id)
2118 {
2119         struct sigevent se;
2120         mm_segment_t oldfs;
2121         timer_t t;
2122         long err;
2123
2124         if (se32 == NULL)
2125                 return sys_timer_create(clock, NULL, timer_id);
2126
2127         memset(&se, 0, sizeof(struct sigevent));
2128         if (get_user(se.sigev_value.sival_int,  &se32->sigev_value.sival_int) ||
2129             __get_user(se.sigev_signo, &se32->sigev_signo) ||
2130             __get_user(se.sigev_notify, &se32->sigev_notify) ||
2131             __copy_from_user(&se._sigev_un._pad, &se32->_sigev_un._pad,
2132             sizeof(se._sigev_un._pad)))
2133                 return -EFAULT;
2134
2135         if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))
2136                 return -EFAULT;
2137
2138         oldfs = get_fs();
2139         set_fs(KERNEL_DS);
2140         err = sys_timer_create(clock, &se, &t);
2141         set_fs(oldfs);
2142
2143         if (!err)
2144                 err = __put_user (t, timer_id);
2145
2146         return err;
2147 }
2148
2149 long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, 
2150                         __u32 len_low, __u32 len_high, int advice)
2151
2152         return sys_fadvise64_64(fd,
2153                                (((u64)offset_high)<<32) | offset_low,
2154                                (((u64)len_high)<<32) | len_low,
2155                                advice); 
2156
2157
2158 #ifdef  NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
2159
2160 asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid)
2161 {
2162         uid_t sruid, seuid;
2163
2164         sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2165         seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
2166         return sys_setreuid(sruid, seuid);
2167 }
2168
2169 asmlinkage long
2170 sys32_setresuid(compat_uid_t ruid, compat_uid_t euid,
2171                 compat_uid_t suid)
2172 {
2173         uid_t sruid, seuid, ssuid;
2174
2175         sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2176         seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
2177         ssuid = (suid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)suid);
2178         return sys_setresuid(sruid, seuid, ssuid);
2179 }
2180
2181 asmlinkage long
2182 sys32_setregid(compat_gid_t rgid, compat_gid_t egid)
2183 {
2184         gid_t srgid, segid;
2185
2186         srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2187         segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
2188         return sys_setregid(srgid, segid);
2189 }
2190
2191 asmlinkage long
2192 sys32_setresgid(compat_gid_t rgid, compat_gid_t egid,
2193                 compat_gid_t sgid)
2194 {
2195         gid_t srgid, segid, ssgid;
2196
2197         srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2198         segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
2199         ssgid = (sgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)sgid);
2200         return sys_setresgid(srgid, segid, ssgid);
2201 }
2202
2203 /* Handle adjtimex compatibility. */
2204
2205 struct timex32 {
2206         u32 modes;
2207         s32 offset, freq, maxerror, esterror;
2208         s32 status, constant, precision, tolerance;
2209         struct compat_timeval time;
2210         s32 tick;
2211         s32 ppsfreq, jitter, shift, stabil;
2212         s32 jitcnt, calcnt, errcnt, stbcnt;
2213         s32  :32; s32  :32; s32  :32; s32  :32;
2214         s32  :32; s32  :32; s32  :32; s32  :32;
2215         s32  :32; s32  :32; s32  :32; s32  :32;
2216 };
2217
2218 extern int do_adjtimex(struct timex *);
2219
2220 asmlinkage long
2221 sys32_adjtimex(struct timex32 *utp)
2222 {
2223         struct timex txc;
2224         int ret;
2225
2226         memset(&txc, 0, sizeof(struct timex));
2227
2228         if(get_user(txc.modes, &utp->modes) ||
2229            __get_user(txc.offset, &utp->offset) ||
2230            __get_user(txc.freq, &utp->freq) ||
2231            __get_user(txc.maxerror, &utp->maxerror) ||
2232            __get_user(txc.esterror, &utp->esterror) ||
2233            __get_user(txc.status, &utp->status) ||
2234            __get_user(txc.constant, &utp->constant) ||
2235            __get_user(txc.precision, &utp->precision) ||
2236            __get_user(txc.tolerance, &utp->tolerance) ||
2237            __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
2238            __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
2239            __get_user(txc.tick, &utp->tick) ||
2240            __get_user(txc.ppsfreq, &utp->ppsfreq) ||
2241            __get_user(txc.jitter, &utp->jitter) ||
2242            __get_user(txc.shift, &utp->shift) ||
2243            __get_user(txc.stabil, &utp->stabil) ||
2244            __get_user(txc.jitcnt, &utp->jitcnt) ||
2245            __get_user(txc.calcnt, &utp->calcnt) ||
2246            __get_user(txc.errcnt, &utp->errcnt) ||
2247            __get_user(txc.stbcnt, &utp->stbcnt))
2248                 return -EFAULT;
2249
2250         ret = do_adjtimex(&txc);
2251
2252         if(put_user(txc.modes, &utp->modes) ||
2253            __put_user(txc.offset, &utp->offset) ||
2254            __put_user(txc.freq, &utp->freq) ||
2255            __put_user(txc.maxerror, &utp->maxerror) ||
2256            __put_user(txc.esterror, &utp->esterror) ||
2257            __put_user(txc.status, &utp->status) ||
2258            __put_user(txc.constant, &utp->constant) ||
2259            __put_user(txc.precision, &utp->precision) ||
2260            __put_user(txc.tolerance, &utp->tolerance) ||
2261            __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
2262            __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
2263            __put_user(txc.tick, &utp->tick) ||
2264            __put_user(txc.ppsfreq, &utp->ppsfreq) ||
2265            __put_user(txc.jitter, &utp->jitter) ||
2266            __put_user(txc.shift, &utp->shift) ||
2267            __put_user(txc.stabil, &utp->stabil) ||
2268            __put_user(txc.jitcnt, &utp->jitcnt) ||
2269            __put_user(txc.calcnt, &utp->calcnt) ||
2270            __put_user(txc.errcnt, &utp->errcnt) ||
2271            __put_user(txc.stbcnt, &utp->stbcnt))
2272                 ret = -EFAULT;
2273
2274         return ret;
2275 }
2276 #endif /* NOTYET */