x86/smpboot: Init apic mapping before usage
[cascardo/linux.git] / fs / compat.c
1 /*
2  *  linux/fs/compat.c
3  *
4  *  Kernel compatibililty routines for e.g. 32 bit syscall support
5  *  on 64 bit kernels.
6  *
7  *  Copyright (C) 2002       Stephen Rothwell, IBM Corporation
8  *  Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
9  *  Copyright (C) 1998       Eddie C. Dost  (ecd@skynet.be)
10  *  Copyright (C) 2001,2002  Andi Kleen, SuSE Labs 
11  *  Copyright (C) 2003       Pavel Machek (pavel@ucw.cz)
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License version 2 as
15  *  published by the Free Software Foundation.
16  */
17
18 #include <linux/stddef.h>
19 #include <linux/kernel.h>
20 #include <linux/linkage.h>
21 #include <linux/compat.h>
22 #include <linux/errno.h>
23 #include <linux/time.h>
24 #include <linux/fs.h>
25 #include <linux/fcntl.h>
26 #include <linux/namei.h>
27 #include <linux/file.h>
28 #include <linux/fdtable.h>
29 #include <linux/vfs.h>
30 #include <linux/ioctl.h>
31 #include <linux/init.h>
32 #include <linux/ncp_mount.h>
33 #include <linux/nfs4_mount.h>
34 #include <linux/syscalls.h>
35 #include <linux/ctype.h>
36 #include <linux/dirent.h>
37 #include <linux/fsnotify.h>
38 #include <linux/highuid.h>
39 #include <linux/personality.h>
40 #include <linux/rwsem.h>
41 #include <linux/tsacct_kern.h>
42 #include <linux/security.h>
43 #include <linux/highmem.h>
44 #include <linux/signal.h>
45 #include <linux/poll.h>
46 #include <linux/mm.h>
47 #include <linux/fs_struct.h>
48 #include <linux/slab.h>
49 #include <linux/pagemap.h>
50 #include <linux/aio.h>
51
52 #include <asm/uaccess.h>
53 #include <asm/mmu_context.h>
54 #include <asm/ioctls.h>
55 #include "internal.h"
56
57 /*
58  * Not all architectures have sys_utime, so implement this in terms
59  * of sys_utimes.
60  */
61 COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,
62                        struct compat_utimbuf __user *, t)
63 {
64         struct timespec tv[2];
65
66         if (t) {
67                 if (get_user(tv[0].tv_sec, &t->actime) ||
68                     get_user(tv[1].tv_sec, &t->modtime))
69                         return -EFAULT;
70                 tv[0].tv_nsec = 0;
71                 tv[1].tv_nsec = 0;
72         }
73         return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0);
74 }
75
76 COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags)
77 {
78         struct timespec tv[2];
79
80         if  (t) {
81                 if (compat_get_timespec(&tv[0], &t[0]) ||
82                     compat_get_timespec(&tv[1], &t[1]))
83                         return -EFAULT;
84
85                 if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
86                         return 0;
87         }
88         return do_utimes(dfd, filename, t ? tv : NULL, flags);
89 }
90
91 COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t)
92 {
93         struct timespec tv[2];
94
95         if (t) {
96                 if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
97                     get_user(tv[0].tv_nsec, &t[0].tv_usec) ||
98                     get_user(tv[1].tv_sec, &t[1].tv_sec) ||
99                     get_user(tv[1].tv_nsec, &t[1].tv_usec))
100                         return -EFAULT;
101                 if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 ||
102                     tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0)
103                         return -EINVAL;
104                 tv[0].tv_nsec *= 1000;
105                 tv[1].tv_nsec *= 1000;
106         }
107         return do_utimes(dfd, filename, t ? tv : NULL, 0);
108 }
109
110 COMPAT_SYSCALL_DEFINE2(utimes, const char __user *, filename, struct compat_timeval __user *, t)
111 {
112         return compat_sys_futimesat(AT_FDCWD, filename, t);
113 }
114
115 static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
116 {
117         struct compat_stat tmp;
118
119         if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
120                 return -EOVERFLOW;
121
122         memset(&tmp, 0, sizeof(tmp));
123         tmp.st_dev = old_encode_dev(stat->dev);
124         tmp.st_ino = stat->ino;
125         if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
126                 return -EOVERFLOW;
127         tmp.st_mode = stat->mode;
128         tmp.st_nlink = stat->nlink;
129         if (tmp.st_nlink != stat->nlink)
130                 return -EOVERFLOW;
131         SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
132         SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
133         tmp.st_rdev = old_encode_dev(stat->rdev);
134         if ((u64) stat->size > MAX_NON_LFS)
135                 return -EOVERFLOW;
136         tmp.st_size = stat->size;
137         tmp.st_atime = stat->atime.tv_sec;
138         tmp.st_atime_nsec = stat->atime.tv_nsec;
139         tmp.st_mtime = stat->mtime.tv_sec;
140         tmp.st_mtime_nsec = stat->mtime.tv_nsec;
141         tmp.st_ctime = stat->ctime.tv_sec;
142         tmp.st_ctime_nsec = stat->ctime.tv_nsec;
143         tmp.st_blocks = stat->blocks;
144         tmp.st_blksize = stat->blksize;
145         return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
146 }
147
148 COMPAT_SYSCALL_DEFINE2(newstat, const char __user *, filename,
149                        struct compat_stat __user *, statbuf)
150 {
151         struct kstat stat;
152         int error;
153
154         error = vfs_stat(filename, &stat);
155         if (error)
156                 return error;
157         return cp_compat_stat(&stat, statbuf);
158 }
159
160 COMPAT_SYSCALL_DEFINE2(newlstat, const char __user *, filename,
161                        struct compat_stat __user *, statbuf)
162 {
163         struct kstat stat;
164         int error;
165
166         error = vfs_lstat(filename, &stat);
167         if (error)
168                 return error;
169         return cp_compat_stat(&stat, statbuf);
170 }
171
172 #ifndef __ARCH_WANT_STAT64
173 COMPAT_SYSCALL_DEFINE4(newfstatat, unsigned int, dfd,
174                        const char __user *, filename,
175                        struct compat_stat __user *, statbuf, int, flag)
176 {
177         struct kstat stat;
178         int error;
179
180         error = vfs_fstatat(dfd, filename, &stat, flag);
181         if (error)
182                 return error;
183         return cp_compat_stat(&stat, statbuf);
184 }
185 #endif
186
187 COMPAT_SYSCALL_DEFINE2(newfstat, unsigned int, fd,
188                        struct compat_stat __user *, statbuf)
189 {
190         struct kstat stat;
191         int error = vfs_fstat(fd, &stat);
192
193         if (!error)
194                 error = cp_compat_stat(&stat, statbuf);
195         return error;
196 }
197
198 static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *kbuf)
199 {
200         
201         if (sizeof ubuf->f_blocks == 4) {
202                 if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail |
203                      kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL)
204                         return -EOVERFLOW;
205                 /* f_files and f_ffree may be -1; it's okay
206                  * to stuff that into 32 bits */
207                 if (kbuf->f_files != 0xffffffffffffffffULL
208                  && (kbuf->f_files & 0xffffffff00000000ULL))
209                         return -EOVERFLOW;
210                 if (kbuf->f_ffree != 0xffffffffffffffffULL
211                  && (kbuf->f_ffree & 0xffffffff00000000ULL))
212                         return -EOVERFLOW;
213         }
214         if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
215             __put_user(kbuf->f_type, &ubuf->f_type) ||
216             __put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
217             __put_user(kbuf->f_blocks, &ubuf->f_blocks) ||
218             __put_user(kbuf->f_bfree, &ubuf->f_bfree) ||
219             __put_user(kbuf->f_bavail, &ubuf->f_bavail) ||
220             __put_user(kbuf->f_files, &ubuf->f_files) ||
221             __put_user(kbuf->f_ffree, &ubuf->f_ffree) ||
222             __put_user(kbuf->f_namelen, &ubuf->f_namelen) ||
223             __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
224             __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) ||
225             __put_user(kbuf->f_frsize, &ubuf->f_frsize) ||
226             __put_user(kbuf->f_flags, &ubuf->f_flags) ||
227             __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare)))
228                 return -EFAULT;
229         return 0;
230 }
231
232 /*
233  * The following statfs calls are copies of code from fs/statfs.c and
234  * should be checked against those from time to time
235  */
236 COMPAT_SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct compat_statfs __user *, buf)
237 {
238         struct kstatfs tmp;
239         int error = user_statfs(pathname, &tmp);
240         if (!error)
241                 error = put_compat_statfs(buf, &tmp);
242         return error;
243 }
244
245 COMPAT_SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct compat_statfs __user *, buf)
246 {
247         struct kstatfs tmp;
248         int error = fd_statfs(fd, &tmp);
249         if (!error)
250                 error = put_compat_statfs(buf, &tmp);
251         return error;
252 }
253
254 static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf)
255 {
256         if (sizeof ubuf->f_blocks == 4) {
257                 if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail |
258                      kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL)
259                         return -EOVERFLOW;
260                 /* f_files and f_ffree may be -1; it's okay
261                  * to stuff that into 32 bits */
262                 if (kbuf->f_files != 0xffffffffffffffffULL
263                  && (kbuf->f_files & 0xffffffff00000000ULL))
264                         return -EOVERFLOW;
265                 if (kbuf->f_ffree != 0xffffffffffffffffULL
266                  && (kbuf->f_ffree & 0xffffffff00000000ULL))
267                         return -EOVERFLOW;
268         }
269         if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
270             __put_user(kbuf->f_type, &ubuf->f_type) ||
271             __put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
272             __put_user(kbuf->f_blocks, &ubuf->f_blocks) ||
273             __put_user(kbuf->f_bfree, &ubuf->f_bfree) ||
274             __put_user(kbuf->f_bavail, &ubuf->f_bavail) ||
275             __put_user(kbuf->f_files, &ubuf->f_files) ||
276             __put_user(kbuf->f_ffree, &ubuf->f_ffree) ||
277             __put_user(kbuf->f_namelen, &ubuf->f_namelen) ||
278             __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
279             __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) ||
280             __put_user(kbuf->f_frsize, &ubuf->f_frsize) ||
281             __put_user(kbuf->f_flags, &ubuf->f_flags) ||
282             __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare)))
283                 return -EFAULT;
284         return 0;
285 }
286
287 COMPAT_SYSCALL_DEFINE3(statfs64, const char __user *, pathname, compat_size_t, sz, struct compat_statfs64 __user *, buf)
288 {
289         struct kstatfs tmp;
290         int error;
291
292         if (sz != sizeof(*buf))
293                 return -EINVAL;
294
295         error = user_statfs(pathname, &tmp);
296         if (!error)
297                 error = put_compat_statfs64(buf, &tmp);
298         return error;
299 }
300
301 COMPAT_SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, compat_size_t, sz, struct compat_statfs64 __user *, buf)
302 {
303         struct kstatfs tmp;
304         int error;
305
306         if (sz != sizeof(*buf))
307                 return -EINVAL;
308
309         error = fd_statfs(fd, &tmp);
310         if (!error)
311                 error = put_compat_statfs64(buf, &tmp);
312         return error;
313 }
314
315 /*
316  * This is a copy of sys_ustat, just dealing with a structure layout.
317  * Given how simple this syscall is that apporach is more maintainable
318  * than the various conversion hacks.
319  */
320 COMPAT_SYSCALL_DEFINE2(ustat, unsigned, dev, struct compat_ustat __user *, u)
321 {
322         struct compat_ustat tmp;
323         struct kstatfs sbuf;
324         int err = vfs_ustat(new_decode_dev(dev), &sbuf);
325         if (err)
326                 return err;
327
328         memset(&tmp, 0, sizeof(struct compat_ustat));
329         tmp.f_tfree = sbuf.f_bfree;
330         tmp.f_tinode = sbuf.f_ffree;
331         if (copy_to_user(u, &tmp, sizeof(struct compat_ustat)))
332                 return -EFAULT;
333         return 0;
334 }
335
336 static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl)
337 {
338         if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) ||
339             __get_user(kfl->l_type, &ufl->l_type) ||
340             __get_user(kfl->l_whence, &ufl->l_whence) ||
341             __get_user(kfl->l_start, &ufl->l_start) ||
342             __get_user(kfl->l_len, &ufl->l_len) ||
343             __get_user(kfl->l_pid, &ufl->l_pid))
344                 return -EFAULT;
345         return 0;
346 }
347
348 static int put_compat_flock(struct flock *kfl, struct compat_flock __user *ufl)
349 {
350         if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) ||
351             __put_user(kfl->l_type, &ufl->l_type) ||
352             __put_user(kfl->l_whence, &ufl->l_whence) ||
353             __put_user(kfl->l_start, &ufl->l_start) ||
354             __put_user(kfl->l_len, &ufl->l_len) ||
355             __put_user(kfl->l_pid, &ufl->l_pid))
356                 return -EFAULT;
357         return 0;
358 }
359
360 #ifndef HAVE_ARCH_GET_COMPAT_FLOCK64
361 static int get_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl)
362 {
363         if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) ||
364             __get_user(kfl->l_type, &ufl->l_type) ||
365             __get_user(kfl->l_whence, &ufl->l_whence) ||
366             __get_user(kfl->l_start, &ufl->l_start) ||
367             __get_user(kfl->l_len, &ufl->l_len) ||
368             __get_user(kfl->l_pid, &ufl->l_pid))
369                 return -EFAULT;
370         return 0;
371 }
372 #endif
373
374 #ifndef HAVE_ARCH_PUT_COMPAT_FLOCK64
375 static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl)
376 {
377         if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) ||
378             __put_user(kfl->l_type, &ufl->l_type) ||
379             __put_user(kfl->l_whence, &ufl->l_whence) ||
380             __put_user(kfl->l_start, &ufl->l_start) ||
381             __put_user(kfl->l_len, &ufl->l_len) ||
382             __put_user(kfl->l_pid, &ufl->l_pid))
383                 return -EFAULT;
384         return 0;
385 }
386 #endif
387
388 static unsigned int
389 convert_fcntl_cmd(unsigned int cmd)
390 {
391         switch (cmd) {
392         case F_GETLK64:
393                 return F_GETLK;
394         case F_SETLK64:
395                 return F_SETLK;
396         case F_SETLKW64:
397                 return F_SETLKW;
398         }
399
400         return cmd;
401 }
402
403 COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
404                        compat_ulong_t, arg)
405 {
406         mm_segment_t old_fs;
407         struct flock f;
408         long ret;
409         unsigned int conv_cmd;
410
411         switch (cmd) {
412         case F_GETLK:
413         case F_SETLK:
414         case F_SETLKW:
415                 ret = get_compat_flock(&f, compat_ptr(arg));
416                 if (ret != 0)
417                         break;
418                 old_fs = get_fs();
419                 set_fs(KERNEL_DS);
420                 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
421                 set_fs(old_fs);
422                 if (cmd == F_GETLK && ret == 0) {
423                         /* GETLK was successful and we need to return the data...
424                          * but it needs to fit in the compat structure.
425                          * l_start shouldn't be too big, unless the original
426                          * start + end is greater than COMPAT_OFF_T_MAX, in which
427                          * case the app was asking for trouble, so we return
428                          * -EOVERFLOW in that case.
429                          * l_len could be too big, in which case we just truncate it,
430                          * and only allow the app to see that part of the conflicting
431                          * lock that might make sense to it anyway
432                          */
433
434                         if (f.l_start > COMPAT_OFF_T_MAX)
435                                 ret = -EOVERFLOW;
436                         if (f.l_len > COMPAT_OFF_T_MAX)
437                                 f.l_len = COMPAT_OFF_T_MAX;
438                         if (ret == 0)
439                                 ret = put_compat_flock(&f, compat_ptr(arg));
440                 }
441                 break;
442
443         case F_GETLK64:
444         case F_SETLK64:
445         case F_SETLKW64:
446         case F_OFD_GETLK:
447         case F_OFD_SETLK:
448         case F_OFD_SETLKW:
449                 ret = get_compat_flock64(&f, compat_ptr(arg));
450                 if (ret != 0)
451                         break;
452                 old_fs = get_fs();
453                 set_fs(KERNEL_DS);
454                 conv_cmd = convert_fcntl_cmd(cmd);
455                 ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f);
456                 set_fs(old_fs);
457                 if ((conv_cmd == F_GETLK || conv_cmd == F_OFD_GETLK) && ret == 0) {
458                         /* need to return lock information - see above for commentary */
459                         if (f.l_start > COMPAT_LOFF_T_MAX)
460                                 ret = -EOVERFLOW;
461                         if (f.l_len > COMPAT_LOFF_T_MAX)
462                                 f.l_len = COMPAT_LOFF_T_MAX;
463                         if (ret == 0)
464                                 ret = put_compat_flock64(&f, compat_ptr(arg));
465                 }
466                 break;
467
468         default:
469                 ret = sys_fcntl(fd, cmd, arg);
470                 break;
471         }
472         return ret;
473 }
474
475 COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd,
476                        compat_ulong_t, arg)
477 {
478         switch (cmd) {
479         case F_GETLK64:
480         case F_SETLK64:
481         case F_SETLKW64:
482         case F_OFD_GETLK:
483         case F_OFD_SETLK:
484         case F_OFD_SETLKW:
485                 return -EINVAL;
486         }
487         return compat_sys_fcntl64(fd, cmd, arg);
488 }
489
490 COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_reqs, u32 __user *, ctx32p)
491 {
492         long ret;
493         aio_context_t ctx64;
494
495         mm_segment_t oldfs = get_fs();
496         if (unlikely(get_user(ctx64, ctx32p)))
497                 return -EFAULT;
498
499         set_fs(KERNEL_DS);
500         /* The __user pointer cast is valid because of the set_fs() */
501         ret = sys_io_setup(nr_reqs, (aio_context_t __user *) &ctx64);
502         set_fs(oldfs);
503         /* truncating is ok because it's a user address */
504         if (!ret)
505                 ret = put_user((u32) ctx64, ctx32p);
506         return ret;
507 }
508
509 COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
510                        compat_long_t, min_nr,
511                        compat_long_t, nr,
512                        struct io_event __user *, events,
513                        struct compat_timespec __user *, timeout)
514 {
515         struct timespec t;
516         struct timespec __user *ut = NULL;
517
518         if (timeout) {
519                 if (compat_get_timespec(&t, timeout))
520                         return -EFAULT;
521
522                 ut = compat_alloc_user_space(sizeof(*ut));
523                 if (copy_to_user(ut, &t, sizeof(t)) )
524                         return -EFAULT;
525         } 
526         return sys_io_getevents(ctx_id, min_nr, nr, events, ut);
527 }
528
529 /* A write operation does a read from user space and vice versa */
530 #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
531
532 ssize_t compat_rw_copy_check_uvector(int type,
533                 const struct compat_iovec __user *uvector, unsigned long nr_segs,
534                 unsigned long fast_segs, struct iovec *fast_pointer,
535                 struct iovec **ret_pointer)
536 {
537         compat_ssize_t tot_len;
538         struct iovec *iov = *ret_pointer = fast_pointer;
539         ssize_t ret = 0;
540         int seg;
541
542         /*
543          * SuS says "The readv() function *may* fail if the iovcnt argument
544          * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
545          * traditionally returned zero for zero segments, so...
546          */
547         if (nr_segs == 0)
548                 goto out;
549
550         ret = -EINVAL;
551         if (nr_segs > UIO_MAXIOV)
552                 goto out;
553         if (nr_segs > fast_segs) {
554                 ret = -ENOMEM;
555                 iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
556                 if (iov == NULL)
557                         goto out;
558         }
559         *ret_pointer = iov;
560
561         ret = -EFAULT;
562         if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
563                 goto out;
564
565         /*
566          * Single unix specification:
567          * We should -EINVAL if an element length is not >= 0 and fitting an
568          * ssize_t.
569          *
570          * In Linux, the total length is limited to MAX_RW_COUNT, there is
571          * no overflow possibility.
572          */
573         tot_len = 0;
574         ret = -EINVAL;
575         for (seg = 0; seg < nr_segs; seg++) {
576                 compat_uptr_t buf;
577                 compat_ssize_t len;
578
579                 if (__get_user(len, &uvector->iov_len) ||
580                    __get_user(buf, &uvector->iov_base)) {
581                         ret = -EFAULT;
582                         goto out;
583                 }
584                 if (len < 0)    /* size_t not fitting in compat_ssize_t .. */
585                         goto out;
586                 if (type >= 0 &&
587                     !access_ok(vrfy_dir(type), compat_ptr(buf), len)) {
588                         ret = -EFAULT;
589                         goto out;
590                 }
591                 if (len > MAX_RW_COUNT - tot_len)
592                         len = MAX_RW_COUNT - tot_len;
593                 tot_len += len;
594                 iov->iov_base = compat_ptr(buf);
595                 iov->iov_len = (compat_size_t) len;
596                 uvector++;
597                 iov++;
598         }
599         ret = tot_len;
600
601 out:
602         return ret;
603 }
604
605 static inline long
606 copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64)
607 {
608         compat_uptr_t uptr;
609         int i;
610
611         for (i = 0; i < nr; ++i) {
612                 if (get_user(uptr, ptr32 + i))
613                         return -EFAULT;
614                 if (put_user(compat_ptr(uptr), ptr64 + i))
615                         return -EFAULT;
616         }
617         return 0;
618 }
619
620 #define MAX_AIO_SUBMITS         (PAGE_SIZE/sizeof(struct iocb *))
621
622 COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id,
623                        int, nr, u32 __user *, iocb)
624 {
625         struct iocb __user * __user *iocb64; 
626         long ret;
627
628         if (unlikely(nr < 0))
629                 return -EINVAL;
630
631         if (nr > MAX_AIO_SUBMITS)
632                 nr = MAX_AIO_SUBMITS;
633         
634         iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64));
635         ret = copy_iocb(nr, iocb, iocb64);
636         if (!ret)
637                 ret = do_io_submit(ctx_id, nr, iocb64, 1);
638         return ret;
639 }
640
641 struct compat_ncp_mount_data {
642         compat_int_t version;
643         compat_uint_t ncp_fd;
644         __compat_uid_t mounted_uid;
645         compat_pid_t wdog_pid;
646         unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
647         compat_uint_t time_out;
648         compat_uint_t retry_count;
649         compat_uint_t flags;
650         __compat_uid_t uid;
651         __compat_gid_t gid;
652         compat_mode_t file_mode;
653         compat_mode_t dir_mode;
654 };
655
656 struct compat_ncp_mount_data_v4 {
657         compat_int_t version;
658         compat_ulong_t flags;
659         compat_ulong_t mounted_uid;
660         compat_long_t wdog_pid;
661         compat_uint_t ncp_fd;
662         compat_uint_t time_out;
663         compat_uint_t retry_count;
664         compat_ulong_t uid;
665         compat_ulong_t gid;
666         compat_ulong_t file_mode;
667         compat_ulong_t dir_mode;
668 };
669
670 static void *do_ncp_super_data_conv(void *raw_data)
671 {
672         int version = *(unsigned int *)raw_data;
673
674         if (version == 3) {
675                 struct compat_ncp_mount_data *c_n = raw_data;
676                 struct ncp_mount_data *n = raw_data;
677
678                 n->dir_mode = c_n->dir_mode;
679                 n->file_mode = c_n->file_mode;
680                 n->gid = c_n->gid;
681                 n->uid = c_n->uid;
682                 memmove (n->mounted_vol, c_n->mounted_vol, (sizeof (c_n->mounted_vol) + 3 * sizeof (unsigned int)));
683                 n->wdog_pid = c_n->wdog_pid;
684                 n->mounted_uid = c_n->mounted_uid;
685         } else if (version == 4) {
686                 struct compat_ncp_mount_data_v4 *c_n = raw_data;
687                 struct ncp_mount_data_v4 *n = raw_data;
688
689                 n->dir_mode = c_n->dir_mode;
690                 n->file_mode = c_n->file_mode;
691                 n->gid = c_n->gid;
692                 n->uid = c_n->uid;
693                 n->retry_count = c_n->retry_count;
694                 n->time_out = c_n->time_out;
695                 n->ncp_fd = c_n->ncp_fd;
696                 n->wdog_pid = c_n->wdog_pid;
697                 n->mounted_uid = c_n->mounted_uid;
698                 n->flags = c_n->flags;
699         } else if (version != 5) {
700                 return NULL;
701         }
702
703         return raw_data;
704 }
705
706
707 struct compat_nfs_string {
708         compat_uint_t len;
709         compat_uptr_t data;
710 };
711
712 static inline void compat_nfs_string(struct nfs_string *dst,
713                                      struct compat_nfs_string *src)
714 {
715         dst->data = compat_ptr(src->data);
716         dst->len = src->len;
717 }
718
719 struct compat_nfs4_mount_data_v1 {
720         compat_int_t version;
721         compat_int_t flags;
722         compat_int_t rsize;
723         compat_int_t wsize;
724         compat_int_t timeo;
725         compat_int_t retrans;
726         compat_int_t acregmin;
727         compat_int_t acregmax;
728         compat_int_t acdirmin;
729         compat_int_t acdirmax;
730         struct compat_nfs_string client_addr;
731         struct compat_nfs_string mnt_path;
732         struct compat_nfs_string hostname;
733         compat_uint_t host_addrlen;
734         compat_uptr_t host_addr;
735         compat_int_t proto;
736         compat_int_t auth_flavourlen;
737         compat_uptr_t auth_flavours;
738 };
739
740 static int do_nfs4_super_data_conv(void *raw_data)
741 {
742         int version = *(compat_uint_t *) raw_data;
743
744         if (version == 1) {
745                 struct compat_nfs4_mount_data_v1 *raw = raw_data;
746                 struct nfs4_mount_data *real = raw_data;
747
748                 /* copy the fields backwards */
749                 real->auth_flavours = compat_ptr(raw->auth_flavours);
750                 real->auth_flavourlen = raw->auth_flavourlen;
751                 real->proto = raw->proto;
752                 real->host_addr = compat_ptr(raw->host_addr);
753                 real->host_addrlen = raw->host_addrlen;
754                 compat_nfs_string(&real->hostname, &raw->hostname);
755                 compat_nfs_string(&real->mnt_path, &raw->mnt_path);
756                 compat_nfs_string(&real->client_addr, &raw->client_addr);
757                 real->acdirmax = raw->acdirmax;
758                 real->acdirmin = raw->acdirmin;
759                 real->acregmax = raw->acregmax;
760                 real->acregmin = raw->acregmin;
761                 real->retrans = raw->retrans;
762                 real->timeo = raw->timeo;
763                 real->wsize = raw->wsize;
764                 real->rsize = raw->rsize;
765                 real->flags = raw->flags;
766                 real->version = raw->version;
767         }
768
769         return 0;
770 }
771
772 #define NCPFS_NAME      "ncpfs"
773 #define NFS4_NAME       "nfs4"
774
775 COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
776                        const char __user *, dir_name,
777                        const char __user *, type, compat_ulong_t, flags,
778                        const void __user *, data)
779 {
780         char *kernel_type;
781         void *options;
782         char *kernel_dev;
783         int retval;
784
785         kernel_type = copy_mount_string(type);
786         retval = PTR_ERR(kernel_type);
787         if (IS_ERR(kernel_type))
788                 goto out;
789
790         kernel_dev = copy_mount_string(dev_name);
791         retval = PTR_ERR(kernel_dev);
792         if (IS_ERR(kernel_dev))
793                 goto out1;
794
795         options = copy_mount_options(data);
796         retval = PTR_ERR(options);
797         if (IS_ERR(options))
798                 goto out2;
799
800         if (kernel_type && options) {
801                 if (!strcmp(kernel_type, NCPFS_NAME)) {
802                         do_ncp_super_data_conv(options);
803                 } else if (!strcmp(kernel_type, NFS4_NAME)) {
804                         retval = -EINVAL;
805                         if (do_nfs4_super_data_conv(options))
806                                 goto out3;
807                 }
808         }
809
810         retval = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
811
812  out3:
813         kfree(options);
814  out2:
815         kfree(kernel_dev);
816  out1:
817         kfree(kernel_type);
818  out:
819         return retval;
820 }
821
822 struct compat_old_linux_dirent {
823         compat_ulong_t  d_ino;
824         compat_ulong_t  d_offset;
825         unsigned short  d_namlen;
826         char            d_name[1];
827 };
828
829 struct compat_readdir_callback {
830         struct dir_context ctx;
831         struct compat_old_linux_dirent __user *dirent;
832         int result;
833 };
834
835 static int compat_fillonedir(struct dir_context *ctx, const char *name,
836                              int namlen, loff_t offset, u64 ino,
837                              unsigned int d_type)
838 {
839         struct compat_readdir_callback *buf =
840                 container_of(ctx, struct compat_readdir_callback, ctx);
841         struct compat_old_linux_dirent __user *dirent;
842         compat_ulong_t d_ino;
843
844         if (buf->result)
845                 return -EINVAL;
846         d_ino = ino;
847         if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
848                 buf->result = -EOVERFLOW;
849                 return -EOVERFLOW;
850         }
851         buf->result++;
852         dirent = buf->dirent;
853         if (!access_ok(VERIFY_WRITE, dirent,
854                         (unsigned long)(dirent->d_name + namlen + 1) -
855                                 (unsigned long)dirent))
856                 goto efault;
857         if (    __put_user(d_ino, &dirent->d_ino) ||
858                 __put_user(offset, &dirent->d_offset) ||
859                 __put_user(namlen, &dirent->d_namlen) ||
860                 __copy_to_user(dirent->d_name, name, namlen) ||
861                 __put_user(0, dirent->d_name + namlen))
862                 goto efault;
863         return 0;
864 efault:
865         buf->result = -EFAULT;
866         return -EFAULT;
867 }
868
869 COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
870                 struct compat_old_linux_dirent __user *, dirent, unsigned int, count)
871 {
872         int error;
873         struct fd f = fdget_pos(fd);
874         struct compat_readdir_callback buf = {
875                 .ctx.actor = compat_fillonedir,
876                 .dirent = dirent
877         };
878
879         if (!f.file)
880                 return -EBADF;
881
882         error = iterate_dir(f.file, &buf.ctx);
883         if (buf.result)
884                 error = buf.result;
885
886         fdput_pos(f);
887         return error;
888 }
889
890 struct compat_linux_dirent {
891         compat_ulong_t  d_ino;
892         compat_ulong_t  d_off;
893         unsigned short  d_reclen;
894         char            d_name[1];
895 };
896
897 struct compat_getdents_callback {
898         struct dir_context ctx;
899         struct compat_linux_dirent __user *current_dir;
900         struct compat_linux_dirent __user *previous;
901         int count;
902         int error;
903 };
904
905 static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
906                 loff_t offset, u64 ino, unsigned int d_type)
907 {
908         struct compat_linux_dirent __user * dirent;
909         struct compat_getdents_callback *buf =
910                 container_of(ctx, struct compat_getdents_callback, ctx);
911         compat_ulong_t d_ino;
912         int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) +
913                 namlen + 2, sizeof(compat_long_t));
914
915         buf->error = -EINVAL;   /* only used if we fail.. */
916         if (reclen > buf->count)
917                 return -EINVAL;
918         d_ino = ino;
919         if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
920                 buf->error = -EOVERFLOW;
921                 return -EOVERFLOW;
922         }
923         dirent = buf->previous;
924         if (dirent) {
925                 if (signal_pending(current))
926                         return -EINTR;
927                 if (__put_user(offset, &dirent->d_off))
928                         goto efault;
929         }
930         dirent = buf->current_dir;
931         if (__put_user(d_ino, &dirent->d_ino))
932                 goto efault;
933         if (__put_user(reclen, &dirent->d_reclen))
934                 goto efault;
935         if (copy_to_user(dirent->d_name, name, namlen))
936                 goto efault;
937         if (__put_user(0, dirent->d_name + namlen))
938                 goto efault;
939         if (__put_user(d_type, (char  __user *) dirent + reclen - 1))
940                 goto efault;
941         buf->previous = dirent;
942         dirent = (void __user *)dirent + reclen;
943         buf->current_dir = dirent;
944         buf->count -= reclen;
945         return 0;
946 efault:
947         buf->error = -EFAULT;
948         return -EFAULT;
949 }
950
951 COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
952                 struct compat_linux_dirent __user *, dirent, unsigned int, count)
953 {
954         struct fd f;
955         struct compat_linux_dirent __user * lastdirent;
956         struct compat_getdents_callback buf = {
957                 .ctx.actor = compat_filldir,
958                 .current_dir = dirent,
959                 .count = count
960         };
961         int error;
962
963         if (!access_ok(VERIFY_WRITE, dirent, count))
964                 return -EFAULT;
965
966         f = fdget_pos(fd);
967         if (!f.file)
968                 return -EBADF;
969
970         error = iterate_dir(f.file, &buf.ctx);
971         if (error >= 0)
972                 error = buf.error;
973         lastdirent = buf.previous;
974         if (lastdirent) {
975                 if (put_user(buf.ctx.pos, &lastdirent->d_off))
976                         error = -EFAULT;
977                 else
978                         error = count - buf.count;
979         }
980         fdput_pos(f);
981         return error;
982 }
983
984 #ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64
985
986 struct compat_getdents_callback64 {
987         struct dir_context ctx;
988         struct linux_dirent64 __user *current_dir;
989         struct linux_dirent64 __user *previous;
990         int count;
991         int error;
992 };
993
994 static int compat_filldir64(struct dir_context *ctx, const char *name,
995                             int namlen, loff_t offset, u64 ino,
996                             unsigned int d_type)
997 {
998         struct linux_dirent64 __user *dirent;
999         struct compat_getdents_callback64 *buf =
1000                 container_of(ctx, struct compat_getdents_callback64, ctx);
1001         int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1,
1002                 sizeof(u64));
1003         u64 off;
1004
1005         buf->error = -EINVAL;   /* only used if we fail.. */
1006         if (reclen > buf->count)
1007                 return -EINVAL;
1008         dirent = buf->previous;
1009
1010         if (dirent) {
1011                 if (signal_pending(current))
1012                         return -EINTR;
1013                 if (__put_user_unaligned(offset, &dirent->d_off))
1014                         goto efault;
1015         }
1016         dirent = buf->current_dir;
1017         if (__put_user_unaligned(ino, &dirent->d_ino))
1018                 goto efault;
1019         off = 0;
1020         if (__put_user_unaligned(off, &dirent->d_off))
1021                 goto efault;
1022         if (__put_user(reclen, &dirent->d_reclen))
1023                 goto efault;
1024         if (__put_user(d_type, &dirent->d_type))
1025                 goto efault;
1026         if (copy_to_user(dirent->d_name, name, namlen))
1027                 goto efault;
1028         if (__put_user(0, dirent->d_name + namlen))
1029                 goto efault;
1030         buf->previous = dirent;
1031         dirent = (void __user *)dirent + reclen;
1032         buf->current_dir = dirent;
1033         buf->count -= reclen;
1034         return 0;
1035 efault:
1036         buf->error = -EFAULT;
1037         return -EFAULT;
1038 }
1039
1040 COMPAT_SYSCALL_DEFINE3(getdents64, unsigned int, fd,
1041                 struct linux_dirent64 __user *, dirent, unsigned int, count)
1042 {
1043         struct fd f;
1044         struct linux_dirent64 __user * lastdirent;
1045         struct compat_getdents_callback64 buf = {
1046                 .ctx.actor = compat_filldir64,
1047                 .current_dir = dirent,
1048                 .count = count
1049         };
1050         int error;
1051
1052         if (!access_ok(VERIFY_WRITE, dirent, count))
1053                 return -EFAULT;
1054
1055         f = fdget_pos(fd);
1056         if (!f.file)
1057                 return -EBADF;
1058
1059         error = iterate_dir(f.file, &buf.ctx);
1060         if (error >= 0)
1061                 error = buf.error;
1062         lastdirent = buf.previous;
1063         if (lastdirent) {
1064                 typeof(lastdirent->d_off) d_off = buf.ctx.pos;
1065                 if (__put_user_unaligned(d_off, &lastdirent->d_off))
1066                         error = -EFAULT;
1067                 else
1068                         error = count - buf.count;
1069         }
1070         fdput_pos(f);
1071         return error;
1072 }
1073 #endif /* __ARCH_WANT_COMPAT_SYS_GETDENTS64 */
1074
1075 /*
1076  * Exactly like fs/open.c:sys_open(), except that it doesn't set the
1077  * O_LARGEFILE flag.
1078  */
1079 COMPAT_SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
1080 {
1081         return do_sys_open(AT_FDCWD, filename, flags, mode);
1082 }
1083
1084 /*
1085  * Exactly like fs/open.c:sys_openat(), except that it doesn't set the
1086  * O_LARGEFILE flag.
1087  */
1088 COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode)
1089 {
1090         return do_sys_open(dfd, filename, flags, mode);
1091 }
1092
1093 #define __COMPAT_NFDBITS       (8 * sizeof(compat_ulong_t))
1094
1095 static int poll_select_copy_remaining(struct timespec *end_time, void __user *p,
1096                                       int timeval, int ret)
1097 {
1098         struct timespec ts;
1099
1100         if (!p)
1101                 return ret;
1102
1103         if (current->personality & STICKY_TIMEOUTS)
1104                 goto sticky;
1105
1106         /* No update for zero timeout */
1107         if (!end_time->tv_sec && !end_time->tv_nsec)
1108                 return ret;
1109
1110         ktime_get_ts(&ts);
1111         ts = timespec_sub(*end_time, ts);
1112         if (ts.tv_sec < 0)
1113                 ts.tv_sec = ts.tv_nsec = 0;
1114
1115         if (timeval) {
1116                 struct compat_timeval rtv;
1117
1118                 rtv.tv_sec = ts.tv_sec;
1119                 rtv.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
1120
1121                 if (!copy_to_user(p, &rtv, sizeof(rtv)))
1122                         return ret;
1123         } else {
1124                 struct compat_timespec rts;
1125
1126                 rts.tv_sec = ts.tv_sec;
1127                 rts.tv_nsec = ts.tv_nsec;
1128
1129                 if (!copy_to_user(p, &rts, sizeof(rts)))
1130                         return ret;
1131         }
1132         /*
1133          * If an application puts its timeval in read-only memory, we
1134          * don't want the Linux-specific update to the timeval to
1135          * cause a fault after the select has completed
1136          * successfully. However, because we're not updating the
1137          * timeval, we can't restart the system call.
1138          */
1139
1140 sticky:
1141         if (ret == -ERESTARTNOHAND)
1142                 ret = -EINTR;
1143         return ret;
1144 }
1145
1146 /*
1147  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
1148  * 64-bit unsigned longs.
1149  */
1150 static
1151 int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1152                         unsigned long *fdset)
1153 {
1154         nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
1155         if (ufdset) {
1156                 unsigned long odd;
1157
1158                 if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t)))
1159                         return -EFAULT;
1160
1161                 odd = nr & 1UL;
1162                 nr &= ~1UL;
1163                 while (nr) {
1164                         unsigned long h, l;
1165                         if (__get_user(l, ufdset) || __get_user(h, ufdset+1))
1166                                 return -EFAULT;
1167                         ufdset += 2;
1168                         *fdset++ = h << 32 | l;
1169                         nr -= 2;
1170                 }
1171                 if (odd && __get_user(*fdset, ufdset))
1172                         return -EFAULT;
1173         } else {
1174                 /* Tricky, must clear full unsigned long in the
1175                  * kernel fdset at the end, this makes sure that
1176                  * actually happens.
1177                  */
1178                 memset(fdset, 0, ((nr + 1) & ~1)*sizeof(compat_ulong_t));
1179         }
1180         return 0;
1181 }
1182
1183 static
1184 int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1185                       unsigned long *fdset)
1186 {
1187         unsigned long odd;
1188         nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
1189
1190         if (!ufdset)
1191                 return 0;
1192
1193         odd = nr & 1UL;
1194         nr &= ~1UL;
1195         while (nr) {
1196                 unsigned long h, l;
1197                 l = *fdset++;
1198                 h = l >> 32;
1199                 if (__put_user(l, ufdset) || __put_user(h, ufdset+1))
1200                         return -EFAULT;
1201                 ufdset += 2;
1202                 nr -= 2;
1203         }
1204         if (odd && __put_user(*fdset, ufdset))
1205                 return -EFAULT;
1206         return 0;
1207 }
1208
1209
1210 /*
1211  * This is a virtual copy of sys_select from fs/select.c and probably
1212  * should be compared to it from time to time
1213  */
1214
1215 /*
1216  * We can actually return ERESTARTSYS instead of EINTR, but I'd
1217  * like to be certain this leads to no problems. So I return
1218  * EINTR just for safety.
1219  *
1220  * Update: ERESTARTSYS breaks at least the xview clock binary, so
1221  * I'm trying ERESTARTNOHAND which restart only when you want to.
1222  */
1223 int compat_core_sys_select(int n, compat_ulong_t __user *inp,
1224         compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1225         struct timespec *end_time)
1226 {
1227         fd_set_bits fds;
1228         void *bits;
1229         int size, max_fds, ret = -EINVAL;
1230         struct fdtable *fdt;
1231         long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
1232
1233         if (n < 0)
1234                 goto out_nofds;
1235
1236         /* max_fds can increase, so grab it once to avoid race */
1237         rcu_read_lock();
1238         fdt = files_fdtable(current->files);
1239         max_fds = fdt->max_fds;
1240         rcu_read_unlock();
1241         if (n > max_fds)
1242                 n = max_fds;
1243
1244         /*
1245          * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1246          * since we used fdset we need to allocate memory in units of
1247          * long-words.
1248          */
1249         size = FDS_BYTES(n);
1250         bits = stack_fds;
1251         if (size > sizeof(stack_fds) / 6) {
1252                 bits = kmalloc(6 * size, GFP_KERNEL);
1253                 ret = -ENOMEM;
1254                 if (!bits)
1255                         goto out_nofds;
1256         }
1257         fds.in      = (unsigned long *)  bits;
1258         fds.out     = (unsigned long *) (bits +   size);
1259         fds.ex      = (unsigned long *) (bits + 2*size);
1260         fds.res_in  = (unsigned long *) (bits + 3*size);
1261         fds.res_out = (unsigned long *) (bits + 4*size);
1262         fds.res_ex  = (unsigned long *) (bits + 5*size);
1263
1264         if ((ret = compat_get_fd_set(n, inp, fds.in)) ||
1265             (ret = compat_get_fd_set(n, outp, fds.out)) ||
1266             (ret = compat_get_fd_set(n, exp, fds.ex)))
1267                 goto out;
1268         zero_fd_set(n, fds.res_in);
1269         zero_fd_set(n, fds.res_out);
1270         zero_fd_set(n, fds.res_ex);
1271
1272         ret = do_select(n, &fds, end_time);
1273
1274         if (ret < 0)
1275                 goto out;
1276         if (!ret) {
1277                 ret = -ERESTARTNOHAND;
1278                 if (signal_pending(current))
1279                         goto out;
1280                 ret = 0;
1281         }
1282
1283         if (compat_set_fd_set(n, inp, fds.res_in) ||
1284             compat_set_fd_set(n, outp, fds.res_out) ||
1285             compat_set_fd_set(n, exp, fds.res_ex))
1286                 ret = -EFAULT;
1287 out:
1288         if (bits != stack_fds)
1289                 kfree(bits);
1290 out_nofds:
1291         return ret;
1292 }
1293
1294 COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
1295         compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1296         struct compat_timeval __user *, tvp)
1297 {
1298         struct timespec end_time, *to = NULL;
1299         struct compat_timeval tv;
1300         int ret;
1301
1302         if (tvp) {
1303                 if (copy_from_user(&tv, tvp, sizeof(tv)))
1304                         return -EFAULT;
1305
1306                 to = &end_time;
1307                 if (poll_select_set_timeout(to,
1308                                 tv.tv_sec + (tv.tv_usec / USEC_PER_SEC),
1309                                 (tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC))
1310                         return -EINVAL;
1311         }
1312
1313         ret = compat_core_sys_select(n, inp, outp, exp, to);
1314         ret = poll_select_copy_remaining(&end_time, tvp, 1, ret);
1315
1316         return ret;
1317 }
1318
1319 struct compat_sel_arg_struct {
1320         compat_ulong_t n;
1321         compat_uptr_t inp;
1322         compat_uptr_t outp;
1323         compat_uptr_t exp;
1324         compat_uptr_t tvp;
1325 };
1326
1327 COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg)
1328 {
1329         struct compat_sel_arg_struct a;
1330
1331         if (copy_from_user(&a, arg, sizeof(a)))
1332                 return -EFAULT;
1333         return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
1334                                  compat_ptr(a.exp), compat_ptr(a.tvp));
1335 }
1336
1337 static long do_compat_pselect(int n, compat_ulong_t __user *inp,
1338         compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1339         struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask,
1340         compat_size_t sigsetsize)
1341 {
1342         compat_sigset_t ss32;
1343         sigset_t ksigmask, sigsaved;
1344         struct compat_timespec ts;
1345         struct timespec end_time, *to = NULL;
1346         int ret;
1347
1348         if (tsp) {
1349                 if (copy_from_user(&ts, tsp, sizeof(ts)))
1350                         return -EFAULT;
1351
1352                 to = &end_time;
1353                 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
1354                         return -EINVAL;
1355         }
1356
1357         if (sigmask) {
1358                 if (sigsetsize != sizeof(compat_sigset_t))
1359                         return -EINVAL;
1360                 if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
1361                         return -EFAULT;
1362                 sigset_from_compat(&ksigmask, &ss32);
1363
1364                 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1365                 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1366         }
1367
1368         ret = compat_core_sys_select(n, inp, outp, exp, to);
1369         ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
1370
1371         if (ret == -ERESTARTNOHAND) {
1372                 /*
1373                  * Don't restore the signal mask yet. Let do_signal() deliver
1374                  * the signal on the way back to userspace, before the signal
1375                  * mask is restored.
1376                  */
1377                 if (sigmask) {
1378                         memcpy(&current->saved_sigmask, &sigsaved,
1379                                         sizeof(sigsaved));
1380                         set_restore_sigmask();
1381                 }
1382         } else if (sigmask)
1383                 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1384
1385         return ret;
1386 }
1387
1388 COMPAT_SYSCALL_DEFINE6(pselect6, int, n, compat_ulong_t __user *, inp,
1389         compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1390         struct compat_timespec __user *, tsp, void __user *, sig)
1391 {
1392         compat_size_t sigsetsize = 0;
1393         compat_uptr_t up = 0;
1394
1395         if (sig) {
1396                 if (!access_ok(VERIFY_READ, sig,
1397                                 sizeof(compat_uptr_t)+sizeof(compat_size_t)) ||
1398                         __get_user(up, (compat_uptr_t __user *)sig) ||
1399                         __get_user(sigsetsize,
1400                                 (compat_size_t __user *)(sig+sizeof(up))))
1401                         return -EFAULT;
1402         }
1403         return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up),
1404                                  sigsetsize);
1405 }
1406
1407 COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
1408         unsigned int,  nfds, struct compat_timespec __user *, tsp,
1409         const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
1410 {
1411         compat_sigset_t ss32;
1412         sigset_t ksigmask, sigsaved;
1413         struct compat_timespec ts;
1414         struct timespec end_time, *to = NULL;
1415         int ret;
1416
1417         if (tsp) {
1418                 if (copy_from_user(&ts, tsp, sizeof(ts)))
1419                         return -EFAULT;
1420
1421                 to = &end_time;
1422                 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
1423                         return -EINVAL;
1424         }
1425
1426         if (sigmask) {
1427                 if (sigsetsize != sizeof(compat_sigset_t))
1428                         return -EINVAL;
1429                 if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
1430                         return -EFAULT;
1431                 sigset_from_compat(&ksigmask, &ss32);
1432
1433                 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1434                 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1435         }
1436
1437         ret = do_sys_poll(ufds, nfds, to);
1438
1439         /* We can restart this syscall, usually */
1440         if (ret == -EINTR) {
1441                 /*
1442                  * Don't restore the signal mask yet. Let do_signal() deliver
1443                  * the signal on the way back to userspace, before the signal
1444                  * mask is restored.
1445                  */
1446                 if (sigmask) {
1447                         memcpy(&current->saved_sigmask, &sigsaved,
1448                                 sizeof(sigsaved));
1449                         set_restore_sigmask();
1450                 }
1451                 ret = -ERESTARTNOHAND;
1452         } else if (sigmask)
1453                 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1454
1455         ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
1456
1457         return ret;
1458 }
1459
1460 #ifdef CONFIG_FHANDLE
1461 /*
1462  * Exactly like fs/open.c:sys_open_by_handle_at(), except that it
1463  * doesn't set the O_LARGEFILE flag.
1464  */
1465 COMPAT_SYSCALL_DEFINE3(open_by_handle_at, int, mountdirfd,
1466                              struct file_handle __user *, handle, int, flags)
1467 {
1468         return do_handle_open(mountdirfd, handle, flags);
1469 }
1470 #endif