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