xref: /openbmc/linux/arch/mips/kernel/linux32.c (revision 3c37026d43c47bec4710cbda286f4a17f416f5e6)
1 /*
2  * Conversion between 32-bit and 64-bit native system calls.
3  *
4  * Copyright (C) 2000 Silicon Graphics, Inc.
5  * Written by Ulf Carlsson (ulfc@engr.sgi.com)
6  * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com)
7  */
8 #include <linux/config.h>
9 #include <linux/compiler.h>
10 #include <linux/mm.h>
11 #include <linux/errno.h>
12 #include <linux/file.h>
13 #include <linux/smp_lock.h>
14 #include <linux/highuid.h>
15 #include <linux/dirent.h>
16 #include <linux/resource.h>
17 #include <linux/highmem.h>
18 #include <linux/time.h>
19 #include <linux/times.h>
20 #include <linux/poll.h>
21 #include <linux/slab.h>
22 #include <linux/skbuff.h>
23 #include <linux/filter.h>
24 #include <linux/shm.h>
25 #include <linux/sem.h>
26 #include <linux/msg.h>
27 #include <linux/icmpv6.h>
28 #include <linux/syscalls.h>
29 #include <linux/sysctl.h>
30 #include <linux/utime.h>
31 #include <linux/utsname.h>
32 #include <linux/personality.h>
33 #include <linux/timex.h>
34 #include <linux/dnotify.h>
35 #include <linux/module.h>
36 #include <linux/binfmts.h>
37 #include <linux/security.h>
38 #include <linux/compat.h>
39 #include <linux/vfs.h>
40 
41 #include <net/sock.h>
42 #include <net/scm.h>
43 
44 #include <asm/ipc.h>
45 #include <asm/sim.h>
46 #include <asm/uaccess.h>
47 #include <asm/mmu_context.h>
48 #include <asm/mman.h>
49 
50 /* Use this to get at 32-bit user passed pointers. */
51 /* A() macro should be used for places where you e.g.
52    have some internal variable u32 and just want to get
53    rid of a compiler warning. AA() has to be used in
54    places where you want to convert a function argument
55    to 32bit pointer or when you e.g. access pt_regs
56    structure and want to consider 32bit registers only.
57  */
58 #define A(__x) ((unsigned long)(__x))
59 #define AA(__x) ((unsigned long)((int)__x))
60 
61 #ifdef __MIPSEB__
62 #define merge_64(r1,r2)	((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
63 #endif
64 #ifdef __MIPSEL__
65 #define merge_64(r1,r2)	((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
66 #endif
67 
68 /*
69  * Revalidate the inode. This is required for proper NFS attribute caching.
70  */
71 
72 int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
73 {
74 	struct compat_stat tmp;
75 
76 	if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
77 		return -EOVERFLOW;
78 
79 	memset(&tmp, 0, sizeof(tmp));
80 	tmp.st_dev = new_encode_dev(stat->dev);
81 	tmp.st_ino = stat->ino;
82 	tmp.st_mode = stat->mode;
83 	tmp.st_nlink = stat->nlink;
84 	SET_UID(tmp.st_uid, stat->uid);
85 	SET_GID(tmp.st_gid, stat->gid);
86 	tmp.st_rdev = new_encode_dev(stat->rdev);
87 	tmp.st_size = stat->size;
88 	tmp.st_atime = stat->atime.tv_sec;
89 	tmp.st_mtime = stat->mtime.tv_sec;
90 	tmp.st_ctime = stat->ctime.tv_sec;
91 #ifdef STAT_HAVE_NSEC
92 	tmp.st_atime_nsec = stat->atime.tv_nsec;
93 	tmp.st_mtime_nsec = stat->mtime.tv_nsec;
94 	tmp.st_ctime_nsec = stat->ctime.tv_nsec;
95 #endif
96 	tmp.st_blocks = stat->blocks;
97 	tmp.st_blksize = stat->blksize;
98 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
99 }
100 
101 asmlinkage unsigned long
102 sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
103          unsigned long flags, unsigned long fd, unsigned long pgoff)
104 {
105 	struct file * file = NULL;
106 	unsigned long error;
107 
108 	error = -EINVAL;
109 	if (!(flags & MAP_ANONYMOUS)) {
110 		error = -EBADF;
111 		file = fget(fd);
112 		if (!file)
113 			goto out;
114 	}
115 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
116 
117 	down_write(&current->mm->mmap_sem);
118 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
119 	up_write(&current->mm->mmap_sem);
120 	if (file)
121 		fput(file);
122 
123 out:
124 	return error;
125 }
126 
127 
128 asmlinkage int sys_truncate64(const char *path, unsigned int high,
129 			      unsigned int low)
130 {
131 	if ((int)high < 0)
132 		return -EINVAL;
133 	return sys_truncate(path, ((long) high << 32) | low);
134 }
135 
136 asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high,
137 			       unsigned int low)
138 {
139 	if ((int)high < 0)
140 		return -EINVAL;
141 	return sys_ftruncate(fd, ((long) high << 32) | low);
142 }
143 
144 /*
145  * sys_execve() executes a new program.
146  */
147 asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs)
148 {
149 	int error;
150 	char * filename;
151 
152 	filename = getname(compat_ptr(regs.regs[4]));
153 	error = PTR_ERR(filename);
154 	if (IS_ERR(filename))
155 		goto out;
156 	error = compat_do_execve(filename, compat_ptr(regs.regs[5]),
157 				 compat_ptr(regs.regs[6]), &regs);
158 	putname(filename);
159 
160 out:
161 	return error;
162 }
163 
164 struct dirent32 {
165 	unsigned int	d_ino;
166 	unsigned int	d_off;
167 	unsigned short	d_reclen;
168 	char		d_name[NAME_MAX + 1];
169 };
170 
171 static void
172 xlate_dirent(void *dirent64, void *dirent32, long n)
173 {
174 	long off;
175 	struct dirent *dirp;
176 	struct dirent32 *dirp32;
177 
178 	off = 0;
179 	while (off < n) {
180 		dirp = (struct dirent *)(dirent64 + off);
181 		dirp32 = (struct dirent32 *)(dirent32 + off);
182 		off += dirp->d_reclen;
183 		dirp32->d_ino = dirp->d_ino;
184 		dirp32->d_off = (unsigned int)dirp->d_off;
185 		dirp32->d_reclen = dirp->d_reclen;
186 		strncpy(dirp32->d_name, dirp->d_name, dirp->d_reclen - ((3 * 4) + 2));
187 	}
188 	return;
189 }
190 
191 asmlinkage long
192 sys32_getdents(unsigned int fd, void * dirent32, unsigned int count)
193 {
194 	long n;
195 	void *dirent64;
196 
197 	dirent64 = (void *)((unsigned long)(dirent32 + (sizeof(long) - 1)) & ~(sizeof(long) - 1));
198 	if ((n = sys_getdents(fd, dirent64, count - (dirent64 - dirent32))) < 0)
199 		return(n);
200 	xlate_dirent(dirent64, dirent32, n);
201 	return(n);
202 }
203 
204 asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count);
205 
206 asmlinkage int
207 sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
208 {
209 	int n;
210 	struct dirent dirent64;
211 
212 	if ((n = old_readdir(fd, &dirent64, count)) < 0)
213 		return(n);
214 	xlate_dirent(&dirent64, dirent32, dirent64.d_reclen);
215 	return(n);
216 }
217 
218 asmlinkage int
219 sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
220 {
221 	return compat_sys_wait4(pid, stat_addr, options, NULL);
222 }
223 
224 asmlinkage long
225 sysn32_waitid(int which, compat_pid_t pid,
226 	      siginfo_t __user *uinfo, int options,
227 	      struct compat_rusage __user *uru)
228 {
229 	struct rusage ru;
230 	long ret;
231 	mm_segment_t old_fs = get_fs();
232 
233 	set_fs (KERNEL_DS);
234 	ret = sys_waitid(which, pid, uinfo, options,
235 			 uru ? (struct rusage __user *) &ru : NULL);
236 	set_fs (old_fs);
237 
238 	if (ret < 0 || uinfo->si_signo == 0)
239 		return ret;
240 
241 	if (uru)
242 		ret = put_compat_rusage(&ru, uru);
243 	return ret;
244 }
245 
246 struct sysinfo32 {
247         s32 uptime;
248         u32 loads[3];
249         u32 totalram;
250         u32 freeram;
251         u32 sharedram;
252         u32 bufferram;
253         u32 totalswap;
254         u32 freeswap;
255         u16 procs;
256 	u32 totalhigh;
257 	u32 freehigh;
258 	u32 mem_unit;
259 	char _f[8];
260 };
261 
262 asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
263 {
264 	struct sysinfo s;
265 	int ret, err;
266 	mm_segment_t old_fs = get_fs ();
267 
268 	set_fs (KERNEL_DS);
269 	ret = sys_sysinfo(&s);
270 	set_fs (old_fs);
271 	err = put_user (s.uptime, &info->uptime);
272 	err |= __put_user (s.loads[0], &info->loads[0]);
273 	err |= __put_user (s.loads[1], &info->loads[1]);
274 	err |= __put_user (s.loads[2], &info->loads[2]);
275 	err |= __put_user (s.totalram, &info->totalram);
276 	err |= __put_user (s.freeram, &info->freeram);
277 	err |= __put_user (s.sharedram, &info->sharedram);
278 	err |= __put_user (s.bufferram, &info->bufferram);
279 	err |= __put_user (s.totalswap, &info->totalswap);
280 	err |= __put_user (s.freeswap, &info->freeswap);
281 	err |= __put_user (s.procs, &info->procs);
282 	err |= __put_user (s.totalhigh, &info->totalhigh);
283 	err |= __put_user (s.freehigh, &info->freehigh);
284 	err |= __put_user (s.mem_unit, &info->mem_unit);
285 	if (err)
286 		return -EFAULT;
287 	return ret;
288 }
289 
290 #define RLIM_INFINITY32	0x7fffffff
291 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
292 
293 struct rlimit32 {
294 	int	rlim_cur;
295 	int	rlim_max;
296 };
297 
298 #ifdef __MIPSEB__
299 asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,
300 	int length_hi, int length_lo)
301 #endif
302 #ifdef __MIPSEL__
303 asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,
304 	int length_lo, int length_hi)
305 #endif
306 {
307 	loff_t length;
308 
309 	length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
310 
311 	return sys_truncate(path, length);
312 }
313 
314 #ifdef __MIPSEB__
315 asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
316 	int length_hi, int length_lo)
317 #endif
318 #ifdef __MIPSEL__
319 asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
320 	int length_lo, int length_hi)
321 #endif
322 {
323 	loff_t length;
324 
325 	length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
326 
327 	return sys_ftruncate(fd, length);
328 }
329 
330 static inline long
331 get_tv32(struct timeval *o, struct compat_timeval *i)
332 {
333 	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
334 		(__get_user(o->tv_sec, &i->tv_sec) |
335 		 __get_user(o->tv_usec, &i->tv_usec)));
336 }
337 
338 static inline long
339 put_tv32(struct compat_timeval *o, struct timeval *i)
340 {
341 	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
342 		(__put_user(i->tv_sec, &o->tv_sec) |
343 		 __put_user(i->tv_usec, &o->tv_usec)));
344 }
345 
346 extern struct timezone sys_tz;
347 
348 asmlinkage int
349 sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
350 {
351 	if (tv) {
352 		struct timeval ktv;
353 		do_gettimeofday(&ktv);
354 		if (put_tv32(tv, &ktv))
355 			return -EFAULT;
356 	}
357 	if (tz) {
358 		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
359 			return -EFAULT;
360 	}
361 	return 0;
362 }
363 
364 static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
365 {
366 	long usec;
367 
368 	if (!access_ok(VERIFY_READ, i, sizeof(*i)))
369 		return -EFAULT;
370 	if (__get_user(o->tv_sec, &i->tv_sec))
371 		return -EFAULT;
372 	if (__get_user(usec, &i->tv_usec))
373 		return -EFAULT;
374 	o->tv_nsec = usec * 1000;
375 		return 0;
376 }
377 
378 asmlinkage int
379 sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
380 {
381 	struct timespec kts;
382 	struct timezone ktz;
383 
384  	if (tv) {
385 		if (get_ts32(&kts, tv))
386 			return -EFAULT;
387 	}
388 	if (tz) {
389 		if (copy_from_user(&ktz, tz, sizeof(ktz)))
390 			return -EFAULT;
391 	}
392 
393 	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
394 }
395 
396 asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
397 			    unsigned int offset_low, loff_t * result,
398 			    unsigned int origin)
399 {
400 	return sys_llseek(fd, offset_high, offset_low, result, origin);
401 }
402 
403 /* From the Single Unix Spec: pread & pwrite act like lseek to pos + op +
404    lseek back to original location.  They fail just like lseek does on
405    non-seekable files.  */
406 
407 asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
408 			       size_t count, u32 unused, u64 a4, u64 a5)
409 {
410 	ssize_t ret;
411 	struct file * file;
412 	ssize_t (*read)(struct file *, char *, size_t, loff_t *);
413 	loff_t pos;
414 
415 	ret = -EBADF;
416 	file = fget(fd);
417 	if (!file)
418 		goto bad_file;
419 	if (!(file->f_mode & FMODE_READ))
420 		goto out;
421 	pos = merge_64(a4, a5);
422 	ret = rw_verify_area(READ, file, &pos, count);
423 	if (ret)
424 		goto out;
425 	ret = -EINVAL;
426 	if (!file->f_op || !(read = file->f_op->read))
427 		goto out;
428 	if (pos < 0)
429 		goto out;
430 	ret = -ESPIPE;
431 	if (!(file->f_mode & FMODE_PREAD))
432 		goto out;
433 	ret = read(file, buf, count, &pos);
434 	if (ret > 0)
435 		dnotify_parent(file->f_dentry, DN_ACCESS);
436 out:
437 	fput(file);
438 bad_file:
439 	return ret;
440 }
441 
442 asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf,
443 			        size_t count, u32 unused, u64 a4, u64 a5)
444 {
445 	ssize_t ret;
446 	struct file * file;
447 	ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
448 	loff_t pos;
449 
450 	ret = -EBADF;
451 	file = fget(fd);
452 	if (!file)
453 		goto bad_file;
454 	if (!(file->f_mode & FMODE_WRITE))
455 		goto out;
456 	pos = merge_64(a4, a5);
457 	ret = rw_verify_area(WRITE, file, &pos, count);
458 	if (ret)
459 		goto out;
460 	ret = -EINVAL;
461 	if (!file->f_op || !(write = file->f_op->write))
462 		goto out;
463 	if (pos < 0)
464 		goto out;
465 
466 	ret = -ESPIPE;
467 	if (!(file->f_mode & FMODE_PWRITE))
468 		goto out;
469 
470 	ret = write(file, buf, count, &pos);
471 	if (ret > 0)
472 		dnotify_parent(file->f_dentry, DN_MODIFY);
473 out:
474 	fput(file);
475 bad_file:
476 	return ret;
477 }
478 
479 asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
480 	struct compat_timespec *interval)
481 {
482 	struct timespec t;
483 	int ret;
484 	mm_segment_t old_fs = get_fs ();
485 
486 	set_fs (KERNEL_DS);
487 	ret = sys_sched_rr_get_interval(pid, &t);
488 	set_fs (old_fs);
489 	if (put_user (t.tv_sec, &interval->tv_sec) ||
490 	    __put_user (t.tv_nsec, &interval->tv_nsec))
491 		return -EFAULT;
492 	return ret;
493 }
494 
495 struct msgbuf32 { s32 mtype; char mtext[1]; };
496 
497 struct ipc_perm32
498 {
499 	key_t    	  key;
500         __compat_uid_t  uid;
501         __compat_gid_t  gid;
502         __compat_uid_t  cuid;
503         __compat_gid_t  cgid;
504         compat_mode_t	mode;
505         unsigned short  seq;
506 };
507 
508 struct ipc64_perm32 {
509 	key_t key;
510 	__compat_uid_t uid;
511 	__compat_gid_t gid;
512 	__compat_uid_t cuid;
513 	__compat_gid_t cgid;
514 	compat_mode_t	mode;
515 	unsigned short	seq;
516 	unsigned short __pad1;
517 	unsigned int __unused1;
518 	unsigned int __unused2;
519 };
520 
521 struct semid_ds32 {
522         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
523         compat_time_t   sem_otime;              /* last semop time */
524         compat_time_t   sem_ctime;              /* last change time */
525         u32 sem_base;              /* ptr to first semaphore in array */
526         u32 sem_pending;          /* pending operations to be processed */
527         u32 sem_pending_last;    /* last pending operation */
528         u32 undo;                  /* undo requests on this array */
529         unsigned short  sem_nsems;              /* no. of semaphores in array */
530 };
531 
532 struct semid64_ds32 {
533 	struct ipc64_perm32	sem_perm;
534 	compat_time_t	sem_otime;
535 	compat_time_t	sem_ctime;
536 	unsigned int		sem_nsems;
537 	unsigned int		__unused1;
538 	unsigned int		__unused2;
539 };
540 
541 struct msqid_ds32
542 {
543         struct ipc_perm32 msg_perm;
544         u32 msg_first;
545         u32 msg_last;
546         compat_time_t   msg_stime;
547         compat_time_t   msg_rtime;
548         compat_time_t   msg_ctime;
549         u32 wwait;
550         u32 rwait;
551         unsigned short msg_cbytes;
552         unsigned short msg_qnum;
553         unsigned short msg_qbytes;
554         compat_ipc_pid_t msg_lspid;
555         compat_ipc_pid_t msg_lrpid;
556 };
557 
558 struct msqid64_ds32 {
559 	struct ipc64_perm32 msg_perm;
560 	compat_time_t msg_stime;
561 	unsigned int __unused1;
562 	compat_time_t msg_rtime;
563 	unsigned int __unused2;
564 	compat_time_t msg_ctime;
565 	unsigned int __unused3;
566 	unsigned int msg_cbytes;
567 	unsigned int msg_qnum;
568 	unsigned int msg_qbytes;
569 	compat_pid_t msg_lspid;
570 	compat_pid_t msg_lrpid;
571 	unsigned int __unused4;
572 	unsigned int __unused5;
573 };
574 
575 struct shmid_ds32 {
576         struct ipc_perm32       shm_perm;
577         int                     shm_segsz;
578         compat_time_t		shm_atime;
579         compat_time_t		shm_dtime;
580         compat_time_t		shm_ctime;
581         compat_ipc_pid_t    shm_cpid;
582         compat_ipc_pid_t    shm_lpid;
583         unsigned short          shm_nattch;
584 };
585 
586 struct shmid64_ds32 {
587 	struct ipc64_perm32	shm_perm;
588 	compat_size_t		shm_segsz;
589 	compat_time_t		shm_atime;
590 	compat_time_t		shm_dtime;
591 	compat_time_t shm_ctime;
592 	compat_pid_t shm_cpid;
593 	compat_pid_t shm_lpid;
594 	unsigned int shm_nattch;
595 	unsigned int __unused1;
596 	unsigned int __unused2;
597 };
598 
599 struct ipc_kludge32 {
600 	u32 msgp;
601 	s32 msgtyp;
602 };
603 
604 static int
605 do_sys32_semctl(int first, int second, int third, void *uptr)
606 {
607 	union semun fourth;
608 	u32 pad;
609 	int err, err2;
610 	struct semid64_ds s;
611 	mm_segment_t old_fs;
612 
613 	if (!uptr)
614 		return -EINVAL;
615 	err = -EFAULT;
616 	if (get_user (pad, (u32 *)uptr))
617 		return err;
618 	if ((third & ~IPC_64) == SETVAL)
619 		fourth.val = (int)pad;
620 	else
621 		fourth.__pad = (void *)A(pad);
622 	switch (third & ~IPC_64) {
623 	case IPC_INFO:
624 	case IPC_RMID:
625 	case IPC_SET:
626 	case SEM_INFO:
627 	case GETVAL:
628 	case GETPID:
629 	case GETNCNT:
630 	case GETZCNT:
631 	case GETALL:
632 	case SETVAL:
633 	case SETALL:
634 		err = sys_semctl (first, second, third, fourth);
635 		break;
636 
637 	case IPC_STAT:
638 	case SEM_STAT:
639 		fourth.__pad = &s;
640 		old_fs = get_fs();
641 		set_fs(KERNEL_DS);
642 		err = sys_semctl(first, second, third | IPC_64, fourth);
643 		set_fs(old_fs);
644 
645 		if (third & IPC_64) {
646 			struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad);
647 
648 			if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
649 				err = -EFAULT;
650 				break;
651 			}
652 			err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
653 			err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
654 			err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
655 			err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
656 			err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
657 			err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
658 			err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
659 			err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
660 			err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
661 			err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
662 		} else {
663 			struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad);
664 
665 			if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
666 				err = -EFAULT;
667 				break;
668 			}
669 			err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
670 			err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
671 			err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
672 			err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
673 			err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
674 			err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
675 			err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
676 			err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
677 			err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
678 			err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
679 		}
680 		if (err2)
681 			err = -EFAULT;
682 		break;
683 
684 	default:
685 		err = - EINVAL;
686 		break;
687 	}
688 
689 	return err;
690 }
691 
692 static int
693 do_sys32_msgsnd (int first, int second, int third, void *uptr)
694 {
695 	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
696 	struct msgbuf *p;
697 	mm_segment_t old_fs;
698 	int err;
699 
700 	if (second < 0)
701 		return -EINVAL;
702 	p = kmalloc (second + sizeof (struct msgbuf)
703 				    + 4, GFP_USER);
704 	if (!p)
705 		return -ENOMEM;
706 	err = get_user (p->mtype, &up->mtype);
707 	if (err)
708 		goto out;
709 	err |= __copy_from_user (p->mtext, &up->mtext, second);
710 	if (err)
711 		goto out;
712 	old_fs = get_fs ();
713 	set_fs (KERNEL_DS);
714 	err = sys_msgsnd (first, p, second, third);
715 	set_fs (old_fs);
716 out:
717 	kfree (p);
718 
719 	return err;
720 }
721 
722 static int
723 do_sys32_msgrcv (int first, int second, int msgtyp, int third,
724 		 int version, void *uptr)
725 {
726 	struct msgbuf32 *up;
727 	struct msgbuf *p;
728 	mm_segment_t old_fs;
729 	int err;
730 
731 	if (!version) {
732 		struct ipc_kludge32 *uipck = (struct ipc_kludge32 *)uptr;
733 		struct ipc_kludge32 ipck;
734 
735 		err = -EINVAL;
736 		if (!uptr)
737 			goto out;
738 		err = -EFAULT;
739 		if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
740 			goto out;
741 		uptr = (void *)AA(ipck.msgp);
742 		msgtyp = ipck.msgtyp;
743 	}
744 
745 	if (second < 0)
746 		return -EINVAL;
747 	err = -ENOMEM;
748 	p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
749 	if (!p)
750 		goto out;
751 	old_fs = get_fs ();
752 	set_fs (KERNEL_DS);
753 	err = sys_msgrcv (first, p, second + 4, msgtyp, third);
754 	set_fs (old_fs);
755 	if (err < 0)
756 		goto free_then_out;
757 	up = (struct msgbuf32 *)uptr;
758 	if (put_user (p->mtype, &up->mtype) ||
759 	    __copy_to_user (&up->mtext, p->mtext, err))
760 		err = -EFAULT;
761 free_then_out:
762 	kfree (p);
763 out:
764 	return err;
765 }
766 
767 static int
768 do_sys32_msgctl (int first, int second, void *uptr)
769 {
770 	int err = -EINVAL, err2;
771 	struct msqid64_ds m;
772 	struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
773 	struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
774 	mm_segment_t old_fs;
775 
776 	switch (second & ~IPC_64) {
777 	case IPC_INFO:
778 	case IPC_RMID:
779 	case MSG_INFO:
780 		err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
781 		break;
782 
783 	case IPC_SET:
784 		if (second & IPC_64) {
785 			if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
786 				err = -EFAULT;
787 				break;
788 			}
789 			err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid);
790 			err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid);
791 			err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode);
792 			err |= __get_user(m.msg_qbytes, &up64->msg_qbytes);
793 		} else {
794 			if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
795 				err = -EFAULT;
796 				break;
797 			}
798 			err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid);
799 			err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid);
800 			err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode);
801 			err |= __get_user(m.msg_qbytes, &up32->msg_qbytes);
802 		}
803 		if (err)
804 			break;
805 		old_fs = get_fs();
806 		set_fs(KERNEL_DS);
807 		err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m);
808 		set_fs(old_fs);
809 		break;
810 
811 	case IPC_STAT:
812 	case MSG_STAT:
813 		old_fs = get_fs();
814 		set_fs(KERNEL_DS);
815 		err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m);
816 		set_fs(old_fs);
817 		if (second & IPC_64) {
818 			if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
819 				err = -EFAULT;
820 				break;
821 			}
822 			err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
823 			err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
824 			err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
825 			err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
826 			err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
827 			err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
828 			err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
829 			err2 |= __put_user(m.msg_stime, &up64->msg_stime);
830 			err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
831 			err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
832 			err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
833 			err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
834 			err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
835 			err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
836 			err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
837 			if (err2)
838 				err = -EFAULT;
839 		} else {
840 			if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
841 				err = -EFAULT;
842 				break;
843 			}
844 			err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
845 			err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
846 			err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
847 			err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
848 			err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
849 			err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
850 			err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
851 			err2 |= __put_user(m.msg_stime, &up32->msg_stime);
852 			err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
853 			err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
854 			err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
855 			err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
856 			err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
857 			err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
858 			err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
859 			if (err2)
860 				err = -EFAULT;
861 		}
862 		break;
863 	}
864 
865 	return err;
866 }
867 
868 static int
869 do_sys32_shmat (int first, int second, int third, int version, void *uptr)
870 {
871 	unsigned long raddr;
872 	u32 *uaddr = (u32 *)A((u32)third);
873 	int err = -EINVAL;
874 
875 	if (version == 1)
876 		return err;
877 	err = do_shmat (first, uptr, second, &raddr);
878 	if (err)
879 		return err;
880 	err = put_user (raddr, uaddr);
881 	return err;
882 }
883 
884 struct shm_info32 {
885 	int used_ids;
886 	u32 shm_tot, shm_rss, shm_swp;
887 	u32 swap_attempts, swap_successes;
888 };
889 
890 static int
891 do_sys32_shmctl (int first, int second, void *uptr)
892 {
893 	struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
894 	struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
895 	struct shm_info32 *uip = (struct shm_info32 *)uptr;
896 	int err = -EFAULT, err2;
897 	struct shmid64_ds s64;
898 	mm_segment_t old_fs;
899 	struct shm_info si;
900 	struct shmid_ds s;
901 
902 	switch (second & ~IPC_64) {
903 	case IPC_INFO:
904 		second = IPC_INFO; /* So that we don't have to translate it */
905 	case IPC_RMID:
906 	case SHM_LOCK:
907 	case SHM_UNLOCK:
908 		err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
909 		break;
910 	case IPC_SET:
911 		if (second & IPC_64) {
912 			err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
913 			err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
914 			err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
915 		} else {
916 			err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
917 			err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
918 			err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
919 		}
920 		if (err)
921 			break;
922 		old_fs = get_fs();
923 		set_fs(KERNEL_DS);
924 		err = sys_shmctl(first, second & ~IPC_64, &s);
925 		set_fs(old_fs);
926 		break;
927 
928 	case IPC_STAT:
929 	case SHM_STAT:
930 		old_fs = get_fs();
931 		set_fs(KERNEL_DS);
932 		err = sys_shmctl(first, second | IPC_64, (void *) &s64);
933 		set_fs(old_fs);
934 		if (err < 0)
935 			break;
936 		if (second & IPC_64) {
937 			if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
938 				err = -EFAULT;
939 				break;
940 			}
941 			err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
942 			err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
943 			err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
944 			err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
945 			err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
946 			err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
947 			err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
948 			err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
949 			err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
950 			err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
951 			err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
952 			err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
953 			err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
954 			err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
955 		} else {
956 			if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
957 				err = -EFAULT;
958 				break;
959 			}
960 			err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
961 			err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
962 			err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
963 			err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
964 			err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
965 			err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
966 			err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
967 			err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
968 			err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
969 			err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
970 			err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
971 			err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
972 			err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
973 			err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
974 		}
975 		if (err2)
976 			err = -EFAULT;
977 		break;
978 
979 	case SHM_INFO:
980 		old_fs = get_fs();
981 		set_fs(KERNEL_DS);
982 		err = sys_shmctl(first, second, (void *)&si);
983 		set_fs(old_fs);
984 		if (err < 0)
985 			break;
986 		err2 = put_user(si.used_ids, &uip->used_ids);
987 		err2 |= __put_user(si.shm_tot, &uip->shm_tot);
988 		err2 |= __put_user(si.shm_rss, &uip->shm_rss);
989 		err2 |= __put_user(si.shm_swp, &uip->shm_swp);
990 		err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
991 		err2 |= __put_user (si.swap_successes, &uip->swap_successes);
992 		if (err2)
993 			err = -EFAULT;
994 		break;
995 
996 	default:
997 		err = -EINVAL;
998 		break;
999 	}
1000 
1001 	return err;
1002 }
1003 
1004 static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems,
1005                             const struct compat_timespec *timeout32)
1006 {
1007 	struct compat_timespec t32;
1008 	struct timespec *t64 = compat_alloc_user_space(sizeof(*t64));
1009 
1010 	if (copy_from_user(&t32, timeout32, sizeof(t32)))
1011 		return -EFAULT;
1012 
1013 	if (put_user(t32.tv_sec, &t64->tv_sec) ||
1014 	    put_user(t32.tv_nsec, &t64->tv_nsec))
1015 		return -EFAULT;
1016 
1017 	return sys_semtimedop(semid, tsems, nsems, t64);
1018 }
1019 
1020 asmlinkage long
1021 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
1022 {
1023 	int version, err;
1024 
1025 	version = call >> 16; /* hack for backward compatibility */
1026 	call &= 0xffff;
1027 
1028 	switch (call) {
1029 	case SEMOP:
1030 		/* struct sembuf is the same on 32 and 64bit :)) */
1031 		err = sys_semtimedop (first, (struct sembuf *)AA(ptr), second,
1032 		                      NULL);
1033 		break;
1034 	case SEMTIMEDOP:
1035 		err = sys32_semtimedop (first, (struct sembuf *)AA(ptr), second,
1036 		                      (const struct compat_timespec __user *)AA(fifth));
1037 		break;
1038 	case SEMGET:
1039 		err = sys_semget (first, second, third);
1040 		break;
1041 	case SEMCTL:
1042 		err = do_sys32_semctl (first, second, third,
1043 				       (void *)AA(ptr));
1044 		break;
1045 
1046 	case MSGSND:
1047 		err = do_sys32_msgsnd (first, second, third,
1048 				       (void *)AA(ptr));
1049 		break;
1050 	case MSGRCV:
1051 		err = do_sys32_msgrcv (first, second, fifth, third,
1052 				       version, (void *)AA(ptr));
1053 		break;
1054 	case MSGGET:
1055 		err = sys_msgget ((key_t) first, second);
1056 		break;
1057 	case MSGCTL:
1058 		err = do_sys32_msgctl (first, second, (void *)AA(ptr));
1059 		break;
1060 
1061 	case SHMAT:
1062 		err = do_sys32_shmat (first, second, third,
1063 				      version, (void *)AA(ptr));
1064 		break;
1065 	case SHMDT:
1066 		err = sys_shmdt ((char *)A(ptr));
1067 		break;
1068 	case SHMGET:
1069 		err = sys_shmget (first, (unsigned)second, third);
1070 		break;
1071 	case SHMCTL:
1072 		err = do_sys32_shmctl (first, second, (void *)AA(ptr));
1073 		break;
1074 	default:
1075 		err = -EINVAL;
1076 		break;
1077 	}
1078 
1079 	return err;
1080 }
1081 
1082 asmlinkage long sys32_shmat(int shmid, char __user *shmaddr,
1083 			  int shmflg, int32_t *addr)
1084 {
1085 	unsigned long raddr;
1086 	int err;
1087 
1088 	err = do_shmat(shmid, shmaddr, shmflg, &raddr);
1089 	if (err)
1090 		return err;
1091 
1092 	return put_user(raddr, addr);
1093 }
1094 
1095 struct sysctl_args32
1096 {
1097 	compat_caddr_t name;
1098 	int nlen;
1099 	compat_caddr_t oldval;
1100 	compat_caddr_t oldlenp;
1101 	compat_caddr_t newval;
1102 	compat_size_t newlen;
1103 	unsigned int __unused[4];
1104 };
1105 
1106 #ifdef CONFIG_SYSCTL
1107 
1108 asmlinkage long sys32_sysctl(struct sysctl_args32 *args)
1109 {
1110 	struct sysctl_args32 tmp;
1111 	int error;
1112 	size_t oldlen, *oldlenp = NULL;
1113 	unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
1114 
1115 	if (copy_from_user(&tmp, args, sizeof(tmp)))
1116 		return -EFAULT;
1117 
1118 	if (tmp.oldval && tmp.oldlenp) {
1119 		/* Duh, this is ugly and might not work if sysctl_args
1120 		   is in read-only memory, but do_sysctl does indirectly
1121 		   a lot of uaccess in both directions and we'd have to
1122 		   basically copy the whole sysctl.c here, and
1123 		   glibc's __sysctl uses rw memory for the structure
1124 		   anyway.  */
1125 		if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
1126 		    put_user(oldlen, (size_t *)addr))
1127 			return -EFAULT;
1128 		oldlenp = (size_t *)addr;
1129 	}
1130 
1131 	lock_kernel();
1132 	error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
1133 			  oldlenp, (void *)A(tmp.newval), tmp.newlen);
1134 	unlock_kernel();
1135 	if (oldlenp) {
1136 		if (!error) {
1137 			if (get_user(oldlen, (size_t *)addr) ||
1138 			    put_user(oldlen, (u32 *)A(tmp.oldlenp)))
1139 				error = -EFAULT;
1140 		}
1141 		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
1142 	}
1143 	return error;
1144 }
1145 
1146 #endif /* CONFIG_SYSCTL */
1147 
1148 asmlinkage long sys32_newuname(struct new_utsname * name)
1149 {
1150 	int ret = 0;
1151 
1152 	down_read(&uts_sem);
1153 	if (copy_to_user(name,&system_utsname,sizeof *name))
1154 		ret = -EFAULT;
1155 	up_read(&uts_sem);
1156 
1157 	if (current->personality == PER_LINUX32 && !ret)
1158 		if (copy_to_user(name->machine, "mips\0\0\0", 8))
1159 			ret = -EFAULT;
1160 
1161 	return ret;
1162 }
1163 
1164 asmlinkage int sys32_personality(unsigned long personality)
1165 {
1166 	int ret;
1167 	if (current->personality == PER_LINUX32 && personality == PER_LINUX)
1168 		personality = PER_LINUX32;
1169 	ret = sys_personality(personality);
1170 	if (ret == PER_LINUX32)
1171 		ret = PER_LINUX;
1172 	return ret;
1173 }
1174 
1175 /* ustat compatibility */
1176 struct ustat32 {
1177 	compat_daddr_t	f_tfree;
1178 	compat_ino_t	f_tinode;
1179 	char		f_fname[6];
1180 	char		f_fpack[6];
1181 };
1182 
1183 extern asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf);
1184 
1185 asmlinkage int sys32_ustat(dev_t dev, struct ustat32 * ubuf32)
1186 {
1187 	int err;
1188         struct ustat tmp;
1189 	struct ustat32 tmp32;
1190 	mm_segment_t old_fs = get_fs();
1191 
1192 	set_fs(KERNEL_DS);
1193 	err = sys_ustat(dev, &tmp);
1194 	set_fs (old_fs);
1195 
1196 	if (err)
1197 		goto out;
1198 
1199         memset(&tmp32,0,sizeof(struct ustat32));
1200         tmp32.f_tfree = tmp.f_tfree;
1201         tmp32.f_tinode = tmp.f_tinode;
1202 
1203         err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0;
1204 
1205 out:
1206 	return err;
1207 }
1208 
1209 /* Handle adjtimex compatibility. */
1210 
1211 struct timex32 {
1212 	u32 modes;
1213 	s32 offset, freq, maxerror, esterror;
1214 	s32 status, constant, precision, tolerance;
1215 	struct compat_timeval time;
1216 	s32 tick;
1217 	s32 ppsfreq, jitter, shift, stabil;
1218 	s32 jitcnt, calcnt, errcnt, stbcnt;
1219 	s32  :32; s32  :32; s32  :32; s32  :32;
1220 	s32  :32; s32  :32; s32  :32; s32  :32;
1221 	s32  :32; s32  :32; s32  :32; s32  :32;
1222 };
1223 
1224 extern int do_adjtimex(struct timex *);
1225 
1226 asmlinkage int sys32_adjtimex(struct timex32 *utp)
1227 {
1228 	struct timex txc;
1229 	int ret;
1230 
1231 	memset(&txc, 0, sizeof(struct timex));
1232 
1233 	if (get_user(txc.modes, &utp->modes) ||
1234 	   __get_user(txc.offset, &utp->offset) ||
1235 	   __get_user(txc.freq, &utp->freq) ||
1236 	   __get_user(txc.maxerror, &utp->maxerror) ||
1237 	   __get_user(txc.esterror, &utp->esterror) ||
1238 	   __get_user(txc.status, &utp->status) ||
1239 	   __get_user(txc.constant, &utp->constant) ||
1240 	   __get_user(txc.precision, &utp->precision) ||
1241 	   __get_user(txc.tolerance, &utp->tolerance) ||
1242 	   __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
1243 	   __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
1244 	   __get_user(txc.tick, &utp->tick) ||
1245 	   __get_user(txc.ppsfreq, &utp->ppsfreq) ||
1246 	   __get_user(txc.jitter, &utp->jitter) ||
1247 	   __get_user(txc.shift, &utp->shift) ||
1248 	   __get_user(txc.stabil, &utp->stabil) ||
1249 	   __get_user(txc.jitcnt, &utp->jitcnt) ||
1250 	   __get_user(txc.calcnt, &utp->calcnt) ||
1251 	   __get_user(txc.errcnt, &utp->errcnt) ||
1252 	   __get_user(txc.stbcnt, &utp->stbcnt))
1253 		return -EFAULT;
1254 
1255 	ret = do_adjtimex(&txc);
1256 
1257 	if (put_user(txc.modes, &utp->modes) ||
1258 	   __put_user(txc.offset, &utp->offset) ||
1259 	   __put_user(txc.freq, &utp->freq) ||
1260 	   __put_user(txc.maxerror, &utp->maxerror) ||
1261 	   __put_user(txc.esterror, &utp->esterror) ||
1262 	   __put_user(txc.status, &utp->status) ||
1263 	   __put_user(txc.constant, &utp->constant) ||
1264 	   __put_user(txc.precision, &utp->precision) ||
1265 	   __put_user(txc.tolerance, &utp->tolerance) ||
1266 	   __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
1267 	   __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
1268 	   __put_user(txc.tick, &utp->tick) ||
1269 	   __put_user(txc.ppsfreq, &utp->ppsfreq) ||
1270 	   __put_user(txc.jitter, &utp->jitter) ||
1271 	   __put_user(txc.shift, &utp->shift) ||
1272 	   __put_user(txc.stabil, &utp->stabil) ||
1273 	   __put_user(txc.jitcnt, &utp->jitcnt) ||
1274 	   __put_user(txc.calcnt, &utp->calcnt) ||
1275 	   __put_user(txc.errcnt, &utp->errcnt) ||
1276 	   __put_user(txc.stbcnt, &utp->stbcnt))
1277 		ret = -EFAULT;
1278 
1279 	return ret;
1280 }
1281 
1282 asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset,
1283 	s32 count)
1284 {
1285 	mm_segment_t old_fs = get_fs();
1286 	int ret;
1287 	off_t of;
1288 
1289 	if (offset && get_user(of, offset))
1290 		return -EFAULT;
1291 
1292 	set_fs(KERNEL_DS);
1293 	ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
1294 	set_fs(old_fs);
1295 
1296 	if (offset && put_user(of, offset))
1297 		return -EFAULT;
1298 
1299 	return ret;
1300 }
1301 
1302 asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3,
1303                                    size_t count)
1304 {
1305 	return sys_readahead(fd, merge_64(a2, a3), count);
1306 }
1307 
1308 /* Argument list sizes for sys_socketcall */
1309 #define AL(x) ((x) * sizeof(unsigned int))
1310 static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
1311 				AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
1312 				AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
1313 #undef AL
1314 
1315 /*
1316  *	System call vectors.
1317  *
1318  *	Argument checking cleaned up. Saved 20% in size.
1319  *  This function doesn't need to set the kernel lock because
1320  *  it is set by the callees.
1321  */
1322 
1323 asmlinkage long sys32_socketcall(int call, unsigned int *args32)
1324 {
1325 	unsigned int a[6];
1326 	unsigned int a0,a1;
1327 	int err;
1328 
1329 	extern asmlinkage long sys_socket(int family, int type, int protocol);
1330 	extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);
1331 	extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen);
1332 	extern asmlinkage long sys_listen(int fd, int backlog);
1333 	extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen);
1334 	extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
1335 	extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
1336 	extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec);
1337 	extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags);
1338 	extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags,
1339 					  struct sockaddr __user *addr, int addr_len);
1340 	extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags);
1341 	extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags,
1342 					    struct sockaddr __user *addr, int __user *addr_len);
1343 	extern asmlinkage long sys_shutdown(int fd, int how);
1344 	extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen);
1345 	extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int *optlen);
1346 	extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
1347 	extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags);
1348 
1349 
1350 	if(call<1||call>SYS_RECVMSG)
1351 		return -EINVAL;
1352 
1353 	/* copy_from_user should be SMP safe. */
1354 	if (copy_from_user(a, args32, socketcall_nargs[call]))
1355 		return -EFAULT;
1356 
1357 	a0=a[0];
1358 	a1=a[1];
1359 
1360 	switch(call)
1361 	{
1362 		case SYS_SOCKET:
1363 			err = sys_socket(a0,a1,a[2]);
1364 			break;
1365 		case SYS_BIND:
1366 			err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]);
1367 			break;
1368 		case SYS_CONNECT:
1369 			err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]);
1370 			break;
1371 		case SYS_LISTEN:
1372 			err = sys_listen(a0,a1);
1373 			break;
1374 		case SYS_ACCEPT:
1375 			err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
1376 			break;
1377 		case SYS_GETSOCKNAME:
1378 			err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
1379 			break;
1380 		case SYS_GETPEERNAME:
1381 			err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
1382 			break;
1383 		case SYS_SOCKETPAIR:
1384 			err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3]));
1385 			break;
1386 		case SYS_SEND:
1387 			err = sys_send(a0, (void __user *)A(a1), a[2], a[3]);
1388 			break;
1389 		case SYS_SENDTO:
1390 			err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3],
1391 					 (struct sockaddr __user *)A(a[4]), a[5]);
1392 			break;
1393 		case SYS_RECV:
1394 			err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]);
1395 			break;
1396 		case SYS_RECVFROM:
1397 			err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3],
1398 					   (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5]));
1399 			break;
1400 		case SYS_SHUTDOWN:
1401 			err = sys_shutdown(a0,a1);
1402 			break;
1403 		case SYS_SETSOCKOPT:
1404 			err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]);
1405 			break;
1406 		case SYS_GETSOCKOPT:
1407 			err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4]));
1408 			break;
1409 		case SYS_SENDMSG:
1410 			err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]);
1411 			break;
1412 		case SYS_RECVMSG:
1413 			err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]);
1414 			break;
1415 		default:
1416 			err = -EINVAL;
1417 			break;
1418 	}
1419 	return err;
1420 }
1421 
1422 struct sigevent32 {
1423 	u32 sigev_value;
1424 	u32 sigev_signo;
1425 	u32 sigev_notify;
1426 	u32 payload[(64 / 4) - 3];
1427 };
1428 
1429 extern asmlinkage long
1430 sys_timer_create(clockid_t which_clock,
1431 		 struct sigevent __user *timer_event_spec,
1432 		 timer_t __user * created_timer_id);
1433 
1434 long
1435 sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
1436 {
1437 	struct sigevent __user *p = NULL;
1438 	if (se32) {
1439 		struct sigevent se;
1440 		p = compat_alloc_user_space(sizeof(struct sigevent));
1441 		memset(&se, 0, sizeof(struct sigevent));
1442 		if (get_user(se.sigev_value.sival_int,  &se32->sigev_value) ||
1443 		    __get_user(se.sigev_signo, &se32->sigev_signo) ||
1444 		    __get_user(se.sigev_notify, &se32->sigev_notify) ||
1445 		    __copy_from_user(&se._sigev_un._pad, &se32->payload,
1446 				     sizeof(se32->payload)) ||
1447 		    copy_to_user(p, &se, sizeof(se)))
1448 			return -EFAULT;
1449 	}
1450 	return sys_timer_create(clock, p, timer_id);
1451 }
1452 
1453 asmlinkage long
1454 sysn32_rt_sigtimedwait(const sigset_t __user *uthese,
1455 		       siginfo_t __user *uinfo,
1456 		       const struct compat_timespec __user *uts32,
1457 		       size_t sigsetsize)
1458 {
1459 	struct timespec __user *uts = NULL;
1460 
1461 	if (uts32) {
1462 		struct timespec ts;
1463 		uts = compat_alloc_user_space(sizeof(struct timespec));
1464 		if (get_user(ts.tv_sec, &uts32->tv_sec) ||
1465 		    get_user(ts.tv_nsec, &uts32->tv_nsec) ||
1466 		    copy_to_user (uts, &ts, sizeof (ts)))
1467 			return -EFAULT;
1468 	}
1469 	return sys_rt_sigtimedwait(uthese, uinfo, uts, sigsetsize);
1470 }
1471 
1472 save_static_function(sys32_clone);
1473 __attribute_used__ noinline static int
1474 _sys32_clone(nabi_no_regargs struct pt_regs regs)
1475 {
1476 	unsigned long clone_flags;
1477 	unsigned long newsp;
1478 	int __user *parent_tidptr, *child_tidptr;
1479 
1480 	clone_flags = regs.regs[4];
1481 	newsp = regs.regs[5];
1482 	if (!newsp)
1483 		newsp = regs.regs[29];
1484 	parent_tidptr = (int *) regs.regs[6];
1485 
1486 	/* Use __dummy4 instead of getting it off the stack, so that
1487 	   syscall() works.  */
1488 	child_tidptr = (int __user *) __dummy4;
1489 	return do_fork(clone_flags, newsp, &regs, 0,
1490 	               parent_tidptr, child_tidptr);
1491 }
1492 
1493 extern asmlinkage void sys_set_thread_area(u32 addr);
1494 asmlinkage void sys32_set_thread_area(u32 addr)
1495 {
1496 	sys_set_thread_area(AA(addr));
1497 }
1498