7e4bc8355a7de38e0fd77e4343f76205bc2a3452
[linux-2.6.git] / arch / ppc64 / kernel / sys_ppc32.c
1 /*
2  * sys_ppc32.c: Conversion between 32bit and 64bit native syscalls.
3  *
4  * Copyright (C) 2001 IBM
5  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
7  *
8  * These routines maintain argument size conversion between 32bit and 64bit
9  * environment.
10  *
11  *      This program is free software; you can redistribute it and/or
12  *      modify it under the terms of the GNU General Public License
13  *      as published by the Free Software Foundation; either version
14  *      2 of the License, or (at your option) any later version.
15  */
16
17 #include <linux/config.h>
18 #include <asm/ptrace.h>
19 #include <linux/kernel.h>
20 #include <linux/sched.h>
21 #include <linux/fs.h> 
22 #include <linux/mm.h> 
23 #include <linux/file.h> 
24 #include <linux/signal.h>
25 #include <linux/resource.h>
26 #include <linux/times.h>
27 #include <linux/utsname.h>
28 #include <linux/timex.h>
29 #include <linux/smp.h>
30 #include <linux/smp_lock.h>
31 #include <linux/sem.h>
32 #include <linux/msg.h>
33 #include <linux/shm.h>
34 #include <linux/slab.h>
35 #include <linux/uio.h>
36 #include <linux/aio.h>
37 #include <linux/nfs_fs.h>
38 #include <linux/module.h>
39 #include <linux/sunrpc/svc.h>
40 #include <linux/nfsd/nfsd.h>
41 #include <linux/nfsd/cache.h>
42 #include <linux/nfsd/xdr.h>
43 #include <linux/nfsd/syscall.h>
44 #include <linux/poll.h>
45 #include <linux/personality.h>
46 #include <linux/stat.h>
47 #include <linux/filter.h>
48 #include <linux/highmem.h>
49 #include <linux/highuid.h>
50 #include <linux/mman.h>
51 #include <linux/ipv6.h>
52 #include <linux/in.h>
53 #include <linux/icmpv6.h>
54 #include <linux/syscalls.h>
55 #include <linux/unistd.h>
56 #include <linux/sysctl.h>
57 #include <linux/binfmts.h>
58 #include <linux/dnotify.h>
59 #include <linux/security.h>
60 #include <linux/compat.h>
61 #include <linux/ptrace.h>
62 #include <linux/aio_abi.h>
63
64 #include <asm/types.h>
65 #include <asm/ipc.h>
66 #include <asm/uaccess.h>
67 #include <asm/unistd.h>
68
69 #include <asm/semaphore.h>
70
71 #include <net/scm.h>
72 #include <net/sock.h>
73 #include <linux/elf.h>
74 #include <asm/ppcdebug.h>
75 #include <asm/time.h>
76 #include <asm/ppc32.h>
77 #include <asm/mmu_context.h>
78
79 #include "pci.h"
80
81 typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
82 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
83
84 static long do_readv_writev32(int type, struct file *file,
85                               const struct compat_iovec *vector, u32 count)
86 {
87         compat_ssize_t tot_len;
88         struct iovec iovstack[UIO_FASTIOV];
89         struct iovec *iov=iovstack, *ivp;
90         struct inode *inode;
91         long retval, i;
92         io_fn_t fn;
93         iov_fn_t fnv;
94
95         /*
96          * SuS says "The readv() function *may* fail if the iovcnt argument
97          * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
98          * traditionally returned zero for zero segments, so...
99          */
100         retval = 0;
101         if (count == 0)
102                 goto out;
103
104         /* First get the "struct iovec" from user memory and
105          * verify all the pointers
106          */
107         retval = -EINVAL;
108         if (count > UIO_MAXIOV)
109                 goto out;
110         if (!file->f_op)
111                 goto out;
112         if (count > UIO_FASTIOV) {
113                 retval = -ENOMEM;
114                 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
115                 if (!iov)
116                         goto out;
117         }
118         retval = -EFAULT;
119         if (verify_area(VERIFY_READ, vector, sizeof(struct compat_iovec)*count))
120                 goto out;
121
122         /*
123          * Single unix specification:
124          * We should -EINVAL if an element length is not >= 0 and fitting an
125          * ssize_t.  The total length is fitting an ssize_t
126          *
127          * Be careful here because iov_len is a size_t not an ssize_t
128          */
129         tot_len = 0;
130         i = count;
131         ivp = iov;
132         retval = -EINVAL;
133         while(i > 0) {
134                 compat_ssize_t tmp = tot_len;
135                 compat_ssize_t len;
136                 u32 buf;
137
138                 if (__get_user(len, &vector->iov_len) ||
139                     __get_user(buf, &vector->iov_base)) {
140                         retval = -EFAULT;
141                         goto out;
142                 }
143                 if (len < 0)    /* size_t not fitting an compat_ssize_t .. */
144                         goto out;
145                 tot_len += len;
146                 if (tot_len < tmp) /* maths overflow on the compat_ssize_t */
147                         goto out;
148                 ivp->iov_base = (void *)A(buf);
149                 ivp->iov_len = (__kernel_size_t) len;
150                 vector++;
151                 ivp++;
152                 i--;
153         }
154         if (tot_len == 0) {
155                 retval = 0;
156                 goto out;
157         }
158
159         inode = file->f_dentry->d_inode;
160         /* VERIFY_WRITE actually means a read, as we write to user space */
161         retval = locks_verify_area((type == READ
162                                     ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
163                                    inode, file, file->f_pos, tot_len);
164         if (retval)
165                 goto out;
166
167         if (type == READ) {
168                 fn = file->f_op->read;
169                 fnv = file->f_op->readv;
170         } else {
171                 fn = (io_fn_t)file->f_op->write;
172                 fnv = file->f_op->writev;
173         }
174         if (fnv) {
175                 retval = fnv(file, iov, count, &file->f_pos);
176                 goto out;
177         }
178
179         /* Do it by hand, with file-ops */
180         ivp = iov;
181         while (count > 0) {
182                 void * base;
183                 int len, nr;
184
185                 base = ivp->iov_base;
186                 len = ivp->iov_len;
187                 ivp++;
188                 count--;
189
190                 nr = fn(file, base, len, &file->f_pos);
191
192                 if (nr < 0) {
193                         if (!retval)
194                                 retval = nr;
195                         break;
196                 }
197                 retval += nr;
198                 if (nr != len)
199                         break;
200         }
201 out:
202         if (iov != iovstack)
203                 kfree(iov);
204         if ((retval + (type == READ)) > 0)
205                 dnotify_parent(file->f_dentry,
206                                (type == READ) ? DN_ACCESS : DN_MODIFY);
207
208         return retval;
209 }
210
211 asmlinkage long sys32_readv(int fd, struct compat_iovec *vector, u32 count)
212 {
213         struct file *file;
214         int ret = -EBADF;
215
216         file = fget(fd);
217         if (!file || !(file->f_mode & FMODE_READ))
218                 goto out; 
219
220         ret = -EINVAL;
221         if (!file->f_op || (!file->f_op->readv && !file->f_op->read))
222                 goto out;
223
224         ret = do_readv_writev32(READ, file, vector, count);
225
226 out:
227         if (file)
228                 fput(file);
229         return ret;
230 }
231
232 asmlinkage long sys32_writev(int fd, struct compat_iovec *vector, u32 count)
233 {
234         struct file *file;
235         int ret = -EBADF;
236
237         file = fget(fd);
238         if (!file || !(file->f_mode & FMODE_WRITE))
239                 goto out;
240
241         ret = -EINVAL;
242         if (!file->f_op || (!file->f_op->writev && !file->f_op->write))
243                 goto out;
244
245         ret = do_readv_writev32(WRITE, file, vector, count);
246
247 out:
248         if (file)
249                 fput(file);
250         return ret;
251 }
252
253 /* readdir & getdents */
254 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
255 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
256
257 struct old_linux_dirent32 {
258         u32             d_ino;
259         u32             d_offset;
260         unsigned short  d_namlen;
261         char            d_name[1];
262 };
263
264 struct readdir_callback32 {
265         struct old_linux_dirent32 * dirent;
266         int count;
267 };
268
269 static int fillonedir(void * __buf, const char * name, int namlen,
270                                   off_t offset, ino_t ino, unsigned int d_type)
271 {
272         struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
273         struct old_linux_dirent32 * dirent;
274
275         if (buf->count)
276                 return -EINVAL;
277         buf->count++;
278         dirent = buf->dirent;
279         put_user(ino, &dirent->d_ino);
280         put_user(offset, &dirent->d_offset);
281         put_user(namlen, &dirent->d_namlen);
282         copy_to_user(dirent->d_name, name, namlen);
283         put_user(0, dirent->d_name + namlen);
284         return 0;
285 }
286
287 asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
288 {
289         int error = -EBADF;
290         struct file * file;
291         struct readdir_callback32 buf;
292
293         file = fget(fd);
294         if (!file)
295                 goto out;
296
297         buf.count = 0;
298         buf.dirent = dirent;
299
300         error = vfs_readdir(file, (filldir_t)fillonedir, &buf);
301         if (error < 0)
302                 goto out_putf;
303         error = buf.count;
304
305 out_putf:
306         fput(file);
307 out:
308         return error;
309 }
310
311 struct linux_dirent32 {
312         u32             d_ino;
313         u32             d_off;
314         unsigned short  d_reclen;
315         char            d_name[1];
316 };
317
318 struct getdents_callback32 {
319         struct linux_dirent32 * current_dir;
320         struct linux_dirent32 * previous;
321         int count;
322         int error;
323 };
324
325 static int filldir(void * __buf, const char * name, int namlen, off_t offset,
326                    ino_t ino, unsigned int d_type)
327 {
328         struct linux_dirent32 * dirent;
329         struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
330         int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
331
332         buf->error = -EINVAL;   /* only used if we fail.. */
333         if (reclen > buf->count)
334                 return -EINVAL;
335         dirent = buf->previous;
336         if (dirent) {
337                 if (__put_user(offset, &dirent->d_off))
338                         goto efault;
339         }
340         dirent = buf->current_dir;
341         if (__put_user(ino, &dirent->d_ino))
342                 goto efault;
343         if (__put_user(reclen, &dirent->d_reclen))
344                 goto efault;
345         if (copy_to_user(dirent->d_name, name, namlen))
346                 goto efault;
347         if (__put_user(0, dirent->d_name + namlen))
348                 goto efault;
349         if (__put_user(d_type, (char *) dirent + reclen - 1))
350                 goto efault;
351         buf->previous = dirent;
352         dirent = (void *)dirent + reclen;
353         buf->current_dir = dirent;
354         buf->count -= reclen;
355         return 0;
356 efault:
357         buf->error = -EFAULT;
358         return -EFAULT;
359 }
360
361 long sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent,
362                     unsigned int count)
363 {
364         struct file * file;
365         struct linux_dirent32 * lastdirent;
366         struct getdents_callback32 buf;
367         int error;
368
369         error = -EFAULT;
370         if (!access_ok(VERIFY_WRITE, dirent, count))
371                 goto out;
372
373         error = -EBADF;
374         file = fget(fd);
375         if (!file)
376                 goto out;
377
378         buf.current_dir = dirent;
379         buf.previous = NULL;
380         buf.count = count;
381         buf.error = 0;
382
383         error = vfs_readdir(file, (filldir_t)filldir, &buf);
384         if (error < 0)
385                 goto out_putf;
386         error = buf.error;
387         lastdirent = buf.previous;
388         if (lastdirent) {
389                 if (put_user(file->f_pos, &lastdirent->d_off))
390                         error = -EFAULT;
391                 else
392                         error = count - buf.count;
393         }
394
395 out_putf:
396         fput(file);
397 out:
398         return error;
399 }
400
401 /*
402  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
403  * 64-bit unsigned longs.
404  */
405 static inline int
406 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
407 {
408         if (ufdset) {
409                 unsigned long odd;
410
411                 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
412                         return -EFAULT;
413
414                 odd = n & 1UL;
415                 n &= ~1UL;
416                 while (n) {
417                         unsigned long h, l;
418                         __get_user(l, ufdset);
419                         __get_user(h, ufdset+1);
420                         ufdset += 2;
421                         *fdset++ = h << 32 | l;
422                         n -= 2;
423                 }
424                 if (odd)
425                         __get_user(*fdset, ufdset);
426         } else {
427                 /* Tricky, must clear full unsigned long in the
428                  * kernel fdset at the end, this makes sure that
429                  * actually happens.
430                  */
431                 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
432         }
433         return 0;
434 }
435
436 static inline void
437 set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
438 {
439         unsigned long odd;
440
441         if (!ufdset)
442                 return;
443
444         odd = n & 1UL;
445         n &= ~1UL;
446         while (n) {
447                 unsigned long h, l;
448                 l = *fdset++;
449                 h = l >> 32;
450                 __put_user(l, ufdset);
451                 __put_user(h, ufdset+1);
452                 ufdset += 2;
453                 n -= 2;
454         }
455         if (odd)
456                 __put_user(*fdset, ufdset);
457 }
458
459
460
461 #define MAX_SELECT_SECONDS ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
462
463 asmlinkage long sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
464 {
465         fd_set_bits fds;
466         struct compat_timeval *tvp = (struct compat_timeval *)AA(tvp_x);
467         char *bits;
468         unsigned long nn;
469         long timeout;
470         int ret, size, max_fdset;
471
472         timeout = MAX_SCHEDULE_TIMEOUT;
473         if (tvp) {
474                 time_t sec, usec;
475                 if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
476                     || (ret = __get_user(sec, &tvp->tv_sec))
477                     || (ret = __get_user(usec, &tvp->tv_usec)))
478                         goto out_nofds;
479
480                 ret = -EINVAL;
481                 if(sec < 0 || usec < 0)
482                         goto out_nofds;
483
484                 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
485                         timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
486                         timeout += sec * (unsigned long) HZ;
487                 }
488         }
489
490         ret = -EINVAL;
491         if (n < 0)
492                 goto out_nofds;
493
494         /* max_fdset can increase, so grab it once to avoid race */
495         max_fdset = current->files->max_fdset;
496         if (n > max_fdset)
497                 n = max_fdset;
498
499         /*
500          * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
501          * since we used fdset we need to allocate memory in units of
502          * long-words. 
503          */
504         ret = -ENOMEM;
505         size = FDS_BYTES(n);
506         bits = kmalloc(6 * size, GFP_KERNEL);
507         if (!bits)
508                 goto out_nofds;
509         fds.in      = (unsigned long *)  bits;
510         fds.out     = (unsigned long *) (bits +   size);
511         fds.ex      = (unsigned long *) (bits + 2*size);
512         fds.res_in  = (unsigned long *) (bits + 3*size);
513         fds.res_out = (unsigned long *) (bits + 4*size);
514         fds.res_ex  = (unsigned long *) (bits + 5*size);
515
516         nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
517         if ((ret = get_fd_set32(nn, fds.in, inp)) ||
518             (ret = get_fd_set32(nn, fds.out, outp)) ||
519             (ret = get_fd_set32(nn, fds.ex, exp)))
520                 goto out;
521         zero_fd_set(n, fds.res_in);
522         zero_fd_set(n, fds.res_out);
523         zero_fd_set(n, fds.res_ex);
524
525         ret = do_select(n, &fds, &timeout);
526
527         if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
528                 time_t sec = 0, usec = 0;
529                 if (timeout) {
530                         sec = timeout / HZ;
531                         usec = timeout % HZ;
532                         usec *= (1000000/HZ);
533                 }
534                 put_user(sec, &tvp->tv_sec);
535                 put_user(usec, &tvp->tv_usec);
536         }
537
538         if (ret < 0)
539                 goto out;
540         if (!ret) {
541                 ret = -ERESTARTNOHAND;
542                 if (signal_pending(current))
543                         goto out;
544                 ret = 0;
545         }
546
547         set_fd_set32(nn, inp, fds.res_in);
548         set_fd_set32(nn, outp, fds.res_out);
549         set_fd_set32(nn, exp, fds.res_ex);
550   
551 out:
552         kfree(bits);
553
554 out_nofds:
555         return ret;
556 }
557
558 int ppc32_select(u32 n, u32* inp, u32* outp, u32* exp, u32 tvp_x)
559 {
560         /* sign extend n */
561         return sys32_select((int)n, inp, outp, exp, tvp_x);
562 }
563
564 int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
565 {
566         long err;
567
568         if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
569             !new_valid_dev(stat->rdev))
570                 return -EOVERFLOW;
571
572         err  = verify_area(VERIFY_WRITE, statbuf, sizeof(*statbuf));
573         err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
574         err |= __put_user(stat->ino, &statbuf->st_ino);
575         err |= __put_user(stat->mode, &statbuf->st_mode);
576         err |= __put_user(stat->nlink, &statbuf->st_nlink);
577         err |= __put_user(stat->uid, &statbuf->st_uid);
578         err |= __put_user(stat->gid, &statbuf->st_gid);
579         err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
580         err |= __put_user(stat->size, &statbuf->st_size);
581         err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime);
582         err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
583         err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
584         err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
585         err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
586         err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
587         err |= __put_user(stat->blksize, &statbuf->st_blksize);
588         err |= __put_user(stat->blocks, &statbuf->st_blocks);
589         err |= __put_user(0, &statbuf->__unused4[0]);
590         err |= __put_user(0, &statbuf->__unused4[1]);
591
592         return err;
593 }
594
595 /* Note: it is necessary to treat option as an unsigned int,
596  * with the corresponding cast to a signed int to insure that the 
597  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
598  * and the register representation of a signed int (msr in 64-bit mode) is performed.
599  */
600 asmlinkage long sys32_sysfs(u32 option, u32 arg1, u32 arg2)
601 {
602         return sys_sysfs((int)option, arg1, arg2);
603 }
604
605 /* Handle adjtimex compatibility. */
606 struct timex32 {
607         u32 modes;
608         s32 offset, freq, maxerror, esterror;
609         s32 status, constant, precision, tolerance;
610         struct compat_timeval time;
611         s32 tick;
612         s32 ppsfreq, jitter, shift, stabil;
613         s32 jitcnt, calcnt, errcnt, stbcnt;
614         s32  :32; s32  :32; s32  :32; s32  :32;
615         s32  :32; s32  :32; s32  :32; s32  :32;
616         s32  :32; s32  :32; s32  :32; s32  :32;
617 };
618
619 extern int do_adjtimex(struct timex *);
620 extern void ppc_adjtimex(void);
621
622 asmlinkage long sys32_adjtimex(struct timex32 *utp)
623 {
624         struct timex txc;
625         int ret;
626         
627         memset(&txc, 0, sizeof(struct timex));
628
629         if(get_user(txc.modes, &utp->modes) ||
630            __get_user(txc.offset, &utp->offset) ||
631            __get_user(txc.freq, &utp->freq) ||
632            __get_user(txc.maxerror, &utp->maxerror) ||
633            __get_user(txc.esterror, &utp->esterror) ||
634            __get_user(txc.status, &utp->status) ||
635            __get_user(txc.constant, &utp->constant) ||
636            __get_user(txc.precision, &utp->precision) ||
637            __get_user(txc.tolerance, &utp->tolerance) ||
638            __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
639            __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
640            __get_user(txc.tick, &utp->tick) ||
641            __get_user(txc.ppsfreq, &utp->ppsfreq) ||
642            __get_user(txc.jitter, &utp->jitter) ||
643            __get_user(txc.shift, &utp->shift) ||
644            __get_user(txc.stabil, &utp->stabil) ||
645            __get_user(txc.jitcnt, &utp->jitcnt) ||
646            __get_user(txc.calcnt, &utp->calcnt) ||
647            __get_user(txc.errcnt, &utp->errcnt) ||
648            __get_user(txc.stbcnt, &utp->stbcnt))
649                 return -EFAULT;
650
651         ret = do_adjtimex(&txc);
652
653         /* adjust the conversion of TB to time of day to track adjtimex */
654         ppc_adjtimex();
655
656         if(put_user(txc.modes, &utp->modes) ||
657            __put_user(txc.offset, &utp->offset) ||
658            __put_user(txc.freq, &utp->freq) ||
659            __put_user(txc.maxerror, &utp->maxerror) ||
660            __put_user(txc.esterror, &utp->esterror) ||
661            __put_user(txc.status, &utp->status) ||
662            __put_user(txc.constant, &utp->constant) ||
663            __put_user(txc.precision, &utp->precision) ||
664            __put_user(txc.tolerance, &utp->tolerance) ||
665            __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
666            __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
667            __put_user(txc.tick, &utp->tick) ||
668            __put_user(txc.ppsfreq, &utp->ppsfreq) ||
669            __put_user(txc.jitter, &utp->jitter) ||
670            __put_user(txc.shift, &utp->shift) ||
671            __put_user(txc.stabil, &utp->stabil) ||
672            __put_user(txc.jitcnt, &utp->jitcnt) ||
673            __put_user(txc.calcnt, &utp->calcnt) ||
674            __put_user(txc.errcnt, &utp->errcnt) ||
675            __put_user(txc.stbcnt, &utp->stbcnt))
676                 ret = -EFAULT;
677
678         return ret;
679 }
680
681 /* Stuff for NFS server syscalls... */
682 struct nfsctl_svc32 {
683         u16                     svc32_port;
684         s32                     svc32_nthreads;
685 };
686
687 struct nfsctl_client32 {
688         s8                      cl32_ident[NFSCLNT_IDMAX+1];
689         s32                     cl32_naddr;
690         struct in_addr          cl32_addrlist[NFSCLNT_ADDRMAX];
691         s32                     cl32_fhkeytype;
692         s32                     cl32_fhkeylen;
693         u8                      cl32_fhkey[NFSCLNT_KEYMAX];
694 };
695
696 struct nfsctl_export32 {
697         s8                      ex32_client[NFSCLNT_IDMAX+1];
698         s8                      ex32_path[NFS_MAXPATHLEN+1];
699         compat_dev_t    ex32_dev;
700         compat_ino_t    ex32_ino;
701         s32                     ex32_flags;
702         compat_uid_t    ex32_anon_uid;
703         compat_gid_t    ex32_anon_gid;
704 };
705
706 struct nfsctl_fdparm32 {
707         struct sockaddr         gd32_addr;
708         s8                      gd32_path[NFS_MAXPATHLEN+1];
709         s32                     gd32_version;
710 };
711
712 struct nfsctl_fsparm32 {
713         struct sockaddr         gd32_addr;
714         s8                      gd32_path[NFS_MAXPATHLEN+1];
715         s32                     gd32_maxlen;
716 };
717
718 struct nfsctl_arg32 {
719         s32                     ca32_version;   /* safeguard */
720         union {
721                 struct nfsctl_svc32     u32_svc;
722                 struct nfsctl_client32  u32_client;
723                 struct nfsctl_export32  u32_export;
724                 struct nfsctl_fdparm32  u32_getfd;
725                 struct nfsctl_fsparm32  u32_getfs;
726         } u;
727 #define ca32_svc        u.u32_svc
728 #define ca32_client     u.u32_client
729 #define ca32_export     u.u32_export
730 #define ca32_getfd      u.u32_getfd
731 #define ca32_getfs      u.u32_getfs
732 };
733
734 union nfsctl_res32 {
735         __u8                    cr32_getfh[NFS_FHSIZE];
736         struct knfsd_fh         cr32_getfs;
737 };
738
739 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
740 {
741         int err;
742         
743         err = __get_user(karg->ca_version, &arg32->ca32_version);
744         err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
745         err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
746         return err;
747 }
748
749 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
750 {
751         int err;
752         
753         err = __get_user(karg->ca_version, &arg32->ca32_version);
754         err |= copy_from_user(&karg->ca_client.cl_ident[0],
755                           &arg32->ca32_client.cl32_ident[0],
756                           NFSCLNT_IDMAX);
757         err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
758         err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
759                           &arg32->ca32_client.cl32_addrlist[0],
760                           (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
761         err |= __get_user(karg->ca_client.cl_fhkeytype,
762                       &arg32->ca32_client.cl32_fhkeytype);
763         err |= __get_user(karg->ca_client.cl_fhkeylen,
764                       &arg32->ca32_client.cl32_fhkeylen);
765         err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
766                           &arg32->ca32_client.cl32_fhkey[0],
767                           NFSCLNT_KEYMAX);
768
769         if(err) return -EFAULT;
770         return 0;
771 }
772
773 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
774 {
775         int err;
776         
777         err = __get_user(karg->ca_version, &arg32->ca32_version);
778         err |= copy_from_user(&karg->ca_export.ex_client[0],
779                           &arg32->ca32_export.ex32_client[0],
780                           NFSCLNT_IDMAX);
781         err |= copy_from_user(&karg->ca_export.ex_path[0],
782                           &arg32->ca32_export.ex32_path[0],
783                           NFS_MAXPATHLEN);
784         err |= __get_user(karg->ca_export.ex_dev,
785                       &arg32->ca32_export.ex32_dev);
786         err |= __get_user(karg->ca_export.ex_ino,
787                       &arg32->ca32_export.ex32_ino);
788         err |= __get_user(karg->ca_export.ex_flags,
789                       &arg32->ca32_export.ex32_flags);
790         err |= __get_user(karg->ca_export.ex_anon_uid,
791                       &arg32->ca32_export.ex32_anon_uid);
792         err |= __get_user(karg->ca_export.ex_anon_gid,
793                       &arg32->ca32_export.ex32_anon_gid);
794         karg->ca_export.ex_anon_uid = karg->ca_export.ex_anon_uid;
795         karg->ca_export.ex_anon_gid = karg->ca_export.ex_anon_gid;
796
797         if(err) return -EFAULT;
798         return 0;
799 }
800
801 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
802 {
803         int err;
804         
805         err = __get_user(karg->ca_version, &arg32->ca32_version);
806         err |= copy_from_user(&karg->ca_getfd.gd_addr,
807                           &arg32->ca32_getfd.gd32_addr,
808                           (sizeof(struct sockaddr)));
809         err |= copy_from_user(&karg->ca_getfd.gd_path,
810                           &arg32->ca32_getfd.gd32_path,
811                           (NFS_MAXPATHLEN+1));
812         err |= __get_user(karg->ca_getfd.gd_version,
813                       &arg32->ca32_getfd.gd32_version);
814
815         if(err) return -EFAULT;
816         return 0;
817 }
818
819 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
820 {
821         int err;
822         
823         err = __get_user(karg->ca_version, &arg32->ca32_version);
824         err |= copy_from_user(&karg->ca_getfs.gd_addr,
825                           &arg32->ca32_getfs.gd32_addr,
826                           (sizeof(struct sockaddr)));
827         err |= copy_from_user(&karg->ca_getfs.gd_path,
828                           &arg32->ca32_getfs.gd32_path,
829                           (NFS_MAXPATHLEN+1));
830         err |= __get_user(karg->ca_getfs.gd_maxlen,
831                       &arg32->ca32_getfs.gd32_maxlen);
832
833         if(err) return -EFAULT;
834         return 0;
835 }
836
837 /* This really doesn't need translations, we are only passing
838  * back a union which contains opaque nfs file handle data.
839  */
840 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
841 {
842         int err;
843
844         err = copy_to_user(res32, kres, sizeof(*res32));
845
846         if(err) return -EFAULT;
847         return 0;
848 }
849
850 /* Note: it is necessary to treat cmd_parm as an unsigned int, 
851  * with the corresponding cast to a signed int to insure that the 
852  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
853  * and the register representation of a signed int (msr in 64-bit mode) is performed.
854  */
855 int asmlinkage sys32_nfsservctl(u32 cmd_parm, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
856 {
857   int cmd = (int)cmd_parm;
858         struct nfsctl_arg *karg = NULL;
859         union nfsctl_res *kres = NULL;
860         mm_segment_t oldfs;
861         int err;
862
863         karg = kmalloc(sizeof(*karg), GFP_USER);
864         if(!karg)
865                 return -ENOMEM;
866         if(res32) {
867                 kres = kmalloc(sizeof(*kres), GFP_USER);
868                 if(!kres) {
869                         kfree(karg);
870                         return -ENOMEM;
871                 }
872         }
873         switch(cmd) {
874         case NFSCTL_SVC:
875                 err = nfs_svc32_trans(karg, arg32);
876                 break;
877         case NFSCTL_ADDCLIENT:
878                 err = nfs_clnt32_trans(karg, arg32);
879                 break;
880         case NFSCTL_DELCLIENT:
881                 err = nfs_clnt32_trans(karg, arg32);
882                 break;
883         case NFSCTL_EXPORT:
884         case NFSCTL_UNEXPORT:
885                 err = nfs_exp32_trans(karg, arg32);
886                 break;
887         case NFSCTL_GETFD:
888                 err = nfs_getfd32_trans(karg, arg32);
889                 break;
890         case NFSCTL_GETFS:
891                 err = nfs_getfs32_trans(karg, arg32);
892                 break;
893         default:
894                 err = -EINVAL;
895                 break;
896         }
897         if(err)
898                 goto done;
899         oldfs = get_fs();
900         set_fs(KERNEL_DS);
901         err = sys_nfsservctl(cmd, karg, kres);
902         set_fs(oldfs);
903
904         if (err)
905                 goto done;
906
907         if((cmd == NFSCTL_GETFD) ||
908            (cmd == NFSCTL_GETFS))
909                 err = nfs_getfh32_res_trans(kres, res32);
910
911 done:
912         if(karg)
913                 kfree(karg);
914         if(kres)
915                 kfree(kres);
916         return err;
917 }
918
919
920
921 /* These are here just in case some old sparc32 binary calls it. */
922 asmlinkage long sys32_pause(void)
923 {
924         current->state = TASK_INTERRUPTIBLE;
925         schedule();
926         
927         return -ERESTARTNOHAND;
928 }
929
930
931
932 static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
933 {
934         long usec;
935
936         if (!access_ok(VERIFY_READ, i, sizeof(*i)))
937                 return -EFAULT;
938         if (__get_user(o->tv_sec, &i->tv_sec))
939                 return -EFAULT;
940         if (__get_user(usec, &i->tv_usec))
941                 return -EFAULT;
942         o->tv_nsec = usec * 1000;
943         return 0;
944 }
945
946 static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
947 {
948         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
949                 (__put_user(i->tv_sec, &o->tv_sec) |
950                  __put_user(i->tv_usec, &o->tv_usec)));
951 }
952
953 struct sysinfo32 {
954         s32 uptime;
955         u32 loads[3];
956         u32 totalram;
957         u32 freeram;
958         u32 sharedram;
959         u32 bufferram;
960         u32 totalswap;
961         u32 freeswap;
962         unsigned short procs;
963         unsigned short pad;
964         u32 totalhigh;
965         u32 freehigh;
966         u32 mem_unit;
967         char _f[20-2*sizeof(int)-sizeof(int)];
968 };
969
970 asmlinkage long sys32_sysinfo(struct sysinfo32 *info)
971 {
972         struct sysinfo s;
973         int ret, err;
974         int bitcount=0;
975         mm_segment_t old_fs = get_fs ();
976         
977         set_fs (KERNEL_DS);
978         ret = sys_sysinfo(&s);
979         set_fs (old_fs);
980         /* Check to see if any memory value is too large for 32-bit and
981          * scale down if needed.
982          */
983         if ((s.totalram >> 32) || (s.totalswap >> 32)) {
984             while (s.mem_unit < PAGE_SIZE) {
985                 s.mem_unit <<= 1;
986                 bitcount++;
987             }
988             s.totalram >>=bitcount;
989             s.freeram >>= bitcount;
990             s.sharedram >>= bitcount;
991             s.bufferram >>= bitcount;
992             s.totalswap >>= bitcount;
993             s.freeswap >>= bitcount;
994             s.totalhigh >>= bitcount;
995             s.freehigh >>= bitcount;
996         }
997
998         err = put_user (s.uptime, &info->uptime);
999         err |= __put_user (s.loads[0], &info->loads[0]);
1000         err |= __put_user (s.loads[1], &info->loads[1]);
1001         err |= __put_user (s.loads[2], &info->loads[2]);
1002         err |= __put_user (s.totalram, &info->totalram);
1003         err |= __put_user (s.freeram, &info->freeram);
1004         err |= __put_user (s.sharedram, &info->sharedram);
1005         err |= __put_user (s.bufferram, &info->bufferram);
1006         err |= __put_user (s.totalswap, &info->totalswap);
1007         err |= __put_user (s.freeswap, &info->freeswap);
1008         err |= __put_user (s.procs, &info->procs);
1009         err |= __put_user (s.totalhigh, &info->totalhigh);
1010         err |= __put_user (s.freehigh, &info->freehigh);
1011         err |= __put_user (s.mem_unit, &info->mem_unit);
1012         if (err)
1013                 return -EFAULT;
1014         
1015         return ret;
1016 }
1017
1018
1019
1020
1021 /* Translations due to time_t size differences.  Which affects all
1022    sorts of things, like timeval and itimerval.  */
1023 extern struct timezone sys_tz;
1024
1025 asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
1026 {
1027         if (tv) {
1028                 struct timeval ktv;
1029                 do_gettimeofday(&ktv);
1030                 if (put_tv32(tv, &ktv))
1031                         return -EFAULT;
1032         }
1033         if (tz) {
1034                 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
1035                         return -EFAULT;
1036         }
1037         
1038         return 0;
1039 }
1040
1041
1042
1043 asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
1044 {
1045         struct timespec kts;
1046         struct timezone ktz;
1047         
1048         if (tv) {
1049                 if (get_ts32(&kts, tv))
1050                         return -EFAULT;
1051         }
1052         if (tz) {
1053                 if (copy_from_user(&ktz, tz, sizeof(ktz)))
1054                         return -EFAULT;
1055         }
1056
1057         return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
1058 }
1059
1060
1061 struct msgbuf32 {
1062         compat_long_t mtype; 
1063         char mtext[1];
1064 };
1065
1066 struct semid_ds32 {
1067         struct ipc_perm sem_perm;
1068         compat_time_t sem_otime;
1069         compat_time_t sem_ctime;
1070         compat_uptr_t sem_base;
1071         compat_uptr_t sem_pending;
1072         compat_uptr_t sem_pending_last;
1073         compat_uptr_t undo;
1074         unsigned short sem_nsems;
1075 };
1076
1077 struct semid64_ds32 {
1078         struct ipc64_perm sem_perm;
1079         unsigned int __unused1;
1080         compat_time_t sem_otime;
1081         unsigned int __unused2;
1082         compat_time_t sem_ctime;
1083         compat_ulong_t sem_nsems;
1084         compat_ulong_t __unused3;
1085         compat_ulong_t __unused4;
1086 };
1087
1088 struct msqid_ds32 {
1089         struct ipc_perm msg_perm;
1090         compat_uptr_t msg_first;
1091         compat_uptr_t msg_last;
1092         compat_time_t msg_stime;
1093         compat_time_t msg_rtime;
1094         compat_time_t msg_ctime;
1095         compat_ulong_t msg_lcbytes;
1096         compat_ulong_t msg_lqbytes;
1097         unsigned short msg_cbytes;
1098         unsigned short msg_qnum;
1099         unsigned short msg_qbytes;
1100         compat_ipc_pid_t msg_lspid;
1101         compat_ipc_pid_t msg_lrpid;
1102 };
1103
1104 struct msqid64_ds32 {
1105         struct ipc64_perm msg_perm;
1106         unsigned int __unused1;
1107         compat_time_t msg_stime;
1108         unsigned int __unused2;
1109         compat_time_t msg_rtime;
1110         unsigned int __unused3;
1111         compat_time_t msg_ctime;
1112         compat_ulong_t msg_cbytes;
1113         compat_ulong_t msg_qnum;
1114         compat_ulong_t msg_qbytes;
1115         compat_pid_t msg_lspid;
1116         compat_pid_t msg_lrpid;
1117         compat_ulong_t __unused4;
1118         compat_ulong_t __unused5;
1119 };
1120
1121 struct shmid_ds32 {
1122         struct ipc_perm shm_perm;
1123         int shm_segsz;
1124         compat_time_t shm_atime;
1125         compat_time_t shm_dtime;
1126         compat_time_t shm_ctime;
1127         compat_ipc_pid_t shm_cpid;
1128         compat_ipc_pid_t shm_lpid;
1129         unsigned short shm_nattch;
1130         unsigned short __unused;
1131         compat_uptr_t __unused2;
1132         compat_uptr_t __unused3;
1133 };
1134
1135 struct shmid64_ds32 {
1136         struct ipc64_perm shm_perm;
1137         unsigned int __unused1;
1138         compat_time_t shm_atime;
1139         unsigned int __unused2;
1140         compat_time_t shm_dtime;
1141         unsigned int __unused3;
1142         compat_time_t shm_ctime;
1143         unsigned int __unused4;
1144         compat_size_t shm_segsz;
1145         compat_pid_t shm_cpid;
1146         compat_pid_t shm_lpid;
1147         compat_ulong_t shm_nattch;
1148         compat_ulong_t __unused5;
1149         compat_ulong_t __unused6;
1150 };
1151
1152 /*
1153  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit
1154  * emulation..
1155  *
1156  * This is really horribly ugly.
1157  */
1158 static long do_sys32_semctl(int first, int second, int third, void *uptr)
1159 {
1160         union semun fourth;
1161         u32 pad;
1162         int err, err2;
1163         mm_segment_t old_fs;
1164
1165         if (!uptr)
1166                 return -EINVAL;
1167         err = -EFAULT;
1168         if (get_user(pad, (u32 *)uptr))
1169                 return err;
1170         if ((third & ~IPC_64) == SETVAL)
1171                 fourth.val = (int)pad;
1172         else
1173                 fourth.__pad = (void *)A(pad);
1174         switch (third & (~IPC_64)) {
1175
1176         case IPC_INFO:
1177         case IPC_RMID:
1178         case SEM_INFO:
1179         case GETVAL:
1180         case GETPID:
1181         case GETNCNT:
1182         case GETZCNT:
1183         case GETALL:
1184         case SETALL:
1185         case SETVAL:
1186                 err = sys_semctl(first, second, third, fourth);
1187                 break;
1188
1189         case IPC_STAT:
1190         case SEM_STAT:
1191                 if (third & IPC_64) {
1192                         struct semid64_ds s64;
1193                         struct semid64_ds32 *usp;
1194
1195                         usp = (struct semid64_ds32 *)A(pad);
1196                         fourth.__pad = &s64;
1197                         old_fs = get_fs();
1198                         set_fs(KERNEL_DS);
1199                         err = sys_semctl(first, second, third, fourth);
1200                         set_fs(old_fs);
1201                         err2 = copy_to_user(&usp->sem_perm, &s64.sem_perm,
1202                                             sizeof(struct ipc64_perm));
1203                         err2 |= __put_user(s64.sem_otime, &usp->sem_otime);
1204                         err2 |= __put_user(s64.sem_ctime, &usp->sem_ctime);
1205                         err2 |= __put_user(s64.sem_nsems, &usp->sem_nsems);
1206                         if (err2)
1207                                 err = -EFAULT;
1208                 } else {
1209                         struct semid_ds s;
1210                         struct semid_ds32 *usp;
1211
1212                         usp = (struct semid_ds32 *)A(pad);
1213                         fourth.__pad = &s;
1214                         old_fs = get_fs();
1215                         set_fs(KERNEL_DS);
1216                         err = sys_semctl(first, second, third, fourth);
1217                         set_fs(old_fs);
1218                         err2 = copy_to_user(&usp->sem_perm, &s.sem_perm,
1219                                             sizeof(struct ipc_perm));
1220                         err2 |= __put_user(s.sem_otime, &usp->sem_otime);
1221                         err2 |= __put_user(s.sem_ctime, &usp->sem_ctime);
1222                         err2 |= __put_user(s.sem_nsems, &usp->sem_nsems);
1223                         if (err2)
1224                                 err = -EFAULT;
1225                 }
1226                 break;
1227  
1228         case IPC_SET:
1229                 if (third & IPC_64) {
1230                         struct semid64_ds s64;
1231                         struct semid64_ds32 *usp;
1232
1233                         usp = (struct semid64_ds32 *)A(pad);
1234
1235                         err = get_user(s64.sem_perm.uid, &usp->sem_perm.uid);
1236                         err |= __get_user(s64.sem_perm.gid,
1237                                           &usp->sem_perm.gid);
1238                         err |= __get_user(s64.sem_perm.mode,
1239                                           &usp->sem_perm.mode);
1240                         if (err)
1241                                 goto out;
1242                         fourth.__pad = &s64;
1243
1244                         old_fs = get_fs();
1245                         set_fs(KERNEL_DS);
1246                         err = sys_semctl(first, second, third, fourth);
1247                         set_fs(old_fs);
1248
1249                 } else {
1250                         struct semid_ds s;
1251                         struct semid_ds32 *usp;
1252
1253                         usp = (struct semid_ds32 *)A(pad);
1254
1255                         err = get_user(s.sem_perm.uid, &usp->sem_perm.uid);
1256                         err |= __get_user(s.sem_perm.gid,
1257                                           &usp->sem_perm.gid);
1258                         err |= __get_user(s.sem_perm.mode,
1259                                           &usp->sem_perm.mode);
1260                         if (err)
1261                                 goto out;
1262                         fourth.__pad = &s;
1263
1264                         old_fs = get_fs();
1265                         set_fs(KERNEL_DS);
1266                         err = sys_semctl(first, second, third, fourth);
1267                         set_fs(old_fs);
1268                 }
1269                 break;
1270         default:
1271                 err = -EINVAL;
1272         }
1273 out:
1274         return err;
1275 }
1276
1277 #define MAXBUF (64*1024)
1278
1279 static int 
1280 do_sys32_msgsnd(int first, int second, int third, void *uptr)
1281 {
1282         struct msgbuf *p;
1283         struct msgbuf32 *up = (struct msgbuf32 *)uptr;
1284         mm_segment_t old_fs;
1285         int err;
1286
1287         if (second < 0 || (second >= MAXBUF-sizeof(struct msgbuf)))
1288                 return -EINVAL;
1289
1290         p = kmalloc(second + sizeof(struct msgbuf), GFP_USER);
1291         if (!p)
1292                 return -ENOMEM;
1293         err = get_user(p->mtype, &up->mtype);
1294         err |= copy_from_user(p->mtext, &up->mtext, second);
1295         if (err) {
1296                 err = -EFAULT;
1297                 goto out;
1298         }
1299         old_fs = get_fs();
1300         set_fs(KERNEL_DS);
1301         err = sys_msgsnd(first, p, second, third);
1302         set_fs(old_fs);
1303 out:
1304         kfree(p);
1305         return err;
1306 }
1307
1308 static int
1309 do_sys32_msgrcv(int first, int second, int msgtyp, int third,
1310                 int version, void *uptr)
1311 {
1312         struct msgbuf32 *up;
1313         struct msgbuf *p;
1314         mm_segment_t old_fs;
1315         int err;
1316
1317         if (second < 0 || (second >= MAXBUF-sizeof(struct msgbuf)))
1318                 return -EINVAL;
1319
1320         if (!version) {
1321                 struct ipc_kludge_32 *uipck = (struct ipc_kludge_32 *)uptr;
1322                 struct ipc_kludge_32 ipck;
1323
1324                 err = -EINVAL;
1325                 if (!uptr)
1326                         goto out;
1327                 err = -EFAULT;
1328                 if (copy_from_user(&ipck, uipck, sizeof(struct ipc_kludge_32)))
1329                         goto out;
1330                 uptr = (void *)A(ipck.msgp);
1331                 msgtyp = ipck.msgtyp;
1332         }
1333         err = -ENOMEM;
1334         p = kmalloc(second + sizeof (struct msgbuf), GFP_USER);
1335         if (!p)
1336                 goto out;
1337         old_fs = get_fs();
1338         set_fs(KERNEL_DS);
1339         err = sys_msgrcv(first, p, second, msgtyp, third);
1340         set_fs(old_fs);
1341         if (err < 0)
1342                 goto free_then_out;
1343         up = (struct msgbuf32 *)uptr;
1344         if (put_user(p->mtype, &up->mtype) ||
1345             copy_to_user(&up->mtext, p->mtext, err))
1346                 err = -EFAULT;
1347 free_then_out:
1348         kfree(p);
1349 out:
1350         return err;
1351 }
1352
1353 static int
1354 do_sys32_msgctl(int first, int second, void *uptr)
1355 {
1356         int err = -EINVAL, err2;
1357         mm_segment_t old_fs;
1358
1359         switch (second & (~IPC_64)) {
1360
1361         case IPC_INFO:
1362         case IPC_RMID:
1363         case MSG_INFO:
1364                 err = sys_msgctl(first, second, (struct msqid_ds *)uptr);
1365                 break;
1366
1367         case IPC_SET:
1368                 if (second & IPC_64) {
1369                         struct msqid64_ds m64;
1370                         struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
1371
1372                         err2 = copy_from_user(&m64.msg_perm, &up->msg_perm,
1373                                               sizeof(struct ipc64_perm));
1374                         err2 |= __get_user(m64.msg_qbytes, &up->msg_qbytes);
1375                         if (err2) {
1376                                 err = -EFAULT;
1377                                 break;
1378                         }
1379                         old_fs = get_fs();
1380                         set_fs(KERNEL_DS);
1381                         err = sys_msgctl(first, second,
1382                                          (struct msqid_ds *)&m64);
1383                         set_fs(old_fs);
1384                 } else {
1385                         struct msqid_ds m;
1386                         struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
1387
1388                         err2 = copy_from_user(&m.msg_perm, &up->msg_perm,
1389                                               sizeof(struct ipc_perm));
1390                         err2 |= __get_user(m.msg_qbytes, &up->msg_qbytes);
1391                         if (err2) {
1392                                 err = -EFAULT;
1393                                 break;
1394                         }
1395                         old_fs = get_fs();
1396                         set_fs(KERNEL_DS);
1397                         err = sys_msgctl(first, second, &m);
1398                         set_fs(old_fs);
1399                 }
1400                 break;
1401
1402         case IPC_STAT:
1403         case MSG_STAT:
1404                 if (second & IPC_64) {
1405                         struct msqid64_ds m64;
1406                         struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
1407
1408                         old_fs = get_fs();
1409                         set_fs(KERNEL_DS);
1410                         err = sys_msgctl(first, second,
1411                                          (struct msqid_ds *)&m64);
1412                         set_fs(old_fs);
1413
1414                         err2 = copy_to_user(&up->msg_perm, &m64.msg_perm,
1415                                             sizeof(struct ipc64_perm));
1416                         err2 |= __put_user(m64.msg_stime, &up->msg_stime);
1417                         err2 |= __put_user(m64.msg_rtime, &up->msg_rtime);
1418                         err2 |= __put_user(m64.msg_ctime, &up->msg_ctime);
1419                         err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes);
1420                         err2 |= __put_user(m64.msg_qnum, &up->msg_qnum);
1421                         err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes);
1422                         err2 |= __put_user(m64.msg_lspid, &up->msg_lspid);
1423                         err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid);
1424                         if (err2)
1425                                 err = -EFAULT;
1426                 } else {
1427                         struct msqid64_ds m;
1428                         struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
1429
1430                         old_fs = get_fs();
1431                         set_fs(KERNEL_DS);
1432                         err = sys_msgctl(first, second, (struct msqid_ds *)&m);
1433                         set_fs(old_fs);
1434
1435                         err2 = copy_to_user(&up->msg_perm, &m.msg_perm,
1436                                             sizeof(struct ipc_perm));
1437                         err2 |= __put_user(m.msg_stime, &up->msg_stime);
1438                         err2 |= __put_user(m.msg_rtime, &up->msg_rtime);
1439                         err2 |= __put_user(m.msg_ctime, &up->msg_ctime);
1440                         err2 |= __put_user(m.msg_cbytes, &up->msg_cbytes);
1441                         err2 |= __put_user(m.msg_qnum, &up->msg_qnum);
1442                         err2 |= __put_user(m.msg_qbytes, &up->msg_qbytes);
1443                         err2 |= __put_user(m.msg_lspid, &up->msg_lspid);
1444                         err2 |= __put_user(m.msg_lrpid, &up->msg_lrpid);
1445                         if (err2)
1446                                 err = -EFAULT;
1447                 }
1448                 break;
1449         }
1450         return err;
1451 }
1452
1453 static int
1454 do_sys32_shmat(int first, int second, int third, int version, void *uptr)
1455 {
1456         unsigned long raddr;
1457         u32 *uaddr = (u32 *)A((u32)third);
1458         int err = -EINVAL;
1459
1460         if (version == 1)
1461                 return err;
1462         err = do_shmat(first, uptr, second, &raddr);
1463         if (err)
1464                 return err;
1465         err = put_user(raddr, uaddr);
1466         return err;
1467 }
1468
1469 static int
1470 do_sys32_shmctl(int first, int second, void *uptr)
1471 {
1472         int err = -EINVAL, err2;
1473         mm_segment_t old_fs;
1474
1475         switch (second & (~IPC_64)) {
1476
1477         case IPC_INFO:
1478         case IPC_RMID:
1479         case SHM_LOCK:
1480         case SHM_UNLOCK:
1481                 err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
1482                 break;
1483         case IPC_SET:
1484                 if (second & IPC_64) {
1485                         struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
1486                         struct shmid64_ds s64;
1487
1488                         err = get_user(s64.shm_perm.uid, &up->shm_perm.uid);
1489                         err |= __get_user(s64.shm_perm.gid, &up->shm_perm.gid);
1490                         err |= __get_user(s64.shm_perm.mode,
1491                                           &up->shm_perm.mode);
1492                         if (err)
1493                                 break;
1494                         old_fs = get_fs();
1495                         set_fs(KERNEL_DS);
1496                         err = sys_shmctl(first, second,
1497                                          (struct shmid_ds *)&s64);
1498                         set_fs(old_fs);
1499                 } else {
1500                         struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
1501                         struct shmid_ds s;
1502
1503                         err = get_user(s.shm_perm.uid, &up->shm_perm.uid);
1504                         err |= __get_user(s.shm_perm.gid, &up->shm_perm.gid);
1505                         err |= __get_user(s.shm_perm.mode, &up->shm_perm.mode);
1506                         if (err)
1507                                 break;
1508                         old_fs = get_fs();
1509                         set_fs(KERNEL_DS);
1510                         err = sys_shmctl(first, second, &s);
1511                         set_fs(old_fs);
1512                 }
1513                 break;
1514
1515         case IPC_STAT:
1516         case SHM_STAT:
1517                 if (second & IPC_64) {
1518                         struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
1519                         struct shmid64_ds s64;
1520
1521                         old_fs = get_fs();
1522                         set_fs(KERNEL_DS);
1523                         err = sys_shmctl(first, second,
1524                                          (struct shmid_ds *)&s64);
1525                         set_fs(old_fs);
1526                         if (err < 0)
1527                                 break;
1528
1529                         err2 = copy_to_user(&up->shm_perm, &s64.shm_perm,
1530                                             sizeof(struct ipc64_perm));
1531                         err2 |= __put_user(s64.shm_atime, &up->shm_atime);
1532                         err2 |= __put_user(s64.shm_dtime, &up->shm_dtime);
1533                         err2 |= __put_user(s64.shm_ctime, &up->shm_ctime);
1534                         err2 |= __put_user(s64.shm_segsz, &up->shm_segsz);
1535                         err2 |= __put_user(s64.shm_nattch, &up->shm_nattch);
1536                         err2 |= __put_user(s64.shm_cpid, &up->shm_cpid);
1537                         err2 |= __put_user(s64.shm_lpid, &up->shm_lpid);
1538                         if (err2)
1539                                 err = -EFAULT;
1540                 } else {
1541                         struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
1542                         struct shmid_ds s;
1543
1544                         old_fs = get_fs();
1545                         set_fs(KERNEL_DS);
1546                         err = sys_shmctl(first, second, &s);
1547                         set_fs(old_fs);
1548                         if (err < 0)
1549                                 break;
1550
1551                         err2 = copy_to_user(&up->shm_perm, &s.shm_perm,
1552                                             sizeof(struct ipc_perm));
1553                         err2 |= __put_user (s.shm_atime, &up->shm_atime);
1554                         err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
1555                         err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
1556                         err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
1557                         err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
1558                         err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
1559                         err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
1560                         if (err2)
1561                                 err = -EFAULT;
1562                 }
1563                 break;
1564
1565         case SHM_INFO: {
1566                 struct shm_info si;
1567                 struct shm_info32 {
1568                         int used_ids;
1569                         u32 shm_tot, shm_rss, shm_swp;
1570                         u32 swap_attempts, swap_successes;
1571                 } *uip = (struct shm_info32 *)uptr;
1572
1573                 old_fs = get_fs();
1574                 set_fs(KERNEL_DS);
1575                 err = sys_shmctl(first, second, (struct shmid_ds *)&si);
1576                 set_fs(old_fs);
1577                 if (err < 0)
1578                         break;
1579                 err2 = put_user(si.used_ids, &uip->used_ids);
1580                 err2 |= __put_user(si.shm_tot, &uip->shm_tot);
1581                 err2 |= __put_user(si.shm_rss, &uip->shm_rss);
1582                 err2 |= __put_user(si.shm_swp, &uip->shm_swp);
1583                 err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
1584                 err2 |= __put_user(si.swap_successes, &uip->swap_successes);
1585                 if (err2)
1586                         err = -EFAULT;
1587                 break;
1588         }
1589         }
1590         return err;
1591 }
1592
1593 static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems,
1594                             const struct compat_timespec *timeout32)
1595 {
1596         struct compat_timespec t32;
1597         struct timespec *t64 = compat_alloc_user_space(sizeof(*t64));
1598
1599         if (copy_from_user(&t32, timeout32, sizeof(t32)))
1600                 return -EFAULT;
1601
1602         if (put_user(t32.tv_sec, &t64->tv_sec) ||
1603             put_user(t32.tv_nsec, &t64->tv_nsec))
1604                 return -EFAULT;
1605
1606         return sys_semtimedop(semid, tsems, nsems, t64);
1607 }
1608
1609 /*
1610  * Note: it is necessary to treat first_parm, second_parm, and
1611  * third_parm as unsigned ints, with the corresponding cast to a
1612  * signed int to insure that the proper conversion (sign extension)
1613  * between the register representation of a signed int (msr in 32-bit
1614  * mode) and the register representation of a signed int (msr in
1615  * 64-bit mode) is performed.
1616  */
1617 asmlinkage long sys32_ipc(u32 call, u32 first_parm, u32 second_parm, u32 third_parm, u32 ptr, u32 fifth)
1618 {
1619         int first  = (int)first_parm;
1620         int second = (int)second_parm;
1621         int third  = (int)third_parm;
1622         int version, err;
1623         
1624         version = call >> 16; /* hack for backward compatibility */
1625         call &= 0xffff;
1626
1627         switch (call) {
1628
1629         case SEMOP:
1630                 /* struct sembuf is the same on 32 and 64bit :)) */
1631                 err = sys_semtimedop(first, (struct sembuf *)AA(ptr),
1632                                      second, NULL);
1633                 break;
1634         case SEMTIMEDOP:
1635                 err = sys32_semtimedop(first, (struct sembuf *)AA(ptr), second,
1636                                        (const struct compat_timespec *)AA(fifth));
1637                 break;
1638         case SEMGET:
1639                 err = sys_semget(first, second, third);
1640                 break;
1641         case SEMCTL:
1642                 err = do_sys32_semctl(first, second, third,
1643                                       (void *)AA(ptr));
1644                 break;
1645
1646         case MSGSND:
1647                 err = do_sys32_msgsnd(first, second, third,
1648                                       (void *)AA(ptr));
1649                 break;
1650         case MSGRCV:
1651                 err = do_sys32_msgrcv(first, second, fifth, third,
1652                                       version, (void *)AA(ptr));
1653                 break;
1654         case MSGGET:
1655                 err = sys_msgget((key_t)first, second);
1656                 break;
1657         case MSGCTL:
1658                 err = do_sys32_msgctl(first, second, (void *)AA(ptr));
1659                 break;
1660
1661         case SHMAT:
1662                 err = do_sys32_shmat(first, second, third,
1663                                      version, (void *)AA(ptr));
1664                 break;
1665         case SHMDT: 
1666                 err = sys_shmdt((char *)AA(ptr));
1667                 break;
1668         case SHMGET:
1669                 err = sys_shmget(first, second_parm, third);
1670                 break;
1671         case SHMCTL:
1672                 err = do_sys32_shmctl(first, second, (void *)AA(ptr));
1673                 break;
1674         default:
1675                 err = -ENOSYS;
1676                 break;
1677         }
1678         return err;
1679 }
1680
1681 /* Note: it is necessary to treat out_fd and in_fd as unsigned ints, 
1682  * with the corresponding cast to a signed int to insure that the 
1683  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
1684  * and the register representation of a signed int (msr in 64-bit mode) is performed.
1685  */
1686 asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t* offset, u32 count)
1687 {
1688         mm_segment_t old_fs = get_fs();
1689         int ret;
1690         off_t of;
1691         
1692         if (offset && get_user(of, offset))
1693                 return -EFAULT;
1694                 
1695         set_fs(KERNEL_DS);
1696         ret = sys_sendfile((int)out_fd, (int)in_fd, offset ? &of : NULL, count);
1697         set_fs(old_fs);
1698         
1699         if (offset && put_user(of, offset))
1700                 return -EFAULT;
1701                 
1702         return ret;
1703 }
1704
1705 asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t *offset, s32 count)
1706 {
1707         mm_segment_t old_fs = get_fs();
1708         int ret;
1709         loff_t lof;
1710         
1711         if (offset && get_user(lof, offset))
1712                 return -EFAULT;
1713                 
1714         set_fs(KERNEL_DS);
1715         ret = sys_sendfile64(out_fd, in_fd, offset ? &lof : NULL, count);
1716         set_fs(old_fs);
1717         
1718         if (offset && put_user(lof, offset))
1719                 return -EFAULT;
1720                 
1721         return ret;
1722 }
1723
1724 /*
1725  * count32() counts the number of arguments/envelopes
1726  */
1727 static int count32(u32 * argv, int max)
1728 {
1729         int i = 0;
1730
1731         if (argv != NULL) {
1732                 for (;;) {
1733                         u32 p; int error;
1734
1735                         error = get_user(p,argv);
1736                         if (error)
1737                                 return error;
1738                         if (!p)
1739                                 break;
1740                         argv++;
1741                         if (++i > max)
1742                                 return -E2BIG;
1743                 }
1744         }
1745         return i;
1746 }
1747
1748 /*
1749  * 'copy_string32()' copies argument/envelope strings from user
1750  * memory to free pages in kernel mem. These are in a format ready
1751  * to be put directly into the top of new user memory.
1752  */
1753 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
1754 {
1755         while (argc-- > 0) {
1756                 u32 str;
1757                 int len;
1758                 unsigned long pos;
1759
1760                 if (get_user(str, argv + argc) ||
1761                     !str ||
1762                     !(len = strnlen_user((char *)A(str), bprm->p)))
1763                         return -EFAULT;
1764
1765                 if (bprm->p < len)
1766                         return -E2BIG;
1767
1768                 bprm->p -= len;
1769
1770                 pos = bprm->p;
1771                 while (len) {
1772                         char *kaddr;
1773                         struct page *page;
1774                         int offset, bytes_to_copy, new, err;
1775
1776                         offset = pos % PAGE_SIZE;
1777                         page = bprm->page[pos / PAGE_SIZE];
1778                         new = 0;
1779                         if (!page) {
1780                                 page = alloc_page(GFP_USER);
1781                                 bprm->page[pos / PAGE_SIZE] = page;
1782                                 if (!page)
1783                                         return -ENOMEM;
1784                                 new = 1;
1785                         }
1786                         kaddr = (char *)kmap(page);
1787
1788                         if (new && offset)
1789                                 memset(kaddr, 0, offset);
1790                         bytes_to_copy = PAGE_SIZE - offset;
1791                         if (bytes_to_copy > len) {
1792                                 bytes_to_copy = len;
1793                                 if (new)
1794                                         memset(kaddr+offset+len, 0,
1795                                                PAGE_SIZE-offset-len);
1796                         }
1797
1798                         err = copy_from_user(kaddr + offset, (char *)A(str),
1799                                              bytes_to_copy);
1800                         kunmap((unsigned long)kaddr);
1801
1802                         if (err)
1803                                 return -EFAULT;
1804
1805                         pos += bytes_to_copy;
1806                         str += bytes_to_copy;
1807                         len -= bytes_to_copy;
1808                 }
1809         }
1810         return 0;
1811 }
1812
1813 /*
1814  * sys32_execve() executes a new program.
1815  */
1816 static int do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
1817 {
1818         struct linux_binprm bprm;
1819         struct file * file;
1820         int retval;
1821         int i;
1822
1823         sched_balance_exec();
1824
1825         file = open_exec(filename);
1826
1827         retval = PTR_ERR(file);
1828         if (IS_ERR(file))
1829                 return retval;
1830
1831         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
1832         memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
1833
1834         bprm.file = file;
1835         bprm.filename = filename;
1836         bprm.interp = filename;
1837         bprm.sh_bang = 0;
1838         bprm.loader = 0;
1839         bprm.exec = 0;
1840         bprm.security = NULL;
1841         bprm.mm = mm_alloc();
1842         retval = -ENOMEM;
1843         if (!bprm.mm)
1844                 goto out_file;
1845
1846         retval = init_new_context(current, bprm.mm);
1847         if (retval < 0)
1848                 goto out_mm;
1849
1850         bprm.argc = count32(argv, bprm.p / sizeof(u32));
1851         if ((retval = bprm.argc) < 0)
1852                 goto out_mm;
1853
1854         bprm.envc = count32(envp, bprm.p / sizeof(u32));
1855         if ((retval = bprm.envc) < 0)
1856                 goto out_mm;
1857
1858         retval = security_bprm_alloc(&bprm);
1859         if (retval)
1860                 goto out;
1861
1862         retval = prepare_binprm(&bprm);
1863         if (retval < 0) 
1864                 goto out; 
1865
1866         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
1867         if (retval < 0) 
1868                 goto out; 
1869
1870         bprm.exec = bprm.p;
1871         retval = copy_strings32(bprm.envc, envp, &bprm);
1872         if (retval < 0) 
1873                 goto out; 
1874
1875         retval = copy_strings32(bprm.argc, argv, &bprm);
1876         if (retval < 0) 
1877                 goto out; 
1878
1879         retval = search_binary_handler(&bprm,regs);
1880         if (retval >= 0) {
1881                 /* execve success */
1882                 security_bprm_free(&bprm);
1883                 return retval;
1884         }
1885
1886 out:
1887         /* Something went wrong, return the inode and free the argument pages*/
1888         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
1889                 struct page * page = bprm.page[i];
1890                 if (page)
1891                         __free_page(page);
1892         }
1893
1894         if (bprm.security)
1895                 security_bprm_free(&bprm);
1896
1897 out_mm:
1898         if (bprm.mm)
1899                 mmdrop(bprm.mm);
1900
1901 out_file:
1902         if (bprm.file) {
1903                 allow_write_access(bprm.file);
1904                 fput(bprm.file);
1905         }
1906         return retval;
1907 }
1908
1909 long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2,
1910                   unsigned long a3, unsigned long a4, unsigned long a5,
1911                   struct pt_regs *regs)
1912 {
1913         int error;
1914         char * filename;
1915         
1916         filename = getname((char *) a0);
1917         error = PTR_ERR(filename);
1918         if (IS_ERR(filename))
1919                 goto out;
1920         if (regs->msr & MSR_FP)
1921                 giveup_fpu(current);
1922 #ifdef CONFIG_ALTIVEC
1923         if (regs->msr & MSR_VEC)
1924                 giveup_altivec(current);
1925 #endif /* CONFIG_ALTIVEC */
1926
1927         error = do_execve32(filename, (u32*) a1, (u32*) a2, regs);
1928
1929         if (error == 0)
1930                 current->ptrace &= ~PT_DTRACE;
1931         putname(filename);
1932
1933 out:
1934         return error;
1935 }
1936
1937 /* Set up a thread for executing a new program. */
1938 void start_thread32(struct pt_regs* regs, unsigned long nip, unsigned long sp)
1939 {
1940         set_fs(USER_DS);
1941         memset(regs->gpr, 0, sizeof(regs->gpr));
1942         memset(&regs->ctr, 0, 4 * sizeof(regs->ctr));
1943         regs->nip = nip;
1944         regs->gpr[1] = sp;
1945         regs->msr = MSR_USER32;
1946 #ifndef CONFIG_SMP
1947         if (last_task_used_math == current)
1948                 last_task_used_math = 0;
1949 #endif /* CONFIG_SMP */
1950         current->thread.fpscr = 0;
1951         memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
1952 #ifdef CONFIG_ALTIVEC
1953 #ifndef CONFIG_SMP
1954         if (last_task_used_altivec == current)
1955                 last_task_used_altivec = 0;
1956 #endif /* CONFIG_SMP */
1957         memset(current->thread.vr, 0, sizeof(current->thread.vr));
1958         current->thread.vscr.u[0] = 0;
1959         current->thread.vscr.u[1] = 0;
1960         current->thread.vscr.u[2] = 0;
1961         current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
1962         current->thread.vrsave = 0;
1963         current->thread.used_vr = 0;
1964 #endif /* CONFIG_ALTIVEC */
1965 }
1966
1967 /* Note: it is necessary to treat option as an unsigned int, 
1968  * with the corresponding cast to a signed int to insure that the 
1969  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
1970  * and the register representation of a signed int (msr in 64-bit mode) is performed.
1971  */
1972 asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
1973 {
1974         return sys_prctl((int)option,
1975                          (unsigned long) arg2,
1976                          (unsigned long) arg3,
1977                          (unsigned long) arg4,
1978                          (unsigned long) arg5);
1979 }
1980
1981 /* Note: it is necessary to treat pid as an unsigned int, 
1982  * with the corresponding cast to a signed int to insure that the 
1983  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
1984  * and the register representation of a signed int (msr in 64-bit mode) is performed.
1985  */
1986 asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec *interval)
1987 {
1988         struct timespec t;
1989         int ret;
1990         mm_segment_t old_fs = get_fs ();
1991         
1992         set_fs (KERNEL_DS);
1993         ret = sys_sched_rr_get_interval((int)pid, &t);
1994         set_fs (old_fs);
1995         if (put_compat_timespec(&t, interval))
1996                 return -EFAULT;
1997         return ret;
1998 }
1999
2000 asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
2001 {
2002         return sys_pciconfig_read((unsigned long) bus,
2003                                   (unsigned long) dfn,
2004                                   (unsigned long) off,
2005                                   (unsigned long) len,
2006                                   (unsigned char *)AA(ubuf));
2007 }
2008
2009 asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
2010 {
2011         return sys_pciconfig_write((unsigned long) bus,
2012                                    (unsigned long) dfn,
2013                                    (unsigned long) off,
2014                                    (unsigned long) len,
2015                                    (unsigned char *)AA(ubuf));
2016 }
2017
2018 #define IOBASE_BRIDGE_NUMBER    0
2019 #define IOBASE_MEMORY           1
2020 #define IOBASE_IO               2
2021 #define IOBASE_ISA_IO           3
2022 #define IOBASE_ISA_MEM          4
2023
2024 asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
2025 {
2026         struct pci_controller* hose;
2027         struct list_head *ln;
2028         struct pci_bus *bus = NULL;
2029         struct device_node *hose_node;
2030
2031         /* Argh ! Please forgive me for that hack, but that's the
2032          * simplest way to get existing XFree to not lockup on some
2033          * G5 machines... So when something asks for bus 0 io base
2034          * (bus 0 is HT root), we return the AGP one instead.
2035          */
2036 #ifdef CONFIG_PPC_PMAC
2037         if (systemcfg->platform == PLATFORM_POWERMAC &&
2038             machine_is_compatible("MacRISC4"))
2039                 if (in_bus == 0)
2040                         in_bus = 0xf0;
2041 #endif /* CONFIG_PPC_PMAC */
2042
2043         /* That syscall isn't quite compatible with PCI domains, but it's
2044          * used on pre-domains setup. We return the first match
2045          */
2046
2047         for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
2048                 bus = pci_bus_b(ln);
2049                 if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
2050                         break;
2051                 bus = NULL;
2052         }
2053         if (bus == NULL || bus->sysdata == NULL)
2054                 return -ENODEV;
2055
2056         hose_node = (struct device_node *)bus->sysdata;
2057         hose = hose_node->phb;
2058
2059         switch (which) {
2060         case IOBASE_BRIDGE_NUMBER:
2061                 return (long)hose->first_busno;
2062         case IOBASE_MEMORY:
2063                 return (long)hose->pci_mem_offset;
2064         case IOBASE_IO:
2065                 return (long)hose->io_base_phys;
2066         case IOBASE_ISA_IO:
2067                 return (long)isa_io_base;
2068         case IOBASE_ISA_MEM:
2069                 return -EINVAL;
2070         }
2071
2072         return -EOPNOTSUPP;
2073 }
2074
2075
2076 asmlinkage int ppc64_newuname(struct new_utsname * name)
2077 {
2078         int errno = sys_newuname(name);
2079
2080         if (current->personality == PER_LINUX32 && !errno) {
2081                 if(copy_to_user(name->machine, "ppc\0\0", 8)) {
2082                         errno = -EFAULT;
2083                 }
2084         }
2085         return errno;
2086 }
2087
2088 asmlinkage int ppc64_personality(unsigned long personality)
2089 {
2090         int ret;
2091         if (current->personality == PER_LINUX32 && personality == PER_LINUX)
2092                 personality = PER_LINUX32;
2093         ret = sys_personality(personality);
2094         if (ret == PER_LINUX32)
2095                 ret = PER_LINUX;
2096         return ret;
2097 }
2098
2099
2100
2101 /* Note: it is necessary to treat mode as an unsigned int,
2102  * with the corresponding cast to a signed int to insure that the 
2103  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2104  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2105  */
2106 asmlinkage long sys32_access(const char * filename, u32 mode)
2107 {
2108         return sys_access(filename, (int)mode);
2109 }
2110
2111
2112 /* Note: it is necessary to treat mode as an unsigned int,
2113  * with the corresponding cast to a signed int to insure that the 
2114  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2115  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2116  */
2117 asmlinkage long sys32_creat(const char * pathname, u32 mode)
2118 {
2119         return sys_creat(pathname, (int)mode);
2120 }
2121
2122
2123 /* Note: it is necessary to treat pid and options as unsigned ints,
2124  * with the corresponding cast to a signed int to insure that the 
2125  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2126  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2127  */
2128 asmlinkage long sys32_waitpid(u32 pid, unsigned int * stat_addr, u32 options)
2129 {
2130         return sys_waitpid((int)pid, stat_addr, (int)options);
2131 }
2132
2133
2134 /* Note: it is necessary to treat gidsetsize as an unsigned int,
2135  * with the corresponding cast to a signed int to insure that the 
2136  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2137  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2138  */
2139 asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t *grouplist)
2140 {
2141         return sys_getgroups((int)gidsetsize, grouplist);
2142 }
2143
2144
2145 /* Note: it is necessary to treat pid as an unsigned int,
2146  * with the corresponding cast to a signed int to insure that the 
2147  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2148  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2149  */
2150 asmlinkage long sys32_getpgid(u32 pid)
2151 {
2152         return sys_getpgid((int)pid);
2153 }
2154
2155
2156 /* Note: it is necessary to treat which and who as unsigned ints,
2157  * with the corresponding cast to a signed int to insure that the 
2158  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2159  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2160  */
2161 asmlinkage long sys32_getpriority(u32 which, u32 who)
2162 {
2163         return sys_getpriority((int)which, (int)who);
2164 }
2165
2166
2167 /* Note: it is necessary to treat pid as an unsigned int,
2168  * with the corresponding cast to a signed int to insure that the 
2169  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2170  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2171  */
2172 asmlinkage long sys32_getsid(u32 pid)
2173 {
2174         return sys_getsid((int)pid);
2175 }
2176
2177
2178 /* Note: it is necessary to treat pid and sig as unsigned ints,
2179  * with the corresponding cast to a signed int to insure that the 
2180  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2181  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2182  */
2183 asmlinkage long sys32_kill(u32 pid, u32 sig)
2184 {
2185         return sys_kill((int)pid, (int)sig);
2186 }
2187
2188
2189 /* Note: it is necessary to treat mode as an unsigned int,
2190  * with the corresponding cast to a signed int to insure that the 
2191  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2192  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2193  */
2194 asmlinkage long sys32_mkdir(const char * pathname, u32 mode)
2195 {
2196         return sys_mkdir(pathname, (int)mode);
2197 }
2198
2199 long sys32_nice(u32 increment)
2200 {
2201         /* sign extend increment */
2202         return sys_nice((int)increment);
2203 }
2204
2205 off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin)
2206 {
2207         /* sign extend n */
2208         return sys_lseek(fd, (int)offset, origin);
2209 }
2210
2211 /*
2212  * This is just a version for 32-bit applications which does
2213  * not force O_LARGEFILE on.
2214  */
2215 long sys32_open(const char * filename, int flags, int mode)
2216 {
2217         char * tmp;
2218         int fd, error;
2219
2220         tmp = getname(filename);
2221         fd = PTR_ERR(tmp);
2222         if (!IS_ERR(tmp)) {
2223                 fd = get_unused_fd();
2224                 if (fd >= 0) {
2225                         struct file * f = filp_open(tmp, flags, mode);
2226                         error = PTR_ERR(f);
2227                         if (IS_ERR(f))
2228                                 goto out_error;
2229                         fd_install(fd, f);
2230                 }
2231 out:
2232                 putname(tmp);
2233         }
2234         return fd;
2235
2236 out_error:
2237         put_unused_fd(fd);
2238         fd = error;
2239         goto out;
2240 }
2241
2242 /* Note: it is necessary to treat bufsiz as an unsigned int,
2243  * with the corresponding cast to a signed int to insure that the 
2244  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2245  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2246  */
2247 asmlinkage long sys32_readlink(const char * path, char * buf, u32 bufsiz)
2248 {
2249         return sys_readlink(path, buf, (int)bufsiz);
2250 }
2251
2252 /* Note: it is necessary to treat option as an unsigned int,
2253  * with the corresponding cast to a signed int to insure that the 
2254  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2255  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2256  */
2257 asmlinkage long sys32_sched_get_priority_max(u32 policy)
2258 {
2259         return sys_sched_get_priority_max((int)policy);
2260 }
2261
2262
2263 /* Note: it is necessary to treat policy as an unsigned int,
2264  * with the corresponding cast to a signed int to insure that the 
2265  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2266  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2267  */
2268 asmlinkage long sys32_sched_get_priority_min(u32 policy)
2269 {
2270         return sys_sched_get_priority_min((int)policy);
2271 }
2272
2273
2274 /* Note: it is necessary to treat pid as an unsigned int,
2275  * with the corresponding cast to a signed int to insure that the 
2276  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2277  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2278  */
2279 asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param *param)
2280 {
2281         return sys_sched_getparam((int)pid, param);
2282 }
2283
2284
2285 /* Note: it is necessary to treat pid as an unsigned int,
2286  * with the corresponding cast to a signed int to insure that the 
2287  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2288  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2289  */
2290 asmlinkage long sys32_sched_getscheduler(u32 pid)
2291 {
2292         return sys_sched_getscheduler((int)pid);
2293 }
2294
2295
2296 /* Note: it is necessary to treat pid as an unsigned int,
2297  * with the corresponding cast to a signed int to insure that the 
2298  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2299  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2300  */
2301 asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param *param)
2302 {
2303         return sys_sched_setparam((int)pid, param);
2304 }
2305
2306
2307 /* Note: it is necessary to treat pid and policy as unsigned ints,
2308  * with the corresponding cast to a signed int to insure that the 
2309  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2310  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2311  */
2312 asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param *param)
2313 {
2314         return sys_sched_setscheduler((int)pid, (int)policy, param);
2315 }
2316
2317
2318 /* Note: it is necessary to treat len as an unsigned int,
2319  * with the corresponding cast to a signed int to insure that the 
2320  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2321  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2322  */
2323 asmlinkage long sys32_setdomainname(char *name, u32 len)
2324 {
2325         return sys_setdomainname(name, (int)len);
2326 }
2327
2328
2329 /* Note: it is necessary to treat gidsetsize as an unsigned int,
2330  * with the corresponding cast to a signed int to insure that the 
2331  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2332  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2333  */
2334 asmlinkage long sys32_setgroups(u32 gidsetsize, gid_t *grouplist)
2335 {
2336         return sys_setgroups((int)gidsetsize, grouplist);
2337 }
2338
2339
2340 asmlinkage long sys32_sethostname(char *name, u32 len)
2341 {
2342         /* sign extend len */
2343         return sys_sethostname(name, (int)len);
2344 }
2345
2346
2347 /* Note: it is necessary to treat pid and pgid as unsigned ints,
2348  * with the corresponding cast to a signed int to insure that the 
2349  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2350  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2351  */
2352 asmlinkage long sys32_setpgid(u32 pid, u32 pgid)
2353 {
2354         return sys_setpgid((int)pid, (int)pgid);
2355 }
2356
2357
2358 long sys32_setpriority(u32 which, u32 who, u32 niceval)
2359 {
2360         /* sign extend which, who and niceval */
2361         return sys_setpriority((int)which, (int)who, (int)niceval);
2362 }
2363
2364 /* Note: it is necessary to treat newmask as an unsigned int,
2365  * with the corresponding cast to a signed int to insure that the 
2366  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2367  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2368  */
2369 asmlinkage long sys32_ssetmask(u32 newmask)
2370 {
2371         return sys_ssetmask((int) newmask);
2372 }
2373
2374 long sys32_syslog(u32 type, char * buf, u32 len)
2375 {
2376         /* sign extend len */
2377         return sys_syslog(type, buf, (int)len);
2378 }
2379
2380
2381 /* Note: it is necessary to treat mask as an unsigned int,
2382  * with the corresponding cast to a signed int to insure that the 
2383  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
2384  * and the register representation of a signed int (msr in 64-bit mode) is performed.
2385  */
2386 asmlinkage long sys32_umask(u32 mask)
2387 {
2388         return sys_umask((int)mask);
2389 }
2390
2391 struct __sysctl_args32 {
2392         u32 name;
2393         int nlen;
2394         u32 oldval;
2395         u32 oldlenp;
2396         u32 newval;
2397         u32 newlen;
2398         u32 __unused[4];
2399 };
2400
2401 extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
2402 {
2403         struct __sysctl_args32 tmp;
2404         int error;
2405         size_t oldlen, *oldlenp = NULL;
2406         unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
2407
2408         if (copy_from_user(&tmp, args, sizeof(tmp)))
2409                 return -EFAULT;
2410
2411         if (tmp.oldval && tmp.oldlenp) {
2412                 /* Duh, this is ugly and might not work if sysctl_args
2413                    is in read-only memory, but do_sysctl does indirectly
2414                    a lot of uaccess in both directions and we'd have to
2415                    basically copy the whole sysctl.c here, and
2416                    glibc's __sysctl uses rw memory for the structure
2417                    anyway.  */
2418                 if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
2419                     put_user(oldlen, (size_t *)addr))
2420                         return -EFAULT;
2421                 oldlenp = (size_t *)addr;
2422         }
2423
2424         lock_kernel();
2425         error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
2426                           oldlenp, (void *)A(tmp.newval), tmp.newlen);
2427         unlock_kernel();
2428         if (oldlenp) {
2429                 if (!error) {
2430                         if (get_user(oldlen, (size_t *)addr) ||
2431                             put_user(oldlen, (u32 *)A(tmp.oldlenp)))
2432                                 error = -EFAULT;
2433                 }
2434                 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
2435         }
2436         return error;
2437 }
2438
2439 asmlinkage long sys32_time(compat_time_t* tloc)
2440 {
2441         compat_time_t secs;
2442
2443         struct timeval tv;
2444
2445         do_gettimeofday( &tv );
2446         secs = tv.tv_sec;
2447
2448         if (tloc) {
2449                 if (put_user(secs,tloc))
2450                         secs = -EFAULT;
2451         }
2452
2453         return secs;
2454 }
2455
2456 int sys32_olduname(struct oldold_utsname * name)
2457 {
2458         int error;
2459         
2460         if (!name)
2461                 return -EFAULT;
2462         if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
2463                 return -EFAULT;
2464   
2465         down_read(&uts_sem);
2466         error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
2467         error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
2468         error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
2469         error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
2470         error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
2471         error -= __put_user(0,name->release+__OLD_UTS_LEN);
2472         error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
2473         error -= __put_user(0,name->version+__OLD_UTS_LEN);
2474         error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
2475         error = __put_user(0,name->machine+__OLD_UTS_LEN);
2476         up_read(&uts_sem);
2477
2478         error = error ? -EFAULT : 0;
2479         
2480         return error;
2481 }
2482
2483 unsigned long sys32_mmap2(unsigned long addr, size_t len,
2484                           unsigned long prot, unsigned long flags,
2485                           unsigned long fd, unsigned long pgoff)
2486 {
2487         /* This should remain 12 even if PAGE_SIZE changes */
2488         return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
2489 }
2490
2491 int get_compat_timeval(struct timeval *tv, struct compat_timeval *ctv)
2492 {
2493         return (verify_area(VERIFY_READ, ctv, sizeof(*ctv)) ||
2494                 __get_user(tv->tv_sec, &ctv->tv_sec) ||
2495                 __get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
2496 }
2497
2498 long sys32_utimes(char *filename, struct compat_timeval *tvs)
2499 {
2500         char *kfilename;
2501         struct timeval ktvs[2];
2502         mm_segment_t old_fs;
2503         long ret;
2504
2505         kfilename = getname(filename);
2506         ret = PTR_ERR(kfilename);
2507         if (!IS_ERR(kfilename)) {
2508                 if (tvs) {
2509                         if (get_compat_timeval(&ktvs[0], &tvs[0]) ||
2510                             get_compat_timeval(&ktvs[1], &tvs[1]))
2511                                 return -EFAULT;
2512                 }
2513
2514                 old_fs = get_fs();
2515                 set_fs(KERNEL_DS);
2516                 ret = do_utimes(kfilename, (tvs ? &ktvs[0] : NULL));
2517                 set_fs(old_fs);
2518
2519                 putname(kfilename);
2520         }
2521         return ret;
2522 }
2523
2524 long sys32_tgkill(u32 tgid, u32 pid, int sig)
2525 {
2526         /* sign extend tgid, pid */
2527         return sys_tgkill((int)tgid, (int)pid, sig);
2528 }
2529
2530 /* 
2531  * long long munging:
2532  * The 32 bit ABI passes long longs in an odd even register pair.
2533  */
2534
2535 compat_ssize_t sys32_pread64(unsigned int fd, char *ubuf, compat_size_t count,
2536                              u32 reg6, u32 poshi, u32 poslo)
2537 {
2538         return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
2539 }
2540
2541 compat_ssize_t sys32_pwrite64(unsigned int fd, char *ubuf, compat_size_t count,
2542                               u32 reg6, u32 poshi, u32 poslo)
2543 {
2544         return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
2545 }
2546
2547 compat_ssize_t sys32_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
2548 {
2549         return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count);
2550 }
2551
2552 asmlinkage int sys32_truncate64(const char * path, u32 reg4,
2553                                 unsigned long high, unsigned long low)
2554 {
2555         return sys_truncate(path, (high << 32) | low);
2556 }
2557
2558 asmlinkage int sys32_ftruncate64(unsigned int fd, u32 reg4, unsigned long high,
2559                                  unsigned long low)
2560 {
2561         return sys_ftruncate(fd, (high << 32) | low);
2562 }
2563
2564 long ppc32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char *buf,
2565                           size_t len)
2566 {
2567         return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
2568                                   buf, len);
2569 }
2570
2571 long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low,
2572                      size_t len, int advice)
2573 {
2574         return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, len,
2575                              advice);
2576 }
2577
2578 long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
2579                         u32 len_high, u32 len_low)
2580 {
2581         return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low,
2582                              (u64)len_high << 32 | len_low, advice);
2583 }
2584
2585 extern long sys_timer_create(clockid_t, sigevent_t *, timer_t *);
2586
2587 long ppc32_timer_create(clockid_t clock,
2588                         struct compat_sigevent __user *ev32,
2589                         timer_t __user *timer_id)
2590 {
2591         sigevent_t event;
2592         timer_t t;
2593         long err;
2594         mm_segment_t savefs;
2595
2596         if (ev32 == NULL)
2597                 return sys_timer_create(clock, NULL, timer_id);
2598
2599         memset(&event, 0, sizeof(event));
2600         if (!access_ok(VERIFY_READ, ev32, sizeof(struct compat_sigevent))
2601             || __get_user(event.sigev_value.sival_int,
2602                           &ev32->sigev_value.sival_int)
2603             || __get_user(event.sigev_signo, &ev32->sigev_signo)
2604             || __get_user(event.sigev_notify, &ev32->sigev_notify)
2605             || __get_user(event.sigev_notify_thread_id,
2606                           &ev32->sigev_notify_thread_id))
2607                 return -EFAULT;
2608
2609         if (!access_ok(VERIFY_WRITE, timer_id, sizeof(timer_t)))
2610                 return -EFAULT;
2611
2612         savefs = get_fs();
2613         set_fs(KERNEL_DS);
2614         err = sys_timer_create(clock, &event, &t);
2615         set_fs(savefs);
2616
2617         if (err == 0)
2618                 err = __put_user(t, timer_id);
2619
2620         return err;
2621 }