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