]> err.no Git - linux-2.6/blob - arch/ia64/ia32/sys_ia32.c
[IA64] rename partial_page
[linux-2.6] / 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/stat.h>
48 #include <linux/ipc.h>
49 #include <linux/capability.h>
50 #include <linux/compat.h>
51 #include <linux/vfs.h>
52 #include <linux/mman.h>
53 #include <linux/mutex.h>
54
55 #include <asm/intrinsics.h>
56 #include <asm/types.h>
57 #include <asm/uaccess.h>
58 #include <asm/unistd.h>
59
60 #include "ia32priv.h"
61
62 #include <net/scm.h>
63 #include <net/sock.h>
64
65 #define DEBUG   0
66
67 #if DEBUG
68 # define DBG(fmt...)    printk(KERN_DEBUG fmt)
69 #else
70 # define DBG(fmt...)
71 #endif
72
73 #define ROUND_UP(x,a)   ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
74
75 #define OFFSET4K(a)             ((a) & 0xfff)
76 #define PAGE_START(addr)        ((addr) & PAGE_MASK)
77 #define MINSIGSTKSZ_IA32        2048
78
79 #define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid))
80 #define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid))
81
82 /*
83  * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
84  * while doing so.
85  */
86 /* XXX make per-mm: */
87 static DEFINE_MUTEX(ia32_mmap_mutex);
88
89 asmlinkage long
90 sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
91               struct pt_regs *regs)
92 {
93         long error;
94         char *filename;
95         unsigned long old_map_base, old_task_size, tssd;
96
97         filename = getname(name);
98         error = PTR_ERR(filename);
99         if (IS_ERR(filename))
100                 return error;
101
102         old_map_base  = current->thread.map_base;
103         old_task_size = current->thread.task_size;
104         tssd = ia64_get_kr(IA64_KR_TSSD);
105
106         /* we may be exec'ing a 64-bit process: reset map base, task-size, and io-base: */
107         current->thread.map_base  = DEFAULT_MAP_BASE;
108         current->thread.task_size = DEFAULT_TASK_SIZE;
109         ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
110         ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
111
112         error = compat_do_execve(filename, argv, envp, regs);
113         putname(filename);
114
115         if (error < 0) {
116                 /* oops, execve failed, switch back to old values... */
117                 ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
118                 ia64_set_kr(IA64_KR_TSSD, tssd);
119                 current->thread.map_base  = old_map_base;
120                 current->thread.task_size = old_task_size;
121         }
122
123         return error;
124 }
125
126 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
127 {
128         compat_ino_t ino;
129         int err;
130
131         if ((u64) stat->size > MAX_NON_LFS ||
132             !old_valid_dev(stat->dev) ||
133             !old_valid_dev(stat->rdev))
134                 return -EOVERFLOW;
135
136         ino = stat->ino;
137         if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
138                 return -EOVERFLOW;
139
140         if (clear_user(ubuf, sizeof(*ubuf)))
141                 return -EFAULT;
142
143         err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
144         err |= __put_user(ino, &ubuf->st_ino);
145         err |= __put_user(stat->mode, &ubuf->st_mode);
146         err |= __put_user(stat->nlink, &ubuf->st_nlink);
147         err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
148         err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
149         err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
150         err |= __put_user(stat->size, &ubuf->st_size);
151         err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
152         err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
153         err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
154         err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
155         err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
156         err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
157         err |= __put_user(stat->blksize, &ubuf->st_blksize);
158         err |= __put_user(stat->blocks, &ubuf->st_blocks);
159         return err;
160 }
161
162 #if PAGE_SHIFT > IA32_PAGE_SHIFT
163
164
165 static int
166 get_page_prot (struct vm_area_struct *vma, unsigned long addr)
167 {
168         int prot = 0;
169
170         if (!vma || vma->vm_start > addr)
171                 return 0;
172
173         if (vma->vm_flags & VM_READ)
174                 prot |= PROT_READ;
175         if (vma->vm_flags & VM_WRITE)
176                 prot |= PROT_WRITE;
177         if (vma->vm_flags & VM_EXEC)
178                 prot |= PROT_EXEC;
179         return prot;
180 }
181
182 /*
183  * Map a subpage by creating an anonymous page that contains the union of the old page and
184  * the subpage.
185  */
186 static unsigned long
187 mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
188               loff_t off)
189 {
190         void *page = NULL;
191         struct inode *inode;
192         unsigned long ret = 0;
193         struct vm_area_struct *vma = find_vma(current->mm, start);
194         int old_prot = get_page_prot(vma, start);
195
196         DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
197             file, start, end, prot, flags, off);
198
199
200         /* Optimize the case where the old mmap and the new mmap are both anonymous */
201         if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
202                 if (clear_user((void __user *) start, end - start)) {
203                         ret = -EFAULT;
204                         goto out;
205                 }
206                 goto skip_mmap;
207         }
208
209         page = (void *) get_zeroed_page(GFP_KERNEL);
210         if (!page)
211                 return -ENOMEM;
212
213         if (old_prot)
214                 copy_from_user(page, (void __user *) PAGE_START(start), PAGE_SIZE);
215
216         down_write(&current->mm->mmap_sem);
217         {
218                 ret = do_mmap(NULL, PAGE_START(start), PAGE_SIZE, prot | PROT_WRITE,
219                               flags | MAP_FIXED | MAP_ANONYMOUS, 0);
220         }
221         up_write(&current->mm->mmap_sem);
222
223         if (IS_ERR((void *) ret))
224                 goto out;
225
226         if (old_prot) {
227                 /* copy back the old page contents.  */
228                 if (offset_in_page(start))
229                         copy_to_user((void __user *) PAGE_START(start), page,
230                                      offset_in_page(start));
231                 if (offset_in_page(end))
232                         copy_to_user((void __user *) end, page + offset_in_page(end),
233                                      PAGE_SIZE - offset_in_page(end));
234         }
235
236         if (!(flags & MAP_ANONYMOUS)) {
237                 /* read the file contents */
238                 inode = file->f_path.dentry->d_inode;
239                 if (!inode->i_fop || !file->f_op->read
240                     || ((*file->f_op->read)(file, (char __user *) start, end - start, &off) < 0))
241                 {
242                         ret = -EINVAL;
243                         goto out;
244                 }
245         }
246
247  skip_mmap:
248         if (!(prot & PROT_WRITE))
249                 ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
250   out:
251         if (page)
252                 free_page((unsigned long) page);
253         return ret;
254 }
255
256 /* SLAB cache for ia64_partial_page structures */
257 struct kmem_cache *ia64_partial_page_cachep;
258
259 /*
260  * init ia64_partial_page_list.
261  * return 0 means kmalloc fail.
262  */
263 struct ia64_partial_page_list*
264 ia32_init_pp_list(void)
265 {
266         struct ia64_partial_page_list *p;
267
268         if ((p = kmalloc(sizeof(*p), GFP_KERNEL)) == NULL)
269                 return p;
270         p->pp_head = NULL;
271         p->ppl_rb = RB_ROOT;
272         p->pp_hint = NULL;
273         atomic_set(&p->pp_count, 1);
274         return p;
275 }
276
277 /*
278  * Search for the partial page with @start in partial page list @ppl.
279  * If finds the partial page, return the found partial page.
280  * Else, return 0 and provide @pprev, @rb_link, @rb_parent to
281  * be used by later __ia32_insert_pp().
282  */
283 static struct ia64_partial_page *
284 __ia32_find_pp(struct ia64_partial_page_list *ppl, unsigned int start,
285         struct ia64_partial_page **pprev, struct rb_node ***rb_link,
286         struct rb_node **rb_parent)
287 {
288         struct ia64_partial_page *pp;
289         struct rb_node **__rb_link, *__rb_parent, *rb_prev;
290
291         pp = ppl->pp_hint;
292         if (pp && pp->base == start)
293                 return pp;
294
295         __rb_link = &ppl->ppl_rb.rb_node;
296         rb_prev = __rb_parent = NULL;
297
298         while (*__rb_link) {
299                 __rb_parent = *__rb_link;
300                 pp = rb_entry(__rb_parent, struct ia64_partial_page, pp_rb);
301
302                 if (pp->base == start) {
303                         ppl->pp_hint = pp;
304                         return pp;
305                 } else if (pp->base < start) {
306                         rb_prev = __rb_parent;
307                         __rb_link = &__rb_parent->rb_right;
308                 } else {
309                         __rb_link = &__rb_parent->rb_left;
310                 }
311         }
312
313         *rb_link = __rb_link;
314         *rb_parent = __rb_parent;
315         *pprev = NULL;
316         if (rb_prev)
317                 *pprev = rb_entry(rb_prev, struct ia64_partial_page, pp_rb);
318         return NULL;
319 }
320
321 /*
322  * insert @pp into @ppl.
323  */
324 static void
325 __ia32_insert_pp(struct ia64_partial_page_list *ppl,
326         struct ia64_partial_page *pp, struct ia64_partial_page *prev,
327         struct rb_node **rb_link, struct rb_node *rb_parent)
328 {
329         /* link list */
330         if (prev) {
331                 pp->next = prev->next;
332                 prev->next = pp;
333         } else {
334                 ppl->pp_head = pp;
335                 if (rb_parent)
336                         pp->next = rb_entry(rb_parent,
337                                 struct ia64_partial_page, pp_rb);
338                 else
339                         pp->next = NULL;
340         }
341
342         /* link rb */
343         rb_link_node(&pp->pp_rb, rb_parent, rb_link);
344         rb_insert_color(&pp->pp_rb, &ppl->ppl_rb);
345
346         ppl->pp_hint = pp;
347 }
348
349 /*
350  * delete @pp from partial page list @ppl.
351  */
352 static void
353 __ia32_delete_pp(struct ia64_partial_page_list *ppl,
354         struct ia64_partial_page *pp, struct ia64_partial_page *prev)
355 {
356         if (prev) {
357                 prev->next = pp->next;
358                 if (ppl->pp_hint == pp)
359                         ppl->pp_hint = prev;
360         } else {
361                 ppl->pp_head = pp->next;
362                 if (ppl->pp_hint == pp)
363                         ppl->pp_hint = pp->next;
364         }
365         rb_erase(&pp->pp_rb, &ppl->ppl_rb);
366         kmem_cache_free(ia64_partial_page_cachep, pp);
367 }
368
369 static struct ia64_partial_page *
370 __pp_prev(struct ia64_partial_page *pp)
371 {
372         struct rb_node *prev = rb_prev(&pp->pp_rb);
373         if (prev)
374                 return rb_entry(prev, struct ia64_partial_page, pp_rb);
375         else
376                 return NULL;
377 }
378
379 /*
380  * Delete partial pages with address between @start and @end.
381  * @start and @end are page aligned.
382  */
383 static void
384 __ia32_delete_pp_range(unsigned int start, unsigned int end)
385 {
386         struct ia64_partial_page *pp, *prev;
387         struct rb_node **rb_link, *rb_parent;
388
389         if (start >= end)
390                 return;
391
392         pp = __ia32_find_pp(current->thread.ppl, start, &prev,
393                                         &rb_link, &rb_parent);
394         if (pp)
395                 prev = __pp_prev(pp);
396         else {
397                 if (prev)
398                         pp = prev->next;
399                 else
400                         pp = current->thread.ppl->pp_head;
401         }
402
403         while (pp && pp->base < end) {
404                 struct ia64_partial_page *tmp = pp->next;
405                 __ia32_delete_pp(current->thread.ppl, pp, prev);
406                 pp = tmp;
407         }
408 }
409
410 /*
411  * Set the range between @start and @end in bitmap.
412  * @start and @end should be IA32 page aligned and in the same IA64 page.
413  */
414 static int
415 __ia32_set_pp(unsigned int start, unsigned int end, int flags)
416 {
417         struct ia64_partial_page *pp, *prev;
418         struct rb_node ** rb_link, *rb_parent;
419         unsigned int pstart, start_bit, end_bit, i;
420
421         pstart = PAGE_START(start);
422         start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
423         end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
424         if (end_bit == 0)
425                 end_bit = PAGE_SIZE / IA32_PAGE_SIZE;
426         pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
427                                         &rb_link, &rb_parent);
428         if (pp) {
429                 for (i = start_bit; i < end_bit; i++)
430                         set_bit(i, &pp->bitmap);
431                 /*
432                  * Check: if this partial page has been set to a full page,
433                  * then delete it.
434                  */
435                 if (find_first_zero_bit(&pp->bitmap, sizeof(pp->bitmap)*8) >=
436                                 PAGE_SIZE/IA32_PAGE_SIZE) {
437                         __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
438                 }
439                 return 0;
440         }
441
442         /*
443          * MAP_FIXED may lead to overlapping mmap.
444          * In this case, the requested mmap area may already mmaped as a full
445          * page. So check vma before adding a new partial page.
446          */
447         if (flags & MAP_FIXED) {
448                 struct vm_area_struct *vma = find_vma(current->mm, pstart);
449                 if (vma && vma->vm_start <= pstart)
450                         return 0;
451         }
452
453         /* new a ia64_partial_page */
454         pp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL);
455         if (!pp)
456                 return -ENOMEM;
457         pp->base = pstart;
458         pp->bitmap = 0;
459         for (i=start_bit; i<end_bit; i++)
460                 set_bit(i, &(pp->bitmap));
461         pp->next = NULL;
462         __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
463         return 0;
464 }
465
466 /*
467  * @start and @end should be IA32 page aligned, but don't need to be in the
468  * same IA64 page. Split @start and @end to make sure they're in the same IA64
469  * page, then call __ia32_set_pp().
470  */
471 static void
472 ia32_set_pp(unsigned int start, unsigned int end, int flags)
473 {
474         down_write(&current->mm->mmap_sem);
475         if (flags & MAP_FIXED) {
476                 /*
477                  * MAP_FIXED may lead to overlapping mmap. When this happens,
478                  * a series of complete IA64 pages results in deletion of
479                  * old partial pages in that range.
480                  */
481                 __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));
482         }
483
484         if (end < PAGE_ALIGN(start)) {
485                 __ia32_set_pp(start, end, flags);
486         } else {
487                 if (offset_in_page(start))
488                         __ia32_set_pp(start, PAGE_ALIGN(start), flags);
489                 if (offset_in_page(end))
490                         __ia32_set_pp(PAGE_START(end), end, flags);
491         }
492         up_write(&current->mm->mmap_sem);
493 }
494
495 /*
496  * Unset the range between @start and @end in bitmap.
497  * @start and @end should be IA32 page aligned and in the same IA64 page.
498  * After doing that, if the bitmap is 0, then free the page and return 1,
499  *      else return 0;
500  * If not find the partial page in the list, then
501  *      If the vma exists, then the full page is set to a partial page;
502  *      Else return -ENOMEM.
503  */
504 static int
505 __ia32_unset_pp(unsigned int start, unsigned int end)
506 {
507         struct ia64_partial_page *pp, *prev;
508         struct rb_node ** rb_link, *rb_parent;
509         unsigned int pstart, start_bit, end_bit, i;
510         struct vm_area_struct *vma;
511
512         pstart = PAGE_START(start);
513         start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
514         end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
515         if (end_bit == 0)
516                 end_bit = PAGE_SIZE / IA32_PAGE_SIZE;
517
518         pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
519                                         &rb_link, &rb_parent);
520         if (pp) {
521                 for (i = start_bit; i < end_bit; i++)
522                         clear_bit(i, &pp->bitmap);
523                 if (pp->bitmap == 0) {
524                         __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
525                         return 1;
526                 }
527                 return 0;
528         }
529
530         vma = find_vma(current->mm, pstart);
531         if (!vma || vma->vm_start > pstart) {
532                 return -ENOMEM;
533         }
534
535         /* new a ia64_partial_page */
536         pp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL);
537         if (!pp)
538                 return -ENOMEM;
539         pp->base = pstart;
540         pp->bitmap = 0;
541         for (i = 0; i < start_bit; i++)
542                 set_bit(i, &(pp->bitmap));
543         for (i = end_bit; i < PAGE_SIZE / IA32_PAGE_SIZE; i++)
544                 set_bit(i, &(pp->bitmap));
545         pp->next = NULL;
546         __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
547         return 0;
548 }
549
550 /*
551  * Delete pp between PAGE_ALIGN(start) and PAGE_START(end) by calling
552  * __ia32_delete_pp_range(). Unset possible partial pages by calling
553  * __ia32_unset_pp().
554  * The returned value see __ia32_unset_pp().
555  */
556 static int
557 ia32_unset_pp(unsigned int *startp, unsigned int *endp)
558 {
559         unsigned int start = *startp, end = *endp;
560         int ret = 0;
561
562         down_write(&current->mm->mmap_sem);
563
564         __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));
565
566         if (end < PAGE_ALIGN(start)) {
567                 ret = __ia32_unset_pp(start, end);
568                 if (ret == 1) {
569                         *startp = PAGE_START(start);
570                         *endp = PAGE_ALIGN(end);
571                 }
572                 if (ret == 0) {
573                         /* to shortcut sys_munmap() in sys32_munmap() */
574                         *startp = PAGE_START(start);
575                         *endp = PAGE_START(end);
576                 }
577         } else {
578                 if (offset_in_page(start)) {
579                         ret = __ia32_unset_pp(start, PAGE_ALIGN(start));
580                         if (ret == 1)
581                                 *startp = PAGE_START(start);
582                         if (ret == 0)
583                                 *startp = PAGE_ALIGN(start);
584                         if (ret < 0)
585                                 goto out;
586                 }
587                 if (offset_in_page(end)) {
588                         ret = __ia32_unset_pp(PAGE_START(end), end);
589                         if (ret == 1)
590                                 *endp = PAGE_ALIGN(end);
591                         if (ret == 0)
592                                 *endp = PAGE_START(end);
593                 }
594         }
595
596  out:
597         up_write(&current->mm->mmap_sem);
598         return ret;
599 }
600
601 /*
602  * Compare the range between @start and @end with bitmap in partial page.
603  * @start and @end should be IA32 page aligned and in the same IA64 page.
604  */
605 static int
606 __ia32_compare_pp(unsigned int start, unsigned int end)
607 {
608         struct ia64_partial_page *pp, *prev;
609         struct rb_node ** rb_link, *rb_parent;
610         unsigned int pstart, start_bit, end_bit, size;
611         unsigned int first_bit, next_zero_bit;  /* the first range in bitmap */
612
613         pstart = PAGE_START(start);
614
615         pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
616                                         &rb_link, &rb_parent);
617         if (!pp)
618                 return 1;
619
620         start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
621         end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
622         size = sizeof(pp->bitmap) * 8;
623         first_bit = find_first_bit(&pp->bitmap, size);
624         next_zero_bit = find_next_zero_bit(&pp->bitmap, size, first_bit);
625         if ((start_bit < first_bit) || (end_bit > next_zero_bit)) {
626                 /* exceeds the first range in bitmap */
627                 return -ENOMEM;
628         } else if ((start_bit == first_bit) && (end_bit == next_zero_bit)) {
629                 first_bit = find_next_bit(&pp->bitmap, size, next_zero_bit);
630                 if ((next_zero_bit < first_bit) && (first_bit < size))
631                         return 1;       /* has next range */
632                 else
633                         return 0;       /* no next range */
634         } else
635                 return 1;
636 }
637
638 /*
639  * @start and @end should be IA32 page aligned, but don't need to be in the
640  * same IA64 page. Split @start and @end to make sure they're in the same IA64
641  * page, then call __ia32_compare_pp().
642  *
643  * Take this as example: the range is the 1st and 2nd 4K page.
644  * Return 0 if they fit bitmap exactly, i.e. bitmap = 00000011;
645  * Return 1 if the range doesn't cover whole bitmap, e.g. bitmap = 00001111;
646  * Return -ENOMEM if the range exceeds the bitmap, e.g. bitmap = 00000001 or
647  *      bitmap = 00000101.
648  */
649 static int
650 ia32_compare_pp(unsigned int *startp, unsigned int *endp)
651 {
652         unsigned int start = *startp, end = *endp;
653         int retval = 0;
654
655         down_write(&current->mm->mmap_sem);
656
657         if (end < PAGE_ALIGN(start)) {
658                 retval = __ia32_compare_pp(start, end);
659                 if (retval == 0) {
660                         *startp = PAGE_START(start);
661                         *endp = PAGE_ALIGN(end);
662                 }
663         } else {
664                 if (offset_in_page(start)) {
665                         retval = __ia32_compare_pp(start,
666                                                    PAGE_ALIGN(start));
667                         if (retval == 0)
668                                 *startp = PAGE_START(start);
669                         if (retval < 0)
670                                 goto out;
671                 }
672                 if (offset_in_page(end)) {
673                         retval = __ia32_compare_pp(PAGE_START(end), end);
674                         if (retval == 0)
675                                 *endp = PAGE_ALIGN(end);
676                 }
677         }
678
679  out:
680         up_write(&current->mm->mmap_sem);
681         return retval;
682 }
683
684 static void
685 __ia32_drop_pp_list(struct ia64_partial_page_list *ppl)
686 {
687         struct ia64_partial_page *pp = ppl->pp_head;
688
689         while (pp) {
690                 struct ia64_partial_page *next = pp->next;
691                 kmem_cache_free(ia64_partial_page_cachep, pp);
692                 pp = next;
693         }
694
695         kfree(ppl);
696 }
697
698 void
699 ia32_drop_ia64_partial_page_list(struct task_struct *task)
700 {
701         struct ia64_partial_page_list* ppl = task->thread.ppl;
702
703         if (ppl && atomic_dec_and_test(&ppl->pp_count))
704                 __ia32_drop_pp_list(ppl);
705 }
706
707 /*
708  * Copy current->thread.ppl to ppl (already initialized).
709  */
710 static int
711 __ia32_copy_pp_list(struct ia64_partial_page_list *ppl)
712 {
713         struct ia64_partial_page *pp, *tmp, *prev;
714         struct rb_node **rb_link, *rb_parent;
715
716         ppl->pp_head = NULL;
717         ppl->pp_hint = NULL;
718         ppl->ppl_rb = RB_ROOT;
719         rb_link = &ppl->ppl_rb.rb_node;
720         rb_parent = NULL;
721         prev = NULL;
722
723         for (pp = current->thread.ppl->pp_head; pp; pp = pp->next) {
724                 tmp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL);
725                 if (!tmp)
726                         return -ENOMEM;
727                 *tmp = *pp;
728                 __ia32_insert_pp(ppl, tmp, prev, rb_link, rb_parent);
729                 prev = tmp;
730                 rb_link = &tmp->pp_rb.rb_right;
731                 rb_parent = &tmp->pp_rb;
732         }
733         return 0;
734 }
735
736 int
737 ia32_copy_ia64_partial_page_list(struct task_struct *p,
738                                 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                 do_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 = -EFAULT;
1272         if (!access_ok(VERIFY_WRITE, dirent, count))
1273                 goto out;
1274
1275         error = -EBADF;
1276         file = fget(fd);
1277         if (!file)
1278                 goto out;
1279
1280         buf.current_dir = dirent;
1281         buf.previous = NULL;
1282         buf.count = count;
1283         buf.error = 0;
1284
1285         error = vfs_readdir(file, filldir32, &buf);
1286         if (error < 0)
1287                 goto out_putf;
1288         error = buf.error;
1289         lastdirent = buf.previous;
1290         if (lastdirent) {
1291                 if (put_user(file->f_pos, &lastdirent->d_off))
1292                         error = -EFAULT;
1293                 else
1294                         error = count - buf.count;
1295         }
1296
1297 out_putf:
1298         fput(file);
1299 out:
1300         return error;
1301 }
1302
1303 static int
1304 fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino,
1305               unsigned int d_type)
1306 {
1307         struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
1308         struct old_linux32_dirent __user * dirent;
1309         u32 d_ino;
1310
1311         if (buf->count)
1312                 return -EINVAL;
1313         d_ino = ino;
1314         if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
1315                 return -EOVERFLOW;
1316         buf->count++;
1317         dirent = buf->dirent;
1318         if (put_user(d_ino, &dirent->d_ino)
1319             || put_user(offset, &dirent->d_offset)
1320             || put_user(namlen, &dirent->d_namlen)
1321             || copy_to_user(dirent->d_name, name, namlen)
1322             || put_user(0, dirent->d_name + namlen))
1323                 return -EFAULT;
1324         return 0;
1325 }
1326
1327 asmlinkage long
1328 sys32_readdir (unsigned int fd, void __user *dirent, unsigned int count)
1329 {
1330         int error;
1331         struct file * file;
1332         struct readdir32_callback buf;
1333
1334         error = -EBADF;
1335         file = fget(fd);
1336         if (!file)
1337                 goto out;
1338
1339         buf.count = 0;
1340         buf.dirent = dirent;
1341
1342         error = vfs_readdir(file, fillonedir32, &buf);
1343         if (error >= 0)
1344                 error = buf.count;
1345         fput(file);
1346 out:
1347         return error;
1348 }
1349
1350 struct sel_arg_struct {
1351         unsigned int n;
1352         unsigned int inp;
1353         unsigned int outp;
1354         unsigned int exp;
1355         unsigned int tvp;
1356 };
1357
1358 asmlinkage long
1359 sys32_old_select (struct sel_arg_struct __user *arg)
1360 {
1361         struct sel_arg_struct a;
1362
1363         if (copy_from_user(&a, arg, sizeof(a)))
1364                 return -EFAULT;
1365         return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
1366                                  compat_ptr(a.exp), compat_ptr(a.tvp));
1367 }
1368
1369 #define SEMOP            1
1370 #define SEMGET           2
1371 #define SEMCTL           3
1372 #define SEMTIMEDOP       4
1373 #define MSGSND          11
1374 #define MSGRCV          12
1375 #define MSGGET          13
1376 #define MSGCTL          14
1377 #define SHMAT           21
1378 #define SHMDT           22
1379 #define SHMGET          23
1380 #define SHMCTL          24
1381
1382 asmlinkage long
1383 sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
1384 {
1385         int version;
1386
1387         version = call >> 16; /* hack for backward compatibility */
1388         call &= 0xffff;
1389
1390         switch (call) {
1391               case SEMTIMEDOP:
1392                 if (fifth)
1393                         return compat_sys_semtimedop(first, compat_ptr(ptr),
1394                                 second, compat_ptr(fifth));
1395                 /* else fall through for normal semop() */
1396               case SEMOP:
1397                 /* struct sembuf is the same on 32 and 64bit :)) */
1398                 return sys_semtimedop(first, compat_ptr(ptr), second,
1399                                       NULL);
1400               case SEMGET:
1401                 return sys_semget(first, second, third);
1402               case SEMCTL:
1403                 return compat_sys_semctl(first, second, third, compat_ptr(ptr));
1404
1405               case MSGSND:
1406                 return compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
1407               case MSGRCV:
1408                 return compat_sys_msgrcv(first, second, fifth, third, version, compat_ptr(ptr));
1409               case MSGGET:
1410                 return sys_msgget((key_t) first, second);
1411               case MSGCTL:
1412                 return compat_sys_msgctl(first, second, compat_ptr(ptr));
1413
1414               case SHMAT:
1415                 return compat_sys_shmat(first, second, third, version, compat_ptr(ptr));
1416                 break;
1417               case SHMDT:
1418                 return sys_shmdt(compat_ptr(ptr));
1419               case SHMGET:
1420                 return sys_shmget(first, (unsigned)second, third);
1421               case SHMCTL:
1422                 return compat_sys_shmctl(first, second, compat_ptr(ptr));
1423
1424               default:
1425                 return -ENOSYS;
1426         }
1427         return -EINVAL;
1428 }
1429
1430 asmlinkage long
1431 compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options,
1432                  struct compat_rusage *ru);
1433
1434 asmlinkage long
1435 sys32_waitpid (int pid, unsigned int *stat_addr, int options)
1436 {
1437         return compat_sys_wait4(pid, stat_addr, options, NULL);
1438 }
1439
1440 static unsigned int
1441 ia32_peek (struct task_struct *child, unsigned long addr, unsigned int *val)
1442 {
1443         size_t copied;
1444         unsigned int ret;
1445
1446         copied = access_process_vm(child, addr, val, sizeof(*val), 0);
1447         return (copied != sizeof(ret)) ? -EIO : 0;
1448 }
1449
1450 static unsigned int
1451 ia32_poke (struct task_struct *child, unsigned long addr, unsigned int val)
1452 {
1453
1454         if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
1455                 return -EIO;
1456         return 0;
1457 }
1458
1459 /*
1460  *  The order in which registers are stored in the ptrace regs structure
1461  */
1462 #define PT_EBX  0
1463 #define PT_ECX  1
1464 #define PT_EDX  2
1465 #define PT_ESI  3
1466 #define PT_EDI  4
1467 #define PT_EBP  5
1468 #define PT_EAX  6
1469 #define PT_DS   7
1470 #define PT_ES   8
1471 #define PT_FS   9
1472 #define PT_GS   10
1473 #define PT_ORIG_EAX 11
1474 #define PT_EIP  12
1475 #define PT_CS   13
1476 #define PT_EFL  14
1477 #define PT_UESP 15
1478 #define PT_SS   16
1479
1480 static unsigned int
1481 getreg (struct task_struct *child, int regno)
1482 {
1483         struct pt_regs *child_regs;
1484
1485         child_regs = task_pt_regs(child);
1486         switch (regno / sizeof(int)) {
1487               case PT_EBX: return child_regs->r11;
1488               case PT_ECX: return child_regs->r9;
1489               case PT_EDX: return child_regs->r10;
1490               case PT_ESI: return child_regs->r14;
1491               case PT_EDI: return child_regs->r15;
1492               case PT_EBP: return child_regs->r13;
1493               case PT_EAX: return child_regs->r8;
1494               case PT_ORIG_EAX: return child_regs->r1; /* see dispatch_to_ia32_handler() */
1495               case PT_EIP: return child_regs->cr_iip;
1496               case PT_UESP: return child_regs->r12;
1497               case PT_EFL: return child->thread.eflag;
1498               case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
1499                 return __USER_DS;
1500               case PT_CS: return __USER_CS;
1501               default:
1502                 printk(KERN_ERR "ia32.getreg(): unknown register %d\n", regno);
1503                 break;
1504         }
1505         return 0;
1506 }
1507
1508 static void
1509 putreg (struct task_struct *child, int regno, unsigned int value)
1510 {
1511         struct pt_regs *child_regs;
1512
1513         child_regs = task_pt_regs(child);
1514         switch (regno / sizeof(int)) {
1515               case PT_EBX: child_regs->r11 = value; break;
1516               case PT_ECX: child_regs->r9 = value; break;
1517               case PT_EDX: child_regs->r10 = value; break;
1518               case PT_ESI: child_regs->r14 = value; break;
1519               case PT_EDI: child_regs->r15 = value; break;
1520               case PT_EBP: child_regs->r13 = value; break;
1521               case PT_EAX: child_regs->r8 = value; break;
1522               case PT_ORIG_EAX: child_regs->r1 = value; break;
1523               case PT_EIP: child_regs->cr_iip = value; break;
1524               case PT_UESP: child_regs->r12 = value; break;
1525               case PT_EFL: child->thread.eflag = value; break;
1526               case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
1527                 if (value != __USER_DS)
1528                         printk(KERN_ERR
1529                                "ia32.putreg: attempt to set invalid segment register %d = %x\n",
1530                                regno, value);
1531                 break;
1532               case PT_CS:
1533                 if (value != __USER_CS)
1534                         printk(KERN_ERR
1535                                "ia32.putreg: attempt to to set invalid segment register %d = %x\n",
1536                                regno, value);
1537                 break;
1538               default:
1539                 printk(KERN_ERR "ia32.putreg: unknown register %d\n", regno);
1540                 break;
1541         }
1542 }
1543
1544 static void
1545 put_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
1546            struct switch_stack *swp, int tos)
1547 {
1548         struct _fpreg_ia32 *f;
1549         char buf[32];
1550
1551         f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
1552         if ((regno += tos) >= 8)
1553                 regno -= 8;
1554         switch (regno) {
1555               case 0:
1556                 ia64f2ia32f(f, &ptp->f8);
1557                 break;
1558               case 1:
1559                 ia64f2ia32f(f, &ptp->f9);
1560                 break;
1561               case 2:
1562                 ia64f2ia32f(f, &ptp->f10);
1563                 break;
1564               case 3:
1565                 ia64f2ia32f(f, &ptp->f11);
1566                 break;
1567               case 4:
1568               case 5:
1569               case 6:
1570               case 7:
1571                 ia64f2ia32f(f, &swp->f12 + (regno - 4));
1572                 break;
1573         }
1574         copy_to_user(reg, f, sizeof(*reg));
1575 }
1576
1577 static void
1578 get_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
1579            struct switch_stack *swp, int tos)
1580 {
1581
1582         if ((regno += tos) >= 8)
1583                 regno -= 8;
1584         switch (regno) {
1585               case 0:
1586                 copy_from_user(&ptp->f8, reg, sizeof(*reg));
1587                 break;
1588               case 1:
1589                 copy_from_user(&ptp->f9, reg, sizeof(*reg));
1590                 break;
1591               case 2:
1592                 copy_from_user(&ptp->f10, reg, sizeof(*reg));
1593                 break;
1594               case 3:
1595                 copy_from_user(&ptp->f11, reg, sizeof(*reg));
1596                 break;
1597               case 4:
1598               case 5:
1599               case 6:
1600               case 7:
1601                 copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg));
1602                 break;
1603         }
1604         return;
1605 }
1606
1607 int
1608 save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
1609 {
1610         struct switch_stack *swp;
1611         struct pt_regs *ptp;
1612         int i, tos;
1613
1614         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1615                 return -EFAULT;
1616
1617         __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1618         __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1619         __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1620         __put_user(tsk->thread.fir, &save->fip);
1621         __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1622         __put_user(tsk->thread.fdr, &save->foo);
1623         __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1624
1625         /*
1626          *  Stack frames start with 16-bytes of temp space
1627          */
1628         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1629         ptp = task_pt_regs(tsk);
1630         tos = (tsk->thread.fsr >> 11) & 7;
1631         for (i = 0; i < 8; i++)
1632                 put_fpreg(i, &save->st_space[i], ptp, swp, tos);
1633         return 0;
1634 }
1635
1636 static int
1637 restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
1638 {
1639         struct switch_stack *swp;
1640         struct pt_regs *ptp;
1641         int i, tos;
1642         unsigned int fsrlo, fsrhi, num32;
1643
1644         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1645                 return(-EFAULT);
1646
1647         __get_user(num32, (unsigned int __user *)&save->cwd);
1648         tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1649         __get_user(fsrlo, (unsigned int __user *)&save->swd);
1650         __get_user(fsrhi, (unsigned int __user *)&save->twd);
1651         num32 = (fsrhi << 16) | fsrlo;
1652         tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1653         __get_user(num32, (unsigned int __user *)&save->fip);
1654         tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1655         __get_user(num32, (unsigned int __user *)&save->foo);
1656         tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1657
1658         /*
1659          *  Stack frames start with 16-bytes of temp space
1660          */
1661         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1662         ptp = task_pt_regs(tsk);
1663         tos = (tsk->thread.fsr >> 11) & 7;
1664         for (i = 0; i < 8; i++)
1665                 get_fpreg(i, &save->st_space[i], ptp, swp, tos);
1666         return 0;
1667 }
1668
1669 int
1670 save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
1671 {
1672         struct switch_stack *swp;
1673         struct pt_regs *ptp;
1674         int i, tos;
1675         unsigned long mxcsr=0;
1676         unsigned long num128[2];
1677
1678         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1679                 return -EFAULT;
1680
1681         __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1682         __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1683         __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1684         __put_user(tsk->thread.fir, &save->fip);
1685         __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1686         __put_user(tsk->thread.fdr, &save->foo);
1687         __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1688
1689         /*
1690          *  Stack frames start with 16-bytes of temp space
1691          */
1692         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1693         ptp = task_pt_regs(tsk);
1694         tos = (tsk->thread.fsr >> 11) & 7;
1695         for (i = 0; i < 8; i++)
1696                 put_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
1697
1698         mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f);
1699         __put_user(mxcsr & 0xffff, &save->mxcsr);
1700         for (i = 0; i < 8; i++) {
1701                 memcpy(&(num128[0]), &(swp->f16) + i*2, sizeof(unsigned long));
1702                 memcpy(&(num128[1]), &(swp->f17) + i*2, sizeof(unsigned long));
1703                 copy_to_user(&save->xmm_space[0] + 4*i, num128, sizeof(struct _xmmreg_ia32));
1704         }
1705         return 0;
1706 }
1707
1708 static int
1709 restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
1710 {
1711         struct switch_stack *swp;
1712         struct pt_regs *ptp;
1713         int i, tos;
1714         unsigned int fsrlo, fsrhi, num32;
1715         int mxcsr;
1716         unsigned long num64;
1717         unsigned long num128[2];
1718
1719         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1720                 return(-EFAULT);
1721
1722         __get_user(num32, (unsigned int __user *)&save->cwd);
1723         tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1724         __get_user(fsrlo, (unsigned int __user *)&save->swd);
1725         __get_user(fsrhi, (unsigned int __user *)&save->twd);
1726         num32 = (fsrhi << 16) | fsrlo;
1727         tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1728         __get_user(num32, (unsigned int __user *)&save->fip);
1729         tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1730         __get_user(num32, (unsigned int __user *)&save->foo);
1731         tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1732
1733         /*
1734          *  Stack frames start with 16-bytes of temp space
1735          */
1736         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1737         ptp = task_pt_regs(tsk);
1738         tos = (tsk->thread.fsr >> 11) & 7;
1739         for (i = 0; i < 8; i++)
1740         get_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
1741
1742         __get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
1743         num64 = mxcsr & 0xff10;
1744         tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000UL)) | (num64<<32);
1745         num64 = mxcsr & 0x3f;
1746         tsk->thread.fsr = (tsk->thread.fsr & (~0x3f00000000UL)) | (num64<<32);
1747
1748         for (i = 0; i < 8; i++) {
1749                 copy_from_user(num128, &save->xmm_space[0] + 4*i, sizeof(struct _xmmreg_ia32));
1750                 memcpy(&(swp->f16) + i*2, &(num128[0]), sizeof(unsigned long));
1751                 memcpy(&(swp->f17) + i*2, &(num128[1]), sizeof(unsigned long));
1752         }
1753         return 0;
1754 }
1755
1756 asmlinkage long
1757 sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
1758 {
1759         struct task_struct *child;
1760         unsigned int value, tmp;
1761         long i, ret;
1762
1763         lock_kernel();
1764         if (request == PTRACE_TRACEME) {
1765                 ret = ptrace_traceme();
1766                 goto out;
1767         }
1768
1769         child = ptrace_get_task_struct(pid);
1770         if (IS_ERR(child)) {
1771                 ret = PTR_ERR(child);
1772                 goto out;
1773         }
1774
1775         if (request == PTRACE_ATTACH) {
1776                 ret = sys_ptrace(request, pid, addr, data);
1777                 goto out_tsk;
1778         }
1779
1780         ret = ptrace_check_attach(child, request == PTRACE_KILL);
1781         if (ret < 0)
1782                 goto out_tsk;
1783
1784         switch (request) {
1785               case PTRACE_PEEKTEXT:
1786               case PTRACE_PEEKDATA:     /* read word at location addr */
1787                 ret = ia32_peek(child, addr, &value);
1788                 if (ret == 0)
1789                         ret = put_user(value, (unsigned int __user *) compat_ptr(data));
1790                 else
1791                         ret = -EIO;
1792                 goto out_tsk;
1793
1794               case PTRACE_POKETEXT:
1795               case PTRACE_POKEDATA:     /* write the word at location addr */
1796                 ret = ia32_poke(child, addr, data);
1797                 goto out_tsk;
1798
1799               case PTRACE_PEEKUSR:      /* read word at addr in USER area */
1800                 ret = -EIO;
1801                 if ((addr & 3) || addr > 17*sizeof(int))
1802                         break;
1803
1804                 tmp = getreg(child, addr);
1805                 if (!put_user(tmp, (unsigned int __user *) compat_ptr(data)))
1806                         ret = 0;
1807                 break;
1808
1809               case PTRACE_POKEUSR:      /* write word at addr in USER area */
1810                 ret = -EIO;
1811                 if ((addr & 3) || addr > 17*sizeof(int))
1812                         break;
1813
1814                 putreg(child, addr, data);
1815                 ret = 0;
1816                 break;
1817
1818               case IA32_PTRACE_GETREGS:
1819                 if (!access_ok(VERIFY_WRITE, compat_ptr(data), 17*sizeof(int))) {
1820                         ret = -EIO;
1821                         break;
1822                 }
1823                 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
1824                         put_user(getreg(child, i), (unsigned int __user *) compat_ptr(data));
1825                         data += sizeof(int);
1826                 }
1827                 ret = 0;
1828                 break;
1829
1830               case IA32_PTRACE_SETREGS:
1831                 if (!access_ok(VERIFY_READ, compat_ptr(data), 17*sizeof(int))) {
1832                         ret = -EIO;
1833                         break;
1834                 }
1835                 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
1836                         get_user(tmp, (unsigned int __user *) compat_ptr(data));
1837                         putreg(child, i, tmp);
1838                         data += sizeof(int);
1839                 }
1840                 ret = 0;
1841                 break;
1842
1843               case IA32_PTRACE_GETFPREGS:
1844                 ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
1845                                         compat_ptr(data));
1846                 break;
1847
1848               case IA32_PTRACE_GETFPXREGS:
1849                 ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
1850                                          compat_ptr(data));
1851                 break;
1852
1853               case IA32_PTRACE_SETFPREGS:
1854                 ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
1855                                            compat_ptr(data));
1856                 break;
1857
1858               case IA32_PTRACE_SETFPXREGS:
1859                 ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
1860                                             compat_ptr(data));
1861                 break;
1862
1863               case PTRACE_GETEVENTMSG:   
1864                 ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data));
1865                 break;
1866
1867               case PTRACE_SYSCALL:      /* continue, stop after next syscall */
1868               case PTRACE_CONT:         /* restart after signal. */
1869               case PTRACE_KILL:
1870               case PTRACE_SINGLESTEP:   /* execute chile for one instruction */
1871               case PTRACE_DETACH:       /* detach a process */
1872                 ret = sys_ptrace(request, pid, addr, data);
1873                 break;
1874
1875               default:
1876                 ret = ptrace_request(child, request, addr, data);
1877                 break;
1878
1879         }
1880   out_tsk:
1881         put_task_struct(child);
1882   out:
1883         unlock_kernel();
1884         return ret;
1885 }
1886
1887 typedef struct {
1888         unsigned int    ss_sp;
1889         unsigned int    ss_flags;
1890         unsigned int    ss_size;
1891 } ia32_stack_t;
1892
1893 asmlinkage long
1894 sys32_sigaltstack (ia32_stack_t __user *uss32, ia32_stack_t __user *uoss32,
1895                    long arg2, long arg3, long arg4, long arg5, long arg6,
1896                    long arg7, struct pt_regs pt)
1897 {
1898         stack_t uss, uoss;
1899         ia32_stack_t buf32;
1900         int ret;
1901         mm_segment_t old_fs = get_fs();
1902
1903         if (uss32) {
1904                 if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t)))
1905                         return -EFAULT;
1906                 uss.ss_sp = (void __user *) (long) buf32.ss_sp;
1907                 uss.ss_flags = buf32.ss_flags;
1908                 /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the
1909                    check and set it to the user requested value later */
1910                 if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) {
1911                         ret = -ENOMEM;
1912                         goto out;
1913                 }
1914                 uss.ss_size = MINSIGSTKSZ;
1915         }
1916         set_fs(KERNEL_DS);
1917         ret = do_sigaltstack(uss32 ? (stack_t __user *) &uss : NULL,
1918                              (stack_t __user *) &uoss, pt.r12);
1919         current->sas_ss_size = buf32.ss_size;
1920         set_fs(old_fs);
1921 out:
1922         if (ret < 0)
1923                 return(ret);
1924         if (uoss32) {
1925                 buf32.ss_sp = (long __user) uoss.ss_sp;
1926                 buf32.ss_flags = uoss.ss_flags;
1927                 buf32.ss_size = uoss.ss_size;
1928                 if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t)))
1929                         return -EFAULT;
1930         }
1931         return ret;
1932 }
1933
1934 asmlinkage int
1935 sys32_pause (void)
1936 {
1937         current->state = TASK_INTERRUPTIBLE;
1938         schedule();
1939         return -ERESTARTNOHAND;
1940 }
1941
1942 asmlinkage int
1943 sys32_msync (unsigned int start, unsigned int len, int flags)
1944 {
1945         unsigned int addr;
1946
1947         if (OFFSET4K(start))
1948                 return -EINVAL;
1949         addr = PAGE_START(start);
1950         return sys_msync(addr, len + (start - addr), flags);
1951 }
1952
1953 struct sysctl32 {
1954         unsigned int    name;
1955         int             nlen;
1956         unsigned int    oldval;
1957         unsigned int    oldlenp;
1958         unsigned int    newval;
1959         unsigned int    newlen;
1960         unsigned int    __unused[4];
1961 };
1962
1963 #ifdef CONFIG_SYSCTL_SYSCALL
1964 asmlinkage long
1965 sys32_sysctl (struct sysctl32 __user *args)
1966 {
1967         struct sysctl32 a32;
1968         mm_segment_t old_fs = get_fs ();
1969         void __user *oldvalp, *newvalp;
1970         size_t oldlen;
1971         int __user *namep;
1972         long ret;
1973
1974         if (copy_from_user(&a32, args, sizeof(a32)))
1975                 return -EFAULT;
1976
1977         /*
1978          * We need to pre-validate these because we have to disable address checking
1979          * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
1980          * user specifying bad addresses here.  Well, since we're dealing with 32 bit
1981          * addresses, we KNOW that access_ok() will always succeed, so this is an
1982          * expensive NOP, but so what...
1983          */
1984         namep = (int __user *) compat_ptr(a32.name);
1985         oldvalp = compat_ptr(a32.oldval);
1986         newvalp = compat_ptr(a32.newval);
1987
1988         if ((oldvalp && get_user(oldlen, (int __user *) compat_ptr(a32.oldlenp)))
1989             || !access_ok(VERIFY_WRITE, namep, 0)
1990             || !access_ok(VERIFY_WRITE, oldvalp, 0)
1991             || !access_ok(VERIFY_WRITE, newvalp, 0))
1992                 return -EFAULT;
1993
1994         set_fs(KERNEL_DS);
1995         lock_kernel();
1996         ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *) &oldlen,
1997                         newvalp, (size_t) a32.newlen);
1998         unlock_kernel();
1999         set_fs(old_fs);
2000
2001         if (oldvalp && put_user (oldlen, (int __user *) compat_ptr(a32.oldlenp)))
2002                 return -EFAULT;
2003
2004         return ret;
2005 }
2006 #endif
2007
2008 asmlinkage long
2009 sys32_newuname (struct new_utsname __user *name)
2010 {
2011         int ret = sys_newuname(name);
2012
2013         if (!ret)
2014                 if (copy_to_user(name->machine, "i686\0\0\0", 8))
2015                         ret = -EFAULT;
2016         return ret;
2017 }
2018
2019 asmlinkage long
2020 sys32_getresuid16 (u16 __user *ruid, u16 __user *euid, u16 __user *suid)
2021 {
2022         uid_t a, b, c;
2023         int ret;
2024         mm_segment_t old_fs = get_fs();
2025
2026         set_fs(KERNEL_DS);
2027         ret = sys_getresuid((uid_t __user *) &a, (uid_t __user *) &b, (uid_t __user *) &c);
2028         set_fs(old_fs);
2029
2030         if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
2031                 return -EFAULT;
2032         return ret;
2033 }
2034
2035 asmlinkage long
2036 sys32_getresgid16 (u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
2037 {
2038         gid_t a, b, c;
2039         int ret;
2040         mm_segment_t old_fs = get_fs();
2041
2042         set_fs(KERNEL_DS);
2043         ret = sys_getresgid((gid_t __user *) &a, (gid_t __user *) &b, (gid_t __user *) &c);
2044         set_fs(old_fs);
2045
2046         if (ret)
2047                 return ret;
2048
2049         return put_user(a, rgid) | put_user(b, egid) | put_user(c, sgid);
2050 }
2051
2052 asmlinkage long
2053 sys32_lseek (unsigned int fd, int offset, unsigned int whence)
2054 {
2055         /* Sign-extension of "offset" is important here... */
2056         return sys_lseek(fd, offset, whence);
2057 }
2058
2059 static int
2060 groups16_to_user(short __user *grouplist, struct group_info *group_info)
2061 {
2062         int i;
2063         short group;
2064
2065         for (i = 0; i < group_info->ngroups; i++) {
2066                 group = (short)GROUP_AT(group_info, i);
2067                 if (put_user(group, grouplist+i))
2068                         return -EFAULT;
2069         }
2070
2071         return 0;
2072 }
2073
2074 static int
2075 groups16_from_user(struct group_info *group_info, short __user *grouplist)
2076 {
2077         int i;
2078         short group;
2079
2080         for (i = 0; i < group_info->ngroups; i++) {
2081                 if (get_user(group, grouplist+i))
2082                         return  -EFAULT;
2083                 GROUP_AT(group_info, i) = (gid_t)group;
2084         }
2085
2086         return 0;
2087 }
2088
2089 asmlinkage long
2090 sys32_getgroups16 (int gidsetsize, short __user *grouplist)
2091 {
2092         int i;
2093
2094         if (gidsetsize < 0)
2095                 return -EINVAL;
2096
2097         get_group_info(current->group_info);
2098         i = current->group_info->ngroups;
2099         if (gidsetsize) {
2100                 if (i > gidsetsize) {
2101                         i = -EINVAL;
2102                         goto out;
2103                 }
2104                 if (groups16_to_user(grouplist, current->group_info)) {
2105                         i = -EFAULT;
2106                         goto out;
2107                 }
2108         }
2109 out:
2110         put_group_info(current->group_info);
2111         return i;
2112 }
2113
2114 asmlinkage long
2115 sys32_setgroups16 (int gidsetsize, short __user *grouplist)
2116 {
2117         struct group_info *group_info;
2118         int retval;
2119
2120         if (!capable(CAP_SETGID))
2121                 return -EPERM;
2122         if ((unsigned)gidsetsize > NGROUPS_MAX)
2123                 return -EINVAL;
2124
2125         group_info = groups_alloc(gidsetsize);
2126         if (!group_info)
2127                 return -ENOMEM;
2128         retval = groups16_from_user(group_info, grouplist);
2129         if (retval) {
2130                 put_group_info(group_info);
2131                 return retval;
2132         }
2133
2134         retval = set_current_groups(group_info);
2135         put_group_info(group_info);
2136
2137         return retval;
2138 }
2139
2140 asmlinkage long
2141 sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi)
2142 {
2143         return sys_truncate(compat_ptr(path), ((unsigned long) len_hi << 32) | len_lo);
2144 }
2145
2146 asmlinkage long
2147 sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi)
2148 {
2149         return sys_ftruncate(fd, ((unsigned long) len_hi << 32) | len_lo);
2150 }
2151
2152 static int
2153 putstat64 (struct stat64 __user *ubuf, struct kstat *kbuf)
2154 {
2155         int err;
2156         u64 hdev;
2157
2158         if (clear_user(ubuf, sizeof(*ubuf)))
2159                 return -EFAULT;
2160
2161         hdev = huge_encode_dev(kbuf->dev);
2162         err  = __put_user(hdev, (u32 __user*)&ubuf->st_dev);
2163         err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_dev) + 1);
2164         err |= __put_user(kbuf->ino, &ubuf->__st_ino);
2165         err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
2166         err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
2167         err |= __put_user(kbuf->mode, &ubuf->st_mode);
2168         err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
2169         err |= __put_user(kbuf->uid, &ubuf->st_uid);
2170         err |= __put_user(kbuf->gid, &ubuf->st_gid);
2171         hdev = huge_encode_dev(kbuf->rdev);
2172         err  = __put_user(hdev, (u32 __user*)&ubuf->st_rdev);
2173         err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_rdev) + 1);
2174         err |= __put_user(kbuf->size, &ubuf->st_size_lo);
2175         err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
2176         err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
2177         err |= __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec);
2178         err |= __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime);
2179         err |= __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec);
2180         err |= __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime);
2181         err |= __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec);
2182         err |= __put_user(kbuf->blksize, &ubuf->st_blksize);
2183         err |= __put_user(kbuf->blocks, &ubuf->st_blocks);
2184         return err;
2185 }
2186
2187 asmlinkage long
2188 sys32_stat64 (char __user *filename, struct stat64 __user *statbuf)
2189 {
2190         struct kstat s;
2191         long ret = vfs_stat(filename, &s);
2192         if (!ret)
2193                 ret = putstat64(statbuf, &s);
2194         return ret;
2195 }
2196
2197 asmlinkage long
2198 sys32_lstat64 (char __user *filename, struct stat64 __user *statbuf)
2199 {
2200         struct kstat s;
2201         long ret = vfs_lstat(filename, &s);
2202         if (!ret)
2203                 ret = putstat64(statbuf, &s);
2204         return ret;
2205 }
2206
2207 asmlinkage long
2208 sys32_fstat64 (unsigned int fd, struct stat64 __user *statbuf)
2209 {
2210         struct kstat s;
2211         long ret = vfs_fstat(fd, &s);
2212         if (!ret)
2213                 ret = putstat64(statbuf, &s);
2214         return ret;
2215 }
2216
2217 asmlinkage long
2218 sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec __user *interval)
2219 {
2220         mm_segment_t old_fs = get_fs();
2221         struct timespec t;
2222         long ret;
2223
2224         set_fs(KERNEL_DS);
2225         ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
2226         set_fs(old_fs);
2227         if (put_compat_timespec(&t, interval))
2228                 return -EFAULT;
2229         return ret;
2230 }
2231
2232 asmlinkage long
2233 sys32_pread (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
2234 {
2235         return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
2236 }
2237
2238 asmlinkage long
2239 sys32_pwrite (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
2240 {
2241         return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
2242 }
2243
2244 asmlinkage long
2245 sys32_sendfile (int out_fd, int in_fd, int __user *offset, unsigned int count)
2246 {
2247         mm_segment_t old_fs = get_fs();
2248         long ret;
2249         off_t of;
2250
2251         if (offset && get_user(of, offset))
2252                 return -EFAULT;
2253
2254         set_fs(KERNEL_DS);
2255         ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *) &of : NULL, count);
2256         set_fs(old_fs);
2257
2258         if (offset && put_user(of, offset))
2259                 return -EFAULT;
2260
2261         return ret;
2262 }
2263
2264 asmlinkage long
2265 sys32_personality (unsigned int personality)
2266 {
2267         long ret;
2268
2269         if (current->personality == PER_LINUX32 && personality == PER_LINUX)
2270                 personality = PER_LINUX32;
2271         ret = sys_personality(personality);
2272         if (ret == PER_LINUX32)
2273                 ret = PER_LINUX;
2274         return ret;
2275 }
2276
2277 asmlinkage unsigned long
2278 sys32_brk (unsigned int brk)
2279 {
2280         unsigned long ret, obrk;
2281         struct mm_struct *mm = current->mm;
2282
2283         obrk = mm->brk;
2284         ret = sys_brk(brk);
2285         if (ret < obrk)
2286                 clear_user(compat_ptr(ret), PAGE_ALIGN(ret) - ret);
2287         return ret;
2288 }
2289
2290 /* Structure for ia32 emulation on ia64 */
2291 struct epoll_event32
2292 {
2293         u32 events;
2294         u32 data[2];
2295 };
2296
2297 asmlinkage long
2298 sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 __user *event)
2299 {
2300         mm_segment_t old_fs = get_fs();
2301         struct epoll_event event64;
2302         int error;
2303         u32 data_halfword;
2304
2305         if (!access_ok(VERIFY_READ, event, sizeof(struct epoll_event32)))
2306                 return -EFAULT;
2307
2308         __get_user(event64.events, &event->events);
2309         __get_user(data_halfword, &event->data[0]);
2310         event64.data = data_halfword;
2311         __get_user(data_halfword, &event->data[1]);
2312         event64.data |= (u64)data_halfword << 32;
2313
2314         set_fs(KERNEL_DS);
2315         error = sys_epoll_ctl(epfd, op, fd, (struct epoll_event __user *) &event64);
2316         set_fs(old_fs);
2317
2318         return error;
2319 }
2320
2321 asmlinkage long
2322 sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents,
2323                  int timeout)
2324 {
2325         struct epoll_event *events64 = NULL;
2326         mm_segment_t old_fs = get_fs();
2327         int numevents, size;
2328         int evt_idx;
2329         int do_free_pages = 0;
2330
2331         if (maxevents <= 0) {
2332                 return -EINVAL;
2333         }
2334
2335         /* Verify that the area passed by the user is writeable */
2336         if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event32)))
2337                 return -EFAULT;
2338
2339         /*
2340          * Allocate space for the intermediate copy.  If the space needed
2341          * is large enough to cause kmalloc to fail, then try again with
2342          * __get_free_pages.
2343          */
2344         size = maxevents * sizeof(struct epoll_event);
2345         events64 = kmalloc(size, GFP_KERNEL);
2346         if (events64 == NULL) {
2347                 events64 = (struct epoll_event *)
2348                                 __get_free_pages(GFP_KERNEL, get_order(size));
2349                 if (events64 == NULL)
2350                         return -ENOMEM;
2351                 do_free_pages = 1;
2352         }
2353
2354         /* Do the system call */
2355         set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/
2356         numevents = sys_epoll_wait(epfd, (struct epoll_event __user *) events64,
2357                                    maxevents, timeout);
2358         set_fs(old_fs);
2359
2360         /* Don't modify userspace memory if we're returning an error */
2361         if (numevents > 0) {
2362                 /* Translate the 64-bit structures back into the 32-bit
2363                    structures */
2364                 for (evt_idx = 0; evt_idx < numevents; evt_idx++) {
2365                         __put_user(events64[evt_idx].events,
2366                                    &events[evt_idx].events);
2367                         __put_user((u32)events64[evt_idx].data,
2368                                    &events[evt_idx].data[0]);
2369                         __put_user((u32)(events64[evt_idx].data >> 32),
2370                                    &events[evt_idx].data[1]);
2371                 }
2372         }
2373
2374         if (do_free_pages)
2375                 free_pages((unsigned long) events64, get_order(size));
2376         else
2377                 kfree(events64);
2378         return numevents;
2379 }
2380
2381 /*
2382  * Get a yet unused TLS descriptor index.
2383  */
2384 static int
2385 get_free_idx (void)
2386 {
2387         struct thread_struct *t = &current->thread;
2388         int idx;
2389
2390         for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
2391                 if (desc_empty(t->tls_array + idx))
2392                         return idx + GDT_ENTRY_TLS_MIN;
2393         return -ESRCH;
2394 }
2395
2396 /*
2397  * Set a given TLS descriptor:
2398  */
2399 asmlinkage int
2400 sys32_set_thread_area (struct ia32_user_desc __user *u_info)
2401 {
2402         struct thread_struct *t = &current->thread;
2403         struct ia32_user_desc info;
2404         struct desc_struct *desc;
2405         int cpu, idx;
2406
2407         if (copy_from_user(&info, u_info, sizeof(info)))
2408                 return -EFAULT;
2409         idx = info.entry_number;
2410
2411         /*
2412          * index -1 means the kernel should try to find and allocate an empty descriptor:
2413          */
2414         if (idx == -1) {
2415                 idx = get_free_idx();
2416                 if (idx < 0)
2417                         return idx;
2418                 if (put_user(idx, &u_info->entry_number))
2419                         return -EFAULT;
2420         }
2421
2422         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2423                 return -EINVAL;
2424
2425         desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
2426
2427         cpu = smp_processor_id();
2428
2429         if (LDT_empty(&info)) {
2430                 desc->a = 0;
2431                 desc->b = 0;
2432         } else {
2433                 desc->a = LDT_entry_a(&info);
2434                 desc->b = LDT_entry_b(&info);
2435         }
2436         load_TLS(t, cpu);
2437         return 0;
2438 }
2439
2440 /*
2441  * Get the current Thread-Local Storage area:
2442  */
2443
2444 #define GET_BASE(desc) (                        \
2445         (((desc)->a >> 16) & 0x0000ffff) |      \
2446         (((desc)->b << 16) & 0x00ff0000) |      \
2447         ( (desc)->b        & 0xff000000)   )
2448
2449 #define GET_LIMIT(desc) (                       \
2450         ((desc)->a & 0x0ffff) |                 \
2451          ((desc)->b & 0xf0000) )
2452
2453 #define GET_32BIT(desc)         (((desc)->b >> 22) & 1)
2454 #define GET_CONTENTS(desc)      (((desc)->b >> 10) & 3)
2455 #define GET_WRITABLE(desc)      (((desc)->b >>  9) & 1)
2456 #define GET_LIMIT_PAGES(desc)   (((desc)->b >> 23) & 1)
2457 #define GET_PRESENT(desc)       (((desc)->b >> 15) & 1)
2458 #define GET_USEABLE(desc)       (((desc)->b >> 20) & 1)
2459
2460 asmlinkage int
2461 sys32_get_thread_area (struct ia32_user_desc __user *u_info)
2462 {
2463         struct ia32_user_desc info;
2464         struct desc_struct *desc;
2465         int idx;
2466
2467         if (get_user(idx, &u_info->entry_number))
2468                 return -EFAULT;
2469         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2470                 return -EINVAL;
2471
2472         desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
2473
2474         info.entry_number = idx;
2475         info.base_addr = GET_BASE(desc);
2476         info.limit = GET_LIMIT(desc);
2477         info.seg_32bit = GET_32BIT(desc);
2478         info.contents = GET_CONTENTS(desc);
2479         info.read_exec_only = !GET_WRITABLE(desc);
2480         info.limit_in_pages = GET_LIMIT_PAGES(desc);
2481         info.seg_not_present = !GET_PRESENT(desc);
2482         info.useable = GET_USEABLE(desc);
2483
2484         if (copy_to_user(u_info, &info, sizeof(info)))
2485                 return -EFAULT;
2486         return 0;
2487 }
2488
2489 long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, 
2490                         __u32 len_low, __u32 len_high, int advice)
2491
2492         return sys_fadvise64_64(fd,
2493                                (((u64)offset_high)<<32) | offset_low,
2494                                (((u64)len_high)<<32) | len_low,
2495                                advice); 
2496
2497
2498 #ifdef  NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
2499
2500 asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid)
2501 {
2502         uid_t sruid, seuid;
2503
2504         sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2505         seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
2506         return sys_setreuid(sruid, seuid);
2507 }
2508
2509 asmlinkage long
2510 sys32_setresuid(compat_uid_t ruid, compat_uid_t euid,
2511                 compat_uid_t suid)
2512 {
2513         uid_t sruid, seuid, ssuid;
2514
2515         sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2516         seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
2517         ssuid = (suid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)suid);
2518         return sys_setresuid(sruid, seuid, ssuid);
2519 }
2520
2521 asmlinkage long
2522 sys32_setregid(compat_gid_t rgid, compat_gid_t egid)
2523 {
2524         gid_t srgid, segid;
2525
2526         srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2527         segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
2528         return sys_setregid(srgid, segid);
2529 }
2530
2531 asmlinkage long
2532 sys32_setresgid(compat_gid_t rgid, compat_gid_t egid,
2533                 compat_gid_t sgid)
2534 {
2535         gid_t srgid, segid, ssgid;
2536
2537         srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2538         segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
2539         ssgid = (sgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)sgid);
2540         return sys_setresgid(srgid, segid, ssgid);
2541 }
2542 #endif /* NOTYET */