File: /usr/src/linux/arch/sparc64/kernel/sys_sparc32.c

1     /* $Id: sys_sparc32.c,v 1.178 2001/08/13 14:40:07 davem Exp $
2      * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
3      *
4      * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5      * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
6      *
7      * These routines maintain argument size conversion between 32bit and 64bit
8      * environment.
9      */
10     
11     #include <linux/config.h>
12     #include <linux/kernel.h>
13     #include <linux/sched.h>
14     #include <linux/fs.h> 
15     #include <linux/mm.h> 
16     #include <linux/file.h> 
17     #include <linux/signal.h>
18     #include <linux/utime.h>
19     #include <linux/resource.h>
20     #include <linux/times.h>
21     #include <linux/utsname.h>
22     #include <linux/timex.h>
23     #include <linux/smp.h>
24     #include <linux/smp_lock.h>
25     #include <linux/sem.h>
26     #include <linux/msg.h>
27     #include <linux/shm.h>
28     #include <linux/slab.h>
29     #include <linux/uio.h>
30     #include <linux/nfs_fs.h>
31     #include <linux/smb_fs.h>
32     #include <linux/smb_mount.h>
33     #include <linux/ncp_fs.h>
34     #include <linux/quota.h>
35     #include <linux/module.h>
36     #include <linux/sunrpc/svc.h>
37     #include <linux/nfsd/nfsd.h>
38     #include <linux/nfsd/cache.h>
39     #include <linux/nfsd/xdr.h>
40     #include <linux/nfsd/syscall.h>
41     #include <linux/poll.h>
42     #include <linux/personality.h>
43     #include <linux/stat.h>
44     #include <linux/filter.h>
45     #include <linux/highmem.h>
46     #include <linux/highuid.h>
47     #include <linux/mman.h>
48     #include <linux/ipv6.h>
49     #include <linux/in.h>
50     #include <linux/icmpv6.h>
51     #include <linux/sysctl.h>
52     
53     #include <asm/types.h>
54     #include <asm/ipc.h>
55     #include <asm/uaccess.h>
56     #include <asm/fpumacro.h>
57     #include <asm/semaphore.h>
58     
59     #include <net/scm.h>
60     
61     /* Use this to get at 32-bit user passed pointers. */
62     /* Things to consider: the low-level assembly stub does
63        srl x, 0, x for first four arguments, so if you have
64        pointer to something in the first four arguments, just
65        declare it as a pointer, not u32. On the other side, 
66        arguments from 5th onwards should be declared as u32
67        for pointers, and need AA() around each usage.
68        A() macro should be used for places where you e.g.
69        have some internal variable u32 and just want to get
70        rid of a compiler warning. AA() has to be used in
71        places where you want to convert a function argument
72        to 32bit pointer or when you e.g. access pt_regs
73        structure and want to consider 32bit registers only.
74        -jj
75      */
76     #define A(__x) ((unsigned long)(__x))
77     #define AA(__x)				\
78     ({	unsigned long __ret;		\
79     	__asm__ ("srl	%0, 0, %0"	\
80     		 : "=r" (__ret)		\
81     		 : "0" (__x));		\
82     	__ret;				\
83     })
84     
85     extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
86     extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
87     extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
88     extern asmlinkage long sys_setregid(gid_t, gid_t);
89     extern asmlinkage long sys_setgid(gid_t);
90     extern asmlinkage long sys_setreuid(uid_t, uid_t);
91     extern asmlinkage long sys_setuid(uid_t);
92     extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
93     extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
94     extern asmlinkage long sys_setfsuid(uid_t);
95     extern asmlinkage long sys_setfsgid(gid_t);
96      
97     /* For this source file, we want overflow handling. */
98     
99     #undef high2lowuid
100     #undef high2lowgid
101     #undef low2highuid
102     #undef low2highgid
103     #undef SET_UID16
104     #undef SET_GID16
105     #undef NEW_TO_OLD_UID
106     #undef NEW_TO_OLD_GID
107     #undef SET_OLDSTAT_UID
108     #undef SET_OLDSTAT_GID
109     #undef SET_STAT_UID
110     #undef SET_STAT_GID
111     
112     #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
113     #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
114     #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
115     #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
116     #define SET_UID16(var, uid)	var = high2lowuid(uid)
117     #define SET_GID16(var, gid)	var = high2lowgid(gid)
118     #define NEW_TO_OLD_UID(uid)	high2lowuid(uid)
119     #define NEW_TO_OLD_GID(gid)	high2lowgid(gid)
120     #define SET_OLDSTAT_UID(stat, uid)	(stat).st_uid = high2lowuid(uid)
121     #define SET_OLDSTAT_GID(stat, gid)	(stat).st_gid = high2lowgid(gid)
122     #define SET_STAT_UID(stat, uid)		(stat).st_uid = high2lowuid(uid)
123     #define SET_STAT_GID(stat, gid)		(stat).st_gid = high2lowgid(gid)
124     
125     asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
126     {
127     	return sys_chown(filename, low2highuid(user), low2highgid(group));
128     }
129     
130     asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
131     {
132     	return sys_lchown(filename, low2highuid(user), low2highgid(group));
133     }
134     
135     asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
136     {
137     	return sys_fchown(fd, low2highuid(user), low2highgid(group));
138     }
139     
140     asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
141     {
142     	return sys_setregid(low2highgid(rgid), low2highgid(egid));
143     }
144     
145     asmlinkage long sys32_setgid16(u16 gid)
146     {
147     	return sys_setgid((gid_t)gid);
148     }
149     
150     asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
151     {
152     	return sys_setreuid(low2highuid(ruid), low2highuid(euid));
153     }
154     
155     asmlinkage long sys32_setuid16(u16 uid)
156     {
157     	return sys_setuid((uid_t)uid);
158     }
159     
160     asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
161     {
162     	return sys_setresuid(low2highuid(ruid), low2highuid(euid),
163     		low2highuid(suid));
164     }
165     
166     asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
167     {
168     	int retval;
169     
170     	if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
171     	    !(retval = put_user(high2lowuid(current->euid), euid)))
172     		retval = put_user(high2lowuid(current->suid), suid);
173     
174     	return retval;
175     }
176     
177     asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
178     {
179     	return sys_setresgid(low2highgid(rgid), low2highgid(egid),
180     		low2highgid(sgid));
181     }
182     
183     asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
184     {
185     	int retval;
186     
187     	if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
188     	    !(retval = put_user(high2lowgid(current->egid), egid)))
189     		retval = put_user(high2lowgid(current->sgid), sgid);
190     
191     	return retval;
192     }
193     
194     asmlinkage long sys32_setfsuid16(u16 uid)
195     {
196     	return sys_setfsuid((uid_t)uid);
197     }
198     
199     asmlinkage long sys32_setfsgid16(u16 gid)
200     {
201     	return sys_setfsgid((gid_t)gid);
202     }
203     
204     asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
205     {
206     	u16 groups[NGROUPS];
207     	int i,j;
208     
209     	if (gidsetsize < 0)
210     		return -EINVAL;
211     	i = current->ngroups;
212     	if (gidsetsize) {
213     		if (i > gidsetsize)
214     			return -EINVAL;
215     		for(j=0;j<i;j++)
216     			groups[j] = current->groups[j];
217     		if (copy_to_user(grouplist, groups, sizeof(u16)*i))
218     			return -EFAULT;
219     	}
220     	return i;
221     }
222     
223     asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
224     {
225     	u16 groups[NGROUPS];
226     	int i;
227     
228     	if (!capable(CAP_SETGID))
229     		return -EPERM;
230     	if ((unsigned) gidsetsize > NGROUPS)
231     		return -EINVAL;
232     	if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16)))
233     		return -EFAULT;
234     	for (i = 0 ; i < gidsetsize ; i++)
235     		current->groups[i] = (gid_t)groups[i];
236     	current->ngroups = gidsetsize;
237     	return 0;
238     }
239     
240     asmlinkage long sys32_getuid16(void)
241     {
242     	return high2lowuid(current->uid);
243     }
244     
245     asmlinkage long sys32_geteuid16(void)
246     {
247     	return high2lowuid(current->euid);
248     }
249     
250     asmlinkage long sys32_getgid16(void)
251     {
252     	return high2lowgid(current->gid);
253     }
254     
255     asmlinkage long sys32_getegid16(void)
256     {
257     	return high2lowgid(current->egid);
258     }
259     
260     /* 32-bit timeval and related flotsam.  */
261     
262     struct timeval32
263     {
264         int tv_sec, tv_usec;
265     };
266     
267     struct itimerval32
268     {
269         struct timeval32 it_interval;
270         struct timeval32 it_value;
271     };
272     
273     static inline long get_tv32(struct timeval *o, struct timeval32 *i)
274     {
275     	return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
276     		(__get_user(o->tv_sec, &i->tv_sec) |
277     		 __get_user(o->tv_usec, &i->tv_usec)));
278     }
279     
280     static inline long put_tv32(struct timeval32 *o, struct timeval *i)
281     {
282     	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
283     		(__put_user(i->tv_sec, &o->tv_sec) |
284     		 __put_user(i->tv_usec, &o->tv_usec)));
285     }
286     
287     static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
288     {
289     	return (!access_ok(VERIFY_READ, i32, sizeof(*i32)) ||
290     		(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
291     		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
292     		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
293     		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
294     }
295     
296     static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
297     {
298     	return (!access_ok(VERIFY_WRITE, i32, sizeof(*i32)) ||
299     		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
300     		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
301     		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
302     		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
303     }
304     
305     extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
306     
307     asmlinkage int sys32_ioperm(u32 from, u32 num, int on)
308     {
309     	return sys_ioperm((unsigned long)from, (unsigned long)num, on);
310     }
311     
312     struct msgbuf32 { s32 mtype; char mtext[1]; };
313     
314     struct ipc_perm32
315     {
316     	key_t    	  key;
317             __kernel_uid_t32  uid;
318             __kernel_gid_t32  gid;
319             __kernel_uid_t32  cuid;
320             __kernel_gid_t32  cgid;
321             __kernel_mode_t32 mode;
322             unsigned short  seq;
323     };
324     
325     struct semid_ds32 {
326             struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
327             __kernel_time_t32 sem_otime;              /* last semop time */
328             __kernel_time_t32 sem_ctime;              /* last change time */
329             u32 sem_base;              /* ptr to first semaphore in array */
330             u32 sem_pending;          /* pending operations to be processed */
331             u32 sem_pending_last;    /* last pending operation */
332             u32 undo;                  /* undo requests on this array */
333             unsigned short  sem_nsems;              /* no. of semaphores in array */
334     };
335     
336     struct semid64_ds32 {
337     	struct ipc64_perm sem_perm;		  /* this structure is the same on sparc32 and sparc64 */
338     	unsigned int	  __pad1;
339     	__kernel_time_t32 sem_otime;
340     	unsigned int	  __pad2;
341     	__kernel_time_t32 sem_ctime;
342     	u32 sem_nsems;
343     	u32 __unused1;
344     	u32 __unused2;
345     };
346     
347     struct msqid_ds32
348     {
349             struct ipc_perm32 msg_perm;
350             u32 msg_first;
351             u32 msg_last;
352             __kernel_time_t32 msg_stime;
353             __kernel_time_t32 msg_rtime;
354             __kernel_time_t32 msg_ctime;
355             u32 wwait;
356             u32 rwait;
357             unsigned short msg_cbytes;
358             unsigned short msg_qnum;  
359             unsigned short msg_qbytes;
360             __kernel_ipc_pid_t32 msg_lspid;
361             __kernel_ipc_pid_t32 msg_lrpid;
362     };
363     
364     struct msqid64_ds32 {
365     	struct ipc64_perm msg_perm;
366     	unsigned int   __pad1;
367     	__kernel_time_t32 msg_stime;
368     	unsigned int   __pad2;
369     	__kernel_time_t32 msg_rtime;
370     	unsigned int   __pad3;
371     	__kernel_time_t32 msg_ctime;
372     	unsigned int  msg_cbytes;
373     	unsigned int  msg_qnum;
374     	unsigned int  msg_qbytes;
375     	__kernel_pid_t32 msg_lspid;
376     	__kernel_pid_t32 msg_lrpid;
377     	unsigned int  __unused1;
378     	unsigned int  __unused2;
379     };
380     
381     
382     struct shmid_ds32 {
383     	struct ipc_perm32       shm_perm;
384     	int                     shm_segsz;
385     	__kernel_time_t32       shm_atime;
386     	__kernel_time_t32       shm_dtime;
387     	__kernel_time_t32       shm_ctime;
388     	__kernel_ipc_pid_t32    shm_cpid; 
389     	__kernel_ipc_pid_t32    shm_lpid; 
390     	unsigned short          shm_nattch;
391     };
392     
393     struct shmid64_ds32 {
394     	struct ipc64_perm	shm_perm;
395     	unsigned int		__pad1;
396     	__kernel_time_t32	shm_atime;
397     	unsigned int		__pad2;
398     	__kernel_time_t32	shm_dtime;
399     	unsigned int		__pad3;
400     	__kernel_time_t32	shm_ctime;
401     	__kernel_size_t32	shm_segsz;
402     	__kernel_pid_t32	shm_cpid;
403     	__kernel_pid_t32	shm_lpid;
404     	unsigned int		shm_nattch;
405     	unsigned int		__unused1;
406     	unsigned int		__unused2;
407     };
408     
409                                                             
410     /*
411      * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
412      *
413      * This is really horribly ugly.
414      */
415     #define IPCOP_MASK(__x)	(1UL << (__x))
416     static int do_sys32_semctl(int first, int second, int third, void *uptr)
417     {
418     	union semun fourth;
419     	u32 pad;
420     	int err = -EINVAL;
421     
422     	if (!uptr)
423     		goto out;
424     	err = -EFAULT;
425     	if (get_user (pad, (u32 *)uptr))
426     		goto out;
427     	if(third == SETVAL)
428     		fourth.val = (int)pad;
429     	else
430     		fourth.__pad = (void *)A(pad);
431     	if (IPCOP_MASK (third) &
432     	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
433     	     IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
434     	     IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
435     		err = sys_semctl (first, second, third, fourth);
436     	} else if (third & IPC_64) {
437     		struct semid64_ds s;
438     		struct semid64_ds32 *usp = (struct semid64_ds32 *)A(pad);
439     		mm_segment_t old_fs;
440     		int need_back_translation;
441     
442     		if (third == (IPC_SET|IPC_64)) {
443     			err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
444     			err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
445     			err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
446     			if (err)
447     				goto out;
448     			fourth.__pad = &s;
449     		}
450     		need_back_translation =
451     			(IPCOP_MASK (third) &
452     			 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
453     		if (need_back_translation)
454     			fourth.__pad = &s;
455     		old_fs = get_fs ();
456     		set_fs (KERNEL_DS);
457     		err = sys_semctl (first, second, third, fourth);
458     		set_fs (old_fs);
459     		if (need_back_translation) {
460     			int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
461     			err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
462     			if (err2) err = -EFAULT;
463     		}
464     	} else {
465     		struct semid_ds s;
466     		struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
467     		mm_segment_t old_fs;
468     		int need_back_translation;
469     
470     		if (third == IPC_SET) {
471     			err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
472     			err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
473     			err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
474     			if (err)
475     				goto out;
476     			fourth.__pad = &s;
477     		}
478     		need_back_translation =
479     			(IPCOP_MASK (third) &
480     			 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
481     		if (need_back_translation)
482     			fourth.__pad = &s;
483     		old_fs = get_fs ();
484     		set_fs (KERNEL_DS);
485     		err = sys_semctl (first, second, third, fourth);
486     		set_fs (old_fs);
487     		if (need_back_translation) {
488     			int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
489     			err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
490     			err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
491     			err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
492     			err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
493     			err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
494     			err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
495     			err2 |= __put_user (s.sem_otime, &usp->sem_otime);
496     			err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
497     			err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
498     			if (err2) err = -EFAULT;
499     		}
500     	}
501     out:
502     	return err;
503     }
504     
505     static int do_sys32_msgsnd (int first, int second, int third, void *uptr)
506     {
507     	struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
508     	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
509     	mm_segment_t old_fs;
510     	int err;
511     
512     	if (!p)
513     		return -ENOMEM;
514     	err = get_user (p->mtype, &up->mtype);
515     	err |= __copy_from_user (p->mtext, &up->mtext, second);
516     	if (err)
517     		goto out;
518     	old_fs = get_fs ();
519     	set_fs (KERNEL_DS);
520     	err = sys_msgsnd (first, p, second, third);
521     	set_fs (old_fs);
522     out:
523     	kfree (p);
524     	return err;
525     }
526     
527     static int do_sys32_msgrcv (int first, int second, int msgtyp, int third,
528     			    int version, void *uptr)
529     {
530     	struct msgbuf32 *up;
531     	struct msgbuf *p;
532     	mm_segment_t old_fs;
533     	int err;
534     
535     	if (!version) {
536     		struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
537     		struct ipc_kludge ipck;
538     
539     		err = -EINVAL;
540     		if (!uptr)
541     			goto out;
542     		err = -EFAULT;
543     		if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
544     			goto out;
545     		uptr = (void *)A(ipck.msgp);
546     		msgtyp = ipck.msgtyp;
547     	}
548     	err = -ENOMEM;
549     	p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
550     	if (!p)
551     		goto out;
552     	old_fs = get_fs ();
553     	set_fs (KERNEL_DS);
554     	err = sys_msgrcv (first, p, second + 4, msgtyp, third);
555     	set_fs (old_fs);
556     	if (err < 0)
557     		goto free_then_out;
558     	up = (struct msgbuf32 *)uptr;
559     	if (put_user (p->mtype, &up->mtype) ||
560     	    __copy_to_user (&up->mtext, p->mtext, err))
561     		err = -EFAULT;
562     free_then_out:
563     	kfree (p);
564     out:
565     	return err;
566     }
567     
568     static int do_sys32_msgctl (int first, int second, void *uptr)
569     {
570     	int err;
571     
572     	if (IPCOP_MASK (second) &
573     	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
574     	     IPCOP_MASK (IPC_RMID))) {
575     		err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
576     	} else if (second & IPC_64) {
577     		struct msqid64_ds m;
578     		struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
579     		mm_segment_t old_fs;
580     
581     		if (second == (IPC_SET|IPC_64)) {
582     			err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
583     			err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
584     			err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
585     			err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
586     			if (err)
587     				goto out;
588     		}
589     		old_fs = get_fs ();
590     		set_fs (KERNEL_DS);
591     		err = sys_msgctl (first, second, (struct msqid_ds *)&m);
592     		set_fs (old_fs);
593     		if (IPCOP_MASK (second) &
594     		    (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
595     			int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
596     			err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
597     			err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
598     			err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
599     			err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
600     			err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
601     			if (err2)
602     				err = -EFAULT;
603     		}
604     	} else {
605     		struct msqid_ds m;
606     		struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
607     		mm_segment_t old_fs;
608     
609     		if (second == IPC_SET) {
610     			err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
611     			err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
612     			err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
613     			err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
614     			if (err)
615     				goto out;
616     		}
617     		old_fs = get_fs ();
618     		set_fs (KERNEL_DS);
619     		err = sys_msgctl (first, second, &m);
620     		set_fs (old_fs);
621     		if (IPCOP_MASK (second) &
622     		    (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
623     			int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
624     			err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
625     			err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
626     			err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
627     			err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
628     			err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
629     			err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
630     			err2 |= __put_user (m.msg_stime, &up->msg_stime);
631     			err2 |= __put_user (m.msg_rtime, &up->msg_rtime);
632     			err2 |= __put_user (m.msg_ctime, &up->msg_ctime);
633     			err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
634     			err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
635     			err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
636     			err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
637     			err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
638     			if (err2)
639     				err = -EFAULT;
640     		}
641     	}
642     
643     out:
644     	return err;
645     }
646     
647     static int do_sys32_shmat (int first, int second, int third, int version, void *uptr)
648     {
649     	unsigned long raddr;
650     	u32 *uaddr = (u32 *)A((u32)third);
651     	int err = -EINVAL;
652     
653     	if (version == 1)
654     		goto out;
655     	err = sys_shmat (first, uptr, second, &raddr);
656     	if (err)
657     		goto out;
658     	err = put_user (raddr, uaddr);
659     out:
660     	return err;
661     }
662     
663     static int do_sys32_shmctl (int first, int second, void *uptr)
664     {
665     	int err;
666     
667     	if (IPCOP_MASK (second) &
668     	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) |
669     	     IPCOP_MASK (IPC_RMID))) {
670     		if (second == (IPC_INFO|IPC_64))
671     			second = IPC_INFO; /* So that we don't have to translate it */
672     		err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
673     	} else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
674     		struct shmid64_ds s;
675     		struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
676     		mm_segment_t old_fs;
677     
678     		if (second == (IPC_SET|IPC_64)) {
679     			err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
680     			err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
681     			err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
682     			if (err)
683     				goto out;
684     		}
685     		old_fs = get_fs ();
686     		set_fs (KERNEL_DS);
687     		err = sys_shmctl (first, second, (struct shmid_ds *)&s);
688     		set_fs (old_fs);
689     		if (err < 0)
690     			goto out;
691     
692     		/* Mask it even in this case so it becomes a CSE. */
693     		if (IPCOP_MASK (second) &
694     		    (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
695     			int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
696     			err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
697     			err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
698     			err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
699     			err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
700     			if (err2)
701     				err = -EFAULT;
702     		}
703     	} else {
704     		struct shmid_ds s;
705     		struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
706     		mm_segment_t old_fs;
707     
708     		second &= ~IPC_64;
709     		if (second == IPC_SET) {
710     			err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
711     			err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
712     			err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
713     			if (err)
714     				goto out;
715     		}
716     		old_fs = get_fs ();
717     		set_fs (KERNEL_DS);
718     		err = sys_shmctl (first, second, &s);
719     		set_fs (old_fs);
720     		if (err < 0)
721     			goto out;
722     
723     		/* Mask it even in this case so it becomes a CSE. */
724     		if (second == SHM_INFO) {
725     			struct shm_info32 {
726     				int used_ids;
727     				u32 shm_tot, shm_rss, shm_swp;
728     				u32 swap_attempts, swap_successes;
729     			} *uip = (struct shm_info32 *)uptr;
730     			struct shm_info *kp = (struct shm_info *)&s;
731     			int err2 = put_user (kp->used_ids, &uip->used_ids);
732     			err2 |= __put_user (kp->shm_tot, &uip->shm_tot);
733     			err2 |= __put_user (kp->shm_rss, &uip->shm_rss);
734     			err2 |= __put_user (kp->shm_swp, &uip->shm_swp);
735     			err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts);
736     			err2 |= __put_user (kp->swap_successes, &uip->swap_successes);
737     			if (err2)
738     				err = -EFAULT;
739     		} else if (IPCOP_MASK (second) &
740     			   (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
741     			int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
742     			err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
743     			err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid);
744     			err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
745     			err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid);
746     			err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
747     			err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
748     			err2 |= __put_user (s.shm_atime, &up->shm_atime);
749     			err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
750     			err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
751     			err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
752     			err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
753     			err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
754     			err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
755     			if (err2)
756     				err = -EFAULT;
757     		}
758     	}
759     out:
760     	return err;
761     }
762     
763     asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
764     {
765     	int version, err;
766     
767     	version = call >> 16; /* hack for backward compatibility */
768     	call &= 0xffff;
769     
770     	if (call <= SEMCTL)
771     		switch (call) {
772     		case SEMOP:
773     			/* struct sembuf is the same on 32 and 64bit :)) */
774     			err = sys_semop (first, (struct sembuf *)AA(ptr), second);
775     			goto out;
776     		case SEMGET:
777     			err = sys_semget (first, second, third);
778     			goto out;
779     		case SEMCTL:
780     			err = do_sys32_semctl (first, second, third, (void *)AA(ptr));
781     			goto out;
782     		default:
783     			err = -EINVAL;
784     			goto out;
785     		};
786     	if (call <= MSGCTL) 
787     		switch (call) {
788     		case MSGSND:
789     			err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr));
790     			goto out;
791     		case MSGRCV:
792     			err = do_sys32_msgrcv (first, second, fifth, third,
793     					       version, (void *)AA(ptr));
794     			goto out;
795     		case MSGGET:
796     			err = sys_msgget ((key_t) first, second);
797     			goto out;
798     		case MSGCTL:
799     			err = do_sys32_msgctl (first, second, (void *)AA(ptr));
800     			goto out;
801     		default:
802     			err = -EINVAL;
803     			goto out;
804     		}
805     	if (call <= SHMCTL) 
806     		switch (call) {
807     		case SHMAT:
808     			err = do_sys32_shmat (first, second, third,
809     					      version, (void *)AA(ptr));
810     			goto out;
811     		case SHMDT: 
812     			err = sys_shmdt ((char *)AA(ptr));
813     			goto out;
814     		case SHMGET:
815     			err = sys_shmget (first, second, third);
816     			goto out;
817     		case SHMCTL:
818     			err = do_sys32_shmctl (first, second, (void *)AA(ptr));
819     			goto out;
820     		default:
821     			err = -EINVAL;
822     			goto out;
823     		}
824     
825     	err = -EINVAL;
826     
827     out:
828     	return err;
829     }
830     
831     static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
832     {
833     	int err;
834     	
835     	err = get_user(kfl->l_type, &ufl->l_type);
836     	err |= __get_user(kfl->l_whence, &ufl->l_whence);
837     	err |= __get_user(kfl->l_start, &ufl->l_start);
838     	err |= __get_user(kfl->l_len, &ufl->l_len);
839     	err |= __get_user(kfl->l_pid, &ufl->l_pid);
840     	return err;
841     }
842     
843     static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
844     {
845     	int err;
846     	
847     	err = __put_user(kfl->l_type, &ufl->l_type);
848     	err |= __put_user(kfl->l_whence, &ufl->l_whence);
849     	err |= __put_user(kfl->l_start, &ufl->l_start);
850     	err |= __put_user(kfl->l_len, &ufl->l_len);
851     	err |= __put_user(kfl->l_pid, &ufl->l_pid);
852     	return err;
853     }
854     
855     extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
856     
857     asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
858     {
859     	switch (cmd) {
860     	case F_GETLK:
861     	case F_SETLK:
862     	case F_SETLKW:
863     		{
864     			struct flock f;
865     			mm_segment_t old_fs;
866     			long ret;
867     			
868     			if (get_flock(&f, (struct flock32 *)arg))
869     				return -EFAULT;
870     			old_fs = get_fs(); set_fs (KERNEL_DS);
871     			ret = sys_fcntl(fd, cmd, (unsigned long)&f);
872     			set_fs (old_fs);
873     			if (ret) return ret;
874     			if (put_flock(&f, (struct flock32 *)arg))
875     				return -EFAULT;
876     			return 0;
877     		}
878     	default:
879     		return sys_fcntl(fd, cmd, (unsigned long)arg);
880     	}
881     }
882     
883     asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
884     {
885     	if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
886     		return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg);
887     	return sys32_fcntl(fd, cmd, arg);
888     }
889     
890     struct dqblk32 {
891         __u32 dqb_bhardlimit;
892         __u32 dqb_bsoftlimit;
893         __u32 dqb_curblocks;
894         __u32 dqb_ihardlimit;
895         __u32 dqb_isoftlimit;
896         __u32 dqb_curinodes;
897         __kernel_time_t32 dqb_btime;
898         __kernel_time_t32 dqb_itime;
899     };
900                                     
901     extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
902     
903     asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
904     {
905     	int cmds = cmd >> SUBCMDSHIFT;
906     	int err;
907     	struct dqblk d;
908     	mm_segment_t old_fs;
909     	char *spec;
910     	
911     	switch (cmds) {
912     	case Q_GETQUOTA:
913     		break;
914     	case Q_SETQUOTA:
915     	case Q_SETUSE:
916     	case Q_SETQLIM:
917     		if (copy_from_user (&d, (struct dqblk32 *)addr,
918     				    sizeof (struct dqblk32)))
919     			return -EFAULT;
920     		d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
921     		d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
922     		break;
923     	default:
924     		return sys_quotactl(cmd, special,
925     				    id, (caddr_t)addr);
926     	}
927     	spec = getname (special);
928     	err = PTR_ERR(spec);
929     	if (IS_ERR(spec)) return err;
930     	old_fs = get_fs ();
931     	set_fs (KERNEL_DS);
932     	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
933     	set_fs (old_fs);
934     	putname (spec);
935     	if (cmds == Q_GETQUOTA) {
936     		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
937     		((struct dqblk32 *)&d)->dqb_itime = i;
938     		((struct dqblk32 *)&d)->dqb_btime = b;
939     		if (copy_to_user ((struct dqblk32 *)addr, &d,
940     				  sizeof (struct dqblk32)))
941     			return -EFAULT;
942     	}
943     	return err;
944     }
945     
946     static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
947     {
948     	int err;
949     	
950     	err = put_user (kbuf->f_type, &ubuf->f_type);
951     	err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
952     	err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
953     	err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
954     	err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
955     	err |= __put_user (kbuf->f_files, &ubuf->f_files);
956     	err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
957     	err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
958     	err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
959     	err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
960     	return err;
961     }
962     
963     extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
964     
965     asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf)
966     {
967     	int ret;
968     	struct statfs s;
969     	mm_segment_t old_fs = get_fs();
970     	char *pth;
971     	
972     	pth = getname (path);
973     	ret = PTR_ERR(pth);
974     	if (!IS_ERR(pth)) {
975     		set_fs (KERNEL_DS);
976     		ret = sys_statfs((const char *)pth, &s);
977     		set_fs (old_fs);
978     		putname (pth);
979     		if (put_statfs(buf, &s))
980     			return -EFAULT;
981     	}
982     	return ret;
983     }
984     
985     extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
986     
987     asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
988     {
989     	int ret;
990     	struct statfs s;
991     	mm_segment_t old_fs = get_fs();
992     	
993     	set_fs (KERNEL_DS);
994     	ret = sys_fstatfs(fd, &s);
995     	set_fs (old_fs);
996     	if (put_statfs(buf, &s))
997     		return -EFAULT;
998     	return ret;
999     }
1000     
1001     extern asmlinkage long sys_truncate(const char * path, unsigned long length);
1002     extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
1003     
1004     asmlinkage int sys32_truncate64(const char * path, unsigned long high, unsigned long low)
1005     {
1006     	if ((int)high < 0)
1007     		return -EINVAL;
1008     	else
1009     		return sys_truncate(path, (high << 32) | low);
1010     }
1011     
1012     asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
1013     {
1014     	if ((int)high < 0)
1015     		return -EINVAL;
1016     	else
1017     		return sys_ftruncate(fd, (high << 32) | low);
1018     }
1019     
1020     extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
1021     
1022     struct utimbuf32 {
1023     	__kernel_time_t32 actime, modtime;
1024     };
1025     
1026     asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
1027     {
1028     	struct utimbuf t;
1029     	mm_segment_t old_fs;
1030     	int ret;
1031     	char *filenam;
1032     	
1033     	if (!times)
1034     		return sys_utime(filename, NULL);
1035     	if (get_user (t.actime, &times->actime) ||
1036     	    __get_user (t.modtime, &times->modtime))
1037     		return -EFAULT;
1038     	filenam = getname (filename);
1039     	ret = PTR_ERR(filenam);
1040     	if (!IS_ERR(filenam)) {
1041     		old_fs = get_fs();
1042     		set_fs (KERNEL_DS); 
1043     		ret = sys_utime(filenam, &t);
1044     		set_fs (old_fs);
1045     		putname (filenam);
1046     	}
1047     	return ret;
1048     }
1049     
1050     struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
1051     
1052     typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
1053     typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
1054     
1055     static long do_readv_writev32(int type, struct file *file,
1056     			      const struct iovec32 *vector, u32 count)
1057     {
1058     	unsigned long tot_len;
1059     	struct iovec iovstack[UIO_FASTIOV];
1060     	struct iovec *iov=iovstack, *ivp;
1061     	struct inode *inode;
1062     	long retval, i;
1063     	io_fn_t fn;
1064     	iov_fn_t fnv;
1065     
1066     	/* First get the "struct iovec" from user memory and
1067     	 * verify all the pointers
1068     	 */
1069     	if (!count)
1070     		return 0;
1071     	if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
1072     		return -EFAULT;
1073     	if (count > UIO_MAXIOV)
1074     		return -EINVAL;
1075     	if (count > UIO_FASTIOV) {
1076     		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1077     		if (!iov)
1078     			return -ENOMEM;
1079     	}
1080     
1081     	tot_len = 0;
1082     	i = count;
1083     	ivp = iov;
1084     	while(i > 0) {
1085     		u32 len;
1086     		u32 buf;
1087     
1088     		__get_user(len, &vector->iov_len);
1089     		__get_user(buf, &vector->iov_base);
1090     		tot_len += len;
1091     		ivp->iov_base = (void *)A(buf);
1092     		ivp->iov_len = (__kernel_size_t) len;
1093     		vector++;
1094     		ivp++;
1095     		i--;
1096     	}
1097     
1098     	inode = file->f_dentry->d_inode;
1099     	/* VERIFY_WRITE actually means a read, as we write to user space */
1100     	retval = locks_verify_area((type == VERIFY_WRITE
1101     				    ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
1102     				   inode, file, file->f_pos, tot_len);
1103     	if (retval)
1104     		goto out;
1105     
1106     	/* VERIFY_WRITE actually means a read, as we write to user space */
1107     	fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
1108     	if (fnv) {
1109     		retval = fnv(file, iov, count, &file->f_pos);
1110     		goto out;
1111     	}
1112     
1113     	fn = (type == VERIFY_WRITE ? file->f_op->read :
1114     	      (io_fn_t) file->f_op->write);
1115     
1116     	ivp = iov;
1117     	while (count > 0) {
1118     		void * base;
1119     		int len, nr;
1120     
1121     		base = ivp->iov_base;
1122     		len = ivp->iov_len;
1123     		ivp++;
1124     		count--;
1125     		nr = fn(file, base, len, &file->f_pos);
1126     		if (nr < 0) {
1127     			if (!retval)
1128     				retval = nr;
1129     			break;
1130     		}
1131     		retval += nr;
1132     		if (nr != len)
1133     			break;
1134     	}
1135     out:
1136     	if (iov != iovstack)
1137     		kfree(iov);
1138     
1139     	return retval;
1140     }
1141     
1142     asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
1143     {
1144     	struct file *file;
1145     	long ret = -EBADF;
1146     
1147     	file = fget(fd);
1148     	if(!file)
1149     		goto bad_file;
1150     
1151     	if (file->f_op && (file->f_mode & FMODE_READ) &&
1152     	    (file->f_op->readv || file->f_op->read))
1153     		ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
1154     	fput(file);
1155     
1156     bad_file:
1157     	return ret;
1158     }
1159     
1160     asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
1161     {
1162     	struct file *file;
1163     	int ret = -EBADF;
1164     
1165     	file = fget(fd);
1166     	if(!file)
1167     		goto bad_file;
1168     	if (file->f_op && (file->f_mode & FMODE_WRITE) &&
1169     	    (file->f_op->writev || file->f_op->write))
1170     		ret = do_readv_writev32(VERIFY_READ, file, vector, count);
1171     	fput(file);
1172     
1173     bad_file:
1174     	return ret;
1175     }
1176     
1177     /* readdir & getdents */
1178     
1179     #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1180     #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1181     
1182     struct old_linux_dirent32 {
1183     	u32		d_ino;
1184     	u32		d_offset;
1185     	unsigned short	d_namlen;
1186     	char		d_name[1];
1187     };
1188     
1189     struct readdir_callback32 {
1190     	struct old_linux_dirent32 * dirent;
1191     	int count;
1192     };
1193     
1194     static int fillonedir(void * __buf, const char * name, int namlen,
1195     		      loff_t offset, ino_t ino, unsigned int d_type)
1196     {
1197     	struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
1198     	struct old_linux_dirent32 * dirent;
1199     
1200     	if (buf->count)
1201     		return -EINVAL;
1202     	buf->count++;
1203     	dirent = buf->dirent;
1204     	put_user(ino, &dirent->d_ino);
1205     	put_user(offset, &dirent->d_offset);
1206     	put_user(namlen, &dirent->d_namlen);
1207     	copy_to_user(dirent->d_name, name, namlen);
1208     	put_user(0, dirent->d_name + namlen);
1209     	return 0;
1210     }
1211     
1212     asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
1213     {
1214     	int error = -EBADF;
1215     	struct file * file;
1216     	struct readdir_callback32 buf;
1217     
1218     	file = fget(fd);
1219     	if (!file)
1220     		goto out;
1221     
1222     	buf.count = 0;
1223     	buf.dirent = dirent;
1224     
1225     	error = vfs_readdir(file, fillonedir, &buf);
1226     	if (error < 0)
1227     		goto out_putf;
1228     	error = buf.count;
1229     
1230     out_putf:
1231     	fput(file);
1232     out:
1233     	return error;
1234     }
1235     
1236     struct linux_dirent32 {
1237     	u32		d_ino;
1238     	u32		d_off;
1239     	unsigned short	d_reclen;
1240     	char		d_name[1];
1241     };
1242     
1243     struct getdents_callback32 {
1244     	struct linux_dirent32 * current_dir;
1245     	struct linux_dirent32 * previous;
1246     	int count;
1247     	int error;
1248     };
1249     
1250     static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
1251     		   unsigned int d_type)
1252     {
1253     	struct linux_dirent32 * dirent;
1254     	struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
1255     	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
1256     
1257     	buf->error = -EINVAL;	/* only used if we fail.. */
1258     	if (reclen > buf->count)
1259     		return -EINVAL;
1260     	dirent = buf->previous;
1261     	if (dirent)
1262     		put_user(offset, &dirent->d_off);
1263     	dirent = buf->current_dir;
1264     	buf->previous = dirent;
1265     	put_user(ino, &dirent->d_ino);
1266     	put_user(reclen, &dirent->d_reclen);
1267     	copy_to_user(dirent->d_name, name, namlen);
1268     	put_user(0, dirent->d_name + namlen);
1269     	((char *) dirent) += reclen;
1270     	buf->current_dir = dirent;
1271     	buf->count -= reclen;
1272     	return 0;
1273     }
1274     
1275     asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
1276     {
1277     	struct file * file;
1278     	struct linux_dirent32 * lastdirent;
1279     	struct getdents_callback32 buf;
1280     	int error = -EBADF;
1281     
1282     	file = fget(fd);
1283     	if (!file)
1284     		goto out;
1285     
1286     	buf.current_dir = dirent;
1287     	buf.previous = NULL;
1288     	buf.count = count;
1289     	buf.error = 0;
1290     
1291     	error = vfs_readdir(file, filldir, &buf);
1292     	if (error < 0)
1293     		goto out_putf;
1294     	lastdirent = buf.previous;
1295     	error = buf.error;
1296     	if(lastdirent) {
1297     		put_user(file->f_pos, &lastdirent->d_off);
1298     		error = count - buf.count;
1299     	}
1300     out_putf:
1301     	fput(file);
1302     out:
1303     	return error;
1304     }
1305     
1306     /* end of readdir & getdents */
1307     
1308     /*
1309      * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
1310      * 64-bit unsigned longs.
1311      */
1312     
1313     static inline int
1314     get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1315     {
1316     	if (ufdset) {
1317     		unsigned long odd;
1318     
1319     		if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
1320     			return -EFAULT;
1321     
1322     		odd = n & 1UL;
1323     		n &= ~1UL;
1324     		while (n) {
1325     			unsigned long h, l;
1326     			__get_user(l, ufdset);
1327     			__get_user(h, ufdset+1);
1328     			ufdset += 2;
1329     			*fdset++ = h << 32 | l;
1330     			n -= 2;
1331     		}
1332     		if (odd)
1333     			__get_user(*fdset, ufdset);
1334     	} else {
1335     		/* Tricky, must clear full unsigned long in the
1336     		 * kernel fdset at the end, this makes sure that
1337     		 * actually happens.
1338     		 */
1339     		memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1340     	}
1341     	return 0;
1342     }
1343     
1344     static inline void
1345     set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
1346     {
1347     	unsigned long odd;
1348     
1349     	if (!ufdset)
1350     		return;
1351     
1352     	odd = n & 1UL;
1353     	n &= ~1UL;
1354     	while (n) {
1355     		unsigned long h, l;
1356     		l = *fdset++;
1357     		h = l >> 32;
1358     		__put_user(l, ufdset);
1359     		__put_user(h, ufdset+1);
1360     		ufdset += 2;
1361     		n -= 2;
1362     	}
1363     	if (odd)
1364     		__put_user(*fdset, ufdset);
1365     }
1366     
1367     #define MAX_SELECT_SECONDS \
1368     	((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1369     
1370     asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
1371     {
1372     	fd_set_bits fds;
1373     	struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
1374     	char *bits;
1375     	unsigned long nn;
1376     	long timeout;
1377     	int ret, size;
1378     
1379     	timeout = MAX_SCHEDULE_TIMEOUT;
1380     	if (tvp) {
1381     		time_t sec, usec;
1382     
1383     		if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
1384     		    || (ret = __get_user(sec, &tvp->tv_sec))
1385     		    || (ret = __get_user(usec, &tvp->tv_usec)))
1386     			goto out_nofds;
1387     
1388     		ret = -EINVAL;
1389     		if(sec < 0 || usec < 0)
1390     			goto out_nofds;
1391     
1392     		if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1393     			timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
1394     			timeout += sec * (unsigned long) HZ;
1395     		}
1396     	}
1397     
1398     	ret = -EINVAL;
1399     	if (n < 0)
1400     		goto out_nofds;
1401     	if (n > current->files->max_fdset)
1402     		n = current->files->max_fdset;
1403     
1404     	/*
1405     	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1406     	 * since we used fdset we need to allocate memory in units of
1407     	 * long-words. 
1408     	 */
1409     	ret = -ENOMEM;
1410     	size = FDS_BYTES(n);
1411     	bits = kmalloc(6 * size, GFP_KERNEL);
1412     	if (!bits)
1413     		goto out_nofds;
1414     	fds.in      = (unsigned long *)  bits;
1415     	fds.out     = (unsigned long *) (bits +   size);
1416     	fds.ex      = (unsigned long *) (bits + 2*size);
1417     	fds.res_in  = (unsigned long *) (bits + 3*size);
1418     	fds.res_out = (unsigned long *) (bits + 4*size);
1419     	fds.res_ex  = (unsigned long *) (bits + 5*size);
1420     
1421     	nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
1422     	if ((ret = get_fd_set32(nn, fds.in, inp)) ||
1423     	    (ret = get_fd_set32(nn, fds.out, outp)) ||
1424     	    (ret = get_fd_set32(nn, fds.ex, exp)))
1425     		goto out;
1426     	zero_fd_set(n, fds.res_in);
1427     	zero_fd_set(n, fds.res_out);
1428     	zero_fd_set(n, fds.res_ex);
1429     
1430     	ret = do_select(n, &fds, &timeout);
1431     
1432     	if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1433     		time_t sec = 0, usec = 0;
1434     		if (timeout) {
1435     			sec = timeout / HZ;
1436     			usec = timeout % HZ;
1437     			usec *= (1000000/HZ);
1438     		}
1439     		put_user(sec, &tvp->tv_sec);
1440     		put_user(usec, &tvp->tv_usec);
1441     	}
1442     
1443     	if (ret < 0)
1444     		goto out;
1445     	if (!ret) {
1446     		ret = -ERESTARTNOHAND;
1447     		if (signal_pending(current))
1448     			goto out;
1449     		ret = 0;
1450     	}
1451     
1452     	set_fd_set32(nn, inp, fds.res_in);
1453     	set_fd_set32(nn, outp, fds.res_out);
1454     	set_fd_set32(nn, exp, fds.res_ex);
1455     
1456     out:
1457     	kfree(bits);
1458     out_nofds:
1459     	return ret;
1460     }
1461     
1462     static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
1463     {
1464     	unsigned long ino, blksize, blocks;
1465     	kdev_t dev, rdev;
1466     	umode_t mode;
1467     	nlink_t nlink;
1468     	uid_t uid;
1469     	gid_t gid;
1470     	off_t size;
1471     	time_t atime, mtime, ctime;
1472     	int err;
1473     
1474     	/* Stream the loads of inode data into the load buffer,
1475     	 * then we push it all into the store buffer below.  This
1476     	 * should give optimal cache performance.
1477     	 */
1478     	ino = inode->i_ino;
1479     	dev = inode->i_dev;
1480     	mode = inode->i_mode;
1481     	nlink = inode->i_nlink;
1482     	uid = inode->i_uid;
1483     	gid = inode->i_gid;
1484     	rdev = inode->i_rdev;
1485     	size = inode->i_size;
1486     	atime = inode->i_atime;
1487     	mtime = inode->i_mtime;
1488     	ctime = inode->i_ctime;
1489     	blksize = inode->i_blksize;
1490     	blocks = inode->i_blocks;
1491     
1492     	err  = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
1493     	err |= put_user(ino, &statbuf->st_ino);
1494     	err |= put_user(mode, &statbuf->st_mode);
1495     	err |= put_user(nlink, &statbuf->st_nlink);
1496     	err |= put_user(high2lowuid(uid), &statbuf->st_uid);
1497     	err |= put_user(high2lowgid(gid), &statbuf->st_gid);
1498     	err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
1499     	err |= put_user(size, &statbuf->st_size);
1500     	err |= put_user(atime, &statbuf->st_atime);
1501     	err |= put_user(0, &statbuf->__unused1);
1502     	err |= put_user(mtime, &statbuf->st_mtime);
1503     	err |= put_user(0, &statbuf->__unused2);
1504     	err |= put_user(ctime, &statbuf->st_ctime);
1505     	err |= put_user(0, &statbuf->__unused3);
1506     	if (blksize) {
1507     		err |= put_user(blksize, &statbuf->st_blksize);
1508     		err |= put_user(blocks, &statbuf->st_blocks);
1509     	} else {
1510     		unsigned int tmp_blocks;
1511     
1512     #define D_B   7
1513     #define I_B   (BLOCK_SIZE / sizeof(unsigned short))
1514     		tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
1515     		if (tmp_blocks > D_B) {
1516     			unsigned int indirect;
1517     
1518     			indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
1519     			tmp_blocks += indirect;
1520     			if (indirect > 1) {
1521     				indirect = (indirect - 1 + I_B - 1) / I_B;
1522     				tmp_blocks += indirect;
1523     				if (indirect > 1)
1524     					tmp_blocks++;
1525     			}
1526     		}
1527     		err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
1528     		err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
1529     #undef D_B
1530     #undef I_B
1531     	}
1532     	err |= put_user(0, &statbuf->__unused4[0]);
1533     	err |= put_user(0, &statbuf->__unused4[1]);
1534     
1535     	return err;
1536     }
1537     
1538     /* Perhaps this belongs in fs.h or similar. -DaveM */
1539     static __inline__ int
1540     do_revalidate(struct dentry *dentry)
1541     {
1542     	struct inode * inode = dentry->d_inode;
1543     	if (inode->i_op && inode->i_op->revalidate)
1544     		return inode->i_op->revalidate(dentry);
1545     	return 0;
1546     }
1547     
1548     asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
1549     {
1550     	struct nameidata nd;
1551     	int error;
1552     
1553     	error = user_path_walk(filename, &nd);
1554     	if (!error) {
1555     		error = do_revalidate(nd.dentry);
1556     		if (!error)
1557     			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1558     		path_release(&nd);
1559     	}
1560     	return error;
1561     }
1562     
1563     asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
1564     {
1565     	struct nameidata nd;
1566     	int error;
1567     
1568     	error = user_path_walk_link(filename, &nd);
1569     	if (!error) {
1570     		error = do_revalidate(nd.dentry);
1571     		if (!error)
1572     			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1573     
1574     		path_release(&nd);
1575     	}
1576     	return error;
1577     }
1578     
1579     asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
1580     {
1581     	struct file *f;
1582     	int err = -EBADF;
1583     
1584     	f = fget(fd);
1585     	if (f) {
1586     		struct dentry * dentry = f->f_dentry;
1587     
1588     		err = do_revalidate(dentry);
1589     		if (!err)
1590     			err = cp_new_stat32(dentry->d_inode, statbuf);
1591     		fput(f);
1592     	}
1593     	return err;
1594     }
1595     
1596     extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
1597     
1598     asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
1599     {
1600     	return sys_sysfs(option, arg1, arg2);
1601     }
1602     
1603     struct ncp_mount_data32 {
1604             int version;
1605             unsigned int ncp_fd;
1606             __kernel_uid_t32 mounted_uid;
1607             __kernel_pid_t32 wdog_pid;
1608             unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
1609             unsigned int time_out;
1610             unsigned int retry_count;
1611             unsigned int flags;
1612             __kernel_uid_t32 uid;
1613             __kernel_gid_t32 gid;
1614             __kernel_mode_t32 file_mode;
1615             __kernel_mode_t32 dir_mode;
1616     };
1617     
1618     static void *do_ncp_super_data_conv(void *raw_data)
1619     {
1620     	struct ncp_mount_data news, *n = &news; 
1621     	struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
1622     
1623     	n->dir_mode = n32->dir_mode;
1624     	n->file_mode = n32->file_mode;
1625     	n->gid = low2highgid(n32->gid);
1626     	n->uid = low2highuid(n32->uid);
1627     	memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
1628     	n->wdog_pid = n32->wdog_pid;
1629     	n->mounted_uid = low2highuid(n32->mounted_uid);
1630     	memcpy(raw_data, n, sizeof(struct ncp_mount_data)); 
1631     	return raw_data;
1632     }
1633     
1634     struct smb_mount_data32 {
1635             int version;
1636             __kernel_uid_t32 mounted_uid;
1637             __kernel_uid_t32 uid;
1638             __kernel_gid_t32 gid;
1639             __kernel_mode_t32 file_mode;
1640             __kernel_mode_t32 dir_mode;
1641     };
1642     
1643     static void *do_smb_super_data_conv(void *raw_data)
1644     {
1645     	struct smb_mount_data news, *s = &news;
1646     	struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
1647     
1648     	s->version = s32->version;
1649     	s->mounted_uid = low2highuid(s32->mounted_uid);
1650     	s->uid = low2highuid(s32->uid);
1651     	s->gid = low2highgid(s32->gid);
1652     	s->file_mode = s32->file_mode;
1653     	s->dir_mode = s32->dir_mode;
1654     	memcpy(raw_data, s, sizeof(struct smb_mount_data)); 
1655     	return raw_data;
1656     }
1657     
1658     static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
1659     {
1660     	int i;
1661     	unsigned long page;
1662     	struct vm_area_struct *vma;
1663     
1664     	*kernel = 0;
1665     	if(!user)
1666     		return 0;
1667     	vma = find_vma(current->mm, (unsigned long)user);
1668     	if(!vma || (unsigned long)user < vma->vm_start)
1669     		return -EFAULT;
1670     	if(!(vma->vm_flags & VM_READ))
1671     		return -EFAULT;
1672     	i = vma->vm_end - (unsigned long) user;
1673     	if(PAGE_SIZE <= (unsigned long) i)
1674     		i = PAGE_SIZE - 1;
1675     	if(!(page = __get_free_page(GFP_KERNEL)))
1676     		return -ENOMEM;
1677     	if(copy_from_user((void *) page, user, i)) {
1678     		free_page(page);
1679     		return -EFAULT;
1680     	}
1681     	*kernel = page;
1682     	return 0;
1683     }
1684     
1685     #define SMBFS_NAME	"smbfs"
1686     #define NCPFS_NAME	"ncpfs"
1687     
1688     asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
1689     {
1690     	unsigned long type_page = 0;
1691     	unsigned long data_page = 0;
1692     	unsigned long dev_page = 0;
1693     	unsigned long dir_page = 0;
1694     	int err, is_smb, is_ncp;
1695     
1696     	is_smb = is_ncp = 0;
1697     
1698     	err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
1699     	if (err)
1700     		goto out;
1701     
1702     	if (!type_page) {
1703     		err = -EINVAL;
1704     		goto out;
1705     	}
1706     
1707     	is_smb = !strcmp((char *)type_page, SMBFS_NAME);
1708     	is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
1709     
1710     	err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
1711     	if (err)
1712     		goto type_out;
1713     
1714     	err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
1715     	if (err)
1716     		goto data_out;
1717     
1718     	err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
1719     	if (err)
1720     		goto dev_out;
1721     
1722     	if (!is_smb && !is_ncp) {
1723     		lock_kernel();
1724     		err = do_mount((char*)dev_page, (char*)dir_page,
1725     				(char*)type_page, new_flags, (char*)data_page);
1726     		unlock_kernel();
1727     	} else {
1728     		if (is_ncp)
1729     			do_ncp_super_data_conv((void *)data_page);
1730     		else
1731     			do_smb_super_data_conv((void *)data_page);
1732     
1733     		lock_kernel();
1734     		err = do_mount((char*)dev_page, (char*)dir_page,
1735     				(char*)type_page, new_flags, (char*)data_page);
1736     		unlock_kernel();
1737     	}
1738     	free_page(dir_page);
1739     
1740     dev_out:
1741     	free_page(dev_page);
1742     
1743     data_out:
1744     	free_page(data_page);
1745     
1746     type_out:
1747     	free_page(type_page);
1748     
1749     out:
1750     	return err;
1751     }
1752     
1753     struct rusage32 {
1754             struct timeval32 ru_utime;
1755             struct timeval32 ru_stime;
1756             s32    ru_maxrss;
1757             s32    ru_ixrss;
1758             s32    ru_idrss;
1759             s32    ru_isrss;
1760             s32    ru_minflt;
1761             s32    ru_majflt;
1762             s32    ru_nswap;
1763             s32    ru_inblock;
1764             s32    ru_oublock;
1765             s32    ru_msgsnd; 
1766             s32    ru_msgrcv; 
1767             s32    ru_nsignals;
1768             s32    ru_nvcsw;
1769             s32    ru_nivcsw;
1770     };
1771     
1772     static int put_rusage (struct rusage32 *ru, struct rusage *r)
1773     {
1774     	int err;
1775     	
1776     	err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1777     	err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1778     	err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1779     	err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1780     	err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1781     	err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1782     	err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1783     	err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1784     	err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1785     	err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1786     	err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1787     	err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1788     	err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1789     	err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1790     	err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1791     	err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1792     	err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1793     	err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1794     	return err;
1795     }
1796     
1797     asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
1798     {
1799     	if (!ru)
1800     		return sys_wait4(pid, stat_addr, options, NULL);
1801     	else {
1802     		struct rusage r;
1803     		int ret;
1804     		unsigned int status;
1805     		mm_segment_t old_fs = get_fs();
1806     		
1807     		set_fs (KERNEL_DS);
1808     		ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
1809     		set_fs (old_fs);
1810     		if (put_rusage (ru, &r)) return -EFAULT;
1811     		if (stat_addr && put_user (status, stat_addr))
1812     			return -EFAULT;
1813     		return ret;
1814     	}
1815     }
1816     
1817     struct sysinfo32 {
1818             s32 uptime;
1819             u32 loads[3];
1820             u32 totalram;
1821             u32 freeram;
1822             u32 sharedram;
1823             u32 bufferram;
1824             u32 totalswap;
1825             u32 freeswap;
1826             unsigned short procs;
1827             char _f[22];
1828     };
1829     
1830     extern asmlinkage int sys_sysinfo(struct sysinfo *info);
1831     
1832     asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
1833     {
1834     	struct sysinfo s;
1835     	int ret, err;
1836     	mm_segment_t old_fs = get_fs ();
1837     	
1838     	set_fs (KERNEL_DS);
1839     	ret = sys_sysinfo(&s);
1840     	set_fs (old_fs);
1841     	err = put_user (s.uptime, &info->uptime);
1842     	err |= __put_user (s.loads[0], &info->loads[0]);
1843     	err |= __put_user (s.loads[1], &info->loads[1]);
1844     	err |= __put_user (s.loads[2], &info->loads[2]);
1845     	err |= __put_user (s.totalram, &info->totalram);
1846     	err |= __put_user (s.freeram, &info->freeram);
1847     	err |= __put_user (s.sharedram, &info->sharedram);
1848     	err |= __put_user (s.bufferram, &info->bufferram);
1849     	err |= __put_user (s.totalswap, &info->totalswap);
1850     	err |= __put_user (s.freeswap, &info->freeswap);
1851     	err |= __put_user (s.procs, &info->procs);
1852     	if (err)
1853     		return -EFAULT;
1854     	return ret;
1855     }
1856     
1857     struct timespec32 {
1858     	s32    tv_sec;
1859     	s32    tv_nsec;
1860     };
1861                     
1862     extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
1863     
1864     asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
1865     {
1866     	struct timespec t;
1867     	int ret;
1868     	mm_segment_t old_fs = get_fs ();
1869     	
1870     	set_fs (KERNEL_DS);
1871     	ret = sys_sched_rr_get_interval(pid, &t);
1872     	set_fs (old_fs);
1873     	if (put_user (t.tv_sec, &interval->tv_sec) ||
1874     	    __put_user (t.tv_nsec, &interval->tv_nsec))
1875     		return -EFAULT;
1876     	return ret;
1877     }
1878     
1879     extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
1880     
1881     asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
1882     {
1883     	struct timespec t;
1884     	int ret;
1885     	mm_segment_t old_fs = get_fs ();
1886     	
1887     	if (get_user (t.tv_sec, &rqtp->tv_sec) ||
1888     	    __get_user (t.tv_nsec, &rqtp->tv_nsec))
1889     		return -EFAULT;
1890     	set_fs (KERNEL_DS);
1891     	ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1892     	set_fs (old_fs);
1893     	if (rmtp && ret == -EINTR) {
1894     		if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1895     	    	    __put_user (t.tv_nsec, &rmtp->tv_nsec))
1896     			return -EFAULT;
1897     	}
1898     	return ret;
1899     }
1900     
1901     extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
1902     
1903     asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
1904     {
1905     	old_sigset_t s;
1906     	int ret;
1907     	mm_segment_t old_fs = get_fs();
1908     	
1909     	if (set && get_user (s, set)) return -EFAULT;
1910     	set_fs (KERNEL_DS);
1911     	ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
1912     	set_fs (old_fs);
1913     	if (ret) return ret;
1914     	if (oset && put_user (s, oset)) return -EFAULT;
1915     	return 0;
1916     }
1917     
1918     extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
1919     
1920     asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
1921     {
1922     	sigset_t s;
1923     	sigset_t32 s32;
1924     	int ret;
1925     	mm_segment_t old_fs = get_fs();
1926     	
1927     	if (set) {
1928     		if (copy_from_user (&s32, set, sizeof(sigset_t32)))
1929     			return -EFAULT;
1930     		switch (_NSIG_WORDS) {
1931     		case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
1932     		case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
1933     		case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
1934     		case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
1935     		}
1936     	}
1937     	set_fs (KERNEL_DS);
1938     	ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
1939     	set_fs (old_fs);
1940     	if (ret) return ret;
1941     	if (oset) {
1942     		switch (_NSIG_WORDS) {
1943     		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1944     		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1945     		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1946     		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1947     		}
1948     		if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
1949     			return -EFAULT;
1950     	}
1951     	return 0;
1952     }
1953     
1954     extern asmlinkage int sys_sigpending(old_sigset_t *set);
1955     
1956     asmlinkage int sys32_sigpending(old_sigset_t32 *set)
1957     {
1958     	old_sigset_t s;
1959     	int ret;
1960     	mm_segment_t old_fs = get_fs();
1961     		
1962     	set_fs (KERNEL_DS);
1963     	ret = sys_sigpending(&s);
1964     	set_fs (old_fs);
1965     	if (put_user (s, set)) return -EFAULT;
1966     	return ret;
1967     }
1968     
1969     extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
1970     
1971     asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
1972     {
1973     	sigset_t s;
1974     	sigset_t32 s32;
1975     	int ret;
1976     	mm_segment_t old_fs = get_fs();
1977     		
1978     	set_fs (KERNEL_DS);
1979     	ret = sys_rt_sigpending(&s, sigsetsize);
1980     	set_fs (old_fs);
1981     	if (!ret) {
1982     		switch (_NSIG_WORDS) {
1983     		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1984     		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1985     		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1986     		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1987     		}
1988     		if (copy_to_user (set, &s32, sizeof(sigset_t32)))
1989     			return -EFAULT;
1990     	}
1991     	return ret;
1992     }
1993     
1994     asmlinkage int
1995     sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
1996     		      struct timespec32 *uts, __kernel_size_t32 sigsetsize)
1997     {
1998     	int ret, sig;
1999     	sigset_t these;
2000     	sigset_t32 these32;
2001     	struct timespec ts;
2002     	siginfo_t info;
2003     	long timeout = 0;
2004     
2005     	/* XXX: Don't preclude handling different sized sigset_t's.  */
2006     	if (sigsetsize != sizeof(sigset_t))
2007     		return -EINVAL;
2008     
2009     	if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
2010     		return -EFAULT;
2011     
2012     	switch (_NSIG_WORDS) {
2013     	case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
2014     	case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
2015     	case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
2016     	case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
2017     	}
2018     		
2019     	/*
2020     	 * Invert the set of allowed signals to get those we
2021     	 * want to block.
2022     	 */
2023     	sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
2024     	signotset(&these);
2025     
2026     	if (uts) {
2027     		if (get_user (ts.tv_sec, &uts->tv_sec) ||
2028     		    get_user (ts.tv_nsec, &uts->tv_nsec))
2029     			return -EINVAL;
2030     		if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
2031     		    || ts.tv_sec < 0)
2032     			return -EINVAL;
2033     	}
2034     
2035     	spin_lock_irq(&current->sigmask_lock);
2036     	sig = dequeue_signal(&these, &info);
2037     	if (!sig) {
2038     		/* None ready -- temporarily unblock those we're interested
2039     		   in so that we'll be awakened when they arrive.  */
2040     		sigset_t oldblocked = current->blocked;
2041     		sigandsets(&current->blocked, &current->blocked, &these);
2042     		recalc_sigpending(current);
2043     		spin_unlock_irq(&current->sigmask_lock);
2044     
2045     		timeout = MAX_SCHEDULE_TIMEOUT;
2046     		if (uts)
2047     			timeout = (timespec_to_jiffies(&ts)
2048     				   + (ts.tv_sec || ts.tv_nsec));
2049     
2050     		current->state = TASK_INTERRUPTIBLE;
2051     		timeout = schedule_timeout(timeout);
2052     
2053     		spin_lock_irq(&current->sigmask_lock);
2054     		sig = dequeue_signal(&these, &info);
2055     		current->blocked = oldblocked;
2056     		recalc_sigpending(current);
2057     	}
2058     	spin_unlock_irq(&current->sigmask_lock);
2059     
2060     	if (sig) {
2061     		ret = sig;
2062     		if (uinfo) {
2063     			if (copy_siginfo_to_user32(uinfo, &info))
2064     				ret = -EFAULT;
2065     		}
2066     	} else {
2067     		ret = -EAGAIN;
2068     		if (timeout)
2069     			ret = -EINTR;
2070     	}
2071     
2072     	return ret;
2073     }
2074     
2075     extern asmlinkage int
2076     sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2077     
2078     asmlinkage int
2079     sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2080     {
2081     	siginfo_t info;
2082     	int ret;
2083     	mm_segment_t old_fs = get_fs();
2084     	
2085     	if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
2086     	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
2087     		return -EFAULT;
2088     	set_fs (KERNEL_DS);
2089     	ret = sys_rt_sigqueueinfo(pid, sig, &info);
2090     	set_fs (old_fs);
2091     	return ret;
2092     }
2093     
2094     struct tms32 {
2095     	__kernel_clock_t32 tms_utime;
2096     	__kernel_clock_t32 tms_stime;
2097     	__kernel_clock_t32 tms_cutime;
2098     	__kernel_clock_t32 tms_cstime;
2099     };
2100                                     
2101     extern asmlinkage long sys_times(struct tms * tbuf);
2102     
2103     asmlinkage long sys32_times(struct tms32 *tbuf)
2104     {
2105     	struct tms t;
2106     	long ret;
2107     	mm_segment_t old_fs = get_fs ();
2108     	int err;
2109     	
2110     	set_fs (KERNEL_DS);
2111     	ret = sys_times(tbuf ? &t : NULL);
2112     	set_fs (old_fs);
2113     	if (tbuf) {
2114     		err = put_user (t.tms_utime, &tbuf->tms_utime);
2115     		err |= __put_user (t.tms_stime, &tbuf->tms_stime);
2116     		err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
2117     		err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
2118     		if (err)
2119     			ret = -EFAULT;
2120     	}
2121     	return ret;
2122     }
2123     
2124     #define RLIM_INFINITY32	0x7fffffff
2125     #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2126     
2127     struct rlimit32 {
2128     	u32	rlim_cur;
2129     	u32	rlim_max;
2130     };
2131     
2132     extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
2133     
2134     asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
2135     {
2136     	struct rlimit r;
2137     	int ret;
2138     	mm_segment_t old_fs = get_fs ();
2139     	
2140     	set_fs (KERNEL_DS);
2141     	ret = sys_getrlimit(resource, &r);
2142     	set_fs (old_fs);
2143     	if (!ret) {
2144     		ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
2145     		ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
2146     	}
2147     	return ret;
2148     }
2149     
2150     extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
2151     
2152     asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
2153     {
2154     	struct rlimit r;
2155     	int ret;
2156     	mm_segment_t old_fs = get_fs ();
2157     
2158     	if (resource >= RLIM_NLIMITS) return -EINVAL;	
2159     	if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
2160     	    __get_user (r.rlim_max, &rlim->rlim_max))
2161     		return -EFAULT;
2162     	if (r.rlim_cur == RLIM_INFINITY32)
2163     		r.rlim_cur = RLIM_INFINITY;
2164     	if (r.rlim_max == RLIM_INFINITY32)
2165     		r.rlim_max = RLIM_INFINITY;
2166     	set_fs (KERNEL_DS);
2167     	ret = sys_setrlimit(resource, &r);
2168     	set_fs (old_fs);
2169     	return ret;
2170     }
2171     
2172     extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
2173     
2174     asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
2175     {
2176     	struct rusage r;
2177     	int ret;
2178     	mm_segment_t old_fs = get_fs();
2179     		
2180     	set_fs (KERNEL_DS);
2181     	ret = sys_getrusage(who, &r);
2182     	set_fs (old_fs);
2183     	if (put_rusage (ru, &r)) return -EFAULT;
2184     	return ret;
2185     }
2186     
2187     /* XXX This really belongs in some header file... -DaveM */
2188     #define MAX_SOCK_ADDR	128		/* 108 for Unix domain - 
2189     					   16 for IP, 16 for IPX,
2190     					   24 for IPv6,
2191     					   about 80 for AX.25 */
2192     
2193     extern struct socket *sockfd_lookup(int fd, int *err);
2194     
2195     /* XXX This as well... */
2196     extern __inline__ void sockfd_put(struct socket *sock)
2197     {
2198     	fput(sock->file);
2199     }
2200     
2201     struct msghdr32 {
2202             u32               msg_name;
2203             int               msg_namelen;
2204             u32               msg_iov;
2205             __kernel_size_t32 msg_iovlen;
2206             u32               msg_control;
2207             __kernel_size_t32 msg_controllen;
2208             unsigned          msg_flags;
2209     };
2210     
2211     struct cmsghdr32 {
2212             __kernel_size_t32 cmsg_len;
2213             int               cmsg_level;
2214             int               cmsg_type;
2215     };
2216     
2217     /* Bleech... */
2218     #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2219     #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2220     
2221     #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2222     
2223     #define CMSG32_DATA(cmsg)	((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2224     #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2225     #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2226     
2227     #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2228     				    (struct cmsghdr32 *)(ctl) : \
2229     				    (struct cmsghdr32 *)NULL)
2230     #define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2231     
2232     __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2233     					      struct cmsghdr32 *__cmsg, int __cmsg_len)
2234     {
2235     	struct cmsghdr32 * __ptr;
2236     
2237     	__ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2238     				     CMSG32_ALIGN(__cmsg_len));
2239     	if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2240     		return NULL;
2241     
2242     	return __ptr;
2243     }
2244     
2245     __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2246     					    struct cmsghdr32 *__cmsg,
2247     					    int __cmsg_len)
2248     {
2249     	return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2250     			       __cmsg, __cmsg_len);
2251     }
2252     
2253     static inline int iov_from_user32_to_kern(struct iovec *kiov,
2254     					  struct iovec32 *uiov32,
2255     					  int niov)
2256     {
2257     	int tot_len = 0;
2258     
2259     	while(niov > 0) {
2260     		u32 len, buf;
2261     
2262     		if(get_user(len, &uiov32->iov_len) ||
2263     		   get_user(buf, &uiov32->iov_base)) {
2264     			tot_len = -EFAULT;
2265     			break;
2266     		}
2267     		tot_len += len;
2268     		kiov->iov_base = (void *)A(buf);
2269     		kiov->iov_len = (__kernel_size_t) len;
2270     		uiov32++;
2271     		kiov++;
2272     		niov--;
2273     	}
2274     	return tot_len;
2275     }
2276     
2277     static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2278     					     struct msghdr32 *umsg)
2279     {
2280     	u32 tmp1, tmp2, tmp3;
2281     	int err;
2282     
2283     	err = get_user(tmp1, &umsg->msg_name);
2284     	err |= __get_user(tmp2, &umsg->msg_iov);
2285     	err |= __get_user(tmp3, &umsg->msg_control);
2286     	if (err)
2287     		return -EFAULT;
2288     
2289     	kmsg->msg_name = (void *)A(tmp1);
2290     	kmsg->msg_iov = (struct iovec *)A(tmp2);
2291     	kmsg->msg_control = (void *)A(tmp3);
2292     
2293     	err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2294     	err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2295     	err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2296     	err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2297     	
2298     	return err;
2299     }
2300     
2301     /* I've named the args so it is easy to tell whose space the pointers are in. */
2302     static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2303     			  char *kern_address, int mode)
2304     {
2305     	int tot_len;
2306     
2307     	if(kern_msg->msg_namelen) {
2308     		if(mode==VERIFY_READ) {
2309     			int err = move_addr_to_kernel(kern_msg->msg_name,
2310     						      kern_msg->msg_namelen,
2311     						      kern_address);
2312     			if(err < 0)
2313     				return err;
2314     		}
2315     		kern_msg->msg_name = kern_address;
2316     	} else
2317     		kern_msg->msg_name = NULL;
2318     
2319     	if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2320     		kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2321     				   GFP_KERNEL);
2322     		if(!kern_iov)
2323     			return -ENOMEM;
2324     	}
2325     
2326     	tot_len = iov_from_user32_to_kern(kern_iov,
2327     					  (struct iovec32 *)kern_msg->msg_iov,
2328     					  kern_msg->msg_iovlen);
2329     	if(tot_len >= 0)
2330     		kern_msg->msg_iov = kern_iov;
2331     	else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2332     		kfree(kern_iov);
2333     
2334     	return tot_len;
2335     }
2336     
2337     /* There is a lot of hair here because the alignment rules (and
2338      * thus placement) of cmsg headers and length are different for
2339      * 32-bit apps.  -DaveM
2340      */
2341     static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2342     				       unsigned char *stackbuf, int stackbuf_size)
2343     {
2344     	struct cmsghdr32 *ucmsg;
2345     	struct cmsghdr *kcmsg, *kcmsg_base;
2346     	__kernel_size_t32 ucmlen;
2347     	__kernel_size_t kcmlen, tmp;
2348     
2349     	kcmlen = 0;
2350     	kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2351     	ucmsg = CMSG32_FIRSTHDR(kmsg);
2352     	while(ucmsg != NULL) {
2353     		if(get_user(ucmlen, &ucmsg->cmsg_len))
2354     			return -EFAULT;
2355     
2356     		/* Catch bogons. */
2357     		if(CMSG32_ALIGN(ucmlen) <
2358     		   CMSG32_ALIGN(sizeof(struct cmsghdr32)))
2359     			return -EINVAL;
2360     		if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
2361     				   + ucmlen) > kmsg->msg_controllen)
2362     			return -EINVAL;
2363     
2364     		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2365     		       CMSG_ALIGN(sizeof(struct cmsghdr)));
2366     		kcmlen += tmp;
2367     		ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2368     	}
2369     	if(kcmlen == 0)
2370     		return -EINVAL;
2371     
2372     	/* The kcmlen holds the 64-bit version of the control length.
2373     	 * It may not be modified as we do not stick it into the kmsg
2374     	 * until we have successfully copied over all of the data
2375     	 * from the user.
2376     	 */
2377     	if(kcmlen > stackbuf_size)
2378     		kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2379     	if(kcmsg == NULL)
2380     		return -ENOBUFS;
2381     
2382     	/* Now copy them over neatly. */
2383     	memset(kcmsg, 0, kcmlen);
2384     	ucmsg = CMSG32_FIRSTHDR(kmsg);
2385     	while(ucmsg != NULL) {
2386     		__get_user(ucmlen, &ucmsg->cmsg_len);
2387     		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2388     		       CMSG_ALIGN(sizeof(struct cmsghdr)));
2389     		kcmsg->cmsg_len = tmp;
2390     		__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
2391     		__get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
2392     
2393     		/* Copy over the data. */
2394     		if(copy_from_user(CMSG_DATA(kcmsg),
2395     				  CMSG32_DATA(ucmsg),
2396     				  (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2397     			goto out_free_efault;
2398     
2399     		/* Advance. */
2400     		kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
2401     		ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2402     	}
2403     
2404     	/* Ok, looks like we made it.  Hook it up and return success. */
2405     	kmsg->msg_control = kcmsg_base;
2406     	kmsg->msg_controllen = kcmlen;
2407     	return 0;
2408     
2409     out_free_efault:
2410     	if(kcmsg_base != (struct cmsghdr *)stackbuf)
2411     		kfree(kcmsg_base);
2412     	return -EFAULT;
2413     }
2414     
2415     static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2416     		       int len, void *data)
2417     {
2418     	struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2419     	struct cmsghdr32 cmhdr;
2420     	int cmlen = CMSG32_LEN(len);
2421     
2422     	if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2423     		kmsg->msg_flags |= MSG_CTRUNC;
2424     		return;
2425     	}
2426     
2427     	if(kmsg->msg_controllen < cmlen) {
2428     		kmsg->msg_flags |= MSG_CTRUNC;
2429     		cmlen = kmsg->msg_controllen;
2430     	}
2431     	cmhdr.cmsg_level = level;
2432     	cmhdr.cmsg_type = type;
2433     	cmhdr.cmsg_len = cmlen;
2434     
2435     	if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2436     		return;
2437     	if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2438     		return;
2439     	cmlen = CMSG32_SPACE(len);
2440     	kmsg->msg_control += cmlen;
2441     	kmsg->msg_controllen -= cmlen;
2442     }
2443     
2444     static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2445     {
2446     	struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2447     	int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2448     	int fdnum = scm->fp->count;
2449     	struct file **fp = scm->fp->fp;
2450     	int *cmfptr;
2451     	int err = 0, i;
2452     
2453     	if (fdnum < fdmax)
2454     		fdmax = fdnum;
2455     
2456     	for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2457     		int new_fd;
2458     		err = get_unused_fd();
2459     		if (err < 0)
2460     			break;
2461     		new_fd = err;
2462     		err = put_user(new_fd, cmfptr);
2463     		if (err) {
2464     			put_unused_fd(new_fd);
2465     			break;
2466     		}
2467     		/* Bump the usage count and install the file. */
2468     		get_file(fp[i]);
2469     		fd_install(new_fd, fp[i]);
2470     	}
2471     
2472     	if (i > 0) {
2473     		int cmlen = CMSG32_LEN(i * sizeof(int));
2474     		if (!err)
2475     			err = put_user(SOL_SOCKET, &cm->cmsg_level);
2476     		if (!err)
2477     			err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2478     		if (!err)
2479     			err = put_user(cmlen, &cm->cmsg_len);
2480     		if (!err) {
2481     			cmlen = CMSG32_SPACE(i * sizeof(int));
2482     			kmsg->msg_control += cmlen;
2483     			kmsg->msg_controllen -= cmlen;
2484     		}
2485     	}
2486     	if (i < fdnum)
2487     		kmsg->msg_flags |= MSG_CTRUNC;
2488     
2489     	/*
2490     	 * All of the files that fit in the message have had their
2491     	 * usage counts incremented, so we just free the list.
2492     	 */
2493     	__scm_destroy(scm);
2494     }
2495     
2496     /* In these cases we (currently) can just copy to data over verbatim
2497      * because all CMSGs created by the kernel have well defined types which
2498      * have the same layout in both the 32-bit and 64-bit API.  One must add
2499      * some special cased conversions here if we start sending control messages
2500      * with incompatible types.
2501      *
2502      * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2503      * we do our work.  The remaining cases are:
2504      *
2505      * SOL_IP	IP_PKTINFO	struct in_pktinfo	32-bit clean
2506      *		IP_TTL		int			32-bit clean
2507      *		IP_TOS		__u8			32-bit clean
2508      *		IP_RECVOPTS	variable length		32-bit clean
2509      *		IP_RETOPTS	variable length		32-bit clean
2510      *		(these last two are clean because the types are defined
2511      *		 by the IPv4 protocol)
2512      *		IP_RECVERR	struct sock_extended_err +
2513      *				struct sockaddr_in	32-bit clean
2514      * SOL_IPV6	IPV6_RECVERR	struct sock_extended_err +
2515      *				struct sockaddr_in6	32-bit clean
2516      *		IPV6_PKTINFO	struct in6_pktinfo	32-bit clean
2517      *		IPV6_HOPLIMIT	int			32-bit clean
2518      *		IPV6_FLOWINFO	u32			32-bit clean
2519      *		IPV6_HOPOPTS	ipv6 hop exthdr		32-bit clean
2520      *		IPV6_DSTOPTS	ipv6 dst exthdr(s)	32-bit clean
2521      *		IPV6_RTHDR	ipv6 routing exthdr	32-bit clean
2522      *		IPV6_AUTHHDR	ipv6 auth exthdr	32-bit clean
2523      */
2524     static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
2525     {
2526     	unsigned char *workbuf, *wp;
2527     	unsigned long bufsz, space_avail;
2528     	struct cmsghdr *ucmsg;
2529     
2530     	bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2531     	space_avail = kmsg->msg_controllen + bufsz;
2532     	wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2533     	if(workbuf == NULL)
2534     		goto fail;
2535     
2536     	/* To make this more sane we assume the kernel sends back properly
2537     	 * formatted control messages.  Because of how the kernel will truncate
2538     	 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2539     	 */
2540     	ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2541     	while(((unsigned long)ucmsg) <=
2542     	      (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
2543     		struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2544     		int clen64, clen32;
2545     
2546     		/* UCMSG is the 64-bit format CMSG entry in user-space.
2547     		 * KCMSG32 is within the kernel space temporary buffer
2548     		 * we use to convert into a 32-bit style CMSG.
2549     		 */
2550     		__get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2551     		__get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2552     		__get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2553     
2554     		clen64 = kcmsg32->cmsg_len;
2555     		copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2556     			       clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2557     		clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2558     			  CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2559     		kcmsg32->cmsg_len = clen32;
2560     
2561     		ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2562     		wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2563     	}
2564     
2565     	/* Copy back fixed up data, and adjust pointers. */
2566     	bufsz = (wp - workbuf);
2567     	copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2568     
2569     	kmsg->msg_control = (struct cmsghdr *)
2570     		(((char *)orig_cmsg_uptr) + bufsz);
2571     	kmsg->msg_controllen = space_avail - bufsz;
2572     
2573     	kfree(workbuf);
2574     	return;
2575     
2576     fail:
2577     	/* If we leave the 64-bit format CMSG chunks in there,
2578     	 * the application could get confused and crash.  So to
2579     	 * ensure greater recovery, we report no CMSGs.
2580     	 */
2581     	kmsg->msg_controllen += bufsz;
2582     	kmsg->msg_control = (void *) orig_cmsg_uptr;
2583     }
2584     
2585     asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2586     {
2587     	struct socket *sock;
2588     	char address[MAX_SOCK_ADDR];
2589     	struct iovec iov[UIO_FASTIOV];
2590     	unsigned char ctl[sizeof(struct cmsghdr) + 20];
2591     	unsigned char *ctl_buf = ctl;
2592     	struct msghdr kern_msg;
2593     	int err, total_len;
2594     
2595     	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2596     		return -EFAULT;
2597     	if(kern_msg.msg_iovlen > UIO_MAXIOV)
2598     		return -EINVAL;
2599     	err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2600     	if (err < 0)
2601     		goto out;
2602     	total_len = err;
2603     
2604     	if(kern_msg.msg_controllen) {
2605     		err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2606     		if(err)
2607     			goto out_freeiov;
2608     		ctl_buf = kern_msg.msg_control;
2609     	}
2610     	kern_msg.msg_flags = user_flags;
2611     
2612     	sock = sockfd_lookup(fd, &err);
2613     	if (sock != NULL) {
2614     		if (sock->file->f_flags & O_NONBLOCK)
2615     			kern_msg.msg_flags |= MSG_DONTWAIT;
2616     		err = sock_sendmsg(sock, &kern_msg, total_len);
2617     		sockfd_put(sock);
2618     	}
2619     
2620     	/* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2621     	if(ctl_buf != ctl)
2622     		kfree(ctl_buf);
2623     out_freeiov:
2624     	if(kern_msg.msg_iov != iov)
2625     		kfree(kern_msg.msg_iov);
2626     out:
2627     	return err;
2628     }
2629     
2630     asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2631     {
2632     	struct iovec iovstack[UIO_FASTIOV];
2633     	struct msghdr kern_msg;
2634     	char addr[MAX_SOCK_ADDR];
2635     	struct socket *sock;
2636     	struct iovec *iov = iovstack;
2637     	struct sockaddr *uaddr;
2638     	int *uaddr_len;
2639     	unsigned long cmsg_ptr;
2640     	int err, total_len, len = 0;
2641     
2642     	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2643     		return -EFAULT;
2644     	if(kern_msg.msg_iovlen > UIO_MAXIOV)
2645     		return -EINVAL;
2646     
2647     	uaddr = kern_msg.msg_name;
2648     	uaddr_len = &user_msg->msg_namelen;
2649     	err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2650     	if (err < 0)
2651     		goto out;
2652     	total_len = err;
2653     
2654     	cmsg_ptr = (unsigned long) kern_msg.msg_control;
2655     	kern_msg.msg_flags = 0;
2656     
2657     	sock = sockfd_lookup(fd, &err);
2658     	if (sock != NULL) {
2659     		struct scm_cookie scm;
2660     
2661     		if (sock->file->f_flags & O_NONBLOCK)
2662     			user_flags |= MSG_DONTWAIT;
2663     		memset(&scm, 0, sizeof(scm));
2664     		err = sock->ops->recvmsg(sock, &kern_msg, total_len,
2665     					 user_flags, &scm);
2666     		if(err >= 0) {
2667     			len = err;
2668     			if(!kern_msg.msg_control) {
2669     				if(sock->passcred || scm.fp)
2670     					kern_msg.msg_flags |= MSG_CTRUNC;
2671     				if(scm.fp)
2672     					__scm_destroy(&scm);
2673     			} else {
2674     				/* If recvmsg processing itself placed some
2675     				 * control messages into user space, it's is
2676     				 * using 64-bit CMSG processing, so we need
2677     				 * to fix it up before we tack on more stuff.
2678     				 */
2679     				if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2680     					cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
2681     
2682     				/* Wheee... */
2683     				if(sock->passcred)
2684     					put_cmsg32(&kern_msg,
2685     						   SOL_SOCKET, SCM_CREDENTIALS,
2686     						   sizeof(scm.creds), &scm.creds);
2687     				if(scm.fp != NULL)
2688     					scm_detach_fds32(&kern_msg, &scm);
2689     			}
2690     		}
2691     		sockfd_put(sock);
2692     	}
2693     
2694     	if(uaddr != NULL && err >= 0)
2695     		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
2696     	if(cmsg_ptr != 0 && err >= 0) {
2697     		unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
2698     		__kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
2699     		err |= __put_user(uclen, &user_msg->msg_controllen);
2700     	}
2701     	if(err >= 0)
2702     		err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
2703     	if(kern_msg.msg_iov != iov)
2704     		kfree(kern_msg.msg_iov);
2705     out:
2706     	if(err < 0)
2707     		return err;
2708     	return len;
2709     }
2710     
2711     extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
2712     				     char *optval, int optlen);
2713     
2714     static int do_set_attach_filter(int fd, int level, int optname,
2715     				char *optval, int optlen)
2716     {
2717     	struct sock_fprog32 {
2718     		__u16 len;
2719     		__u32 filter;
2720     	} *fprog32 = (struct sock_fprog32 *)optval;
2721     	struct sock_fprog kfprog;
2722     	struct sock_filter *kfilter;
2723     	unsigned int fsize;
2724     	mm_segment_t old_fs;
2725     	__u32 uptr;
2726     	int ret;
2727     
2728     	if (get_user(kfprog.len, &fprog32->len) ||
2729     	    __get_user(uptr, &fprog32->filter))
2730     		return -EFAULT;
2731     
2732     	kfprog.filter = (struct sock_filter *)A(uptr);
2733     	fsize = kfprog.len * sizeof(struct sock_filter);
2734     
2735     	kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
2736     	if (kfilter == NULL)
2737     		return -ENOMEM;
2738     
2739     	if (copy_from_user(kfilter, kfprog.filter, fsize)) {
2740     		kfree(kfilter);
2741     		return -EFAULT;
2742     	}
2743     
2744     	kfprog.filter = kfilter;
2745     
2746     	old_fs = get_fs();
2747     	set_fs(KERNEL_DS);
2748     	ret = sys_setsockopt(fd, level, optname,
2749     			     (char *)&kfprog, sizeof(kfprog));
2750     	set_fs(old_fs);
2751     
2752     	kfree(kfilter);
2753     
2754     	return ret;
2755     }
2756     
2757     static int do_set_icmpv6_filter(int fd, int level, int optname,
2758     				char *optval, int optlen)
2759     {
2760     	struct icmp6_filter kfilter;
2761     	mm_segment_t old_fs;
2762     	int ret, i;
2763     
2764     	if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
2765     		return -EFAULT;
2766     
2767     
2768     	for (i = 0; i < 8; i += 2) {
2769     		u32 tmp = kfilter.data[i];
2770     
2771     		kfilter.data[i] = kfilter.data[i + 1];
2772     		kfilter.data[i + 1] = tmp;
2773     	}
2774     
2775     	old_fs = get_fs();
2776     	set_fs(KERNEL_DS);
2777     	ret = sys_setsockopt(fd, level, optname,
2778     			     (char *) &kfilter, sizeof(kfilter));
2779     	set_fs(old_fs);
2780     
2781     	return ret;
2782     }
2783     
2784     asmlinkage int sys32_setsockopt(int fd, int level, int optname,
2785     				char *optval, int optlen)
2786     {
2787     	if (optname == SO_ATTACH_FILTER)
2788     		return do_set_attach_filter(fd, level, optname,
2789     					    optval, optlen);
2790     	if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
2791     		return do_set_icmpv6_filter(fd, level, optname,
2792     					    optval, optlen);
2793     
2794     	return sys_setsockopt(fd, level, optname, optval, optlen);
2795     }
2796     
2797     extern void check_pending(int signum);
2798     
2799     asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
2800     {
2801             struct k_sigaction new_ka, old_ka;
2802             int ret;
2803     
2804     	if(sig < 0) {
2805     		current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2806     		sig = -sig;
2807     	}
2808     
2809             if (act) {
2810     		old_sigset_t32 mask;
2811     		
2812     		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2813     		ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2814     		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2815     		ret |= __get_user(mask, &act->sa_mask);
2816     		if (ret)
2817     			return ret;
2818     		new_ka.ka_restorer = NULL;
2819     		siginitset(&new_ka.sa.sa_mask, mask);
2820             }
2821     
2822             ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2823     
2824     	if (!ret && oact) {
2825     		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2826     		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2827     		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2828     		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
2829             }
2830     
2831     	return ret;
2832     }
2833     
2834     asmlinkage int
2835     sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact,
2836     		   void *restorer, __kernel_size_t32 sigsetsize)
2837     {
2838             struct k_sigaction new_ka, old_ka;
2839             int ret;
2840     	sigset_t32 set32;
2841     
2842             /* XXX: Don't preclude handling different sized sigset_t's.  */
2843             if (sigsetsize != sizeof(sigset_t32))
2844                     return -EINVAL;
2845     
2846     	/* All tasks which use RT signals (effectively) use
2847     	 * new style signals.
2848     	 */
2849     	current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2850     
2851             if (act) {
2852     		new_ka.ka_restorer = restorer;
2853     		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2854     		ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32));
2855     		switch (_NSIG_WORDS) {
2856     		case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
2857     		case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
2858     		case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
2859     		case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
2860     		}
2861     		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2862     		ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2863                     if (ret)
2864                     	return -EFAULT;
2865     	}
2866     
2867     	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2868     
2869     	if (!ret && oact) {
2870     		switch (_NSIG_WORDS) {
2871     		case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
2872     		case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
2873     		case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
2874     		case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
2875     		}
2876     		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2877     		ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
2878     		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2879     		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2880             }
2881     
2882             return ret;
2883     }
2884     
2885     
2886     /*
2887      * count32() counts the number of arguments/envelopes
2888      */
2889     static int count32(u32 * argv, int max)
2890     {
2891     	int i = 0;
2892     
2893     	if (argv != NULL) {
2894     		for (;;) {
2895     			u32 p; int error;
2896     
2897     			error = get_user(p,argv);
2898     			if (error)
2899     				return error;
2900     			if (!p)
2901     				break;
2902     			argv++;
2903     			if (++i > max)
2904     				return -E2BIG;
2905     		}
2906     	}
2907     	return i;
2908     }
2909     
2910     /*
2911      * 'copy_string32()' copies argument/envelope strings from user
2912      * memory to free pages in kernel mem. These are in a format ready
2913      * to be put directly into the top of new user memory.
2914      */
2915     static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
2916     {
2917     	while (argc-- > 0) {
2918     		u32 str;
2919     		int len;
2920     		unsigned long pos;
2921     
2922     		if (get_user(str, argv + argc) ||
2923     		    !str ||
2924     		    !(len = strnlen_user((char *)A(str), bprm->p)))
2925     			return -EFAULT;
2926     
2927     		if (bprm->p < len)
2928     			return -E2BIG;
2929     
2930     		bprm->p -= len;
2931     
2932     		pos = bprm->p;
2933     		while (len) {
2934     			char *kaddr;
2935     			struct page *page;
2936     			int offset, bytes_to_copy, new, err;
2937     
2938     			offset = pos % PAGE_SIZE;
2939     			page = bprm->page[pos / PAGE_SIZE];
2940     			new = 0;
2941     			if (!page) {
2942     				page = alloc_page(GFP_USER);
2943     				bprm->page[pos / PAGE_SIZE] = page;
2944     				if (!page)
2945     					return -ENOMEM;
2946     				new = 1;
2947     			}
2948     			kaddr = kmap(page);
2949     
2950     			if (new && offset)
2951     				memset(kaddr, 0, offset);
2952     			bytes_to_copy = PAGE_SIZE - offset;
2953     			if (bytes_to_copy > len) {
2954     				bytes_to_copy = len;
2955     				if (new)
2956     					memset(kaddr+offset+len, 0,
2957     					       PAGE_SIZE-offset-len);
2958     			}
2959     
2960     			err = copy_from_user(kaddr + offset, (char *)A(str),
2961     					     bytes_to_copy);
2962     			kunmap(page);
2963     
2964     			if (err)
2965     				return -EFAULT;
2966     
2967     			pos += bytes_to_copy;
2968     			str += bytes_to_copy;
2969     			len -= bytes_to_copy;
2970     		}
2971     	}
2972     	return 0;
2973     }
2974     
2975     /*
2976      * sys32_execve() executes a new program.
2977      */
2978     static inline int 
2979     do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
2980     {
2981     	struct linux_binprm bprm;
2982     	struct file * file;
2983     	int retval;
2984     	int i;
2985     
2986     	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
2987     	memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
2988     
2989     	file = open_exec(filename);
2990     
2991     	retval = PTR_ERR(file);
2992     	if (IS_ERR(file))
2993     		return retval;
2994     
2995     	bprm.file = file;
2996     	bprm.filename = filename;
2997     	bprm.sh_bang = 0;
2998     	bprm.loader = 0;
2999     	bprm.exec = 0;
3000     	if ((bprm.argc = count32(argv, bprm.p / sizeof(u32))) < 0) {
3001     		allow_write_access(file);
3002     		fput(file);
3003     		return bprm.argc;
3004     	}
3005     	if ((bprm.envc = count32(envp, bprm.p / sizeof(u32))) < 0) {
3006     		allow_write_access(file);
3007     		fput(file);
3008     		return bprm.envc;
3009     	}
3010     
3011     	retval = prepare_binprm(&bprm);
3012     	if (retval < 0)
3013     		goto out;
3014     	
3015     	retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3016     	if (retval < 0)
3017     		goto out;
3018     
3019     	bprm.exec = bprm.p;
3020     	retval = copy_strings32(bprm.envc, envp, &bprm);
3021     	if (retval < 0)
3022     		goto out;
3023     
3024     	retval = copy_strings32(bprm.argc, argv, &bprm);
3025     	if (retval < 0)
3026     		goto out;
3027     
3028     	retval = search_binary_handler(&bprm, regs);
3029     	if (retval >= 0)
3030     		/* execve success */
3031     		return retval;
3032     
3033     out:
3034     	/* Something went wrong, return the inode and free the argument pages*/
3035     	allow_write_access(bprm.file);
3036     	if (bprm.file)
3037     		fput(bprm.file);
3038     
3039     	for (i=0 ; i<MAX_ARG_PAGES ; i++)
3040     		if (bprm.page[i])
3041     			__free_page(bprm.page[i]);
3042     
3043     	return retval;
3044     }
3045     
3046     /*
3047      * sparc32_execve() executes a new program after the asm stub has set
3048      * things up for us.  This should basically do what I want it to.
3049      */
3050     asmlinkage int sparc32_execve(struct pt_regs *regs)
3051     {
3052             int error, base = 0;
3053             char *filename;
3054     
3055     	/* User register window flush is done by entry.S */
3056     
3057             /* Check for indirect call. */
3058             if((u32)regs->u_regs[UREG_G1] == 0)
3059                     base = 1;
3060     
3061             filename = getname((char *)AA(regs->u_regs[base + UREG_I0]));
3062     	error = PTR_ERR(filename);
3063             if(IS_ERR(filename))
3064                     goto out;
3065             error = do_execve32(filename,
3066             	(u32 *)AA((u32)regs->u_regs[base + UREG_I1]),
3067             	(u32 *)AA((u32)regs->u_regs[base + UREG_I2]), regs);
3068             putname(filename);
3069     
3070     	if(!error) {
3071     		fprs_write(0);
3072     		current->thread.xfsr[0] = 0;
3073     		current->thread.fpsaved[0] = 0;
3074     		regs->tstate &= ~TSTATE_PEF;
3075     	}
3076     out:
3077             return error;
3078     }
3079     
3080     #ifdef CONFIG_MODULES
3081     
3082     extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
3083     
3084     asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
3085     {
3086     	return sys_create_module(name_user, (size_t)size);
3087     }
3088     
3089     extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
3090     
3091     /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3092      * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3093      */
3094     asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
3095     {
3096     	return sys_init_module(name_user, mod_user);
3097     }
3098     
3099     extern asmlinkage int sys_delete_module(const char *name_user);
3100     
3101     asmlinkage int sys32_delete_module(const char *name_user)
3102     {
3103     	return sys_delete_module(name_user);
3104     }
3105     
3106     struct module_info32 {
3107     	u32 addr;
3108     	u32 size;
3109     	u32 flags;
3110     	s32 usecount;
3111     };
3112     
3113     /* Query various bits about modules.  */
3114     
3115     static inline long
3116     get_mod_name(const char *user_name, char **buf)
3117     {
3118     	unsigned long page;
3119     	long retval;
3120     
3121     	if ((unsigned long)user_name >= TASK_SIZE
3122     	    && !segment_eq(get_fs (), KERNEL_DS))
3123     		return -EFAULT;
3124     
3125     	page = __get_free_page(GFP_KERNEL);
3126     	if (!page)
3127     		return -ENOMEM;
3128     
3129     	retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
3130     	if (retval > 0) {
3131     		if (retval < PAGE_SIZE) {
3132     			*buf = (char *)page;
3133     			return retval;
3134     		}
3135     		retval = -ENAMETOOLONG;
3136     	} else if (!retval)
3137     		retval = -EINVAL;
3138     
3139     	free_page(page);
3140     	return retval;
3141     }
3142     
3143     static inline void
3144     put_mod_name(char *buf)
3145     {
3146     	free_page((unsigned long)buf);
3147     }
3148     
3149     static __inline__ struct module *find_module(const char *name)
3150     {
3151     	struct module *mod;
3152     
3153     	for (mod = module_list; mod ; mod = mod->next) {
3154     		if (mod->flags & MOD_DELETED)
3155     			continue;
3156     		if (!strcmp(mod->name, name))
3157     			break;
3158     	}
3159     
3160     	return mod;
3161     }
3162     
3163     static int
3164     qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
3165     {
3166     	struct module *mod;
3167     	size_t nmod, space, len;
3168     
3169     	nmod = space = 0;
3170     
3171     	for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
3172     		len = strlen(mod->name)+1;
3173     		if (len > bufsize)
3174     			goto calc_space_needed;
3175     		if (copy_to_user(buf, mod->name, len))
3176     			return -EFAULT;
3177     		buf += len;
3178     		bufsize -= len;
3179     		space += len;
3180     	}
3181     
3182     	if (put_user(nmod, ret))
3183     		return -EFAULT;
3184     	else
3185     		return 0;
3186     
3187     calc_space_needed:
3188     	space += len;
3189     	while ((mod = mod->next)->next != NULL)
3190     		space += strlen(mod->name)+1;
3191     
3192     	if (put_user(space, ret))
3193     		return -EFAULT;
3194     	else
3195     		return -ENOSPC;
3196     }
3197     
3198     static int
3199     qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3200     {
3201     	size_t i, space, len;
3202     
3203     	if (mod->next == NULL)
3204     		return -EINVAL;
3205     	if (!MOD_CAN_QUERY(mod))
3206     		return put_user(0, ret);
3207     
3208     	space = 0;
3209     	for (i = 0; i < mod->ndeps; ++i) {
3210     		const char *dep_name = mod->deps[i].dep->name;
3211     
3212     		len = strlen(dep_name)+1;
3213     		if (len > bufsize)
3214     			goto calc_space_needed;
3215     		if (copy_to_user(buf, dep_name, len))
3216     			return -EFAULT;
3217     		buf += len;
3218     		bufsize -= len;
3219     		space += len;
3220     	}
3221     
3222     	return put_user(i, ret);
3223     
3224     calc_space_needed:
3225     	space += len;
3226     	while (++i < mod->ndeps)
3227     		space += strlen(mod->deps[i].dep->name)+1;
3228     
3229     	if (put_user(space, ret))
3230     		return -EFAULT;
3231     	else
3232     		return -ENOSPC;
3233     }
3234     
3235     static int
3236     qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3237     {
3238     	size_t nrefs, space, len;
3239     	struct module_ref *ref;
3240     
3241     	if (mod->next == NULL)
3242     		return -EINVAL;
3243     	if (!MOD_CAN_QUERY(mod))
3244     		if (put_user(0, ret))
3245     			return -EFAULT;
3246     		else
3247     			return 0;
3248     
3249     	space = 0;
3250     	for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
3251     		const char *ref_name = ref->ref->name;
3252     
3253     		len = strlen(ref_name)+1;
3254     		if (len > bufsize)
3255     			goto calc_space_needed;
3256     		if (copy_to_user(buf, ref_name, len))
3257     			return -EFAULT;
3258     		buf += len;
3259     		bufsize -= len;
3260     		space += len;
3261     	}
3262     
3263     	if (put_user(nrefs, ret))
3264     		return -EFAULT;
3265     	else
3266     		return 0;
3267     
3268     calc_space_needed:
3269     	space += len;
3270     	while ((ref = ref->next_ref) != NULL)
3271     		space += strlen(ref->ref->name)+1;
3272     
3273     	if (put_user(space, ret))
3274     		return -EFAULT;
3275     	else
3276     		return -ENOSPC;
3277     }
3278     
3279     static inline int
3280     qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3281     {
3282     	size_t i, space, len;
3283     	struct module_symbol *s;
3284     	char *strings;
3285     	unsigned *vals;
3286     
3287     	if (!MOD_CAN_QUERY(mod))
3288     		if (put_user(0, ret))
3289     			return -EFAULT;
3290     		else
3291     			return 0;
3292     
3293     	space = mod->nsyms * 2*sizeof(u32);
3294     
3295     	i = len = 0;
3296     	s = mod->syms;
3297     
3298     	if (space > bufsize)
3299     		goto calc_space_needed;
3300     
3301     	if (!access_ok(VERIFY_WRITE, buf, space))
3302     		return -EFAULT;
3303     
3304     	bufsize -= space;
3305     	vals = (unsigned *)buf;
3306     	strings = buf+space;
3307     
3308     	for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
3309     		len = strlen(s->name)+1;
3310     		if (len > bufsize)
3311     			goto calc_space_needed;
3312     
3313     		if (copy_to_user(strings, s->name, len)
3314     		    || __put_user(s->value, vals+0)
3315     		    || __put_user(space, vals+1))
3316     			return -EFAULT;
3317     
3318     		strings += len;
3319     		bufsize -= len;
3320     		space += len;
3321     	}
3322     
3323     	if (put_user(i, ret))
3324     		return -EFAULT;
3325     	else
3326     		return 0;
3327     
3328     calc_space_needed:
3329     	for (; i < mod->nsyms; ++i, ++s)
3330     		space += strlen(s->name)+1;
3331     
3332     	if (put_user(space, ret))
3333     		return -EFAULT;
3334     	else
3335     		return -ENOSPC;
3336     }
3337     
3338     static inline int
3339     qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3340     {
3341     	int error = 0;
3342     
3343     	if (mod->next == NULL)
3344     		return -EINVAL;
3345     
3346     	if (sizeof(struct module_info32) <= bufsize) {
3347     		struct module_info32 info;
3348     		info.addr = (unsigned long)mod;
3349     		info.size = mod->size;
3350     		info.flags = mod->flags;
3351     		info.usecount =
3352     			((mod_member_present(mod, can_unload)
3353     			  && mod->can_unload)
3354     			 ? -1 : atomic_read(&mod->uc.usecount));
3355     
3356     		if (copy_to_user(buf, &info, sizeof(struct module_info32)))
3357     			return -EFAULT;
3358     	} else
3359     		error = -ENOSPC;
3360     
3361     	if (put_user(sizeof(struct module_info32), ret))
3362     		return -EFAULT;
3363     
3364     	return error;
3365     }
3366     
3367     asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
3368     {
3369     	struct module *mod;
3370     	int err;
3371     
3372     	lock_kernel();
3373     	if (name_user == 0) {
3374     		/* This finds "kernel_module" which is not exported. */
3375     		for(mod = module_list; mod->next != NULL; mod = mod->next)
3376     			;
3377     	} else {
3378     		long namelen;
3379     		char *name;
3380     
3381     		if ((namelen = get_mod_name(name_user, &name)) < 0) {
3382     			err = namelen;
3383     			goto out;
3384     		}
3385     		err = -ENOENT;
3386     		if (namelen == 0) {
3387     			/* This finds "kernel_module" which is not exported. */
3388     			for(mod = module_list; mod->next != NULL; mod = mod->next)
3389     				;
3390     		} else if ((mod = find_module(name)) == NULL) {
3391     			put_mod_name(name);
3392     			goto out;
3393     		}
3394     		put_mod_name(name);
3395     	}
3396     
3397     	switch (which)
3398     	{
3399     	case 0:
3400     		err = 0;
3401     		break;
3402     	case QM_MODULES:
3403     		err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
3404     		break;
3405     	case QM_DEPS:
3406     		err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3407     		break;
3408     	case QM_REFS:
3409     		err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3410     		break;
3411     	case QM_SYMBOLS:
3412     		err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3413     		break;
3414     	case QM_INFO:
3415     		err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3416     		break;
3417     	default:
3418     		err = -EINVAL;
3419     		break;
3420     	}
3421     out:
3422     	unlock_kernel();
3423     	return err;
3424     }
3425     
3426     struct kernel_sym32 {
3427     	u32 value;
3428     	char name[60];
3429     };
3430     		 
3431     extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3432     
3433     asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3434     {
3435     	int len, i;
3436     	struct kernel_sym *tbl;
3437     	mm_segment_t old_fs;
3438     	
3439     	len = sys_get_kernel_syms(NULL);
3440     	if (!table) return len;
3441     	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3442     	if (!tbl) return -ENOMEM;
3443     	old_fs = get_fs();
3444     	set_fs (KERNEL_DS);
3445     	sys_get_kernel_syms(tbl);
3446     	set_fs (old_fs);
3447     	for (i = 0; i < len; i++, table++) {
3448     		if (put_user (tbl[i].value, &table->value) ||
3449     		    copy_to_user (table->name, tbl[i].name, 60))
3450     			break;
3451     	}
3452     	kfree (tbl);
3453     	return i;
3454     }
3455     
3456     #else /* CONFIG_MODULES */
3457     
3458     asmlinkage unsigned long
3459     sys32_create_module(const char *name_user, size_t size)
3460     {
3461     	return -ENOSYS;
3462     }
3463     
3464     asmlinkage int
3465     sys32_init_module(const char *name_user, struct module *mod_user)
3466     {
3467     	return -ENOSYS;
3468     }
3469     
3470     asmlinkage int
3471     sys32_delete_module(const char *name_user)
3472     {
3473     	return -ENOSYS;
3474     }
3475     
3476     asmlinkage int
3477     sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3478     		 size_t *ret)
3479     {
3480     	/* Let the program know about the new interface.  Not that
3481     	   it'll do them much good.  */
3482     	if (which == 0)
3483     		return 0;
3484     
3485     	return -ENOSYS;
3486     }
3487     
3488     asmlinkage int
3489     sys32_get_kernel_syms(struct kernel_sym *table)
3490     {
3491     	return -ENOSYS;
3492     }
3493     
3494     #endif  /* CONFIG_MODULES */
3495     
3496     #if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
3497     /* Stuff for NFS server syscalls... */
3498     struct nfsctl_svc32 {
3499     	u16			svc32_port;
3500     	s32			svc32_nthreads;
3501     };
3502     
3503     struct nfsctl_client32 {
3504     	s8			cl32_ident[NFSCLNT_IDMAX+1];
3505     	s32			cl32_naddr;
3506     	struct in_addr		cl32_addrlist[NFSCLNT_ADDRMAX];
3507     	s32			cl32_fhkeytype;
3508     	s32			cl32_fhkeylen;
3509     	u8			cl32_fhkey[NFSCLNT_KEYMAX];
3510     };
3511     
3512     struct nfsctl_export32 {
3513     	s8			ex32_client[NFSCLNT_IDMAX+1];
3514     	s8			ex32_path[NFS_MAXPATHLEN+1];
3515     	__kernel_dev_t32	ex32_dev;
3516     	__kernel_ino_t32	ex32_ino;
3517     	s32			ex32_flags;
3518     	__kernel_uid_t32	ex32_anon_uid;
3519     	__kernel_gid_t32	ex32_anon_gid;
3520     };
3521     
3522     struct nfsctl_uidmap32 {
3523     	u32			ug32_ident;   /* char * */
3524     	__kernel_uid_t32	ug32_uidbase;
3525     	s32			ug32_uidlen;
3526     	u32			ug32_udimap;  /* uid_t * */
3527     	__kernel_uid_t32	ug32_gidbase;
3528     	s32			ug32_gidlen;
3529     	u32			ug32_gdimap;  /* gid_t * */
3530     };
3531     
3532     struct nfsctl_fhparm32 {
3533     	struct sockaddr		gf32_addr;
3534     	__kernel_dev_t32	gf32_dev;
3535     	__kernel_ino_t32	gf32_ino;
3536     	s32			gf32_version;
3537     };
3538     
3539     struct nfsctl_fdparm32 {
3540     	struct sockaddr		gd32_addr;
3541     	s8			gd32_path[NFS_MAXPATHLEN+1];
3542     	s32			gd32_version;
3543     };
3544     
3545     struct nfsctl_fsparm32 {
3546     	struct sockaddr		gd32_addr;
3547     	s8			gd32_path[NFS_MAXPATHLEN+1];
3548     	s32			gd32_maxlen;
3549     };
3550     
3551     struct nfsctl_arg32 {
3552     	s32			ca32_version;	/* safeguard */
3553     	union {
3554     		struct nfsctl_svc32	u32_svc;
3555     		struct nfsctl_client32	u32_client;
3556     		struct nfsctl_export32	u32_export;
3557     		struct nfsctl_uidmap32	u32_umap;
3558     		struct nfsctl_fhparm32	u32_getfh;
3559     		struct nfsctl_fdparm32	u32_getfd;
3560     		struct nfsctl_fsparm32	u32_getfs;
3561     	} u;
3562     #define ca32_svc	u.u32_svc
3563     #define ca32_client	u.u32_client
3564     #define ca32_export	u.u32_export
3565     #define ca32_umap	u.u32_umap
3566     #define ca32_getfh	u.u32_getfh
3567     #define ca32_getfd	u.u32_getfd
3568     #define ca32_getfs	u.u32_getfs
3569     #define ca32_authd	u.u32_authd
3570     };
3571     
3572     union nfsctl_res32 {
3573     	__u8			cr32_getfh[NFS_FHSIZE];
3574     	struct knfsd_fh		cr32_getfs;
3575     };
3576     
3577     static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3578     {
3579     	int err;
3580     	
3581     	err = __get_user(karg->ca_version, &arg32->ca32_version);
3582     	err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3583     	err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3584     	return err;
3585     }
3586     
3587     static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3588     {
3589     	int err;
3590     	
3591     	err = __get_user(karg->ca_version, &arg32->ca32_version);
3592     	err |= copy_from_user(&karg->ca_client.cl_ident[0],
3593     			  &arg32->ca32_client.cl32_ident[0],
3594     			  NFSCLNT_IDMAX);
3595     	err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3596     	err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3597     			  &arg32->ca32_client.cl32_addrlist[0],
3598     			  (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3599     	err |= __get_user(karg->ca_client.cl_fhkeytype,
3600     		      &arg32->ca32_client.cl32_fhkeytype);
3601     	err |= __get_user(karg->ca_client.cl_fhkeylen,
3602     		      &arg32->ca32_client.cl32_fhkeylen);
3603     	err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3604     			  &arg32->ca32_client.cl32_fhkey[0],
3605     			  NFSCLNT_KEYMAX);
3606     	return err;
3607     }
3608     
3609     static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3610     {
3611     	int err;
3612     	
3613     	err = __get_user(karg->ca_version, &arg32->ca32_version);
3614     	err |= copy_from_user(&karg->ca_export.ex_client[0],
3615     			  &arg32->ca32_export.ex32_client[0],
3616     			  NFSCLNT_IDMAX);
3617     	err |= copy_from_user(&karg->ca_export.ex_path[0],
3618     			  &arg32->ca32_export.ex32_path[0],
3619     			  NFS_MAXPATHLEN);
3620     	err |= __get_user(karg->ca_export.ex_dev,
3621     		      &arg32->ca32_export.ex32_dev);
3622     	err |= __get_user(karg->ca_export.ex_ino,
3623     		      &arg32->ca32_export.ex32_ino);
3624     	err |= __get_user(karg->ca_export.ex_flags,
3625     		      &arg32->ca32_export.ex32_flags);
3626     	err |= __get_user(karg->ca_export.ex_anon_uid,
3627     		      &arg32->ca32_export.ex32_anon_uid);
3628     	err |= __get_user(karg->ca_export.ex_anon_gid,
3629     		      &arg32->ca32_export.ex32_anon_gid);
3630     	karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3631     	karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3632     	return err;
3633     }
3634     
3635     static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3636     {
3637     	u32 uaddr;
3638     	int i;
3639     	int err;
3640     
3641     	memset(karg, 0, sizeof(*karg));
3642     	if(__get_user(karg->ca_version, &arg32->ca32_version))
3643     		return -EFAULT;
3644     	karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
3645     	if(!karg->ca_umap.ug_ident)
3646     		return -ENOMEM;
3647     	err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3648     	if(strncpy_from_user(karg->ca_umap.ug_ident,
3649     			     (char *)A(uaddr), PAGE_SIZE) <= 0)
3650     		return -EFAULT;
3651     	err |= __get_user(karg->ca_umap.ug_uidbase,
3652     		      &arg32->ca32_umap.ug32_uidbase);
3653     	err |= __get_user(karg->ca_umap.ug_uidlen,
3654     		      &arg32->ca32_umap.ug32_uidlen);
3655     	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3656     	if (err)
3657     		return -EFAULT;
3658     	karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3659     					  GFP_USER);
3660     	if(!karg->ca_umap.ug_udimap)
3661     		return -ENOMEM;
3662     	for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3663     		err |= __get_user(karg->ca_umap.ug_udimap[i],
3664     			      &(((__kernel_uid_t32 *)A(uaddr))[i]));
3665     	err |= __get_user(karg->ca_umap.ug_gidbase,
3666     		      &arg32->ca32_umap.ug32_gidbase);
3667     	err |= __get_user(karg->ca_umap.ug_uidlen,
3668     		      &arg32->ca32_umap.ug32_gidlen);
3669     	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3670     	if (err)
3671     		return -EFAULT;
3672     	karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3673     					  GFP_USER);
3674     	if(!karg->ca_umap.ug_gdimap)
3675     		return -ENOMEM;
3676     	for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3677     		err |= __get_user(karg->ca_umap.ug_gdimap[i],
3678     			      &(((__kernel_gid_t32 *)A(uaddr))[i]));
3679     
3680     	return err;
3681     }
3682     
3683     static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3684     {
3685     	int err;
3686     	
3687     	err = __get_user(karg->ca_version, &arg32->ca32_version);
3688     	err |= copy_from_user(&karg->ca_getfh.gf_addr,
3689     			  &arg32->ca32_getfh.gf32_addr,
3690     			  (sizeof(struct sockaddr)));
3691     	err |= __get_user(karg->ca_getfh.gf_dev,
3692     		      &arg32->ca32_getfh.gf32_dev);
3693     	err |= __get_user(karg->ca_getfh.gf_ino,
3694     		      &arg32->ca32_getfh.gf32_ino);
3695     	err |= __get_user(karg->ca_getfh.gf_version,
3696     		      &arg32->ca32_getfh.gf32_version);
3697     	return err;
3698     }
3699     
3700     static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3701     {
3702     	int err;
3703     	
3704     	err = __get_user(karg->ca_version, &arg32->ca32_version);
3705     	err |= copy_from_user(&karg->ca_getfd.gd_addr,
3706     			  &arg32->ca32_getfd.gd32_addr,
3707     			  (sizeof(struct sockaddr)));
3708     	err |= copy_from_user(&karg->ca_getfd.gd_path,
3709     			  &arg32->ca32_getfd.gd32_path,
3710     			  (NFS_MAXPATHLEN+1));
3711     	err |= __get_user(karg->ca_getfd.gd_version,
3712     		      &arg32->ca32_getfd.gd32_version);
3713     	return err;
3714     }
3715     
3716     static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3717     {
3718     	int err;
3719     	
3720     	err = __get_user(karg->ca_version, &arg32->ca32_version);
3721     	err |= copy_from_user(&karg->ca_getfs.gd_addr,
3722     			  &arg32->ca32_getfs.gd32_addr,
3723     			  (sizeof(struct sockaddr)));
3724     	err |= copy_from_user(&karg->ca_getfs.gd_path,
3725     			  &arg32->ca32_getfs.gd32_path,
3726     			  (NFS_MAXPATHLEN+1));
3727     	err |= __get_user(karg->ca_getfs.gd_maxlen,
3728     		      &arg32->ca32_getfs.gd32_maxlen);
3729     	return err;
3730     }
3731     
3732     /* This really doesn't need translations, we are only passing
3733      * back a union which contains opaque nfs file handle data.
3734      */
3735     static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
3736     {
3737     	return copy_to_user(res32, kres, sizeof(*res32));
3738     }
3739     
3740     int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
3741     {
3742     	struct nfsctl_arg *karg = NULL;
3743     	union nfsctl_res *kres = NULL;
3744     	mm_segment_t oldfs;
3745     	int err;
3746     
3747     	karg = kmalloc(sizeof(*karg), GFP_USER);
3748     	if(!karg)
3749     		return -ENOMEM;
3750     	if(res32) {
3751     		kres = kmalloc(sizeof(*kres), GFP_USER);
3752     		if(!kres) {
3753     			kfree(karg);
3754     			return -ENOMEM;
3755     		}
3756     	}
3757     	switch(cmd) {
3758     	case NFSCTL_SVC:
3759     		err = nfs_svc32_trans(karg, arg32);
3760     		break;
3761     	case NFSCTL_ADDCLIENT:
3762     		err = nfs_clnt32_trans(karg, arg32);
3763     		break;
3764     	case NFSCTL_DELCLIENT:
3765     		err = nfs_clnt32_trans(karg, arg32);
3766     		break;
3767     	case NFSCTL_EXPORT:
3768     	case NFSCTL_UNEXPORT:
3769     		err = nfs_exp32_trans(karg, arg32);
3770     		break;
3771     	/* This one is unimplemented, be we're ready for it. */
3772     	case NFSCTL_UGIDUPDATE:
3773     		err = nfs_uud32_trans(karg, arg32);
3774     		break;
3775     	case NFSCTL_GETFH:
3776     		err = nfs_getfh32_trans(karg, arg32);
3777     		break;
3778     	case NFSCTL_GETFD:
3779     		err = nfs_getfd32_trans(karg, arg32);
3780     		break;
3781     	case NFSCTL_GETFS:
3782     		err = nfs_getfs32_trans(karg, arg32);
3783     		break;
3784     	default:
3785     		err = -EINVAL;
3786     		break;
3787     	}
3788     	if(err)
3789     		goto done;
3790     	oldfs = get_fs();
3791     	set_fs(KERNEL_DS);
3792     	err = sys_nfsservctl(cmd, karg, kres);
3793     	set_fs(oldfs);
3794     
3795     	if (err)
3796     		goto done;
3797     
3798     	if((cmd == NFSCTL_GETFH) ||
3799     	   (cmd == NFSCTL_GETFD) ||
3800     	   (cmd == NFSCTL_GETFS))
3801     		err = nfs_getfh32_res_trans(kres, res32);
3802     
3803     done:
3804     	if(karg) {
3805     		if(cmd == NFSCTL_UGIDUPDATE) {
3806     			if(karg->ca_umap.ug_ident)
3807     				kfree(karg->ca_umap.ug_ident);
3808     			if(karg->ca_umap.ug_udimap)
3809     				kfree(karg->ca_umap.ug_udimap);
3810     			if(karg->ca_umap.ug_gdimap)
3811     				kfree(karg->ca_umap.ug_gdimap);
3812     		}
3813     		kfree(karg);
3814     	}
3815     	if(kres)
3816     		kfree(kres);
3817     	return err;
3818     }
3819     #else /* !NFSD */
3820     extern asmlinkage long sys_ni_syscall(void);
3821     int asmlinkage sys32_nfsservctl(int cmd, void *notused, void *notused2)
3822     {
3823     	return sys_ni_syscall();
3824     }
3825     #endif
3826     
3827     /* Translations due to time_t size differences.  Which affects all
3828        sorts of things, like timeval and itimerval.  */
3829     
3830     extern struct timezone sys_tz;
3831     extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
3832     
3833     asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
3834     {
3835     	if (tv) {
3836     		struct timeval ktv;
3837     		do_gettimeofday(&ktv);
3838     		if (put_tv32(tv, &ktv))
3839     			return -EFAULT;
3840     	}
3841     	if (tz) {
3842     		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
3843     			return -EFAULT;
3844     	}
3845     	return 0;
3846     }
3847     
3848     asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
3849     {
3850     	struct timeval ktv;
3851     	struct timezone ktz;
3852     
3853      	if (tv) {
3854     		if (get_tv32(&ktv, tv))
3855     			return -EFAULT;
3856     	}
3857     	if (tz) {
3858     		if (copy_from_user(&ktz, tz, sizeof(ktz)))
3859     			return -EFAULT;
3860     	}
3861     
3862     	return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
3863     }
3864     
3865     extern int do_getitimer(int which, struct itimerval *value);
3866     
3867     asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
3868     {
3869     	struct itimerval kit;
3870     	int error;
3871     
3872     	error = do_getitimer(which, &kit);
3873     	if (!error && put_it32(it, &kit))
3874     		error = -EFAULT;
3875     
3876     	return error;
3877     }
3878     
3879     extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
3880     
3881     asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
3882     {
3883     	struct itimerval kin, kout;
3884     	int error;
3885     
3886     	if (in) {
3887     		if (get_it32(&kin, in))
3888     			return -EFAULT;
3889     	} else
3890     		memset(&kin, 0, sizeof(kin));
3891     
3892     	error = do_setitimer(which, &kin, out ? &kout : NULL);
3893     	if (error || !out)
3894     		return error;
3895     	if (put_it32(out, &kout))
3896     		return -EFAULT;
3897     
3898     	return 0;
3899     
3900     }
3901     
3902     asmlinkage int sys_utimes(char *, struct timeval *);
3903     
3904     asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
3905     {
3906     	char *kfilename;
3907     	struct timeval ktvs[2];
3908     	mm_segment_t old_fs;
3909     	int ret;
3910     
3911     	kfilename = getname(filename);
3912     	ret = PTR_ERR(kfilename);
3913     	if (!IS_ERR(kfilename)) {
3914     		if (tvs) {
3915     			if (get_tv32(&ktvs[0], tvs) ||
3916     			    get_tv32(&ktvs[1], 1+tvs))
3917     				return -EFAULT;
3918     		}
3919     
3920     		old_fs = get_fs();
3921     		set_fs(KERNEL_DS);
3922     		ret = sys_utimes(kfilename, &ktvs[0]);
3923     		set_fs(old_fs);
3924     
3925     		putname(kfilename);
3926     	}
3927     	return ret;
3928     }
3929     
3930     /* These are here just in case some old sparc32 binary calls it. */
3931     asmlinkage int sys32_pause(void)
3932     {
3933     	current->state = TASK_INTERRUPTIBLE;
3934     	schedule();
3935     	return -ERESTARTNOHAND;
3936     }
3937     
3938     /* PCI config space poking. */
3939     extern asmlinkage int sys_pciconfig_read(unsigned long bus,
3940     					 unsigned long dfn,
3941     					 unsigned long off,
3942     					 unsigned long len,
3943     					 unsigned char *buf);
3944     
3945     extern asmlinkage int sys_pciconfig_write(unsigned long bus,
3946     					  unsigned long dfn,
3947     					  unsigned long off,
3948     					  unsigned long len,
3949     					  unsigned char *buf);
3950     
3951     asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3952     {
3953     	return sys_pciconfig_read((unsigned long) bus,
3954     				  (unsigned long) dfn,
3955     				  (unsigned long) off,
3956     				  (unsigned long) len,
3957     				  (unsigned char *)AA(ubuf));
3958     }
3959     
3960     asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3961     {
3962     	return sys_pciconfig_write((unsigned long) bus,
3963     				   (unsigned long) dfn,
3964     				   (unsigned long) off,
3965     				   (unsigned long) len,
3966     				   (unsigned char *)AA(ubuf));
3967     }
3968     
3969     extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
3970     				unsigned long arg4, unsigned long arg5);
3971     
3972     asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
3973     {
3974     	return sys_prctl(option,
3975     			 (unsigned long) arg2,
3976     			 (unsigned long) arg3,
3977     			 (unsigned long) arg4,
3978     			 (unsigned long) arg5);
3979     }
3980     
3981     
3982     extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
3983     				    size_t count, loff_t pos);
3984     
3985     extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
3986     				     size_t count, loff_t pos);
3987     
3988     typedef __kernel_ssize_t32 ssize_t32;
3989     
3990     asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
3991     				 __kernel_size_t32 count, u32 poshi, u32 poslo)
3992     {
3993     	return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
3994     }
3995     
3996     asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
3997     				  __kernel_size_t32 count, u32 poshi, u32 poslo)
3998     {
3999     	return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4000     }
4001     
4002     
4003     extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
4004     
4005     asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
4006     {
4007     	mm_segment_t old_fs = get_fs();
4008     	int ret;
4009     	off_t of;
4010     	
4011     	if (offset && get_user(of, offset))
4012     		return -EFAULT;
4013     		
4014     	set_fs(KERNEL_DS);
4015     	ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
4016     	set_fs(old_fs);
4017     	
4018     	if (!ret && offset && put_user(of, offset))
4019     		return -EFAULT;
4020     		
4021     	return ret;
4022     }
4023     
4024     /* Handle adjtimex compatability. */
4025     
4026     struct timex32 {
4027     	u32 modes;
4028     	s32 offset, freq, maxerror, esterror;
4029     	s32 status, constant, precision, tolerance;
4030     	struct timeval32 time;
4031     	s32 tick;
4032     	s32 ppsfreq, jitter, shift, stabil;
4033     	s32 jitcnt, calcnt, errcnt, stbcnt;
4034     	s32  :32; s32  :32; s32  :32; s32  :32;
4035     	s32  :32; s32  :32; s32  :32; s32  :32;
4036     	s32  :32; s32  :32; s32  :32; s32  :32;
4037     };
4038     
4039     extern int do_adjtimex(struct timex *);
4040     
4041     asmlinkage int sys32_adjtimex(struct timex32 *utp)
4042     {
4043     	struct timex txc;
4044     	int ret;
4045     
4046     	memset(&txc, 0, sizeof(struct timex));
4047     
4048     	if(get_user(txc.modes, &utp->modes) ||
4049     	   __get_user(txc.offset, &utp->offset) ||
4050     	   __get_user(txc.freq, &utp->freq) ||
4051     	   __get_user(txc.maxerror, &utp->maxerror) ||
4052     	   __get_user(txc.esterror, &utp->esterror) ||
4053     	   __get_user(txc.status, &utp->status) ||
4054     	   __get_user(txc.constant, &utp->constant) ||
4055     	   __get_user(txc.precision, &utp->precision) ||
4056     	   __get_user(txc.tolerance, &utp->tolerance) ||
4057     	   __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4058     	   __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4059     	   __get_user(txc.tick, &utp->tick) ||
4060     	   __get_user(txc.ppsfreq, &utp->ppsfreq) ||
4061     	   __get_user(txc.jitter, &utp->jitter) ||
4062     	   __get_user(txc.shift, &utp->shift) ||
4063     	   __get_user(txc.stabil, &utp->stabil) ||
4064     	   __get_user(txc.jitcnt, &utp->jitcnt) ||
4065     	   __get_user(txc.calcnt, &utp->calcnt) ||
4066     	   __get_user(txc.errcnt, &utp->errcnt) ||
4067     	   __get_user(txc.stbcnt, &utp->stbcnt))
4068     		return -EFAULT;
4069     
4070     	ret = do_adjtimex(&txc);
4071     
4072     	if(put_user(txc.modes, &utp->modes) ||
4073     	   __put_user(txc.offset, &utp->offset) ||
4074     	   __put_user(txc.freq, &utp->freq) ||
4075     	   __put_user(txc.maxerror, &utp->maxerror) ||
4076     	   __put_user(txc.esterror, &utp->esterror) ||
4077     	   __put_user(txc.status, &utp->status) ||
4078     	   __put_user(txc.constant, &utp->constant) ||
4079     	   __put_user(txc.precision, &utp->precision) ||
4080     	   __put_user(txc.tolerance, &utp->tolerance) ||
4081     	   __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4082     	   __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4083     	   __put_user(txc.tick, &utp->tick) ||
4084     	   __put_user(txc.ppsfreq, &utp->ppsfreq) ||
4085     	   __put_user(txc.jitter, &utp->jitter) ||
4086     	   __put_user(txc.shift, &utp->shift) ||
4087     	   __put_user(txc.stabil, &utp->stabil) ||
4088     	   __put_user(txc.jitcnt, &utp->jitcnt) ||
4089     	   __put_user(txc.calcnt, &utp->calcnt) ||
4090     	   __put_user(txc.errcnt, &utp->errcnt) ||
4091     	   __put_user(txc.stbcnt, &utp->stbcnt))
4092     		ret = -EFAULT;
4093     
4094     	return ret;
4095     }
4096     
4097     /* This is just a version for 32-bit applications which does
4098      * not force O_LARGEFILE on.
4099      */
4100     
4101     asmlinkage long sparc32_open(const char * filename, int flags, int mode)
4102     {
4103     	char * tmp;
4104     	int fd, error;
4105     
4106     	tmp = getname(filename);
4107     	fd = PTR_ERR(tmp);
4108     	if (!IS_ERR(tmp)) {
4109     		fd = get_unused_fd();
4110     		if (fd >= 0) {
4111     			struct file * f = filp_open(tmp, flags, mode);
4112     			error = PTR_ERR(f);
4113     			if (IS_ERR(f))
4114     				goto out_error;
4115     			fd_install(fd, f);
4116     		}
4117     out:
4118     		putname(tmp);
4119     	}
4120     	return fd;
4121     
4122     out_error:
4123     	put_unused_fd(fd);
4124     	fd = error;
4125     	goto out;
4126     }
4127     
4128     extern unsigned long do_mremap(unsigned long addr,
4129     	unsigned long old_len, unsigned long new_len,
4130     	unsigned long flags, unsigned long new_addr);
4131                     
4132     asmlinkage unsigned long sys32_mremap(unsigned long addr,
4133     	unsigned long old_len, unsigned long new_len,
4134     	unsigned long flags, u32 __new_addr)
4135     {
4136     	struct vm_area_struct *vma;
4137     	unsigned long ret = -EINVAL;
4138     	unsigned long new_addr = AA(__new_addr);
4139     
4140     	if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)
4141     		goto out;
4142     	if (addr > 0xf0000000UL - old_len)
4143     		goto out;
4144     	down_write(&current->mm->mmap_sem);
4145     	if (flags & MREMAP_FIXED) {
4146     		if (new_addr > 0xf0000000UL - new_len)
4147     			goto out_sem;
4148     	} else if (addr > 0xf0000000UL - new_len) {
4149     		unsigned long map_flags = 0;
4150     		struct file *file = NULL;
4151     
4152     		ret = -ENOMEM;
4153     		if (!(flags & MREMAP_MAYMOVE))
4154     			goto out_sem;
4155     
4156     		vma = find_vma(current->mm, addr);
4157     		if (vma) {
4158     			if (vma->vm_flags & VM_SHARED)
4159     				map_flags |= MAP_SHARED;
4160     			file = vma->vm_file;
4161     		}
4162     
4163     		/* MREMAP_FIXED checked above. */
4164     		new_addr = get_unmapped_area(file, addr, new_len,
4165     				    vma ? vma->vm_pgoff : 0,
4166     				    map_flags);
4167     		ret = new_addr;
4168     		if (new_addr & ~PAGE_MASK)
4169     			goto out_sem;
4170     		flags |= MREMAP_FIXED;
4171     	}
4172     	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
4173     out_sem:
4174     	up_write(&current->mm->mmap_sem);
4175     out:
4176     	return ret;       
4177     }
4178     
4179     extern asmlinkage long sys_setpriority(int which, int who, int niceval);
4180     
4181     asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval)
4182     {
4183     	return sys_setpriority((int) which,
4184     			       (int) who,
4185     			       (int) niceval);
4186     }
4187     
4188     struct __sysctl_args32 {
4189     	u32 name;
4190     	int nlen;
4191     	u32 oldval;
4192     	u32 oldlenp;
4193     	u32 newval;
4194     	u32 newlen;
4195     	u32 __unused[4];
4196     };
4197     
4198     extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
4199     {
4200     	struct __sysctl_args32 tmp;
4201     	int error;
4202     	size_t oldlen, *oldlenp = NULL;
4203     	unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
4204     
4205     	if (copy_from_user(&tmp, args, sizeof(tmp)))
4206     		return -EFAULT;
4207     
4208     	if (tmp.oldval && tmp.oldlenp) {
4209     		/* Duh, this is ugly and might not work if sysctl_args
4210     		   is in read-only memory, but do_sysctl does indirectly
4211     		   a lot of uaccess in both directions and we'd have to
4212     		   basically copy the whole sysctl.c here, and
4213     		   glibc's __sysctl uses rw memory for the structure
4214     		   anyway.  */
4215     		if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
4216     		    put_user(oldlen, (size_t *)addr))
4217     			return -EFAULT;
4218     		oldlenp = (size_t *)addr;
4219     	}
4220     
4221     	lock_kernel();
4222     	error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
4223     			  oldlenp, (void *)A(tmp.newval), tmp.newlen);
4224     	unlock_kernel();
4225     	if (oldlenp) {
4226     		if (!error) {
4227     			if (get_user(oldlen, (size_t *)addr) ||
4228     			    put_user(oldlen, (u32 *)A(tmp.oldlenp)))
4229     				error = -EFAULT;
4230     		}
4231     		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
4232     	}
4233     	return error;
4234     }
4235