fedora core 6 1.2949 + vserver 2.2.0
[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, 2005 Hewlett-Packard Co
10  *      David Mosberger-Tang <davidm@hpl.hp.com>
11  * Copyright (C) 2004           Gordon Jin <gordon.jin@intel.com>
12  *
13  * These routines maintain argument size conversion between 32bit and 64bit
14  * environment.
15  */
16
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/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/quota.h>
37 #include <linux/syscalls.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/tracehook.h>
48 #include <linux/stat.h>
49 #include <linux/ipc.h>
50 #include <linux/capability.h>
51 #include <linux/compat.h>
52 #include <linux/vfs.h>
53 #include <linux/mman.h>
54 #include <linux/mutex.h>
55
56 #include <asm/intrinsics.h>
57 #include <asm/types.h>
58 #include <asm/uaccess.h>
59 #include <asm/unistd.h>
60
61 #include "ia32priv.h"
62
63 #include <net/scm.h>
64 #include <net/sock.h>
65
66 #define DEBUG   0
67
68 #if DEBUG
69 # define DBG(fmt...)    printk(KERN_DEBUG fmt)
70 #else
71 # define DBG(fmt...)
72 #endif
73
74 #define ROUND_UP(x,a)   ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
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 /*
84  * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
85  * while doing so.
86  */
87 /* XXX make per-mm: */
88 static DEFINE_MUTEX(ia32_mmap_mutex);
89
90 asmlinkage long
91 sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
92               struct pt_regs *regs)
93 {
94         long error;
95         char *filename;
96         unsigned long old_map_base, old_task_size, tssd;
97
98         filename = getname(name);
99         error = PTR_ERR(filename);
100         if (IS_ERR(filename))
101                 return error;
102
103         old_map_base  = current->thread.map_base;
104         old_task_size = current->thread.task_size;
105         tssd = ia64_get_kr(IA64_KR_TSSD);
106
107         /* we may be exec'ing a 64-bit process: reset map base, task-size, and io-base: */
108         current->thread.map_base  = DEFAULT_MAP_BASE;
109         current->thread.task_size = DEFAULT_TASK_SIZE;
110         ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
111         ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
112
113         error = compat_do_execve(filename, argv, envp, regs);
114         putname(filename);
115
116         if (error < 0) {
117                 /* oops, execve failed, switch back to old values... */
118                 ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
119                 ia64_set_kr(IA64_KR_TSSD, tssd);
120                 current->thread.map_base  = old_map_base;
121                 current->thread.task_size = old_task_size;
122         }
123
124         return error;
125 }
126
127 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
128 {
129         compat_ino_t ino;
130         int err;
131
132         if ((u64) stat->size > MAX_NON_LFS ||
133             !old_valid_dev(stat->dev) ||
134             !old_valid_dev(stat->rdev))
135                 return -EOVERFLOW;
136
137         ino = stat->ino;
138         if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
139                 return -EOVERFLOW;
140
141         if (clear_user(ubuf, sizeof(*ubuf)))
142                 return -EFAULT;
143
144         err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
145         err |= __put_user(ino, &ubuf->st_ino);
146         err |= __put_user(stat->mode, &ubuf->st_mode);
147         err |= __put_user(stat->nlink, &ubuf->st_nlink);
148         err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
149         err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
150         err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
151         err |= __put_user(stat->size, &ubuf->st_size);
152         err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
153         err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
154         err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
155         err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
156         err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
157         err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
158         err |= __put_user(stat->blksize, &ubuf->st_blksize);
159         err |= __put_user(stat->blocks, &ubuf->st_blocks);
160         return err;
161 }
162
163 #if PAGE_SHIFT > IA32_PAGE_SHIFT
164
165
166 static int
167 get_page_prot (struct vm_area_struct *vma, unsigned long addr)
168 {
169         int prot = 0;
170
171         if (!vma || vma->vm_start > addr)
172                 return 0;
173
174         if (vma->vm_flags & VM_READ)
175                 prot |= PROT_READ;
176         if (vma->vm_flags & VM_WRITE)
177                 prot |= PROT_WRITE;
178         if (vma->vm_flags & VM_EXEC)
179                 prot |= PROT_EXEC;
180         return prot;
181 }
182
183 /*
184  * Map a subpage by creating an anonymous page that contains the union of the old page and
185  * the subpage.
186  */
187 static unsigned long
188 mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
189               loff_t off)
190 {
191         void *page = NULL;
192         struct inode *inode;
193         unsigned long ret = 0;
194         struct vm_area_struct *vma = find_vma(current->mm, start);
195         int old_prot = get_page_prot(vma, start);
196
197         DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
198             file, start, end, prot, flags, off);
199
200
201         /* Optimize the case where the old mmap and the new mmap are both anonymous */
202         if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
203                 if (clear_user((void __user *) start, end - start)) {
204                         ret = -EFAULT;
205                         goto out;
206                 }
207                 goto skip_mmap;
208         }
209
210         page = (void *) get_zeroed_page(GFP_KERNEL);
211         if (!page)
212                 return -ENOMEM;
213
214         if (old_prot)
215                 copy_from_user(page, (void __user *) PAGE_START(start), PAGE_SIZE);
216
217         down_write(&current->mm->mmap_sem);
218         {
219                 ret = do_mmap(NULL, PAGE_START(start), PAGE_SIZE, prot | PROT_WRITE,
220                               flags | MAP_FIXED | MAP_ANONYMOUS, 0);
221         }
222         up_write(&current->mm->mmap_sem);
223
224         if (IS_ERR((void *) ret))
225                 goto out;
226
227         if (old_prot) {
228                 /* copy back the old page contents.  */
229                 if (offset_in_page(start))
230                         copy_to_user((void __user *) PAGE_START(start), page,
231                                      offset_in_page(start));
232                 if (offset_in_page(end))
233                         copy_to_user((void __user *) end, page + offset_in_page(end),
234                                      PAGE_SIZE - offset_in_page(end));
235         }
236
237         if (!(flags & MAP_ANONYMOUS)) {
238                 /* read the file contents */
239                 inode = file->f_path.dentry->d_inode;
240                 if (!inode->i_fop || !file->f_op->read
241                     || ((*file->f_op->read)(file, (char __user *) start, end - start, &off) < 0))
242                 {
243                         ret = -EINVAL;
244                         goto out;
245                 }
246         }
247
248  skip_mmap:
249         if (!(prot & PROT_WRITE))
250                 ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
251   out:
252         if (page)
253                 free_page((unsigned long) page);
254         return ret;
255 }
256
257 /* SLAB cache for partial_page structures */
258 struct kmem_cache *partial_page_cachep;
259
260 /*
261  * init partial_page_list.
262  * return 0 means kmalloc fail.
263  */
264 struct partial_page_list*
265 ia32_init_pp_list(void)
266 {
267         struct partial_page_list *p;
268
269         if ((p = kmalloc(sizeof(*p), GFP_KERNEL)) == NULL)
270                 return p;
271         p->pp_head = NULL;
272         p->ppl_rb = RB_ROOT;
273         p->pp_hint = NULL;
274         atomic_set(&p->pp_count, 1);
275         return p;
276 }
277
278 /*
279  * Search for the partial page with @start in partial page list @ppl.
280  * If finds the partial page, return the found partial page.
281  * Else, return 0 and provide @pprev, @rb_link, @rb_parent to
282  * be used by later __ia32_insert_pp().
283  */
284 static struct partial_page *
285 __ia32_find_pp(struct partial_page_list *ppl, unsigned int start,
286         struct partial_page **pprev, struct rb_node ***rb_link,
287         struct rb_node **rb_parent)
288 {
289         struct partial_page *pp;
290         struct rb_node **__rb_link, *__rb_parent, *rb_prev;
291
292         pp = ppl->pp_hint;
293         if (pp && pp->base == start)
294                 return pp;
295
296         __rb_link = &ppl->ppl_rb.rb_node;
297         rb_prev = __rb_parent = NULL;
298
299         while (*__rb_link) {
300                 __rb_parent = *__rb_link;
301                 pp = rb_entry(__rb_parent, struct partial_page, pp_rb);
302
303                 if (pp->base == start) {
304                         ppl->pp_hint = pp;
305                         return pp;
306                 } else if (pp->base < start) {
307                         rb_prev = __rb_parent;
308                         __rb_link = &__rb_parent->rb_right;
309                 } else {
310                         __rb_link = &__rb_parent->rb_left;
311                 }
312         }
313
314         *rb_link = __rb_link;
315         *rb_parent = __rb_parent;
316         *pprev = NULL;
317         if (rb_prev)
318                 *pprev = rb_entry(rb_prev, struct partial_page, pp_rb);
319         return NULL;
320 }
321
322 /*
323  * insert @pp into @ppl.
324  */
325 static void
326 __ia32_insert_pp(struct partial_page_list *ppl, struct partial_page *pp,
327          struct partial_page *prev, struct rb_node **rb_link,
328         struct rb_node *rb_parent)
329 {
330         /* link list */
331         if (prev) {
332                 pp->next = prev->next;
333                 prev->next = pp;
334         } else {
335                 ppl->pp_head = pp;
336                 if (rb_parent)
337                         pp->next = rb_entry(rb_parent,
338                                 struct partial_page, pp_rb);
339                 else
340                         pp->next = NULL;
341         }
342
343         /* link rb */
344         rb_link_node(&pp->pp_rb, rb_parent, rb_link);
345         rb_insert_color(&pp->pp_rb, &ppl->ppl_rb);
346
347         ppl->pp_hint = pp;
348 }
349
350 /*
351  * delete @pp from partial page list @ppl.
352  */
353 static void
354 __ia32_delete_pp(struct partial_page_list *ppl, struct partial_page *pp,
355         struct partial_page *prev)
356 {
357         if (prev) {
358                 prev->next = pp->next;
359                 if (ppl->pp_hint == pp)
360                         ppl->pp_hint = prev;
361         } else {
362                 ppl->pp_head = pp->next;
363                 if (ppl->pp_hint == pp)
364                         ppl->pp_hint = pp->next;
365         }
366         rb_erase(&pp->pp_rb, &ppl->ppl_rb);
367         kmem_cache_free(partial_page_cachep, pp);
368 }
369
370 static struct partial_page *
371 __pp_prev(struct partial_page *pp)
372 {
373         struct rb_node *prev = rb_prev(&pp->pp_rb);
374         if (prev)
375                 return rb_entry(prev, struct partial_page, pp_rb);
376         else
377                 return NULL;
378 }
379
380 /*
381  * Delete partial pages with address between @start and @end.
382  * @start and @end are page aligned.
383  */
384 static void
385 __ia32_delete_pp_range(unsigned int start, unsigned int end)
386 {
387         struct partial_page *pp, *prev;
388         struct rb_node **rb_link, *rb_parent;
389
390         if (start >= end)
391                 return;
392
393         pp = __ia32_find_pp(current->thread.ppl, start, &prev,
394                                         &rb_link, &rb_parent);
395         if (pp)
396                 prev = __pp_prev(pp);
397         else {
398                 if (prev)
399                         pp = prev->next;
400                 else
401                         pp = current->thread.ppl->pp_head;
402         }
403
404         while (pp && pp->base < end) {
405                 struct partial_page *tmp = pp->next;
406                 __ia32_delete_pp(current->thread.ppl, pp, prev);
407                 pp = tmp;
408         }
409 }
410
411 /*
412  * Set the range between @start and @end in bitmap.
413  * @start and @end should be IA32 page aligned and in the same IA64 page.
414  */
415 static int
416 __ia32_set_pp(unsigned int start, unsigned int end, int flags)
417 {
418         struct partial_page *pp, *prev;
419         struct rb_node ** rb_link, *rb_parent;
420         unsigned int pstart, start_bit, end_bit, i;
421
422         pstart = PAGE_START(start);
423         start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
424         end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
425         if (end_bit == 0)
426                 end_bit = PAGE_SIZE / IA32_PAGE_SIZE;
427         pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
428                                         &rb_link, &rb_parent);
429         if (pp) {
430                 for (i = start_bit; i < end_bit; i++)
431                         set_bit(i, &pp->bitmap);
432                 /*
433                  * Check: if this partial page has been set to a full page,
434                  * then delete it.
435                  */
436                 if (find_first_zero_bit(&pp->bitmap, sizeof(pp->bitmap)*8) >=
437                                 PAGE_SIZE/IA32_PAGE_SIZE) {
438                         __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
439                 }
440                 return 0;
441         }
442
443         /*
444          * MAP_FIXED may lead to overlapping mmap.
445          * In this case, the requested mmap area may already mmaped as a full
446          * page. So check vma before adding a new partial page.
447          */
448         if (flags & MAP_FIXED) {
449                 struct vm_area_struct *vma = find_vma(current->mm, pstart);
450                 if (vma && vma->vm_start <= pstart)
451                         return 0;
452         }
453
454         /* new a partial_page */
455         pp = kmem_cache_alloc(partial_page_cachep, GFP_KERNEL);
456         if (!pp)
457                 return -ENOMEM;
458         pp->base = pstart;
459         pp->bitmap = 0;
460         for (i=start_bit; i<end_bit; i++)
461                 set_bit(i, &(pp->bitmap));
462         pp->next = NULL;
463         __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
464         return 0;
465 }
466
467 /*
468  * @start and @end should be IA32 page aligned, but don't need to be in the
469  * same IA64 page. Split @start and @end to make sure they're in the same IA64
470  * page, then call __ia32_set_pp().
471  */
472 static void
473 ia32_set_pp(unsigned int start, unsigned int end, int flags)
474 {
475         down_write(&current->mm->mmap_sem);
476         if (flags & MAP_FIXED) {
477                 /*
478                  * MAP_FIXED may lead to overlapping mmap. When this happens,
479                  * a series of complete IA64 pages results in deletion of
480                  * old partial pages in that range.
481                  */
482                 __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));
483         }
484
485         if (end < PAGE_ALIGN(start)) {
486                 __ia32_set_pp(start, end, flags);
487         } else {
488                 if (offset_in_page(start))
489                         __ia32_set_pp(start, PAGE_ALIGN(start), flags);
490                 if (offset_in_page(end))
491                         __ia32_set_pp(PAGE_START(end), end, flags);
492         }
493         up_write(&current->mm->mmap_sem);
494 }
495
496 /*
497  * Unset the range between @start and @end in bitmap.
498  * @start and @end should be IA32 page aligned and in the same IA64 page.
499  * After doing that, if the bitmap is 0, then free the page and return 1,
500  *      else return 0;
501  * If not find the partial page in the list, then
502  *      If the vma exists, then the full page is set to a partial page;
503  *      Else return -ENOMEM.
504  */
505 static int
506 __ia32_unset_pp(unsigned int start, unsigned int end)
507 {
508         struct partial_page *pp, *prev;
509         struct rb_node ** rb_link, *rb_parent;
510         unsigned int pstart, start_bit, end_bit, i;
511         struct vm_area_struct *vma;
512
513         pstart = PAGE_START(start);
514         start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
515         end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
516         if (end_bit == 0)
517                 end_bit = PAGE_SIZE / IA32_PAGE_SIZE;
518
519         pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
520                                         &rb_link, &rb_parent);
521         if (pp) {
522                 for (i = start_bit; i < end_bit; i++)
523                         clear_bit(i, &pp->bitmap);
524                 if (pp->bitmap == 0) {
525                         __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
526                         return 1;
527                 }
528                 return 0;
529         }
530
531         vma = find_vma(current->mm, pstart);
532         if (!vma || vma->vm_start > pstart) {
533                 return -ENOMEM;
534         }
535
536         /* new a partial_page */
537         pp = kmem_cache_alloc(partial_page_cachep, GFP_KERNEL);
538         if (!pp)
539                 return -ENOMEM;
540         pp->base = pstart;
541         pp->bitmap = 0;
542         for (i = 0; i < start_bit; i++)
543                 set_bit(i, &(pp->bitmap));
544         for (i = end_bit; i < PAGE_SIZE / IA32_PAGE_SIZE; i++)
545                 set_bit(i, &(pp->bitmap));
546         pp->next = NULL;
547         __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
548         return 0;
549 }
550
551 /*
552  * Delete pp between PAGE_ALIGN(start) and PAGE_START(end) by calling
553  * __ia32_delete_pp_range(). Unset possible partial pages by calling
554  * __ia32_unset_pp().
555  * The returned value see __ia32_unset_pp().
556  */
557 static int
558 ia32_unset_pp(unsigned int *startp, unsigned int *endp)
559 {
560         unsigned int start = *startp, end = *endp;
561         int ret = 0;
562
563         down_write(&current->mm->mmap_sem);
564
565         __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));
566
567         if (end < PAGE_ALIGN(start)) {
568                 ret = __ia32_unset_pp(start, end);
569                 if (ret == 1) {
570                         *startp = PAGE_START(start);
571                         *endp = PAGE_ALIGN(end);
572                 }
573                 if (ret == 0) {
574                         /* to shortcut sys_munmap() in sys32_munmap() */
575                         *startp = PAGE_START(start);
576                         *endp = PAGE_START(end);
577                 }
578         } else {
579                 if (offset_in_page(start)) {
580                         ret = __ia32_unset_pp(start, PAGE_ALIGN(start));
581                         if (ret == 1)
582                                 *startp = PAGE_START(start);
583                         if (ret == 0)
584                                 *startp = PAGE_ALIGN(start);
585                         if (ret < 0)
586                                 goto out;
587                 }
588                 if (offset_in_page(end)) {
589                         ret = __ia32_unset_pp(PAGE_START(end), end);
590                         if (ret == 1)
591                                 *endp = PAGE_ALIGN(end);
592                         if (ret == 0)
593                                 *endp = PAGE_START(end);
594                 }
595         }
596
597  out:
598         up_write(&current->mm->mmap_sem);
599         return ret;
600 }
601
602 /*
603  * Compare the range between @start and @end with bitmap in partial page.
604  * @start and @end should be IA32 page aligned and in the same IA64 page.
605  */
606 static int
607 __ia32_compare_pp(unsigned int start, unsigned int end)
608 {
609         struct partial_page *pp, *prev;
610         struct rb_node ** rb_link, *rb_parent;
611         unsigned int pstart, start_bit, end_bit, size;
612         unsigned int first_bit, next_zero_bit;  /* the first range in bitmap */
613
614         pstart = PAGE_START(start);
615
616         pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
617                                         &rb_link, &rb_parent);
618         if (!pp)
619                 return 1;
620
621         start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
622         end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
623         size = sizeof(pp->bitmap) * 8;
624         first_bit = find_first_bit(&pp->bitmap, size);
625         next_zero_bit = find_next_zero_bit(&pp->bitmap, size, first_bit);
626         if ((start_bit < first_bit) || (end_bit > next_zero_bit)) {
627                 /* exceeds the first range in bitmap */
628                 return -ENOMEM;
629         } else if ((start_bit == first_bit) && (end_bit == next_zero_bit)) {
630                 first_bit = find_next_bit(&pp->bitmap, size, next_zero_bit);
631                 if ((next_zero_bit < first_bit) && (first_bit < size))
632                         return 1;       /* has next range */
633                 else
634                         return 0;       /* no next range */
635         } else
636                 return 1;
637 }
638
639 /*
640  * @start and @end should be IA32 page aligned, but don't need to be in the
641  * same IA64 page. Split @start and @end to make sure they're in the same IA64
642  * page, then call __ia32_compare_pp().
643  *
644  * Take this as example: the range is the 1st and 2nd 4K page.
645  * Return 0 if they fit bitmap exactly, i.e. bitmap = 00000011;
646  * Return 1 if the range doesn't cover whole bitmap, e.g. bitmap = 00001111;
647  * Return -ENOMEM if the range exceeds the bitmap, e.g. bitmap = 00000001 or
648  *      bitmap = 00000101.
649  */
650 static int
651 ia32_compare_pp(unsigned int *startp, unsigned int *endp)
652 {
653         unsigned int start = *startp, end = *endp;
654         int retval = 0;
655
656         down_write(&current->mm->mmap_sem);
657
658         if (end < PAGE_ALIGN(start)) {
659                 retval = __ia32_compare_pp(start, end);
660                 if (retval == 0) {
661                         *startp = PAGE_START(start);
662                         *endp = PAGE_ALIGN(end);
663                 }
664         } else {
665                 if (offset_in_page(start)) {
666                         retval = __ia32_compare_pp(start,
667                                                    PAGE_ALIGN(start));
668                         if (retval == 0)
669                                 *startp = PAGE_START(start);
670                         if (retval < 0)
671                                 goto out;
672                 }
673                 if (offset_in_page(end)) {
674                         retval = __ia32_compare_pp(PAGE_START(end), end);
675                         if (retval == 0)
676                                 *endp = PAGE_ALIGN(end);
677                 }
678         }
679
680  out:
681         up_write(&current->mm->mmap_sem);
682         return retval;
683 }
684
685 static void
686 __ia32_drop_pp_list(struct partial_page_list *ppl)
687 {
688         struct partial_page *pp = ppl->pp_head;
689
690         while (pp) {
691                 struct partial_page *next = pp->next;
692                 kmem_cache_free(partial_page_cachep, pp);
693                 pp = next;
694         }
695
696         kfree(ppl);
697 }
698
699 void
700 ia32_drop_partial_page_list(struct task_struct *task)
701 {
702         struct partial_page_list* ppl = task->thread.ppl;
703
704         if (ppl && atomic_dec_and_test(&ppl->pp_count))
705                 __ia32_drop_pp_list(ppl);
706 }
707
708 /*
709  * Copy current->thread.ppl to ppl (already initialized).
710  */
711 static int
712 __ia32_copy_pp_list(struct partial_page_list *ppl)
713 {
714         struct partial_page *pp, *tmp, *prev;
715         struct rb_node **rb_link, *rb_parent;
716
717         ppl->pp_head = NULL;
718         ppl->pp_hint = NULL;
719         ppl->ppl_rb = RB_ROOT;
720         rb_link = &ppl->ppl_rb.rb_node;
721         rb_parent = NULL;
722         prev = NULL;
723
724         for (pp = current->thread.ppl->pp_head; pp; pp = pp->next) {
725                 tmp = kmem_cache_alloc(partial_page_cachep, GFP_KERNEL);
726                 if (!tmp)
727                         return -ENOMEM;
728                 *tmp = *pp;
729                 __ia32_insert_pp(ppl, tmp, prev, rb_link, rb_parent);
730                 prev = tmp;
731                 rb_link = &tmp->pp_rb.rb_right;
732                 rb_parent = &tmp->pp_rb;
733         }
734         return 0;
735 }
736
737 int
738 ia32_copy_partial_page_list(struct task_struct *p, unsigned long clone_flags)
739 {
740         int retval = 0;
741
742         if (clone_flags & CLONE_VM) {
743                 atomic_inc(&current->thread.ppl->pp_count);
744                 p->thread.ppl = current->thread.ppl;
745         } else {
746                 p->thread.ppl = ia32_init_pp_list();
747                 if (!p->thread.ppl)
748                         return -ENOMEM;
749                 down_write(&current->mm->mmap_sem);
750                 {
751                         retval = __ia32_copy_pp_list(p->thread.ppl);
752                 }
753                 up_write(&current->mm->mmap_sem);
754         }
755
756         return retval;
757 }
758
759 static unsigned long
760 emulate_mmap (struct file *file, unsigned long start, unsigned long len, int prot, int flags,
761               loff_t off)
762 {
763         unsigned long tmp, end, pend, pstart, ret, is_congruent, fudge = 0;
764         struct inode *inode;
765         loff_t poff;
766
767         end = start + len;
768         pstart = PAGE_START(start);
769         pend = PAGE_ALIGN(end);
770
771         if (flags & MAP_FIXED) {
772                 ia32_set_pp((unsigned int)start, (unsigned int)end, flags);
773                 if (start > pstart) {
774                         if (flags & MAP_SHARED)
775                                 printk(KERN_INFO
776                                        "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
777                                        current->comm, current->pid, start);
778                         ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
779                                            off);
780                         if (IS_ERR((void *) ret))
781                                 return ret;
782                         pstart += PAGE_SIZE;
783                         if (pstart >= pend)
784                                 goto out;       /* done */
785                 }
786                 if (end < pend) {
787                         if (flags & MAP_SHARED)
788                                 printk(KERN_INFO
789                                        "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
790                                        current->comm, current->pid, end);
791                         ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
792                                            (off + len) - offset_in_page(end));
793                         if (IS_ERR((void *) ret))
794                                 return ret;
795                         pend -= PAGE_SIZE;
796                         if (pstart >= pend)
797                                 goto out;       /* done */
798                 }
799         } else {
800                 /*
801                  * If a start address was specified, use it if the entire rounded out area
802                  * is available.
803                  */
804                 if (start && !pstart)
805                         fudge = 1;      /* handle case of mapping to range (0,PAGE_SIZE) */
806                 tmp = arch_get_unmapped_area(file, pstart - fudge, pend - pstart, 0, flags);
807                 if (tmp != pstart) {
808                         pstart = tmp;
809                         start = pstart + offset_in_page(off);   /* make start congruent with off */
810                         end = start + len;
811                         pend = PAGE_ALIGN(end);
812                 }
813         }
814
815         poff = off + (pstart - start);  /* note: (pstart - start) may be negative */
816         is_congruent = (flags & MAP_ANONYMOUS) || (offset_in_page(poff) == 0);
817
818         if ((flags & MAP_SHARED) && !is_congruent)
819                 printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
820                        "(addr=0x%lx,off=0x%llx)\n", current->comm, current->pid, start, off);
821
822         DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
823             is_congruent ? "congruent" : "not congruent", poff);
824
825         down_write(&current->mm->mmap_sem);
826         {
827                 if (!(flags & MAP_ANONYMOUS) && is_congruent)
828                         ret = do_mmap(file, pstart, pend - pstart, prot, flags | MAP_FIXED, poff);
829                 else
830                         ret = do_mmap(NULL, pstart, pend - pstart,
831                                       prot | ((flags & MAP_ANONYMOUS) ? 0 : PROT_WRITE),
832                                       flags | MAP_FIXED | MAP_ANONYMOUS, 0);
833         }
834         up_write(&current->mm->mmap_sem);
835
836         if (IS_ERR((void *) ret))
837                 return ret;
838
839         if (!is_congruent) {
840                 /* read the file contents */
841                 inode = file->f_path.dentry->d_inode;
842                 if (!inode->i_fop || !file->f_op->read
843                     || ((*file->f_op->read)(file, (char __user *) pstart, pend - pstart, &poff)
844                         < 0))
845                 {
846                         sys_munmap(pstart, pend - pstart);
847                         return -EINVAL;
848                 }
849                 if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0)
850                         return -EINVAL;
851         }
852
853         if (!(flags & MAP_FIXED))
854                 ia32_set_pp((unsigned int)start, (unsigned int)end, flags);
855 out:
856         return start;
857 }
858
859 #endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
860
861 static inline unsigned int
862 get_prot32 (unsigned int prot)
863 {
864         if (prot & PROT_WRITE)
865                 /* on x86, PROT_WRITE implies PROT_READ which implies PROT_EEC */
866                 prot |= PROT_READ | PROT_WRITE | PROT_EXEC;
867         else if (prot & (PROT_READ | PROT_EXEC))
868                 /* on x86, there is no distinction between PROT_READ and PROT_EXEC */
869                 prot |= (PROT_READ | PROT_EXEC);
870
871         return prot;
872 }
873
874 unsigned long
875 ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot, int flags,
876               loff_t offset)
877 {
878         DBG("ia32_do_mmap(file=%p,addr=0x%lx,len=0x%lx,prot=%x,flags=%x,offset=0x%llx)\n",
879             file, addr, len, prot, flags, offset);
880
881         if (file && (!file->f_op || !file->f_op->mmap))
882                 return -ENODEV;
883
884         len = IA32_PAGE_ALIGN(len);
885         if (len == 0)
886                 return addr;
887
888         if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len)
889         {
890                 if (flags & MAP_FIXED)
891                         return -ENOMEM;
892                 else
893                 return -EINVAL;
894         }
895
896         if (OFFSET4K(offset))
897                 return -EINVAL;
898
899         prot = get_prot32(prot);
900
901 #if PAGE_SHIFT > IA32_PAGE_SHIFT
902         mutex_lock(&ia32_mmap_mutex);
903         {
904                 addr = emulate_mmap(file, addr, len, prot, flags, offset);
905         }
906         mutex_unlock(&ia32_mmap_mutex);
907 #else
908         down_write(&current->mm->mmap_sem);
909         {
910                 addr = do_mmap(file, addr, len, prot, flags, offset);
911         }
912         up_write(&current->mm->mmap_sem);
913 #endif
914         DBG("ia32_do_mmap: returning 0x%lx\n", addr);
915         return addr;
916 }
917
918 /*
919  * Linux/i386 didn't use to be able to handle more than 4 system call parameters, so these
920  * system calls used a memory block for parameter passing..
921  */
922
923 struct mmap_arg_struct {
924         unsigned int addr;
925         unsigned int len;
926         unsigned int prot;
927         unsigned int flags;
928         unsigned int fd;
929         unsigned int offset;
930 };
931
932 asmlinkage long
933 sys32_mmap (struct mmap_arg_struct __user *arg)
934 {
935         struct mmap_arg_struct a;
936         struct file *file = NULL;
937         unsigned long addr;
938         int flags;
939
940         if (copy_from_user(&a, arg, sizeof(a)))
941                 return -EFAULT;
942
943         if (OFFSET4K(a.offset))
944                 return -EINVAL;
945
946         flags = a.flags;
947
948         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
949         if (!(flags & MAP_ANONYMOUS)) {
950                 file = fget(a.fd);
951                 if (!file)
952                         return -EBADF;
953         }
954
955         addr = ia32_do_mmap(file, a.addr, a.len, a.prot, flags, a.offset);
956
957         if (file)
958                 fput(file);
959         return addr;
960 }
961
962 asmlinkage long
963 sys32_mmap2 (unsigned int addr, unsigned int len, unsigned int prot, unsigned int flags,
964              unsigned int fd, unsigned int pgoff)
965 {
966         struct file *file = NULL;
967         unsigned long retval;
968
969         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
970         if (!(flags & MAP_ANONYMOUS)) {
971                 file = fget(fd);
972                 if (!file)
973                         return -EBADF;
974         }
975
976         retval = ia32_do_mmap(file, addr, len, prot, flags,
977                               (unsigned long) pgoff << IA32_PAGE_SHIFT);
978
979         if (file)
980                 fput(file);
981         return retval;
982 }
983
984 asmlinkage long
985 sys32_munmap (unsigned int start, unsigned int len)
986 {
987         unsigned int end = start + len;
988         long ret;
989
990 #if PAGE_SHIFT <= IA32_PAGE_SHIFT
991         ret = sys_munmap(start, end - start);
992 #else
993         if (OFFSET4K(start))
994                 return -EINVAL;
995
996         end = IA32_PAGE_ALIGN(end);
997         if (start >= end)
998                 return -EINVAL;
999
1000         ret = ia32_unset_pp(&start, &end);
1001         if (ret < 0)
1002                 return ret;
1003
1004         if (start >= end)
1005                 return 0;
1006
1007         mutex_lock(&ia32_mmap_mutex);
1008         ret = sys_munmap(start, end - start);
1009         mutex_unlock(&ia32_mmap_mutex);
1010 #endif
1011         return ret;
1012 }
1013
1014 #if PAGE_SHIFT > IA32_PAGE_SHIFT
1015
1016 /*
1017  * When mprotect()ing a partial page, we set the permission to the union of the old
1018  * settings and the new settings.  In other words, it's only possible to make access to a
1019  * partial page less restrictive.
1020  */
1021 static long
1022 mprotect_subpage (unsigned long address, int new_prot)
1023 {
1024         int old_prot;
1025         struct vm_area_struct *vma;
1026
1027         if (new_prot == PROT_NONE)
1028                 return 0;               /* optimize case where nothing changes... */
1029         vma = find_vma(current->mm, address);
1030         old_prot = get_page_prot(vma, address);
1031         return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
1032 }
1033
1034 #endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
1035
1036 asmlinkage long
1037 sys32_mprotect (unsigned int start, unsigned int len, int prot)
1038 {
1039         unsigned int end = start + len;
1040 #if PAGE_SHIFT > IA32_PAGE_SHIFT
1041         long retval = 0;
1042 #endif
1043
1044         prot = get_prot32(prot);
1045
1046 #if PAGE_SHIFT <= IA32_PAGE_SHIFT
1047         return sys_mprotect(start, end - start, prot);
1048 #else
1049         if (OFFSET4K(start))
1050                 return -EINVAL;
1051
1052         end = IA32_PAGE_ALIGN(end);
1053         if (end < start)
1054                 return -EINVAL;
1055
1056         retval = ia32_compare_pp(&start, &end);
1057
1058         if (retval < 0)
1059                 return retval;
1060
1061         mutex_lock(&ia32_mmap_mutex);
1062         {
1063                 if (offset_in_page(start)) {
1064                         /* start address is 4KB aligned but not page aligned. */
1065                         retval = mprotect_subpage(PAGE_START(start), prot);
1066                         if (retval < 0)
1067                                 goto out;
1068
1069                         start = PAGE_ALIGN(start);
1070                         if (start >= end)
1071                                 goto out;       /* retval is already zero... */
1072                 }
1073
1074                 if (offset_in_page(end)) {
1075                         /* end address is 4KB aligned but not page aligned. */
1076                         retval = mprotect_subpage(PAGE_START(end), prot);
1077                         if (retval < 0)
1078                                 goto out;
1079
1080                         end = PAGE_START(end);
1081                 }
1082                 retval = sys_mprotect(start, end - start, prot);
1083         }
1084   out:
1085         mutex_unlock(&ia32_mmap_mutex);
1086         return retval;
1087 #endif
1088 }
1089
1090 asmlinkage long
1091 sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len,
1092                 unsigned int flags, unsigned int new_addr)
1093 {
1094         long ret;
1095
1096 #if PAGE_SHIFT <= IA32_PAGE_SHIFT
1097         ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
1098 #else
1099         unsigned int old_end, new_end;
1100
1101         if (OFFSET4K(addr))
1102                 return -EINVAL;
1103
1104         old_len = IA32_PAGE_ALIGN(old_len);
1105         new_len = IA32_PAGE_ALIGN(new_len);
1106         old_end = addr + old_len;
1107         new_end = addr + new_len;
1108
1109         if (!new_len)
1110                 return -EINVAL;
1111
1112         if ((flags & MREMAP_FIXED) && (OFFSET4K(new_addr)))
1113                 return -EINVAL;
1114
1115         if (old_len >= new_len) {
1116                 ret = sys32_munmap(addr + new_len, old_len - new_len);
1117                 if (ret && old_len != new_len)
1118                         return ret;
1119                 ret = addr;
1120                 if (!(flags & MREMAP_FIXED) || (new_addr == addr))
1121                         return ret;
1122                 old_len = new_len;
1123         }
1124
1125         addr = PAGE_START(addr);
1126         old_len = PAGE_ALIGN(old_end) - addr;
1127         new_len = PAGE_ALIGN(new_end) - addr;
1128
1129         mutex_lock(&ia32_mmap_mutex);
1130         ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
1131         mutex_unlock(&ia32_mmap_mutex);
1132
1133         if ((ret >= 0) && (old_len < new_len)) {
1134                 /* mremap expanded successfully */
1135                 ia32_set_pp(old_end, new_end, flags);
1136         }
1137 #endif
1138         return ret;
1139 }
1140
1141 asmlinkage long
1142 sys32_pipe (int __user *fd)
1143 {
1144         int retval;
1145         int fds[2];
1146
1147         retval = do_pipe(fds);
1148         if (retval)
1149                 goto out;
1150         if (copy_to_user(fd, fds, sizeof(fds)))
1151                 retval = -EFAULT;
1152   out:
1153         return retval;
1154 }
1155
1156 static inline long
1157 get_tv32 (struct timeval *o, struct compat_timeval __user *i)
1158 {
1159         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
1160                 (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec)));
1161 }
1162
1163 static inline long
1164 put_tv32 (struct compat_timeval __user *o, struct timeval *i)
1165 {
1166         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
1167                 (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec)));
1168 }
1169
1170 asmlinkage unsigned long
1171 sys32_alarm (unsigned int seconds)
1172 {
1173         return alarm_setitimer(seconds);
1174 }
1175
1176 /* Translations due to time_t size differences.  Which affects all
1177    sorts of things, like timeval and itimerval.  */
1178
1179 extern struct timezone sys_tz;
1180
1181 asmlinkage long
1182 sys32_gettimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
1183 {
1184         if (tv) {
1185                 struct timeval ktv;
1186                 vx_gettimeofday(&ktv);
1187                 if (put_tv32(tv, &ktv))
1188                         return -EFAULT;
1189         }
1190         if (tz) {
1191                 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
1192                         return -EFAULT;
1193         }
1194         return 0;
1195 }
1196
1197 asmlinkage long
1198 sys32_settimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
1199 {
1200         struct timeval ktv;
1201         struct timespec kts;
1202         struct timezone ktz;
1203
1204         if (tv) {
1205                 if (get_tv32(&ktv, tv))
1206                         return -EFAULT;
1207                 kts.tv_sec = ktv.tv_sec;
1208                 kts.tv_nsec = ktv.tv_usec * 1000;
1209         }
1210         if (tz) {
1211                 if (copy_from_user(&ktz, tz, sizeof(ktz)))
1212                         return -EFAULT;
1213         }
1214
1215         return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
1216 }
1217
1218 struct getdents32_callback {
1219         struct compat_dirent __user *current_dir;
1220         struct compat_dirent __user *previous;
1221         int count;
1222         int error;
1223 };
1224
1225 struct readdir32_callback {
1226         struct old_linux32_dirent __user * dirent;
1227         int count;
1228 };
1229
1230 static int
1231 filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino,
1232            unsigned int d_type)
1233 {
1234         struct compat_dirent __user * dirent;
1235         struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
1236         int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4);
1237         u32 d_ino;
1238
1239         buf->error = -EINVAL;   /* only used if we fail.. */
1240         if (reclen > buf->count)
1241                 return -EINVAL;
1242         d_ino = ino;
1243         if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
1244                 return -EOVERFLOW;
1245         buf->error = -EFAULT;   /* only used if we fail.. */
1246         dirent = buf->previous;
1247         if (dirent)
1248                 if (put_user(offset, &dirent->d_off))
1249                         return -EFAULT;
1250         dirent = buf->current_dir;
1251         buf->previous = dirent;
1252         if (put_user(d_ino, &dirent->d_ino)
1253             || put_user(reclen, &dirent->d_reclen)
1254             || copy_to_user(dirent->d_name, name, namlen)
1255             || put_user(0, dirent->d_name + namlen))
1256                 return -EFAULT;
1257         dirent = (struct compat_dirent __user *) ((char __user *) dirent + reclen);
1258         buf->current_dir = dirent;
1259         buf->count -= reclen;
1260         return 0;
1261 }
1262
1263 asmlinkage long
1264 sys32_getdents (unsigned int fd, struct compat_dirent __user *dirent, unsigned int count)
1265 {
1266         struct file * file;
1267         struct compat_dirent __user * lastdirent;
1268         struct getdents32_callback buf;
1269         int error;
1270
1271         error = -EBADF;
1272         file = fget(fd);
1273         if (!file)
1274                 goto out;
1275
1276         buf.current_dir = dirent;
1277         buf.previous = NULL;
1278         buf.count = count;
1279         buf.error = 0;
1280
1281         error = vfs_readdir(file, filldir32, &buf);
1282         if (error < 0)
1283                 goto out_putf;
1284         error = buf.error;
1285         lastdirent = buf.previous;
1286         if (lastdirent) {
1287                 error = -EINVAL;
1288                 if (put_user(file->f_pos, &lastdirent->d_off))
1289                         goto out_putf;
1290                 error = count - buf.count;
1291         }
1292
1293 out_putf:
1294         fput(file);
1295 out:
1296         return error;
1297 }
1298
1299 static int
1300 fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino,
1301               unsigned int d_type)
1302 {
1303         struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
1304         struct old_linux32_dirent __user * dirent;
1305         u32 d_ino;
1306
1307         if (buf->count)
1308                 return -EINVAL;
1309         d_ino = ino;
1310         if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
1311                 return -EOVERFLOW;
1312         buf->count++;
1313         dirent = buf->dirent;
1314         if (put_user(d_ino, &dirent->d_ino)
1315             || put_user(offset, &dirent->d_offset)
1316             || put_user(namlen, &dirent->d_namlen)
1317             || copy_to_user(dirent->d_name, name, namlen)
1318             || put_user(0, dirent->d_name + namlen))
1319                 return -EFAULT;
1320         return 0;
1321 }
1322
1323 asmlinkage long
1324 sys32_readdir (unsigned int fd, void __user *dirent, unsigned int count)
1325 {
1326         int error;
1327         struct file * file;
1328         struct readdir32_callback buf;
1329
1330         error = -EBADF;
1331         file = fget(fd);
1332         if (!file)
1333                 goto out;
1334
1335         buf.count = 0;
1336         buf.dirent = dirent;
1337
1338         error = vfs_readdir(file, fillonedir32, &buf);
1339         if (error >= 0)
1340                 error = buf.count;
1341         fput(file);
1342 out:
1343         return error;
1344 }
1345
1346 struct sel_arg_struct {
1347         unsigned int n;
1348         unsigned int inp;
1349         unsigned int outp;
1350         unsigned int exp;
1351         unsigned int tvp;
1352 };
1353
1354 asmlinkage long
1355 sys32_old_select (struct sel_arg_struct __user *arg)
1356 {
1357         struct sel_arg_struct a;
1358
1359         if (copy_from_user(&a, arg, sizeof(a)))
1360                 return -EFAULT;
1361         return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
1362                                  compat_ptr(a.exp), compat_ptr(a.tvp));
1363 }
1364
1365 #define SEMOP            1
1366 #define SEMGET           2
1367 #define SEMCTL           3
1368 #define SEMTIMEDOP       4
1369 #define MSGSND          11
1370 #define MSGRCV          12
1371 #define MSGGET          13
1372 #define MSGCTL          14
1373 #define SHMAT           21
1374 #define SHMDT           22
1375 #define SHMGET          23
1376 #define SHMCTL          24
1377
1378 asmlinkage long
1379 sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
1380 {
1381         int version;
1382
1383         version = call >> 16; /* hack for backward compatibility */
1384         call &= 0xffff;
1385
1386         switch (call) {
1387               case SEMTIMEDOP:
1388                 if (fifth)
1389                         return compat_sys_semtimedop(first, compat_ptr(ptr),
1390                                 second, compat_ptr(fifth));
1391                 /* else fall through for normal semop() */
1392               case SEMOP:
1393                 /* struct sembuf is the same on 32 and 64bit :)) */
1394                 return sys_semtimedop(first, compat_ptr(ptr), second,
1395                                       NULL);
1396               case SEMGET:
1397                 return sys_semget(first, second, third);
1398               case SEMCTL:
1399                 return compat_sys_semctl(first, second, third, compat_ptr(ptr));
1400
1401               case MSGSND:
1402                 return compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
1403               case MSGRCV:
1404                 return compat_sys_msgrcv(first, second, fifth, third, version, compat_ptr(ptr));
1405               case MSGGET:
1406                 return sys_msgget((key_t) first, second);
1407               case MSGCTL:
1408                 return compat_sys_msgctl(first, second, compat_ptr(ptr));
1409
1410               case SHMAT:
1411                 return compat_sys_shmat(first, second, third, version, compat_ptr(ptr));
1412                 break;
1413               case SHMDT:
1414                 return sys_shmdt(compat_ptr(ptr));
1415               case SHMGET:
1416                 return sys_shmget(first, (unsigned)second, third);
1417               case SHMCTL:
1418                 return compat_sys_shmctl(first, second, compat_ptr(ptr));
1419
1420               default:
1421                 return -ENOSYS;
1422         }
1423         return -EINVAL;
1424 }
1425
1426 asmlinkage long
1427 compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options,
1428                  struct compat_rusage *ru);
1429
1430 asmlinkage long
1431 sys32_waitpid (int pid, unsigned int *stat_addr, int options)
1432 {
1433         return compat_sys_wait4(pid, stat_addr, options, NULL);
1434 }
1435
1436 /*
1437  *  The order in which registers are stored in the ptrace regs structure
1438  */
1439 #define PT_EBX  0
1440 #define PT_ECX  1
1441 #define PT_EDX  2
1442 #define PT_ESI  3
1443 #define PT_EDI  4
1444 #define PT_EBP  5
1445 #define PT_EAX  6
1446 #define PT_DS   7
1447 #define PT_ES   8
1448 #define PT_FS   9
1449 #define PT_GS   10
1450 #define PT_ORIG_EAX 11
1451 #define PT_EIP  12
1452 #define PT_CS   13
1453 #define PT_EFL  14
1454 #define PT_UESP 15
1455 #define PT_SS   16
1456
1457 static unsigned int
1458 getreg (struct task_struct *child, int regno)
1459 {
1460         struct pt_regs *child_regs;
1461
1462         child_regs = task_pt_regs(child);
1463         switch (regno / sizeof(int)) {
1464               case PT_EBX: return child_regs->r11;
1465               case PT_ECX: return child_regs->r9;
1466               case PT_EDX: return child_regs->r10;
1467               case PT_ESI: return child_regs->r14;
1468               case PT_EDI: return child_regs->r15;
1469               case PT_EBP: return child_regs->r13;
1470               case PT_EAX: return child_regs->r8;
1471               case PT_ORIG_EAX: return child_regs->r1; /* see dispatch_to_ia32_handler() */
1472               case PT_EIP: return child_regs->cr_iip;
1473               case PT_UESP: return child_regs->r12;
1474               case PT_EFL: return child->thread.eflag;
1475               case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
1476                 return __USER_DS;
1477               case PT_CS: return __USER_CS;
1478               default:
1479                 printk(KERN_ERR "ia32.getreg(): unknown register %d\n", regno);
1480                 break;
1481         }
1482         return 0;
1483 }
1484
1485 static void
1486 putreg (struct task_struct *child, int regno, unsigned int value)
1487 {
1488         struct pt_regs *child_regs;
1489
1490         child_regs = task_pt_regs(child);
1491         switch (regno / sizeof(int)) {
1492               case PT_EBX: child_regs->r11 = value; break;
1493               case PT_ECX: child_regs->r9 = value; break;
1494               case PT_EDX: child_regs->r10 = value; break;
1495               case PT_ESI: child_regs->r14 = value; break;
1496               case PT_EDI: child_regs->r15 = value; break;
1497               case PT_EBP: child_regs->r13 = value; break;
1498               case PT_EAX: child_regs->r8 = value; break;
1499               case PT_ORIG_EAX: child_regs->r1 = value; break;
1500               case PT_EIP: child_regs->cr_iip = value; break;
1501               case PT_UESP: child_regs->r12 = value; break;
1502               case PT_EFL: child->thread.eflag = value; break;
1503               case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
1504                 if (value != __USER_DS)
1505                         printk(KERN_ERR
1506                                "ia32.putreg: attempt to set invalid segment register %d = %x\n",
1507                                regno, value);
1508                 break;
1509               case PT_CS:
1510                 if (value != __USER_CS)
1511                         printk(KERN_ERR
1512                                "ia32.putreg: attempt to to set invalid segment register %d = %x\n",
1513                                regno, value);
1514                 break;
1515               default:
1516                 printk(KERN_ERR "ia32.putreg: unknown register %d\n", regno);
1517                 break;
1518         }
1519 }
1520
1521 static void
1522 put_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
1523            struct switch_stack *swp, int tos)
1524 {
1525         struct _fpreg_ia32 *f;
1526         char buf[32];
1527
1528         f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
1529         if ((regno += tos) >= 8)
1530                 regno -= 8;
1531         switch (regno) {
1532               case 0:
1533                 ia64f2ia32f(f, &ptp->f8);
1534                 break;
1535               case 1:
1536                 ia64f2ia32f(f, &ptp->f9);
1537                 break;
1538               case 2:
1539                 ia64f2ia32f(f, &ptp->f10);
1540                 break;
1541               case 3:
1542                 ia64f2ia32f(f, &ptp->f11);
1543                 break;
1544               case 4:
1545               case 5:
1546               case 6:
1547               case 7:
1548                 ia64f2ia32f(f, &swp->f12 + (regno - 4));
1549                 break;
1550         }
1551         copy_to_user(reg, f, sizeof(*reg));
1552 }
1553
1554 static void
1555 get_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
1556            struct switch_stack *swp, int tos)
1557 {
1558
1559         if ((regno += tos) >= 8)
1560                 regno -= 8;
1561         switch (regno) {
1562               case 0:
1563                 copy_from_user(&ptp->f8, reg, sizeof(*reg));
1564                 break;
1565               case 1:
1566                 copy_from_user(&ptp->f9, reg, sizeof(*reg));
1567                 break;
1568               case 2:
1569                 copy_from_user(&ptp->f10, reg, sizeof(*reg));
1570                 break;
1571               case 3:
1572                 copy_from_user(&ptp->f11, reg, sizeof(*reg));
1573                 break;
1574               case 4:
1575               case 5:
1576               case 6:
1577               case 7:
1578                 copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg));
1579                 break;
1580         }
1581         return;
1582 }
1583
1584 int
1585 save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
1586 {
1587         struct switch_stack *swp;
1588         struct pt_regs *ptp;
1589         int i, tos;
1590
1591         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1592                 return -EFAULT;
1593
1594         __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1595         __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1596         __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1597         __put_user(tsk->thread.fir, &save->fip);
1598         __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1599         __put_user(tsk->thread.fdr, &save->foo);
1600         __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1601
1602         /*
1603          *  Stack frames start with 16-bytes of temp space
1604          */
1605         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1606         ptp = task_pt_regs(tsk);
1607         tos = (tsk->thread.fsr >> 11) & 7;
1608         for (i = 0; i < 8; i++)
1609                 put_fpreg(i, &save->st_space[i], ptp, swp, tos);
1610         return 0;
1611 }
1612
1613 static int
1614 restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
1615 {
1616         struct switch_stack *swp;
1617         struct pt_regs *ptp;
1618         int i, tos;
1619         unsigned int fsrlo, fsrhi, num32;
1620
1621         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1622                 return(-EFAULT);
1623
1624         __get_user(num32, (unsigned int __user *)&save->cwd);
1625         tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1626         __get_user(fsrlo, (unsigned int __user *)&save->swd);
1627         __get_user(fsrhi, (unsigned int __user *)&save->twd);
1628         num32 = (fsrhi << 16) | fsrlo;
1629         tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1630         __get_user(num32, (unsigned int __user *)&save->fip);
1631         tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1632         __get_user(num32, (unsigned int __user *)&save->foo);
1633         tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1634
1635         /*
1636          *  Stack frames start with 16-bytes of temp space
1637          */
1638         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1639         ptp = task_pt_regs(tsk);
1640         tos = (tsk->thread.fsr >> 11) & 7;
1641         for (i = 0; i < 8; i++)
1642                 get_fpreg(i, &save->st_space[i], ptp, swp, tos);
1643         return 0;
1644 }
1645
1646 int
1647 save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
1648 {
1649         struct switch_stack *swp;
1650         struct pt_regs *ptp;
1651         int i, tos;
1652         unsigned long mxcsr=0;
1653         unsigned long num128[2];
1654
1655         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1656                 return -EFAULT;
1657
1658         __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1659         __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1660         __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1661         __put_user(tsk->thread.fir, &save->fip);
1662         __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1663         __put_user(tsk->thread.fdr, &save->foo);
1664         __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1665
1666         /*
1667          *  Stack frames start with 16-bytes of temp space
1668          */
1669         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1670         ptp = task_pt_regs(tsk);
1671         tos = (tsk->thread.fsr >> 11) & 7;
1672         for (i = 0; i < 8; i++)
1673                 put_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
1674
1675         mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f);
1676         __put_user(mxcsr & 0xffff, &save->mxcsr);
1677         for (i = 0; i < 8; i++) {
1678                 memcpy(&(num128[0]), &(swp->f16) + i*2, sizeof(unsigned long));
1679                 memcpy(&(num128[1]), &(swp->f17) + i*2, sizeof(unsigned long));
1680                 copy_to_user(&save->xmm_space[0] + 4*i, num128, sizeof(struct _xmmreg_ia32));
1681         }
1682         return 0;
1683 }
1684
1685 static int
1686 restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
1687 {
1688         struct switch_stack *swp;
1689         struct pt_regs *ptp;
1690         int i, tos;
1691         unsigned int fsrlo, fsrhi, num32;
1692         int mxcsr;
1693         unsigned long num64;
1694         unsigned long num128[2];
1695
1696         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1697                 return(-EFAULT);
1698
1699         __get_user(num32, (unsigned int __user *)&save->cwd);
1700         tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1701         __get_user(fsrlo, (unsigned int __user *)&save->swd);
1702         __get_user(fsrhi, (unsigned int __user *)&save->twd);
1703         num32 = (fsrhi << 16) | fsrlo;
1704         tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1705         __get_user(num32, (unsigned int __user *)&save->fip);
1706         tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1707         __get_user(num32, (unsigned int __user *)&save->foo);
1708         tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1709
1710         /*
1711          *  Stack frames start with 16-bytes of temp space
1712          */
1713         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1714         ptp = task_pt_regs(tsk);
1715         tos = (tsk->thread.fsr >> 11) & 7;
1716         for (i = 0; i < 8; i++)
1717         get_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
1718
1719         __get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
1720         num64 = mxcsr & 0xff10;
1721         tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000UL)) | (num64<<32);
1722         num64 = mxcsr & 0x3f;
1723         tsk->thread.fsr = (tsk->thread.fsr & (~0x3f00000000UL)) | (num64<<32);
1724
1725         for (i = 0; i < 8; i++) {
1726                 copy_from_user(num128, &save->xmm_space[0] + 4*i, sizeof(struct _xmmreg_ia32));
1727                 memcpy(&(swp->f16) + i*2, &(num128[0]), sizeof(unsigned long));
1728                 memcpy(&(swp->f17) + i*2, &(num128[1]), sizeof(unsigned long));
1729         }
1730         return 0;
1731 }
1732
1733 #if 0                           /* XXX */
1734 asmlinkage long
1735 sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
1736 {
1737         struct task_struct *child;
1738         unsigned int value, tmp;
1739         long i, ret;
1740
1741         lock_kernel();
1742         if (request == PTRACE_TRACEME) {
1743                 ret = ptrace_traceme();
1744                 goto out;
1745         }
1746
1747         child = ptrace_get_task_struct(pid);
1748         if (IS_ERR(child)) {
1749                 ret = PTR_ERR(child);
1750                 goto out;
1751         }
1752
1753         if (request == PTRACE_ATTACH) {
1754                 ret = sys_ptrace(request, pid, addr, data);
1755                 goto out_tsk;
1756         }
1757
1758         ret = ptrace_check_attach(child, request == PTRACE_KILL);
1759         if (ret < 0)
1760                 goto out_tsk;
1761
1762         switch (request) {
1763               case PTRACE_PEEKTEXT:
1764               case PTRACE_PEEKDATA:     /* read word at location addr */
1765                 ret = ia32_peek(child, addr, &value);
1766                 if (ret == 0)
1767                         ret = put_user(value, (unsigned int __user *) compat_ptr(data));
1768                 else
1769                         ret = -EIO;
1770                 goto out_tsk;
1771
1772               case PTRACE_POKETEXT:
1773               case PTRACE_POKEDATA:     /* write the word at location addr */
1774                 ret = ia32_poke(child, addr, data);
1775                 goto out_tsk;
1776
1777               case PTRACE_PEEKUSR:      /* read word at addr in USER area */
1778                 ret = -EIO;
1779                 if ((addr & 3) || addr > 17*sizeof(int))
1780                         break;
1781
1782                 tmp = getreg(child, addr);
1783                 if (!put_user(tmp, (unsigned int __user *) compat_ptr(data)))
1784                         ret = 0;
1785                 break;
1786
1787               case PTRACE_POKEUSR:      /* write word at addr in USER area */
1788                 ret = -EIO;
1789                 if ((addr & 3) || addr > 17*sizeof(int))
1790                         break;
1791
1792                 putreg(child, addr, data);
1793                 ret = 0;
1794                 break;
1795
1796               case IA32_PTRACE_GETREGS:
1797                 if (!access_ok(VERIFY_WRITE, compat_ptr(data), 17*sizeof(int))) {
1798                         ret = -EIO;
1799                         break;
1800                 }
1801                 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
1802                         put_user(getreg(child, i), (unsigned int __user *) compat_ptr(data));
1803                         data += sizeof(int);
1804                 }
1805                 ret = 0;
1806                 break;
1807
1808               case IA32_PTRACE_SETREGS:
1809                 if (!access_ok(VERIFY_READ, compat_ptr(data), 17*sizeof(int))) {
1810                         ret = -EIO;
1811                         break;
1812                 }
1813                 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
1814                         get_user(tmp, (unsigned int __user *) compat_ptr(data));
1815                         putreg(child, i, tmp);
1816                         data += sizeof(int);
1817                 }
1818                 ret = 0;
1819                 break;
1820
1821               case IA32_PTRACE_GETFPREGS:
1822                 ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
1823                                         compat_ptr(data));
1824                 break;
1825
1826               case IA32_PTRACE_GETFPXREGS:
1827                 ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
1828                                          compat_ptr(data));
1829                 break;
1830
1831               case IA32_PTRACE_SETFPREGS:
1832                 ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
1833                                            compat_ptr(data));
1834                 break;
1835
1836               case IA32_PTRACE_SETFPXREGS:
1837                 ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
1838                                             compat_ptr(data));
1839                 break;
1840
1841 #if 0                           /* XXX */
1842               case PTRACE_GETEVENTMSG:   
1843                 ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data));
1844                 break;
1845 #endif
1846
1847               case PTRACE_SYSCALL:      /* continue, stop after next syscall */
1848               case PTRACE_CONT:         /* restart after signal. */
1849               case PTRACE_KILL:
1850               case PTRACE_SINGLESTEP:   /* execute chile for one instruction */
1851               case PTRACE_DETACH:       /* detach a process */
1852                 ret = sys_ptrace(request, pid, addr, data);
1853                 break;
1854
1855               default:
1856                 ret = ptrace_request(child, request, addr, data);
1857                 break;
1858
1859         }
1860   out_tsk:
1861         put_task_struct(child);
1862   out:
1863         unlock_kernel();
1864         return ret;
1865 }
1866 #endif
1867
1868 #ifdef CONFIG_UTRACE
1869 typedef struct utrace_get {
1870         void *kbuf;
1871         void __user *ubuf;
1872 } utrace_get_t;
1873
1874 typedef struct utrace_set {
1875         const void *kbuf;
1876         const void __user *ubuf;
1877 } utrace_set_t;
1878
1879 typedef struct utrace_getset {
1880         struct task_struct *target;
1881         const struct utrace_regset *regset;
1882         union {
1883                 utrace_get_t get;
1884                 utrace_set_t set;
1885         } u;
1886         unsigned int pos;
1887         unsigned int count;
1888         int ret;
1889 } utrace_getset_t;
1890
1891 static void getfpreg(struct task_struct *task, int regno,int *val)
1892 {
1893         switch (regno / sizeof(int)) {
1894                 case 0: *val = task->thread.fcr & 0xffff; break;
1895                 case 1: *val = task->thread.fsr & 0xffff; break;
1896                 case 2: *val = (task->thread.fsr>>16) & 0xffff; break;
1897                 case 3: *val = task->thread.fir; break;
1898                 case 4: *val = (task->thread.fir>>32) & 0xffff; break;
1899                 case 5: *val = task->thread.fdr; break;
1900                 case 6: *val = (task->thread.fdr >> 32) & 0xffff; break;
1901         }
1902 }
1903
1904 static void setfpreg(struct task_struct *task, int regno, int val)
1905 {
1906         switch (regno / sizeof(int)) {
1907                 case 0:
1908                         task->thread.fcr = (task->thread.fcr & (~0x1f3f))
1909                                 | (val & 0x1f3f);
1910                         break;
1911                 case 1:
1912                         task->thread.fsr = (task->thread.fsr & (~0xffff)) | val;
1913                         break;
1914                 case 2:
1915                         task->thread.fsr = (task->thread.fsr & (~0xffff0000))
1916                                 | (val << 16);
1917                         break;
1918                 case 3:
1919                         task->thread.fir = (task->thread.fir & (~0xffffffff)) | val;
1920                         break;
1921                 case 5:
1922                         task->thread.fdr = (task->thread.fdr & (~0xffffffff)) | val;
1923                         break;
1924         }
1925 }
1926
1927 static void access_fpreg_ia32(int regno, void *reg,
1928                 struct pt_regs *pt, struct switch_stack *sw,
1929                 int tos, int write)
1930 {
1931         void *f;
1932
1933         if ((regno += tos) >= 8)
1934                 regno -= 8;
1935         if (regno <= 4)
1936                 f = &pt->f8 + regno;
1937         else if (regno <= 7)
1938                 f = &sw->f12 + (regno - 4);
1939         else {
1940                 printk(" regno must be less than 7 \n");
1941                  return;
1942         }
1943
1944         if (write)
1945                 memcpy(f, reg, sizeof(struct _fpreg_ia32));
1946         else
1947                 memcpy(reg, f, sizeof(struct _fpreg_ia32));
1948 }
1949
1950 static void do_fpregs_get(struct unw_frame_info *info, void *arg)
1951 {
1952         utrace_getset_t *dst = arg;
1953         struct task_struct *task = dst->target;
1954         struct pt_regs *pt;
1955         int start, end, tos;
1956         char buf[80];
1957
1958         if (dst->count == 0 || unw_unwind_to_user(info) < 0)
1959                 return;
1960         if (dst->pos < 7 * sizeof(int)) {
1961                 end = min((dst->pos + dst->count), (unsigned int)(7 * sizeof(int)));
1962                 for (start = dst->pos; start < end; start += sizeof(int))
1963                         getfpreg(task, start,(int *)( buf + start));
1964                 dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
1965                                 &dst->u.get.kbuf, &dst->u.get.ubuf, buf,
1966                                 0, 7 * sizeof(int));
1967                 if (dst->ret || dst->count == 0)
1968                         return;
1969         }
1970         if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
1971                 pt = task_pt_regs(task);
1972                 tos = (task->thread.fsr >> 11) & 7;
1973                 end = min(dst->pos + dst->count,
1974                                 (unsigned int)(sizeof(struct ia32_user_i387_struct)));
1975                 start = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
1976                 end = (end - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
1977                 for (; start < end; start++)
1978                         access_fpreg_ia32(start, (struct _fpreg_ia32 *)buf + start,
1979                                         pt, info->sw, tos, 0);
1980                 dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
1981                                 &dst->u.get.kbuf, &dst->u.get.ubuf,
1982                                 buf, 7 * sizeof(int),
1983                                 sizeof(struct ia32_user_i387_struct));
1984                 if (dst->ret || dst->count == 0)
1985                         return;
1986         }
1987 }
1988
1989 static void do_fpregs_set(struct unw_frame_info *info, void *arg)
1990 {
1991         utrace_getset_t *dst = arg;
1992         struct task_struct *task = dst->target;
1993         struct pt_regs *pt;
1994         char buf[80];
1995         int end, start, tos;
1996
1997         if (dst->count == 0 || unw_unwind_to_user(info) < 0)
1998                 return;
1999
2000         if (dst->pos < 7 * sizeof(int)) {
2001                 start = dst->pos;
2002                 dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
2003                                 &dst->u.set.kbuf, &dst->u.set.ubuf, buf,
2004                                 0, 7 * sizeof(int));
2005                 if (dst->ret)
2006                         return;
2007                 for (; start < dst->pos; start += sizeof(int))
2008                         setfpreg(task, start, *((int*)(buf + start)));
2009                 if (dst->count == 0)
2010                         return;
2011         }
2012         if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
2013                 start = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
2014                 dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
2015                                 &dst->u.set.kbuf, &dst->u.set.ubuf,
2016                                 buf, 7 * sizeof(int),
2017                                 sizeof(struct ia32_user_i387_struct));
2018                 if (dst->ret)
2019                         return;
2020                 pt = task_pt_regs(task);
2021                 tos = (task->thread.fsr >> 11) & 7;
2022                 end = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
2023                 for (; start < end; start++)
2024                         access_fpreg_ia32(start, (struct _fpreg_ia32 *)buf + start,
2025                                         pt, info->sw, tos, 0);
2026                 if (dst->count == 0)
2027                         return;
2028         }
2029 }
2030
2031 #define OFFSET(member) ((int)(offsetof(struct ia32_user_fxsr_struct, member)))
2032 static void getfpxreg(struct task_struct *task, int start, int end, char *buf)
2033 {
2034         int min_val;
2035
2036         min_val = min(end, OFFSET(fop));
2037         while (start < min_val) {
2038                 if (start == OFFSET(cwd))
2039                         *((short *)buf) = task->thread.fcr & 0xffff;
2040                 else if (start == OFFSET(swd))
2041                         *((short *)buf) = task->thread.fsr & 0xffff;
2042                 else if (start == OFFSET(twd))
2043                         *((short *)buf) = (task->thread.fsr>>16) & 0xffff;
2044                 buf += 2;
2045                 start += 2;
2046         }
2047         /* skip fop element */
2048         if (start == OFFSET(fop)) {
2049                 start += 2;
2050                 buf += 2;
2051         }
2052         while (start < end) {
2053                 if (start == OFFSET(fip))
2054                         *((int *)buf) = task->thread.fir;
2055                 else if (start == OFFSET(fcs))
2056                         *((int *)buf) = (task->thread.fir>>32) & 0xffff;
2057                 else if (start == OFFSET(foo))
2058                         *((int *)buf) = task->thread.fdr;
2059                 else if (start == OFFSET(fos))
2060                         *((int *)buf) = (task->thread.fdr>>32) & 0xffff;
2061                 else if (start == OFFSET(mxcsr))
2062                         *((int *)buf) = ((task->thread.fcr>>32) & 0xff80)
2063                                          | ((task->thread.fsr>>32) & 0x3f);
2064                 buf += 4;
2065                 start += 4;
2066         }
2067 }
2068
2069 static void setfpxreg(struct task_struct *task, int start, int end, char *buf)
2070 {
2071         int min_val, num32;
2072         short num;
2073         unsigned long num64;
2074
2075         min_val = min(end, OFFSET(fop));
2076         while (start < min_val) {
2077                 num = *((short *)buf);
2078                 if (start == OFFSET(cwd)) {
2079                         task->thread.fcr = (task->thread.fcr & (~0x1f3f))
2080                                                 | (num & 0x1f3f);
2081                 } else if (start == OFFSET(swd)) {
2082                         task->thread.fsr = (task->thread.fsr & (~0xffff)) | num;
2083                 } else if (start == OFFSET(twd)) {
2084                         task->thread.fsr = (task->thread.fsr & (~0xffff0000)) | num;
2085                 }
2086                 buf += 2;
2087                 start += 2;
2088         }
2089         /* skip fop element */
2090         if (start == OFFSET(fop)) {
2091                 start += 2;
2092                 buf += 2;
2093         }
2094         while (start < end) {
2095                 num32 = *((int *)buf);
2096                 if (start == OFFSET(fip))
2097                         task->thread.fir = (task->thread.fir & (~0xffffffff))
2098                                                  | num32;
2099                 else if (start == OFFSET(foo))
2100                         task->thread.fdr = (task->thread.fdr & (~0xffffffff))
2101                                                  | num32;
2102                 else if (start == OFFSET(mxcsr)) {
2103                         num64 = num32 & 0xff10;
2104                         task->thread.fcr = (task->thread.fcr & (~0xff1000000000UL))
2105                                                  | (num64<<32);
2106                         num64 = num32 & 0x3f;
2107                         task->thread.fsr = (task->thread.fsr & (~0x3f00000000UL))
2108                                                  | (num64<<32);
2109                 }
2110                 buf += 4;
2111                 start += 4;
2112         }
2113 }
2114
2115 static void do_fpxregs_get(struct unw_frame_info *info, void *arg)
2116 {
2117         utrace_getset_t *dst = arg;
2118         struct task_struct *task = dst->target;
2119         struct pt_regs *pt;
2120         char buf[128];
2121         int start, end, tos;
2122
2123         if (dst->count == 0 || unw_unwind_to_user(info) < 0)
2124                 return;
2125         if (dst->pos < OFFSET(st_space[0])) {
2126                 end = min(dst->pos + dst->count, (unsigned int)32);
2127                 getfpxreg(task, dst->pos, end, buf);
2128                 dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
2129                                 &dst->u.get.kbuf, &dst->u.get.ubuf, buf,
2130                                 0, OFFSET(st_space[0]));
2131                 if (dst->ret || dst->count == 0)
2132                         return;
2133         }
2134         if (dst->pos < OFFSET(xmm_space[0])) {
2135                 pt = task_pt_regs(task);
2136                 tos = (task->thread.fsr >> 11) & 7;
2137                 end = min(dst->pos + dst->count,
2138                                 (unsigned int)OFFSET(xmm_space[0]));
2139                 start = (dst->pos - OFFSET(st_space[0])) / 16;
2140                 end = (end - OFFSET(st_space[0])) / 16;
2141                 for (; start < end; start++)
2142                         access_fpreg_ia32(start, buf + 16 * start, pt,
2143                                                 info->sw, tos, 0);
2144                 dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
2145                                 &dst->u.get.kbuf, &dst->u.get.ubuf,
2146                                 buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
2147                 if (dst->ret || dst->count == 0)
2148                         return;
2149         }
2150         if (dst->pos < OFFSET(padding[0]))
2151                 dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
2152                                 &dst->u.get.kbuf, &dst->u.get.ubuf,
2153                                 &info->sw->f16, OFFSET(xmm_space[0]),
2154                                 OFFSET(padding[0]));
2155 }
2156
2157 static void do_fpxregs_set(struct unw_frame_info *info, void *arg)
2158 {
2159         utrace_getset_t *dst = arg;
2160         struct task_struct *task = dst->target;
2161         char buf[128];
2162         int start, end;
2163
2164         if (dst->count == 0 || unw_unwind_to_user(info) < 0)
2165                 return;
2166
2167         if (dst->pos < OFFSET(st_space[0])) {
2168                 start = dst->pos;
2169                 dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
2170                                 &dst->u.set.kbuf, &dst->u.set.ubuf,
2171                                 buf, 0, OFFSET(st_space[0]));
2172                 if (dst->ret)
2173                         return;
2174                 setfpxreg(task, start, dst->pos, buf);
2175                 if (dst->count == 0)
2176                         return;
2177         }
2178         if (dst->pos < OFFSET(xmm_space[0])) {
2179                 struct pt_regs *pt;
2180                 int tos;
2181                 pt = task_pt_regs(task);
2182                 tos = (task->thread.fsr >> 11) & 7;
2183                 start = (dst->pos - OFFSET(st_space[0])) / 16;
2184                 dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
2185                                 &dst->u.set.kbuf, &dst->u.set.ubuf,
2186                                 buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
2187                 if (dst->ret)
2188                         return;
2189                 end = (dst->pos - OFFSET(st_space[0])) / 16;
2190                 for (; start < end; start++)
2191                         access_fpreg_ia32(start, buf + 16 * start, pt, info->sw,
2192                                                  tos, 1);
2193                 if (dst->count == 0)
2194                         return;
2195         }
2196         if (dst->pos < OFFSET(padding[0]))
2197                 dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
2198                                 &dst->u.set.kbuf, &dst->u.set.ubuf,
2199                                 &info->sw->f16, OFFSET(xmm_space[0]),
2200                                  OFFSET(padding[0]));
2201 }
2202 #undef OFFSET
2203
2204 static int do_regset_call(void (*call)(struct unw_frame_info *, void *),
2205                 struct task_struct *target,
2206                 const struct utrace_regset *regset,
2207                 unsigned int pos, unsigned int count,
2208                 const void *kbuf, const void __user *ubuf)
2209 {
2210         utrace_getset_t info = { .target = target, .regset = regset,
2211                 .pos = pos, .count = count,
2212                 .u.set = { .kbuf = kbuf, .ubuf = ubuf },
2213                 .ret = 0 };
2214
2215         if (target == current)
2216                 unw_init_running(call, &info);
2217         else {
2218                 struct unw_frame_info ufi;
2219                 memset(&ufi, 0, sizeof(ufi));
2220                 unw_init_from_blocked_task(&ufi, target);
2221                 (*call)(&ufi, &info);
2222         }
2223
2224         return info.ret;
2225 }
2226
2227 static int ia32_fpregs_get(struct task_struct *target,
2228                 const struct utrace_regset *regset,
2229                 unsigned int pos, unsigned int count,
2230                 void *kbuf, void __user *ubuf)
2231 {
2232         return do_regset_call(do_fpregs_get, target, regset, pos, count, kbuf, ubuf);
2233 }
2234
2235 static int ia32_fpregs_set(struct task_struct *target,
2236                 const struct utrace_regset *regset,
2237                 unsigned int pos, unsigned int count,
2238                 const void *kbuf, const void __user *ubuf)
2239 {
2240         return do_regset_call(do_fpregs_set, target, regset, pos, count, kbuf, ubuf);
2241 }
2242
2243 static int ia32_fpxregs_get(struct task_struct *target,
2244                 const struct utrace_regset *regset,
2245                 unsigned int pos, unsigned int count,
2246                 void *kbuf, void __user *ubuf)
2247 {
2248         return do_regset_call(do_fpxregs_get, target, regset, pos, count, kbuf, ubuf);
2249 }
2250
2251 static int ia32_fpxregs_set(struct task_struct *target,
2252                 const struct utrace_regset *regset,
2253                 unsigned int pos, unsigned int count,
2254                 const void *kbuf, const void __user *ubuf)
2255 {
2256         return do_regset_call(do_fpxregs_set, target, regset, pos, count, kbuf, ubuf);
2257 }
2258
2259 static int ia32_genregs_get(struct task_struct *target,
2260                 const struct utrace_regset *regset,
2261                 unsigned int pos, unsigned int count,
2262                 void *kbuf, void __user *ubuf)
2263 {
2264         if (kbuf) {
2265                 u32 *kp = kbuf;
2266                 while (count > 0) {
2267                         *kp++ = getreg(target, pos);
2268                         pos += 4;
2269                         count -= 4;
2270                 }
2271         } else {
2272                 u32 __user *up = ubuf;
2273                 while (count > 0) {
2274                         if (__put_user(getreg(target, pos), up++))
2275                                 return -EFAULT;
2276                         pos += 4;
2277                         count -= 4;
2278                 }
2279         }
2280         return 0;
2281 }
2282
2283 static int ia32_genregs_set(struct task_struct *target,
2284                 const struct utrace_regset *regset,
2285                 unsigned int pos, unsigned int count,
2286                 const void *kbuf, const void __user *ubuf)
2287 {
2288         int ret = 0;
2289
2290         if (kbuf) {
2291                 const u32 *kp = kbuf;
2292                 while (!ret && count > 0) {
2293                         putreg(target, pos, *kp++);
2294                         pos += 4;
2295                         count -= 4;
2296                 }
2297         } else {
2298                 const u32 __user *up = ubuf;
2299                 u32 val;
2300                 while (!ret && count > 0) {
2301                         ret = __get_user(val, up++);
2302                         if (!ret)
2303                                 putreg(target, pos, val);
2304                         pos += 4;
2305                         count -= 4;
2306                 }
2307         }
2308         return ret;
2309 }
2310
2311 /*
2312  * This should match arch/i386/kernel/ptrace.c:native_regsets.
2313  * XXX ioperm? vm86?
2314  */
2315 static const struct utrace_regset ia32_regsets[] = {
2316         {
2317                 .n = sizeof(struct user_regs_struct32)/4,
2318                 .size = 4, .align = 4,
2319                 .get = ia32_genregs_get, .set = ia32_genregs_set
2320         },
2321         {
2322                 .n = sizeof(struct ia32_user_i387_struct) / 4,
2323                 .size = 4, .align = 4,
2324                 .get = ia32_fpregs_get, .set = ia32_fpregs_set
2325         },
2326         {
2327                 .n = sizeof(struct ia32_user_fxsr_struct) / 4,
2328                 .size = 4, .align = 4,
2329                 .get = ia32_fpxregs_get, .set = ia32_fpxregs_set
2330         },
2331 };
2332
2333 const struct utrace_regset_view utrace_ia32_view = {
2334         .name = "i386", .e_machine = EM_386,
2335         .regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
2336 };
2337 EXPORT_SYMBOL_GPL(utrace_ia32_view);
2338 #endif
2339
2340 #ifdef CONFIG_PTRACE
2341 /*
2342  * This matches the arch/i386/kernel/ptrace.c definitions.
2343  */
2344
2345 static const struct ptrace_layout_segment ia32_uarea[] = {
2346         {0, sizeof(struct user_regs_struct32), 0, 0},
2347         {0, 0, -1, 0}
2348 };
2349
2350 fastcall int arch_compat_ptrace(compat_long_t *request,
2351                 struct task_struct *child,
2352                 struct utrace_attached_engine *engine,
2353                 compat_ulong_t addr, compat_ulong_t data,
2354                 compat_long_t *retval)
2355 {
2356         switch (*request) {
2357                 case PTRACE_PEEKUSR:
2358                         return ptrace_compat_peekusr(child, engine, ia32_uarea,
2359                                         addr, data);
2360                 case PTRACE_POKEUSR:
2361                         return ptrace_compat_pokeusr(child, engine, ia32_uarea,
2362                                         addr, data);
2363                 case IA32_PTRACE_GETREGS:
2364                         return ptrace_whole_regset(child, engine, data, 0, 0);
2365                 case IA32_PTRACE_SETREGS:
2366                         return ptrace_whole_regset(child, engine, data, 0, 1);
2367                 case IA32_PTRACE_GETFPREGS:
2368                         return ptrace_whole_regset(child, engine, data, 1, 0);
2369                 case IA32_PTRACE_SETFPREGS:
2370                         return ptrace_whole_regset(child, engine, data, 1, 1);
2371                 case IA32_PTRACE_GETFPXREGS:
2372                         return ptrace_whole_regset(child, engine, data, 2, 0);
2373                 case IA32_PTRACE_SETFPXREGS:
2374                         return ptrace_whole_regset(child, engine, data, 2, 1);
2375         }
2376         return -ENOSYS;
2377 }
2378 #endif
2379
2380 typedef struct {
2381         unsigned int    ss_sp;
2382         unsigned int    ss_flags;
2383         unsigned int    ss_size;
2384 } ia32_stack_t;
2385
2386 asmlinkage long
2387 sys32_sigaltstack (ia32_stack_t __user *uss32, ia32_stack_t __user *uoss32,
2388                    long arg2, long arg3, long arg4, long arg5, long arg6,
2389                    long arg7, struct pt_regs pt)
2390 {
2391         stack_t uss, uoss;
2392         ia32_stack_t buf32;
2393         int ret;
2394         mm_segment_t old_fs = get_fs();
2395
2396         if (uss32) {
2397                 if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t)))
2398                         return -EFAULT;
2399                 uss.ss_sp = (void __user *) (long) buf32.ss_sp;
2400                 uss.ss_flags = buf32.ss_flags;
2401                 /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the
2402                    check and set it to the user requested value later */
2403                 if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) {
2404                         ret = -ENOMEM;
2405                         goto out;
2406                 }
2407                 uss.ss_size = MINSIGSTKSZ;
2408         }
2409         set_fs(KERNEL_DS);
2410         ret = do_sigaltstack(uss32 ? (stack_t __user *) &uss : NULL,
2411                              (stack_t __user *) &uoss, pt.r12);
2412         current->sas_ss_size = buf32.ss_size;
2413         set_fs(old_fs);
2414 out:
2415         if (ret < 0)
2416                 return(ret);
2417         if (uoss32) {
2418                 buf32.ss_sp = (long __user) uoss.ss_sp;
2419                 buf32.ss_flags = uoss.ss_flags;
2420                 buf32.ss_size = uoss.ss_size;
2421                 if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t)))
2422                         return -EFAULT;
2423         }
2424         return ret;
2425 }
2426
2427 asmlinkage int
2428 sys32_pause (void)
2429 {
2430         current->state = TASK_INTERRUPTIBLE;
2431         schedule();
2432         return -ERESTARTNOHAND;
2433 }
2434
2435 asmlinkage int
2436 sys32_msync (unsigned int start, unsigned int len, int flags)
2437 {
2438         unsigned int addr;
2439
2440         if (OFFSET4K(start))
2441                 return -EINVAL;
2442         addr = PAGE_START(start);
2443         return sys_msync(addr, len + (start - addr), flags);
2444 }
2445
2446 struct sysctl32 {
2447         unsigned int    name;
2448         int             nlen;
2449         unsigned int    oldval;
2450         unsigned int    oldlenp;
2451         unsigned int    newval;
2452         unsigned int    newlen;
2453         unsigned int    __unused[4];
2454 };
2455
2456 #ifdef CONFIG_SYSCTL_SYSCALL
2457 asmlinkage long
2458 sys32_sysctl (struct sysctl32 __user *args)
2459 {
2460         struct sysctl32 a32;
2461         mm_segment_t old_fs = get_fs ();
2462         void __user *oldvalp, *newvalp;
2463         size_t oldlen;
2464         int __user *namep;
2465         long ret;
2466
2467         if (copy_from_user(&a32, args, sizeof(a32)))
2468                 return -EFAULT;
2469
2470         /*
2471          * We need to pre-validate these because we have to disable address checking
2472          * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
2473          * user specifying bad addresses here.  Well, since we're dealing with 32 bit
2474          * addresses, we KNOW that access_ok() will always succeed, so this is an
2475          * expensive NOP, but so what...
2476          */
2477         namep = (int __user *) compat_ptr(a32.name);
2478         oldvalp = compat_ptr(a32.oldval);
2479         newvalp = compat_ptr(a32.newval);
2480
2481         if ((oldvalp && get_user(oldlen, (int __user *) compat_ptr(a32.oldlenp)))
2482             || !access_ok(VERIFY_WRITE, namep, 0)
2483             || !access_ok(VERIFY_WRITE, oldvalp, 0)
2484             || !access_ok(VERIFY_WRITE, newvalp, 0))
2485                 return -EFAULT;
2486
2487         set_fs(KERNEL_DS);
2488         lock_kernel();
2489         ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *) &oldlen,
2490                         newvalp, (size_t) a32.newlen);
2491         unlock_kernel();
2492         set_fs(old_fs);
2493
2494         if (oldvalp && put_user (oldlen, (int __user *) compat_ptr(a32.oldlenp)))
2495                 return -EFAULT;
2496
2497         return ret;
2498 }
2499 #endif
2500
2501 asmlinkage long
2502 sys32_newuname (struct new_utsname __user *name)
2503 {
2504         int ret = sys_newuname(name);
2505
2506         if (!ret)
2507                 if (copy_to_user(name->machine, "i686\0\0\0", 8))
2508                         ret = -EFAULT;
2509         return ret;
2510 }
2511
2512 asmlinkage long
2513 sys32_getresuid16 (u16 __user *ruid, u16 __user *euid, u16 __user *suid)
2514 {
2515         uid_t a, b, c;
2516         int ret;
2517         mm_segment_t old_fs = get_fs();
2518
2519         set_fs(KERNEL_DS);
2520         ret = sys_getresuid((uid_t __user *) &a, (uid_t __user *) &b, (uid_t __user *) &c);
2521         set_fs(old_fs);
2522
2523         if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
2524                 return -EFAULT;
2525         return ret;
2526 }
2527
2528 asmlinkage long
2529 sys32_getresgid16 (u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
2530 {
2531         gid_t a, b, c;
2532         int ret;
2533         mm_segment_t old_fs = get_fs();
2534
2535         set_fs(KERNEL_DS);
2536         ret = sys_getresgid((gid_t __user *) &a, (gid_t __user *) &b, (gid_t __user *) &c);
2537         set_fs(old_fs);
2538
2539         if (ret)
2540                 return ret;
2541
2542         return put_user(a, rgid) | put_user(b, egid) | put_user(c, sgid);
2543 }
2544
2545 asmlinkage long
2546 sys32_lseek (unsigned int fd, int offset, unsigned int whence)
2547 {
2548         /* Sign-extension of "offset" is important here... */
2549         return sys_lseek(fd, offset, whence);
2550 }
2551
2552 static int
2553 groups16_to_user(short __user *grouplist, struct group_info *group_info)
2554 {
2555         int i;
2556         short group;
2557
2558         for (i = 0; i < group_info->ngroups; i++) {
2559                 group = (short)GROUP_AT(group_info, i);
2560                 if (put_user(group, grouplist+i))
2561                         return -EFAULT;
2562         }
2563
2564         return 0;
2565 }
2566
2567 static int
2568 groups16_from_user(struct group_info *group_info, short __user *grouplist)
2569 {
2570         int i;
2571         short group;
2572
2573         for (i = 0; i < group_info->ngroups; i++) {
2574                 if (get_user(group, grouplist+i))
2575                         return  -EFAULT;
2576                 GROUP_AT(group_info, i) = (gid_t)group;
2577         }
2578
2579         return 0;
2580 }
2581
2582 asmlinkage long
2583 sys32_getgroups16 (int gidsetsize, short __user *grouplist)
2584 {
2585         int i;
2586
2587         if (gidsetsize < 0)
2588                 return -EINVAL;
2589
2590         get_group_info(current->group_info);
2591         i = current->group_info->ngroups;
2592         if (gidsetsize) {
2593                 if (i > gidsetsize) {
2594                         i = -EINVAL;
2595                         goto out;
2596                 }
2597                 if (groups16_to_user(grouplist, current->group_info)) {
2598                         i = -EFAULT;
2599                         goto out;
2600                 }
2601         }
2602 out:
2603         put_group_info(current->group_info);
2604         return i;
2605 }
2606
2607 asmlinkage long
2608 sys32_setgroups16 (int gidsetsize, short __user *grouplist)
2609 {
2610         struct group_info *group_info;
2611         int retval;
2612
2613         if (!capable(CAP_SETGID))
2614                 return -EPERM;
2615         if ((unsigned)gidsetsize > NGROUPS_MAX)
2616                 return -EINVAL;
2617
2618         group_info = groups_alloc(gidsetsize);
2619         if (!group_info)
2620                 return -ENOMEM;
2621         retval = groups16_from_user(group_info, grouplist);
2622         if (retval) {
2623                 put_group_info(group_info);
2624                 return retval;
2625         }
2626
2627         retval = set_current_groups(group_info);
2628         put_group_info(group_info);
2629
2630         return retval;
2631 }
2632
2633 asmlinkage long
2634 sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi)
2635 {
2636         return sys_truncate(compat_ptr(path), ((unsigned long) len_hi << 32) | len_lo);
2637 }
2638
2639 asmlinkage long
2640 sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi)
2641 {
2642         return sys_ftruncate(fd, ((unsigned long) len_hi << 32) | len_lo);
2643 }
2644
2645 static int
2646 putstat64 (struct stat64 __user *ubuf, struct kstat *kbuf)
2647 {
2648         int err;
2649         u64 hdev;
2650
2651         if (clear_user(ubuf, sizeof(*ubuf)))
2652                 return -EFAULT;
2653
2654         hdev = huge_encode_dev(kbuf->dev);
2655         err  = __put_user(hdev, (u32 __user*)&ubuf->st_dev);
2656         err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_dev) + 1);
2657         err |= __put_user(kbuf->ino, &ubuf->__st_ino);
2658         err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
2659         err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
2660         err |= __put_user(kbuf->mode, &ubuf->st_mode);
2661         err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
2662         err |= __put_user(kbuf->uid, &ubuf->st_uid);
2663         err |= __put_user(kbuf->gid, &ubuf->st_gid);
2664         hdev = huge_encode_dev(kbuf->rdev);
2665         err  = __put_user(hdev, (u32 __user*)&ubuf->st_rdev);
2666         err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_rdev) + 1);
2667         err |= __put_user(kbuf->size, &ubuf->st_size_lo);
2668         err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
2669         err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
2670         err |= __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec);
2671         err |= __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime);
2672         err |= __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec);
2673         err |= __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime);
2674         err |= __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec);
2675         err |= __put_user(kbuf->blksize, &ubuf->st_blksize);
2676         err |= __put_user(kbuf->blocks, &ubuf->st_blocks);
2677         return err;
2678 }
2679
2680 asmlinkage long
2681 sys32_stat64 (char __user *filename, struct stat64 __user *statbuf)
2682 {
2683         struct kstat s;
2684         long ret = vfs_stat(filename, &s);
2685         if (!ret)
2686                 ret = putstat64(statbuf, &s);
2687         return ret;
2688 }
2689
2690 asmlinkage long
2691 sys32_lstat64 (char __user *filename, struct stat64 __user *statbuf)
2692 {
2693         struct kstat s;
2694         long ret = vfs_lstat(filename, &s);
2695         if (!ret)
2696                 ret = putstat64(statbuf, &s);
2697         return ret;
2698 }
2699
2700 asmlinkage long
2701 sys32_fstat64 (unsigned int fd, struct stat64 __user *statbuf)
2702 {
2703         struct kstat s;
2704         long ret = vfs_fstat(fd, &s);
2705         if (!ret)
2706                 ret = putstat64(statbuf, &s);
2707         return ret;
2708 }
2709
2710 struct sysinfo32 {
2711         s32 uptime;
2712         u32 loads[3];
2713         u32 totalram;
2714         u32 freeram;
2715         u32 sharedram;
2716         u32 bufferram;
2717         u32 totalswap;
2718         u32 freeswap;
2719         u16 procs;
2720         u16 pad;
2721         u32 totalhigh;
2722         u32 freehigh;
2723         u32 mem_unit;
2724         char _f[8];
2725 };
2726
2727 asmlinkage long
2728 sys32_sysinfo (struct sysinfo32 __user *info)
2729 {
2730         struct sysinfo s;
2731         long ret, err;
2732         int bitcount = 0;
2733         mm_segment_t old_fs = get_fs();
2734
2735         set_fs(KERNEL_DS);
2736         ret = sys_sysinfo((struct sysinfo __user *) &s);
2737         set_fs(old_fs);
2738         /* Check to see if any memory value is too large for 32-bit and
2739          * scale down if needed.
2740          */
2741         if ((s.totalram >> 32) || (s.totalswap >> 32)) {
2742                 while (s.mem_unit < PAGE_SIZE) {
2743                         s.mem_unit <<= 1;
2744                         bitcount++;
2745                 }
2746                 s.totalram >>= bitcount;
2747                 s.freeram >>= bitcount;
2748                 s.sharedram >>= bitcount;
2749                 s.bufferram >>= bitcount;
2750                 s.totalswap >>= bitcount;
2751                 s.freeswap >>= bitcount;
2752                 s.totalhigh >>= bitcount;
2753                 s.freehigh >>= bitcount;
2754         }
2755
2756         if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
2757                 return -EFAULT;
2758
2759         err  = __put_user(s.uptime, &info->uptime);
2760         err |= __put_user(s.loads[0], &info->loads[0]);
2761         err |= __put_user(s.loads[1], &info->loads[1]);
2762         err |= __put_user(s.loads[2], &info->loads[2]);
2763         err |= __put_user(s.totalram, &info->totalram);
2764         err |= __put_user(s.freeram, &info->freeram);
2765         err |= __put_user(s.sharedram, &info->sharedram);
2766         err |= __put_user(s.bufferram, &info->bufferram);
2767         err |= __put_user(s.totalswap, &info->totalswap);
2768         err |= __put_user(s.freeswap, &info->freeswap);
2769         err |= __put_user(s.procs, &info->procs);
2770         err |= __put_user (s.totalhigh, &info->totalhigh);
2771         err |= __put_user (s.freehigh, &info->freehigh);
2772         err |= __put_user (s.mem_unit, &info->mem_unit);
2773         if (err)
2774                 return -EFAULT;
2775         return ret;
2776 }
2777
2778 asmlinkage long
2779 sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec __user *interval)
2780 {
2781         mm_segment_t old_fs = get_fs();
2782         struct timespec t;
2783         long ret;
2784
2785         set_fs(KERNEL_DS);
2786         ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
2787         set_fs(old_fs);
2788         if (put_compat_timespec(&t, interval))
2789                 return -EFAULT;
2790         return ret;
2791 }
2792
2793 asmlinkage long
2794 sys32_pread (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
2795 {
2796         return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
2797 }
2798
2799 asmlinkage long
2800 sys32_pwrite (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
2801 {
2802         return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
2803 }
2804
2805 asmlinkage long
2806 sys32_sendfile (int out_fd, int in_fd, int __user *offset, unsigned int count)
2807 {
2808         mm_segment_t old_fs = get_fs();
2809         long ret;
2810         off_t of;
2811
2812         if (offset && get_user(of, offset))
2813                 return -EFAULT;
2814
2815         set_fs(KERNEL_DS);
2816         ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *) &of : NULL, count);
2817         set_fs(old_fs);
2818
2819         if (offset && put_user(of, offset))
2820                 return -EFAULT;
2821
2822         return ret;
2823 }
2824
2825 asmlinkage long
2826 sys32_personality (unsigned int personality)
2827 {
2828         long ret;
2829
2830         if (current->personality == PER_LINUX32 && personality == PER_LINUX)
2831                 personality = PER_LINUX32;
2832         ret = sys_personality(personality);
2833         if (ret == PER_LINUX32)
2834                 ret = PER_LINUX;
2835         return ret;
2836 }
2837
2838 asmlinkage unsigned long
2839 sys32_brk (unsigned int brk)
2840 {
2841         unsigned long ret, obrk;
2842         struct mm_struct *mm = current->mm;
2843
2844         obrk = mm->brk;
2845         ret = sys_brk(brk);
2846         if (ret < obrk)
2847                 clear_user(compat_ptr(ret), PAGE_ALIGN(ret) - ret);
2848         return ret;
2849 }
2850
2851 /* Structure for ia32 emulation on ia64 */
2852 struct epoll_event32
2853 {
2854         u32 events;
2855         u32 data[2];
2856 };
2857
2858 asmlinkage long
2859 sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 __user *event)
2860 {
2861         mm_segment_t old_fs = get_fs();
2862         struct epoll_event event64;
2863         int error;
2864         u32 data_halfword;
2865
2866         if (!access_ok(VERIFY_READ, event, sizeof(struct epoll_event32)))
2867                 return -EFAULT;
2868
2869         __get_user(event64.events, &event->events);
2870         __get_user(data_halfword, &event->data[0]);
2871         event64.data = data_halfword;
2872         __get_user(data_halfword, &event->data[1]);
2873         event64.data |= (u64)data_halfword << 32;
2874
2875         set_fs(KERNEL_DS);
2876         error = sys_epoll_ctl(epfd, op, fd, (struct epoll_event __user *) &event64);
2877         set_fs(old_fs);
2878
2879         return error;
2880 }
2881
2882 asmlinkage long
2883 sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents,
2884                  int timeout)
2885 {
2886         struct epoll_event *events64 = NULL;
2887         mm_segment_t old_fs = get_fs();
2888         int numevents, size;
2889         int evt_idx;
2890         int do_free_pages = 0;
2891
2892         if (maxevents <= 0) {
2893                 return -EINVAL;
2894         }
2895
2896         /* Verify that the area passed by the user is writeable */
2897         if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event32)))
2898                 return -EFAULT;
2899
2900         /*
2901          * Allocate space for the intermediate copy.  If the space needed
2902          * is large enough to cause kmalloc to fail, then try again with
2903          * __get_free_pages.
2904          */
2905         size = maxevents * sizeof(struct epoll_event);
2906         events64 = kmalloc(size, GFP_KERNEL);
2907         if (events64 == NULL) {
2908                 events64 = (struct epoll_event *)
2909                                 __get_free_pages(GFP_KERNEL, get_order(size));
2910                 if (events64 == NULL)
2911                         return -ENOMEM;
2912                 do_free_pages = 1;
2913         }
2914
2915         /* Do the system call */
2916         set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/
2917         numevents = sys_epoll_wait(epfd, (struct epoll_event __user *) events64,
2918                                    maxevents, timeout);
2919         set_fs(old_fs);
2920
2921         /* Don't modify userspace memory if we're returning an error */
2922         if (numevents > 0) {
2923                 /* Translate the 64-bit structures back into the 32-bit
2924                    structures */
2925                 for (evt_idx = 0; evt_idx < numevents; evt_idx++) {
2926                         __put_user(events64[evt_idx].events,
2927                                    &events[evt_idx].events);
2928                         __put_user((u32)events64[evt_idx].data,
2929                                    &events[evt_idx].data[0]);
2930                         __put_user((u32)(events64[evt_idx].data >> 32),
2931                                    &events[evt_idx].data[1]);
2932                 }
2933         }
2934
2935         if (do_free_pages)
2936                 free_pages((unsigned long) events64, get_order(size));
2937         else
2938                 kfree(events64);
2939         return numevents;
2940 }
2941
2942 /*
2943  * Get a yet unused TLS descriptor index.
2944  */
2945 static int
2946 get_free_idx (void)
2947 {
2948         struct thread_struct *t = &current->thread;
2949         int idx;
2950
2951         for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
2952                 if (desc_empty(t->tls_array + idx))
2953                         return idx + GDT_ENTRY_TLS_MIN;
2954         return -ESRCH;
2955 }
2956
2957 /*
2958  * Set a given TLS descriptor:
2959  */
2960 asmlinkage int
2961 sys32_set_thread_area (struct ia32_user_desc __user *u_info)
2962 {
2963         struct thread_struct *t = &current->thread;
2964         struct ia32_user_desc info;
2965         struct desc_struct *desc;
2966         int cpu, idx;
2967
2968         if (copy_from_user(&info, u_info, sizeof(info)))
2969                 return -EFAULT;
2970         idx = info.entry_number;
2971
2972         /*
2973          * index -1 means the kernel should try to find and allocate an empty descriptor:
2974          */
2975         if (idx == -1) {
2976                 idx = get_free_idx();
2977                 if (idx < 0)
2978                         return idx;
2979                 if (put_user(idx, &u_info->entry_number))
2980                         return -EFAULT;
2981         }
2982
2983         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2984                 return -EINVAL;
2985
2986         desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
2987
2988         cpu = smp_processor_id();
2989
2990         if (LDT_empty(&info)) {
2991                 desc->a = 0;
2992                 desc->b = 0;
2993         } else {
2994                 desc->a = LDT_entry_a(&info);
2995                 desc->b = LDT_entry_b(&info);
2996         }
2997         load_TLS(t, cpu);
2998         return 0;
2999 }
3000
3001 /*
3002  * Get the current Thread-Local Storage area:
3003  */
3004
3005 #define GET_BASE(desc) (                        \
3006         (((desc)->a >> 16) & 0x0000ffff) |      \
3007         (((desc)->b << 16) & 0x00ff0000) |      \
3008         ( (desc)->b        & 0xff000000)   )
3009
3010 #define GET_LIMIT(desc) (                       \
3011         ((desc)->a & 0x0ffff) |                 \
3012          ((desc)->b & 0xf0000) )
3013
3014 #define GET_32BIT(desc)         (((desc)->b >> 22) & 1)
3015 #define GET_CONTENTS(desc)      (((desc)->b >> 10) & 3)
3016 #define GET_WRITABLE(desc)      (((desc)->b >>  9) & 1)
3017 #define GET_LIMIT_PAGES(desc)   (((desc)->b >> 23) & 1)
3018 #define GET_PRESENT(desc)       (((desc)->b >> 15) & 1)
3019 #define GET_USEABLE(desc)       (((desc)->b >> 20) & 1)
3020
3021 asmlinkage int
3022 sys32_get_thread_area (struct ia32_user_desc __user *u_info)
3023 {
3024         struct ia32_user_desc info;
3025         struct desc_struct *desc;
3026         int idx;
3027
3028         if (get_user(idx, &u_info->entry_number))
3029                 return -EFAULT;
3030         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
3031                 return -EINVAL;
3032
3033         desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
3034
3035         info.entry_number = idx;
3036         info.base_addr = GET_BASE(desc);
3037         info.limit = GET_LIMIT(desc);
3038         info.seg_32bit = GET_32BIT(desc);
3039         info.contents = GET_CONTENTS(desc);
3040         info.read_exec_only = !GET_WRITABLE(desc);
3041         info.limit_in_pages = GET_LIMIT_PAGES(desc);
3042         info.seg_not_present = !GET_PRESENT(desc);
3043         info.useable = GET_USEABLE(desc);
3044
3045         if (copy_to_user(u_info, &info, sizeof(info)))
3046                 return -EFAULT;
3047         return 0;
3048 }
3049
3050 long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, 
3051                         __u32 len_low, __u32 len_high, int advice)
3052
3053         return sys_fadvise64_64(fd,
3054                                (((u64)offset_high)<<32) | offset_low,
3055                                (((u64)len_high)<<32) | len_low,
3056                                advice); 
3057
3058
3059 #ifdef  NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
3060
3061 asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid)
3062 {
3063         uid_t sruid, seuid;
3064
3065         sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
3066         seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
3067         return sys_setreuid(sruid, seuid);
3068 }
3069
3070 asmlinkage long
3071 sys32_setresuid(compat_uid_t ruid, compat_uid_t euid,
3072                 compat_uid_t suid)
3073 {
3074         uid_t sruid, seuid, ssuid;
3075
3076         sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
3077         seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
3078         ssuid = (suid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)suid);
3079         return sys_setresuid(sruid, seuid, ssuid);
3080 }
3081
3082 asmlinkage long
3083 sys32_setregid(compat_gid_t rgid, compat_gid_t egid)
3084 {
3085         gid_t srgid, segid;
3086
3087         srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
3088         segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
3089         return sys_setregid(srgid, segid);
3090 }
3091
3092 asmlinkage long
3093 sys32_setresgid(compat_gid_t rgid, compat_gid_t egid,
3094                 compat_gid_t sgid)
3095 {
3096         gid_t srgid, segid, ssgid;
3097
3098         srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
3099         segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
3100         ssgid = (sgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)sgid);
3101         return sys_setresgid(srgid, segid, ssgid);
3102 }
3103 #endif /* NOTYET */