timers: fix itimer/many thread hang
[linux-2.6.git] / kernel / compat.c
1 /*
2  *  linux/kernel/compat.c
3  *
4  *  Kernel compatibililty routines for e.g. 32 bit syscall support
5  *  on 64 bit kernels.
6  *
7  *  Copyright (C) 2002-2003 Stephen Rothwell, IBM Corporation
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License version 2 as
11  *  published by the Free Software Foundation.
12  */
13
14 #include <linux/linkage.h>
15 #include <linux/compat.h>
16 #include <linux/errno.h>
17 #include <linux/time.h>
18 #include <linux/signal.h>
19 #include <linux/sched.h>        /* for MAX_SCHEDULE_TIMEOUT */
20 #include <linux/syscalls.h>
21 #include <linux/unistd.h>
22 #include <linux/security.h>
23 #include <linux/timex.h>
24 #include <linux/migrate.h>
25 #include <linux/posix-timers.h>
26 #include <linux/times.h>
27
28 #include <asm/uaccess.h>
29
30 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
31 {
32         return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
33                         __get_user(ts->tv_sec, &cts->tv_sec) ||
34                         __get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
35 }
36
37 int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user *cts)
38 {
39         return (!access_ok(VERIFY_WRITE, cts, sizeof(*cts)) ||
40                         __put_user(ts->tv_sec, &cts->tv_sec) ||
41                         __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
42 }
43
44 static long compat_nanosleep_restart(struct restart_block *restart)
45 {
46         struct compat_timespec __user *rmtp;
47         struct timespec rmt;
48         mm_segment_t oldfs;
49         long ret;
50
51         restart->nanosleep.rmtp = (struct timespec __user *) &rmt;
52         oldfs = get_fs();
53         set_fs(KERNEL_DS);
54         ret = hrtimer_nanosleep_restart(restart);
55         set_fs(oldfs);
56
57         if (ret) {
58                 rmtp = restart->nanosleep.compat_rmtp;
59
60                 if (rmtp && put_compat_timespec(&rmt, rmtp))
61                         return -EFAULT;
62         }
63
64         return ret;
65 }
66
67 asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
68                                      struct compat_timespec __user *rmtp)
69 {
70         struct timespec tu, rmt;
71         mm_segment_t oldfs;
72         long ret;
73
74         if (get_compat_timespec(&tu, rqtp))
75                 return -EFAULT;
76
77         if (!timespec_valid(&tu))
78                 return -EINVAL;
79
80         oldfs = get_fs();
81         set_fs(KERNEL_DS);
82         ret = hrtimer_nanosleep(&tu,
83                                 rmtp ? (struct timespec __user *)&rmt : NULL,
84                                 HRTIMER_MODE_REL, CLOCK_MONOTONIC);
85         set_fs(oldfs);
86
87         if (ret) {
88                 struct restart_block *restart
89                         = &current_thread_info()->restart_block;
90
91                 restart->fn = compat_nanosleep_restart;
92                 restart->nanosleep.compat_rmtp = rmtp;
93
94                 if (rmtp && put_compat_timespec(&rmt, rmtp))
95                         return -EFAULT;
96         }
97
98         return ret;
99 }
100
101 static inline long get_compat_itimerval(struct itimerval *o,
102                 struct compat_itimerval __user *i)
103 {
104         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
105                 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
106                  __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
107                  __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
108                  __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
109 }
110
111 static inline long put_compat_itimerval(struct compat_itimerval __user *o,
112                 struct itimerval *i)
113 {
114         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
115                 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
116                  __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
117                  __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
118                  __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
119 }
120
121 asmlinkage long compat_sys_getitimer(int which,
122                 struct compat_itimerval __user *it)
123 {
124         struct itimerval kit;
125         int error;
126
127         error = do_getitimer(which, &kit);
128         if (!error && put_compat_itimerval(it, &kit))
129                 error = -EFAULT;
130         return error;
131 }
132
133 asmlinkage long compat_sys_setitimer(int which,
134                 struct compat_itimerval __user *in,
135                 struct compat_itimerval __user *out)
136 {
137         struct itimerval kin, kout;
138         int error;
139
140         if (in) {
141                 if (get_compat_itimerval(&kin, in))
142                         return -EFAULT;
143         } else
144                 memset(&kin, 0, sizeof(kin));
145
146         error = do_setitimer(which, &kin, out ? &kout : NULL);
147         if (error || !out)
148                 return error;
149         if (put_compat_itimerval(out, &kout))
150                 return -EFAULT;
151         return 0;
152 }
153
154 static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
155 {
156         return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
157 }
158
159 asmlinkage long compat_sys_times(struct compat_tms __user *tbuf)
160 {
161         if (tbuf) {
162                 struct tms tms;
163                 struct compat_tms tmp;
164
165                 do_sys_times(&tms);
166                 /* Convert our struct tms to the compat version. */
167                 tmp.tms_utime = clock_t_to_compat_clock_t(tms.tms_utime);
168                 tmp.tms_stime = clock_t_to_compat_clock_t(tms.tms_stime);
169                 tmp.tms_cutime = clock_t_to_compat_clock_t(tms.tms_cutime);
170                 tmp.tms_cstime = clock_t_to_compat_clock_t(tms.tms_cstime);
171                 if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
172                         return -EFAULT;
173         }
174         return compat_jiffies_to_clock_t(jiffies);
175 }
176
177 /*
178  * Assumption: old_sigset_t and compat_old_sigset_t are both
179  * types that can be passed to put_user()/get_user().
180  */
181
182 asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set)
183 {
184         old_sigset_t s;
185         long ret;
186         mm_segment_t old_fs = get_fs();
187
188         set_fs(KERNEL_DS);
189         ret = sys_sigpending((old_sigset_t __user *) &s);
190         set_fs(old_fs);
191         if (ret == 0)
192                 ret = put_user(s, set);
193         return ret;
194 }
195
196 asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
197                 compat_old_sigset_t __user *oset)
198 {
199         old_sigset_t s;
200         long ret;
201         mm_segment_t old_fs;
202
203         if (set && get_user(s, set))
204                 return -EFAULT;
205         old_fs = get_fs();
206         set_fs(KERNEL_DS);
207         ret = sys_sigprocmask(how,
208                               set ? (old_sigset_t __user *) &s : NULL,
209                               oset ? (old_sigset_t __user *) &s : NULL);
210         set_fs(old_fs);
211         if (ret == 0)
212                 if (oset)
213                         ret = put_user(s, oset);
214         return ret;
215 }
216
217 asmlinkage long compat_sys_setrlimit(unsigned int resource,
218                 struct compat_rlimit __user *rlim)
219 {
220         struct rlimit r;
221         int ret;
222         mm_segment_t old_fs = get_fs ();
223
224         if (resource >= RLIM_NLIMITS)
225                 return -EINVAL;
226
227         if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
228             __get_user(r.rlim_cur, &rlim->rlim_cur) ||
229             __get_user(r.rlim_max, &rlim->rlim_max))
230                 return -EFAULT;
231
232         if (r.rlim_cur == COMPAT_RLIM_INFINITY)
233                 r.rlim_cur = RLIM_INFINITY;
234         if (r.rlim_max == COMPAT_RLIM_INFINITY)
235                 r.rlim_max = RLIM_INFINITY;
236         set_fs(KERNEL_DS);
237         ret = sys_setrlimit(resource, (struct rlimit __user *) &r);
238         set_fs(old_fs);
239         return ret;
240 }
241
242 #ifdef COMPAT_RLIM_OLD_INFINITY
243
244 asmlinkage long compat_sys_old_getrlimit(unsigned int resource,
245                 struct compat_rlimit __user *rlim)
246 {
247         struct rlimit r;
248         int ret;
249         mm_segment_t old_fs = get_fs();
250
251         set_fs(KERNEL_DS);
252         ret = sys_old_getrlimit(resource, &r);
253         set_fs(old_fs);
254
255         if (!ret) {
256                 if (r.rlim_cur > COMPAT_RLIM_OLD_INFINITY)
257                         r.rlim_cur = COMPAT_RLIM_INFINITY;
258                 if (r.rlim_max > COMPAT_RLIM_OLD_INFINITY)
259                         r.rlim_max = COMPAT_RLIM_INFINITY;
260
261                 if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
262                     __put_user(r.rlim_cur, &rlim->rlim_cur) ||
263                     __put_user(r.rlim_max, &rlim->rlim_max))
264                         return -EFAULT;
265         }
266         return ret;
267 }
268
269 #endif
270
271 asmlinkage long compat_sys_getrlimit (unsigned int resource,
272                 struct compat_rlimit __user *rlim)
273 {
274         struct rlimit r;
275         int ret;
276         mm_segment_t old_fs = get_fs();
277
278         set_fs(KERNEL_DS);
279         ret = sys_getrlimit(resource, (struct rlimit __user *) &r);
280         set_fs(old_fs);
281         if (!ret) {
282                 if (r.rlim_cur > COMPAT_RLIM_INFINITY)
283                         r.rlim_cur = COMPAT_RLIM_INFINITY;
284                 if (r.rlim_max > COMPAT_RLIM_INFINITY)
285                         r.rlim_max = COMPAT_RLIM_INFINITY;
286
287                 if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
288                     __put_user(r.rlim_cur, &rlim->rlim_cur) ||
289                     __put_user(r.rlim_max, &rlim->rlim_max))
290                         return -EFAULT;
291         }
292         return ret;
293 }
294
295 int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
296 {
297         if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)) ||
298             __put_user(r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
299             __put_user(r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
300             __put_user(r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
301             __put_user(r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
302             __put_user(r->ru_maxrss, &ru->ru_maxrss) ||
303             __put_user(r->ru_ixrss, &ru->ru_ixrss) ||
304             __put_user(r->ru_idrss, &ru->ru_idrss) ||
305             __put_user(r->ru_isrss, &ru->ru_isrss) ||
306             __put_user(r->ru_minflt, &ru->ru_minflt) ||
307             __put_user(r->ru_majflt, &ru->ru_majflt) ||
308             __put_user(r->ru_nswap, &ru->ru_nswap) ||
309             __put_user(r->ru_inblock, &ru->ru_inblock) ||
310             __put_user(r->ru_oublock, &ru->ru_oublock) ||
311             __put_user(r->ru_msgsnd, &ru->ru_msgsnd) ||
312             __put_user(r->ru_msgrcv, &ru->ru_msgrcv) ||
313             __put_user(r->ru_nsignals, &ru->ru_nsignals) ||
314             __put_user(r->ru_nvcsw, &ru->ru_nvcsw) ||
315             __put_user(r->ru_nivcsw, &ru->ru_nivcsw))
316                 return -EFAULT;
317         return 0;
318 }
319
320 asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru)
321 {
322         struct rusage r;
323         int ret;
324         mm_segment_t old_fs = get_fs();
325
326         set_fs(KERNEL_DS);
327         ret = sys_getrusage(who, (struct rusage __user *) &r);
328         set_fs(old_fs);
329
330         if (ret)
331                 return ret;
332
333         if (put_compat_rusage(&r, ru))
334                 return -EFAULT;
335
336         return 0;
337 }
338
339 asmlinkage long
340 compat_sys_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options,
341         struct compat_rusage __user *ru)
342 {
343         if (!ru) {
344                 return sys_wait4(pid, stat_addr, options, NULL);
345         } else {
346                 struct rusage r;
347                 int ret;
348                 unsigned int status;
349                 mm_segment_t old_fs = get_fs();
350
351                 set_fs (KERNEL_DS);
352                 ret = sys_wait4(pid,
353                                 (stat_addr ?
354                                  (unsigned int __user *) &status : NULL),
355                                 options, (struct rusage __user *) &r);
356                 set_fs (old_fs);
357
358                 if (ret > 0) {
359                         if (put_compat_rusage(&r, ru))
360                                 return -EFAULT;
361                         if (stat_addr && put_user(status, stat_addr))
362                                 return -EFAULT;
363                 }
364                 return ret;
365         }
366 }
367
368 asmlinkage long compat_sys_waitid(int which, compat_pid_t pid,
369                 struct compat_siginfo __user *uinfo, int options,
370                 struct compat_rusage __user *uru)
371 {
372         siginfo_t info;
373         struct rusage ru;
374         long ret;
375         mm_segment_t old_fs = get_fs();
376
377         memset(&info, 0, sizeof(info));
378
379         set_fs(KERNEL_DS);
380         ret = sys_waitid(which, pid, (siginfo_t __user *)&info, options,
381                          uru ? (struct rusage __user *)&ru : NULL);
382         set_fs(old_fs);
383
384         if ((ret < 0) || (info.si_signo == 0))
385                 return ret;
386
387         if (uru) {
388                 ret = put_compat_rusage(&ru, uru);
389                 if (ret)
390                         return ret;
391         }
392
393         BUG_ON(info.si_code & __SI_MASK);
394         info.si_code |= __SI_CHLD;
395         return copy_siginfo_to_user32(uinfo, &info);
396 }
397
398 static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr,
399                                     unsigned len, cpumask_t *new_mask)
400 {
401         unsigned long *k;
402
403         if (len < sizeof(cpumask_t))
404                 memset(new_mask, 0, sizeof(cpumask_t));
405         else if (len > sizeof(cpumask_t))
406                 len = sizeof(cpumask_t);
407
408         k = cpus_addr(*new_mask);
409         return compat_get_bitmap(k, user_mask_ptr, len * 8);
410 }
411
412 asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
413                                              unsigned int len,
414                                              compat_ulong_t __user *user_mask_ptr)
415 {
416         cpumask_t new_mask;
417         int retval;
418
419         retval = compat_get_user_cpu_mask(user_mask_ptr, len, &new_mask);
420         if (retval)
421                 return retval;
422
423         return sched_setaffinity(pid, &new_mask);
424 }
425
426 asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
427                                              compat_ulong_t __user *user_mask_ptr)
428 {
429         int ret;
430         cpumask_t mask;
431         unsigned long *k;
432         unsigned int min_length = sizeof(cpumask_t);
433
434         if (NR_CPUS <= BITS_PER_COMPAT_LONG)
435                 min_length = sizeof(compat_ulong_t);
436
437         if (len < min_length)
438                 return -EINVAL;
439
440         ret = sched_getaffinity(pid, &mask);
441         if (ret < 0)
442                 return ret;
443
444         k = cpus_addr(mask);
445         ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8);
446         if (ret)
447                 return ret;
448
449         return min_length;
450 }
451
452 int get_compat_itimerspec(struct itimerspec *dst,
453                           const struct compat_itimerspec __user *src)
454 {
455         if (get_compat_timespec(&dst->it_interval, &src->it_interval) ||
456             get_compat_timespec(&dst->it_value, &src->it_value))
457                 return -EFAULT;
458         return 0;
459 }
460
461 int put_compat_itimerspec(struct compat_itimerspec __user *dst,
462                           const struct itimerspec *src)
463 {
464         if (put_compat_timespec(&src->it_interval, &dst->it_interval) ||
465             put_compat_timespec(&src->it_value, &dst->it_value))
466                 return -EFAULT;
467         return 0;
468 }
469
470 long compat_sys_timer_create(clockid_t which_clock,
471                         struct compat_sigevent __user *timer_event_spec,
472                         timer_t __user *created_timer_id)
473 {
474         struct sigevent __user *event = NULL;
475
476         if (timer_event_spec) {
477                 struct sigevent kevent;
478
479                 event = compat_alloc_user_space(sizeof(*event));
480                 if (get_compat_sigevent(&kevent, timer_event_spec) ||
481                     copy_to_user(event, &kevent, sizeof(*event)))
482                         return -EFAULT;
483         }
484
485         return sys_timer_create(which_clock, event, created_timer_id);
486 }
487
488 long compat_sys_timer_settime(timer_t timer_id, int flags,
489                           struct compat_itimerspec __user *new,
490                           struct compat_itimerspec __user *old)
491 {
492         long err;
493         mm_segment_t oldfs;
494         struct itimerspec newts, oldts;
495
496         if (!new)
497                 return -EINVAL;
498         if (get_compat_itimerspec(&newts, new))
499                 return -EFAULT;
500         oldfs = get_fs();
501         set_fs(KERNEL_DS);
502         err = sys_timer_settime(timer_id, flags,
503                                 (struct itimerspec __user *) &newts,
504                                 (struct itimerspec __user *) &oldts);
505         set_fs(oldfs);
506         if (!err && old && put_compat_itimerspec(old, &oldts))
507                 return -EFAULT;
508         return err;
509 }
510
511 long compat_sys_timer_gettime(timer_t timer_id,
512                 struct compat_itimerspec __user *setting)
513 {
514         long err;
515         mm_segment_t oldfs;
516         struct itimerspec ts;
517
518         oldfs = get_fs();
519         set_fs(KERNEL_DS);
520         err = sys_timer_gettime(timer_id,
521                                 (struct itimerspec __user *) &ts);
522         set_fs(oldfs);
523         if (!err && put_compat_itimerspec(setting, &ts))
524                 return -EFAULT;
525         return err;
526 }
527
528 long compat_sys_clock_settime(clockid_t which_clock,
529                 struct compat_timespec __user *tp)
530 {
531         long err;
532         mm_segment_t oldfs;
533         struct timespec ts;
534
535         if (get_compat_timespec(&ts, tp))
536                 return -EFAULT;
537         oldfs = get_fs();
538         set_fs(KERNEL_DS);
539         err = sys_clock_settime(which_clock,
540                                 (struct timespec __user *) &ts);
541         set_fs(oldfs);
542         return err;
543 }
544
545 long compat_sys_clock_gettime(clockid_t which_clock,
546                 struct compat_timespec __user *tp)
547 {
548         long err;
549         mm_segment_t oldfs;
550         struct timespec ts;
551
552         oldfs = get_fs();
553         set_fs(KERNEL_DS);
554         err = sys_clock_gettime(which_clock,
555                                 (struct timespec __user *) &ts);
556         set_fs(oldfs);
557         if (!err && put_compat_timespec(&ts, tp))
558                 return -EFAULT;
559         return err;
560 }
561
562 long compat_sys_clock_getres(clockid_t which_clock,
563                 struct compat_timespec __user *tp)
564 {
565         long err;
566         mm_segment_t oldfs;
567         struct timespec ts;
568
569         oldfs = get_fs();
570         set_fs(KERNEL_DS);
571         err = sys_clock_getres(which_clock,
572                                (struct timespec __user *) &ts);
573         set_fs(oldfs);
574         if (!err && tp && put_compat_timespec(&ts, tp))
575                 return -EFAULT;
576         return err;
577 }
578
579 static long compat_clock_nanosleep_restart(struct restart_block *restart)
580 {
581         long err;
582         mm_segment_t oldfs;
583         struct timespec tu;
584         struct compat_timespec *rmtp = restart->nanosleep.compat_rmtp;
585
586         restart->nanosleep.rmtp = (struct timespec __user *) &tu;
587         oldfs = get_fs();
588         set_fs(KERNEL_DS);
589         err = clock_nanosleep_restart(restart);
590         set_fs(oldfs);
591
592         if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
593             put_compat_timespec(&tu, rmtp))
594                 return -EFAULT;
595
596         if (err == -ERESTART_RESTARTBLOCK) {
597                 restart->fn = compat_clock_nanosleep_restart;
598                 restart->nanosleep.compat_rmtp = rmtp;
599         }
600         return err;
601 }
602
603 long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
604                             struct compat_timespec __user *rqtp,
605                             struct compat_timespec __user *rmtp)
606 {
607         long err;
608         mm_segment_t oldfs;
609         struct timespec in, out;
610         struct restart_block *restart;
611
612         if (get_compat_timespec(&in, rqtp))
613                 return -EFAULT;
614
615         oldfs = get_fs();
616         set_fs(KERNEL_DS);
617         err = sys_clock_nanosleep(which_clock, flags,
618                                   (struct timespec __user *) &in,
619                                   (struct timespec __user *) &out);
620         set_fs(oldfs);
621
622         if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
623             put_compat_timespec(&out, rmtp))
624                 return -EFAULT;
625
626         if (err == -ERESTART_RESTARTBLOCK) {
627                 restart = &current_thread_info()->restart_block;
628                 restart->fn = compat_clock_nanosleep_restart;
629                 restart->nanosleep.compat_rmtp = rmtp;
630         }
631         return err;
632 }
633
634 /*
635  * We currently only need the following fields from the sigevent
636  * structure: sigev_value, sigev_signo, sig_notify and (sometimes
637  * sigev_notify_thread_id).  The others are handled in user mode.
638  * We also assume that copying sigev_value.sival_int is sufficient
639  * to keep all the bits of sigev_value.sival_ptr intact.
640  */
641 int get_compat_sigevent(struct sigevent *event,
642                 const struct compat_sigevent __user *u_event)
643 {
644         memset(event, 0, sizeof(*event));
645         return (!access_ok(VERIFY_READ, u_event, sizeof(*u_event)) ||
646                 __get_user(event->sigev_value.sival_int,
647                         &u_event->sigev_value.sival_int) ||
648                 __get_user(event->sigev_signo, &u_event->sigev_signo) ||
649                 __get_user(event->sigev_notify, &u_event->sigev_notify) ||
650                 __get_user(event->sigev_notify_thread_id,
651                         &u_event->sigev_notify_thread_id))
652                 ? -EFAULT : 0;
653 }
654
655 long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
656                        unsigned long bitmap_size)
657 {
658         int i, j;
659         unsigned long m;
660         compat_ulong_t um;
661         unsigned long nr_compat_longs;
662
663         /* align bitmap up to nearest compat_long_t boundary */
664         bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
665
666         if (!access_ok(VERIFY_READ, umask, bitmap_size / 8))
667                 return -EFAULT;
668
669         nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
670
671         for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
672                 m = 0;
673
674                 for (j = 0; j < sizeof(m)/sizeof(um); j++) {
675                         /*
676                          * We dont want to read past the end of the userspace
677                          * bitmap. We must however ensure the end of the
678                          * kernel bitmap is zeroed.
679                          */
680                         if (nr_compat_longs-- > 0) {
681                                 if (__get_user(um, umask))
682                                         return -EFAULT;
683                         } else {
684                                 um = 0;
685                         }
686
687                         umask++;
688                         m |= (long)um << (j * BITS_PER_COMPAT_LONG);
689                 }
690                 *mask++ = m;
691         }
692
693         return 0;
694 }
695
696 long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
697                        unsigned long bitmap_size)
698 {
699         int i, j;
700         unsigned long m;
701         compat_ulong_t um;
702         unsigned long nr_compat_longs;
703
704         /* align bitmap up to nearest compat_long_t boundary */
705         bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
706
707         if (!access_ok(VERIFY_WRITE, umask, bitmap_size / 8))
708                 return -EFAULT;
709
710         nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
711
712         for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
713                 m = *mask++;
714
715                 for (j = 0; j < sizeof(m)/sizeof(um); j++) {
716                         um = m;
717
718                         /*
719                          * We dont want to write past the end of the userspace
720                          * bitmap.
721                          */
722                         if (nr_compat_longs-- > 0) {
723                                 if (__put_user(um, umask))
724                                         return -EFAULT;
725                         }
726
727                         umask++;
728                         m >>= 4*sizeof(um);
729                         m >>= 4*sizeof(um);
730                 }
731         }
732
733         return 0;
734 }
735
736 void
737 sigset_from_compat (sigset_t *set, compat_sigset_t *compat)
738 {
739         switch (_NSIG_WORDS) {
740         case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 );
741         case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32 );
742         case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32 );
743         case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 );
744         }
745 }
746
747 asmlinkage long
748 compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
749                 struct compat_siginfo __user *uinfo,
750                 struct compat_timespec __user *uts, compat_size_t sigsetsize)
751 {
752         compat_sigset_t s32;
753         sigset_t s;
754         int sig;
755         struct timespec t;
756         siginfo_t info;
757         long ret, timeout = 0;
758
759         if (sigsetsize != sizeof(sigset_t))
760                 return -EINVAL;
761
762         if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
763                 return -EFAULT;
764         sigset_from_compat(&s, &s32);
765         sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP));
766         signotset(&s);
767
768         if (uts) {
769                 if (get_compat_timespec (&t, uts))
770                         return -EFAULT;
771                 if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0
772                                 || t.tv_sec < 0)
773                         return -EINVAL;
774         }
775
776         spin_lock_irq(&current->sighand->siglock);
777         sig = dequeue_signal(current, &s, &info);
778         if (!sig) {
779                 timeout = MAX_SCHEDULE_TIMEOUT;
780                 if (uts)
781                         timeout = timespec_to_jiffies(&t)
782                                 +(t.tv_sec || t.tv_nsec);
783                 if (timeout) {
784                         current->real_blocked = current->blocked;
785                         sigandsets(&current->blocked, &current->blocked, &s);
786
787                         recalc_sigpending();
788                         spin_unlock_irq(&current->sighand->siglock);
789
790                         timeout = schedule_timeout_interruptible(timeout);
791
792                         spin_lock_irq(&current->sighand->siglock);
793                         sig = dequeue_signal(current, &s, &info);
794                         current->blocked = current->real_blocked;
795                         siginitset(&current->real_blocked, 0);
796                         recalc_sigpending();
797                 }
798         }
799         spin_unlock_irq(&current->sighand->siglock);
800
801         if (sig) {
802                 ret = sig;
803                 if (uinfo) {
804                         if (copy_siginfo_to_user32(uinfo, &info))
805                                 ret = -EFAULT;
806                 }
807         }else {
808                 ret = timeout?-EINTR:-EAGAIN;
809         }
810         return ret;
811
812 }
813
814 #ifdef __ARCH_WANT_COMPAT_SYS_TIME
815
816 /* compat_time_t is a 32 bit "long" and needs to get converted. */
817
818 asmlinkage long compat_sys_time(compat_time_t __user * tloc)
819 {
820         compat_time_t i;
821         struct timeval tv;
822
823         do_gettimeofday(&tv);
824         i = tv.tv_sec;
825
826         if (tloc) {
827                 if (put_user(i,tloc))
828                         i = -EFAULT;
829         }
830         return i;
831 }
832
833 asmlinkage long compat_sys_stime(compat_time_t __user *tptr)
834 {
835         struct timespec tv;
836         int err;
837
838         if (get_user(tv.tv_sec, tptr))
839                 return -EFAULT;
840
841         tv.tv_nsec = 0;
842
843         err = security_settime(&tv, NULL);
844         if (err)
845                 return err;
846
847         do_settimeofday(&tv);
848         return 0;
849 }
850
851 #endif /* __ARCH_WANT_COMPAT_SYS_TIME */
852
853 #ifdef __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
854 asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat_size_t sigsetsize)
855 {
856         sigset_t newset;
857         compat_sigset_t newset32;
858
859         /* XXX: Don't preclude handling different sized sigset_t's.  */
860         if (sigsetsize != sizeof(sigset_t))
861                 return -EINVAL;
862
863         if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
864                 return -EFAULT;
865         sigset_from_compat(&newset, &newset32);
866         sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
867
868         spin_lock_irq(&current->sighand->siglock);
869         current->saved_sigmask = current->blocked;
870         current->blocked = newset;
871         recalc_sigpending();
872         spin_unlock_irq(&current->sighand->siglock);
873
874         current->state = TASK_INTERRUPTIBLE;
875         schedule();
876         set_restore_sigmask();
877         return -ERESTARTNOHAND;
878 }
879 #endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */
880
881 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp)
882 {
883         struct timex txc;
884         int ret;
885
886         memset(&txc, 0, sizeof(struct timex));
887
888         if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) ||
889                         __get_user(txc.modes, &utp->modes) ||
890                         __get_user(txc.offset, &utp->offset) ||
891                         __get_user(txc.freq, &utp->freq) ||
892                         __get_user(txc.maxerror, &utp->maxerror) ||
893                         __get_user(txc.esterror, &utp->esterror) ||
894                         __get_user(txc.status, &utp->status) ||
895                         __get_user(txc.constant, &utp->constant) ||
896                         __get_user(txc.precision, &utp->precision) ||
897                         __get_user(txc.tolerance, &utp->tolerance) ||
898                         __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
899                         __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
900                         __get_user(txc.tick, &utp->tick) ||
901                         __get_user(txc.ppsfreq, &utp->ppsfreq) ||
902                         __get_user(txc.jitter, &utp->jitter) ||
903                         __get_user(txc.shift, &utp->shift) ||
904                         __get_user(txc.stabil, &utp->stabil) ||
905                         __get_user(txc.jitcnt, &utp->jitcnt) ||
906                         __get_user(txc.calcnt, &utp->calcnt) ||
907                         __get_user(txc.errcnt, &utp->errcnt) ||
908                         __get_user(txc.stbcnt, &utp->stbcnt))
909                 return -EFAULT;
910
911         ret = do_adjtimex(&txc);
912
913         if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) ||
914                         __put_user(txc.modes, &utp->modes) ||
915                         __put_user(txc.offset, &utp->offset) ||
916                         __put_user(txc.freq, &utp->freq) ||
917                         __put_user(txc.maxerror, &utp->maxerror) ||
918                         __put_user(txc.esterror, &utp->esterror) ||
919                         __put_user(txc.status, &utp->status) ||
920                         __put_user(txc.constant, &utp->constant) ||
921                         __put_user(txc.precision, &utp->precision) ||
922                         __put_user(txc.tolerance, &utp->tolerance) ||
923                         __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
924                         __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
925                         __put_user(txc.tick, &utp->tick) ||
926                         __put_user(txc.ppsfreq, &utp->ppsfreq) ||
927                         __put_user(txc.jitter, &utp->jitter) ||
928                         __put_user(txc.shift, &utp->shift) ||
929                         __put_user(txc.stabil, &utp->stabil) ||
930                         __put_user(txc.jitcnt, &utp->jitcnt) ||
931                         __put_user(txc.calcnt, &utp->calcnt) ||
932                         __put_user(txc.errcnt, &utp->errcnt) ||
933                         __put_user(txc.stbcnt, &utp->stbcnt) ||
934                         __put_user(txc.tai, &utp->tai))
935                 ret = -EFAULT;
936
937         return ret;
938 }
939
940 #ifdef CONFIG_NUMA
941 asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_pages,
942                 compat_uptr_t __user *pages32,
943                 const int __user *nodes,
944                 int __user *status,
945                 int flags)
946 {
947         const void __user * __user *pages;
948         int i;
949
950         pages = compat_alloc_user_space(nr_pages * sizeof(void *));
951         for (i = 0; i < nr_pages; i++) {
952                 compat_uptr_t p;
953
954                 if (get_user(p, pages32 + i) ||
955                         put_user(compat_ptr(p), pages + i))
956                         return -EFAULT;
957         }
958         return sys_move_pages(pid, nr_pages, pages, nodes, status, flags);
959 }
960
961 asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
962                         compat_ulong_t maxnode,
963                         const compat_ulong_t __user *old_nodes,
964                         const compat_ulong_t __user *new_nodes)
965 {
966         unsigned long __user *old = NULL;
967         unsigned long __user *new = NULL;
968         nodemask_t tmp_mask;
969         unsigned long nr_bits;
970         unsigned long size;
971
972         nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES);
973         size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
974         if (old_nodes) {
975                 if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits))
976                         return -EFAULT;
977                 old = compat_alloc_user_space(new_nodes ? size * 2 : size);
978                 if (new_nodes)
979                         new = old + size / sizeof(unsigned long);
980                 if (copy_to_user(old, nodes_addr(tmp_mask), size))
981                         return -EFAULT;
982         }
983         if (new_nodes) {
984                 if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits))
985                         return -EFAULT;
986                 if (new == NULL)
987                         new = compat_alloc_user_space(size);
988                 if (copy_to_user(new, nodes_addr(tmp_mask), size))
989                         return -EFAULT;
990         }
991         return sys_migrate_pages(pid, nr_bits + 1, old, new);
992 }
993 #endif
994
995 struct compat_sysinfo {
996         s32 uptime;
997         u32 loads[3];
998         u32 totalram;
999         u32 freeram;
1000         u32 sharedram;
1001         u32 bufferram;
1002         u32 totalswap;
1003         u32 freeswap;
1004         u16 procs;
1005         u16 pad;
1006         u32 totalhigh;
1007         u32 freehigh;
1008         u32 mem_unit;
1009         char _f[20-2*sizeof(u32)-sizeof(int)];
1010 };
1011
1012 asmlinkage long
1013 compat_sys_sysinfo(struct compat_sysinfo __user *info)
1014 {
1015         struct sysinfo s;
1016
1017         do_sysinfo(&s);
1018
1019         /* Check to see if any memory value is too large for 32-bit and scale
1020          *  down if needed
1021          */
1022         if ((s.totalram >> 32) || (s.totalswap >> 32)) {
1023                 int bitcount = 0;
1024
1025                 while (s.mem_unit < PAGE_SIZE) {
1026                         s.mem_unit <<= 1;
1027                         bitcount++;
1028                 }
1029
1030                 s.totalram >>= bitcount;
1031                 s.freeram >>= bitcount;
1032                 s.sharedram >>= bitcount;
1033                 s.bufferram >>= bitcount;
1034                 s.totalswap >>= bitcount;
1035                 s.freeswap >>= bitcount;
1036                 s.totalhigh >>= bitcount;
1037                 s.freehigh >>= bitcount;
1038         }
1039
1040         if (!access_ok(VERIFY_WRITE, info, sizeof(struct compat_sysinfo)) ||
1041             __put_user (s.uptime, &info->uptime) ||
1042             __put_user (s.loads[0], &info->loads[0]) ||
1043             __put_user (s.loads[1], &info->loads[1]) ||
1044             __put_user (s.loads[2], &info->loads[2]) ||
1045             __put_user (s.totalram, &info->totalram) ||
1046             __put_user (s.freeram, &info->freeram) ||
1047             __put_user (s.sharedram, &info->sharedram) ||
1048             __put_user (s.bufferram, &info->bufferram) ||
1049             __put_user (s.totalswap, &info->totalswap) ||
1050             __put_user (s.freeswap, &info->freeswap) ||
1051             __put_user (s.procs, &info->procs) ||
1052             __put_user (s.totalhigh, &info->totalhigh) ||
1053             __put_user (s.freehigh, &info->freehigh) ||
1054             __put_user (s.mem_unit, &info->mem_unit))
1055                 return -EFAULT;
1056
1057         return 0;
1058 }