1/*
2 * sysirix.c: IRIX system call emulation.
3 *
4 * Copyright (C) 1996 David S. Miller
5 * Copyright (C) 1997 Miguel de Icaza
6 * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle
7 */
8#include <linux/kernel.h>
9#include <linux/sched.h>
10#include <linux/binfmts.h>
11#include <linux/capability.h>
12#include <linux/highuid.h>
13#include <linux/pagemap.h>
14#include <linux/mm.h>
15#include <linux/mman.h>
16#include <linux/slab.h>
17#include <linux/swap.h>
18#include <linux/errno.h>
19#include <linux/time.h>
20#include <linux/timex.h>
21#include <linux/times.h>
22#include <linux/elf.h>
23#include <linux/msg.h>
24#include <linux/shm.h>
25#include <linux/smp.h>
26#include <linux/smp_lock.h>
27#include <linux/utsname.h>
28#include <linux/file.h>
29#include <linux/vfs.h>
30#include <linux/namei.h>
31#include <linux/socket.h>
32#include <linux/security.h>
33#include <linux/syscalls.h>
34#include <linux/resource.h>
35
36#include <asm/ptrace.h>
37#include <asm/page.h>
38#include <asm/uaccess.h>
39#include <asm/inventory.h>
40
41/* 2,191 lines of complete and utter shit coming up... */
42
43extern int max_threads;
44
45/* The sysmp commands supported thus far. */
46#define MP_NPROCS       	1 /* # processor in complex */
47#define MP_NAPROCS      	2 /* # active processors in complex */
48#define MP_PGSIZE           	14 /* Return system page size in v1. */
49
50asmlinkage int irix_sysmp(struct pt_regs *regs)
51{
52	unsigned long cmd;
53	int base = 0;
54	int error = 0;
55
56	if(regs->regs[2] == 1000)
57		base = 1;
58	cmd = regs->regs[base + 4];
59	switch(cmd) {
60	case MP_PGSIZE:
61		error = PAGE_SIZE;
62		break;
63	case MP_NPROCS:
64	case MP_NAPROCS:
65		error = num_online_cpus();
66		break;
67	default:
68		printk("SYSMP[%s:%d]: Unsupported opcode %d\n",
69		       current->comm, current->pid, (int)cmd);
70		error = -EINVAL;
71		break;
72	}
73
74	return error;
75}
76
77/* The prctl commands. */
78#define PR_MAXPROCS		 1 /* Tasks/user. */
79#define PR_ISBLOCKED		 2 /* If blocked, return 1. */
80#define PR_SETSTACKSIZE		 3 /* Set largest task stack size. */
81#define PR_GETSTACKSIZE		 4 /* Get largest task stack size. */
82#define PR_MAXPPROCS		 5 /* Num parallel tasks. */
83#define PR_UNBLKONEXEC		 6 /* When task exec/exit's, unblock. */
84#define PR_SETEXITSIG		 8 /* When task exit's, set signal. */
85#define PR_RESIDENT		 9 /* Make task unswappable. */
86#define PR_ATTACHADDR		10 /* (Re-)Connect a vma to a task. */
87#define PR_DETACHADDR		11 /* Disconnect a vma from a task. */
88#define PR_TERMCHILD		12 /* Kill child if the parent dies. */
89#define PR_GETSHMASK		13 /* Get the sproc() share mask. */
90#define PR_GETNSHARE		14 /* Number of share group members. */
91#define PR_COREPID		15 /* Add task pid to name when it core. */
92#define PR_ATTACHADDRPERM	16 /* (Re-)Connect vma, with specified prot. */
93#define PR_PTHREADEXIT		17 /* Kill a pthread, only for IRIX 6.[234] */
94
95asmlinkage int irix_prctl(unsigned option, ...)
96{
97	va_list args;
98	int error = 0;
99
100	va_start(args, option);
101	switch (option) {
102	case PR_MAXPROCS:
103		printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
104		       current->comm, current->pid);
105		error = max_threads;
106		break;
107
108	case PR_ISBLOCKED: {
109		struct task_struct *task;
110
111		printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
112		       current->comm, current->pid);
113		read_lock(&tasklist_lock);
114		task = find_task_by_pid(va_arg(args, pid_t));
115		error = -ESRCH;
116		if (error)
117			error = (task->run_list.next != NULL);
118		read_unlock(&tasklist_lock);
119		/* Can _your_ OS find this out that fast? */
120		break;
121	}
122
123	case PR_SETSTACKSIZE: {
124		long value = va_arg(args, long);
125
126		printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n",
127		       current->comm, current->pid, (unsigned long) value);
128		if (value > RLIM_INFINITY)
129			value = RLIM_INFINITY;
130		if (capable(CAP_SYS_ADMIN)) {
131			task_lock(current->group_leader);
132			current->signal->rlim[RLIMIT_STACK].rlim_max =
133				current->signal->rlim[RLIMIT_STACK].rlim_cur = value;
134			task_unlock(current->group_leader);
135			error = value;
136			break;
137		}
138		task_lock(current->group_leader);
139		if (value > current->signal->rlim[RLIMIT_STACK].rlim_max) {
140			error = -EINVAL;
141			task_unlock(current->group_leader);
142			break;
143		}
144		current->signal->rlim[RLIMIT_STACK].rlim_cur = value;
145		task_unlock(current->group_leader);
146		error = value;
147		break;
148	}
149
150	case PR_GETSTACKSIZE:
151		printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZE\n",
152		       current->comm, current->pid);
153		error = current->signal->rlim[RLIMIT_STACK].rlim_cur;
154		break;
155
156	case PR_MAXPPROCS:
157		printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
158		       current->comm, current->pid);
159		error = 1;
160		break;
161
162	case PR_UNBLKONEXEC:
163		printk("irix_prctl[%s:%d]: Wants PR_UNBLKONEXEC\n",
164		       current->comm, current->pid);
165		error = -EINVAL;
166		break;
167
168	case PR_SETEXITSIG:
169		printk("irix_prctl[%s:%d]: Wants PR_SETEXITSIG\n",
170		       current->comm, current->pid);
171
172		/* We can probably play some game where we set the task
173		 * exit_code to some non-zero value when this is requested,
174		 * and check whether exit_code is already set in do_exit().
175		 */
176		error = -EINVAL;
177		break;
178
179	case PR_RESIDENT:
180		printk("irix_prctl[%s:%d]: Wants PR_RESIDENT\n",
181		       current->comm, current->pid);
182		error = 0; /* Compatibility indeed. */
183		break;
184
185	case PR_ATTACHADDR:
186		printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDR\n",
187		       current->comm, current->pid);
188		error = -EINVAL;
189		break;
190
191	case PR_DETACHADDR:
192		printk("irix_prctl[%s:%d]: Wants PR_DETACHADDR\n",
193		       current->comm, current->pid);
194		error = -EINVAL;
195		break;
196
197	case PR_TERMCHILD:
198		printk("irix_prctl[%s:%d]: Wants PR_TERMCHILD\n",
199		       current->comm, current->pid);
200		error = -EINVAL;
201		break;
202
203	case PR_GETSHMASK:
204		printk("irix_prctl[%s:%d]: Wants PR_GETSHMASK\n",
205		       current->comm, current->pid);
206		error = -EINVAL; /* Until I have the sproc() stuff in. */
207		break;
208
209	case PR_GETNSHARE:
210		error = 0;       /* Until I have the sproc() stuff in. */
211		break;
212
213	case PR_COREPID:
214		printk("irix_prctl[%s:%d]: Wants PR_COREPID\n",
215		       current->comm, current->pid);
216		error = -EINVAL;
217		break;
218
219	case PR_ATTACHADDRPERM:
220		printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRPERM\n",
221		       current->comm, current->pid);
222		error = -EINVAL;
223		break;
224
225	default:
226		printk("irix_prctl[%s:%d]: Non-existant opcode %d\n",
227		       current->comm, current->pid, option);
228		error = -EINVAL;
229		break;
230	}
231	va_end(args);
232
233	return error;
234}
235
236#undef DEBUG_PROCGRPS
237
238extern unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt);
239extern char *prom_getenv(char *name);
240extern long prom_setenv(char *name, char *value);
241
242/* The syssgi commands supported thus far. */
243#define SGI_SYSID         1       /* Return unique per-machine identifier. */
244#define SGI_INVENT        5       /* Fetch inventory  */
245#   define SGI_INV_SIZEOF 1
246#   define SGI_INV_READ   2
247#define SGI_RDNAME        6       /* Return string name of a process. */
248#define SGI_SETNVRAM	  8	  /* Set PROM variable. */
249#define SGI_GETNVRAM	  9	  /* Get PROM variable. */
250#define SGI_SETPGID      21       /* Set process group id. */
251#define SGI_SYSCONF      22       /* POSIX sysconf garbage. */
252#define SGI_PATHCONF     24       /* POSIX sysconf garbage. */
253#define SGI_SETGROUPS    40       /* POSIX sysconf garbage. */
254#define SGI_GETGROUPS    41       /* POSIX sysconf garbage. */
255#define SGI_RUSAGE       56       /* BSD style rusage(). */
256#define SGI_SSYNC        62       /* Synchronous fs sync. */
257#define SGI_GETSID       65       /* SysVr4 get session id. */
258#define SGI_ELFMAP       68       /* Map an elf image. */
259#define SGI_TOSSTSAVE   108       /* Toss saved vma's. */
260#define SGI_FP_BCOPY    129       /* Should FPU bcopy be used on this machine? */
261#define SGI_PHYSP      1011       /* Translate virtual into physical page. */
262
263asmlinkage int irix_syssgi(struct pt_regs *regs)
264{
265	unsigned long cmd;
266	int retval, base = 0;
267
268	if (regs->regs[2] == 1000)
269		base = 1;
270
271	cmd = regs->regs[base + 4];
272	switch(cmd) {
273	case SGI_SYSID: {
274		char __user *buf = (char __user *) regs->regs[base + 5];
275
276		retval = clear_user(buf, 64) ? -EFAULT : 0;
277		break;
278	}
279
280	case SGI_SETPGID: {
281#ifdef DEBUG_PROCGRPS
282		printk("[%s:%d] setpgid(%d, %d) ",
283		       current->comm, current->pid,
284		       (int) regs->regs[base + 5], (int)regs->regs[base + 6]);
285#endif
286		retval = sys_setpgid(regs->regs[base + 5], regs->regs[base + 6]);
287
288#ifdef DEBUG_PROCGRPS
289		printk("retval=%d\n", retval);
290#endif
291	}
292
293	case SGI_SYSCONF: {
294		switch(regs->regs[base + 5]) {
295		case 1:
296			retval = (MAX_ARG_PAGES >> 4);
297			goto out;
298		case 2:
299			retval = max_threads;
300			goto out;
301		case 3:
302			retval = HZ;
303			goto out;
304		case 4:
305			retval = NGROUPS_MAX;
306			goto out;
307		case 5:
308			retval = NR_OPEN;
309			goto out;
310		case 6:
311			retval = 1;
312			goto out;
313		case 7:
314			retval = 1;
315			goto out;
316		case 8:
317			retval = 199009;
318			goto out;
319		case 11:
320			retval = PAGE_SIZE;
321			goto out;
322		case 12:
323			retval = 4;
324			goto out;
325		case 25:
326		case 26:
327		case 27:
328		case 28:
329		case 29:
330		case 30:
331			retval = 0;
332			goto out;
333		case 31:
334			retval = 32;
335			goto out;
336		default:
337			retval = -EINVAL;
338			goto out;
339		};
340	}
341
342	case SGI_SETGROUPS:
343		retval = sys_setgroups((int) regs->regs[base + 5],
344		                       (gid_t __user *) regs->regs[base + 6]);
345		break;
346
347	case SGI_GETGROUPS:
348		retval = sys_getgroups((int) regs->regs[base + 5],
349		                       (gid_t __user *) regs->regs[base + 6]);
350		break;
351
352	case SGI_RUSAGE: {
353		struct rusage __user *ru = (struct rusage __user *) regs->regs[base + 6];
354
355		switch((int) regs->regs[base + 5]) {
356		case 0:
357			/* rusage self */
358			retval = getrusage(current, RUSAGE_SELF, ru);
359			goto out;
360
361		case -1:
362			/* rusage children */
363			retval = getrusage(current, RUSAGE_CHILDREN, ru);
364			goto out;
365
366		default:
367			retval = -EINVAL;
368			goto out;
369		};
370	}
371
372	case SGI_SSYNC:
373		sys_sync();
374		retval = 0;
375		break;
376
377	case SGI_GETSID:
378#ifdef DEBUG_PROCGRPS
379		printk("[%s:%d] getsid(%d) ", current->comm, current->pid,
380		       (int) regs->regs[base + 5]);
381#endif
382		retval = sys_getsid(regs->regs[base + 5]);
383#ifdef DEBUG_PROCGRPS
384		printk("retval=%d\n", retval);
385#endif
386		break;
387
388	case SGI_ELFMAP:
389		retval = irix_mapelf((int) regs->regs[base + 5],
390				     (struct elf_phdr __user *) regs->regs[base + 6],
391				     (int) regs->regs[base + 7]);
392		break;
393
394	case SGI_TOSSTSAVE:
395		retval = 0;
396		break;
397
398	case SGI_FP_BCOPY:
399		retval = 0;
400		break;
401
402	case SGI_PHYSP: {
403		unsigned long addr = regs->regs[base + 5];
404		int __user *pageno = (int __user *) (regs->regs[base + 6]);
405		struct mm_struct *mm = current->mm;
406		pgd_t *pgdp;
407		pud_t *pudp;
408		pmd_t *pmdp;
409		pte_t *ptep;
410
411		down_read(&mm->mmap_sem);
412		pgdp = pgd_offset(mm, addr);
413		pudp = pud_offset(pgdp, addr);
414		pmdp = pmd_offset(pudp, addr);
415		ptep = pte_offset(pmdp, addr);
416		retval = -EINVAL;
417		if (ptep) {
418			pte_t pte = *ptep;
419
420			if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) {
421				/* b0rked on 64-bit */
422				retval =  put_user((pte_val(pte) & PAGE_MASK) >>
423				                   PAGE_SHIFT, pageno);
424			}
425		}
426		up_read(&mm->mmap_sem);
427		break;
428	}
429
430	case SGI_INVENT: {
431		int  arg1    = (int)    regs->regs [base + 5];
432		void __user *buffer = (void __user *) regs->regs [base + 6];
433		int  count   = (int)    regs->regs [base + 7];
434
435		switch (arg1) {
436		case SGI_INV_SIZEOF:
437			retval = sizeof (inventory_t);
438			break;
439		case SGI_INV_READ:
440			retval = dump_inventory_to_user (buffer, count);
441			break;
442		default:
443			retval = -EINVAL;
444		}
445		break;
446	}
447
448	default:
449		printk("irix_syssgi: Unsupported command %d\n", (int)cmd);
450		retval = -EINVAL;
451		break;
452	};
453
454out:
455	return retval;
456}
457
458asmlinkage int irix_gtime(struct pt_regs *regs)
459{
460	return get_seconds();
461}
462
463/*
464 * IRIX is completely broken... it returns 0 on success, otherwise
465 * ENOMEM.
466 */
467asmlinkage int irix_brk(unsigned long brk)
468{
469	unsigned long rlim;
470	unsigned long newbrk, oldbrk;
471	struct mm_struct *mm = current->mm;
472	int ret;
473
474	down_write(&mm->mmap_sem);
475	if (brk < mm->end_code) {
476		ret = -ENOMEM;
477		goto out;
478	}
479
480	newbrk = PAGE_ALIGN(brk);
481	oldbrk = PAGE_ALIGN(mm->brk);
482	if (oldbrk == newbrk) {
483		mm->brk = brk;
484		ret = 0;
485		goto out;
486	}
487
488	/*
489	 * Always allow shrinking brk
490	 */
491	if (brk <= mm->brk) {
492		mm->brk = brk;
493		do_munmap(mm, newbrk, oldbrk-newbrk);
494		ret = 0;
495		goto out;
496	}
497	/*
498	 * Check against rlimit and stack..
499	 */
500	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
501	if (rlim >= RLIM_INFINITY)
502		rlim = ~0;
503	if (brk - mm->end_code > rlim) {
504		ret = -ENOMEM;
505		goto out;
506	}
507
508	/*
509	 * Check against existing mmap mappings.
510	 */
511	if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) {
512		ret = -ENOMEM;
513		goto out;
514	}
515
516	/*
517	 * Ok, looks good - let it rip.
518	 */
519	if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) {
520		ret = -ENOMEM;
521		goto out;
522	}
523	mm->brk = brk;
524	ret = 0;
525
526out:
527	up_write(&mm->mmap_sem);
528	return ret;
529}
530
531asmlinkage int irix_getpid(struct pt_regs *regs)
532{
533	regs->regs[3] = current->real_parent->pid;
534	return current->pid;
535}
536
537asmlinkage int irix_getuid(struct pt_regs *regs)
538{
539	regs->regs[3] = current->euid;
540	return current->uid;
541}
542
543asmlinkage int irix_getgid(struct pt_regs *regs)
544{
545	regs->regs[3] = current->egid;
546	return current->gid;
547}
548
549asmlinkage int irix_stime(int value)
550{
551	int err;
552	struct timespec tv;
553
554	tv.tv_sec = value;
555	tv.tv_nsec = 0;
556	err = security_settime(&tv, NULL);
557	if (err)
558		return err;
559
560	write_seqlock_irq(&xtime_lock);
561	xtime.tv_sec = value;
562	xtime.tv_nsec = 0;
563	ntp_clear();
564	write_sequnlock_irq(&xtime_lock);
565
566	return 0;
567}
568
569static inline void jiffiestotv(unsigned long jiffies, struct timeval *value)
570{
571	value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
572	value->tv_sec = jiffies / HZ;
573}
574
575static inline void getitimer_real(struct itimerval *value)
576{
577	register unsigned long val, interval;
578
579	interval = current->it_real_incr;
580	val = 0;
581	if (del_timer(&current->real_timer)) {
582		unsigned long now = jiffies;
583		val = current->real_timer.expires;
584		add_timer(&current->real_timer);
585		/* look out for negative/zero itimer.. */
586		if (val <= now)
587			val = now+1;
588		val -= now;
589	}
590	jiffiestotv(val, &value->it_value);
591	jiffiestotv(interval, &value->it_interval);
592}
593
594asmlinkage unsigned int irix_alarm(unsigned int seconds)
595{
596	return alarm_setitimer(seconds);
597}
598
599asmlinkage int irix_pause(void)
600{
601	current->state = TASK_INTERRUPTIBLE;
602	schedule();
603
604	return -EINTR;
605}
606
607asmlinkage int irix_mount(char __user *dev_name, char __user *dir_name,
608	unsigned long flags, char __user *type, void __user *data, int datalen)
609{
610	printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
611	       current->comm, current->pid,
612	       dev_name, dir_name, flags, type, data, datalen);
613
614	return sys_mount(dev_name, dir_name, type, flags, data);
615}
616
617struct irix_statfs {
618	short f_type;
619	long  f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree;
620	char  f_fname[6], f_fpack[6];
621};
622
623asmlinkage int irix_statfs(const char __user *path,
624	struct irix_statfs __user *buf, int len, int fs_type)
625{
626	struct nameidata nd;
627	struct kstatfs kbuf;
628	int error, i;
629
630	/* We don't support this feature yet. */
631	if (fs_type) {
632		error = -EINVAL;
633		goto out;
634	}
635	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) {
636		error = -EFAULT;
637		goto out;
638	}
639
640	error = user_path_walk(path, &nd);
641	if (error)
642		goto out;
643
644	error = vfs_statfs(nd.dentry, &kbuf);
645	if (error)
646		goto dput_and_out;
647
648	error = __put_user(kbuf.f_type, &buf->f_type);
649	error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
650	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
651	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
652	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
653	error |= __put_user(kbuf.f_files, &buf->f_files);
654	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
655	for (i = 0; i < 6; i++) {
656		error |= __put_user(0, &buf->f_fname[i]);
657		error |= __put_user(0, &buf->f_fpack[i]);
658	}
659
660dput_and_out:
661	path_release(&nd);
662out:
663	return error;
664}
665
666asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf)
667{
668	struct kstatfs kbuf;
669	struct file *file;
670	int error, i;
671
672	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) {
673		error = -EFAULT;
674		goto out;
675	}
676
677	if (!(file = fget(fd))) {
678		error = -EBADF;
679		goto out;
680	}
681
682	error = vfs_statfs(file->f_path.dentry, &kbuf);
683	if (error)
684		goto out_f;
685
686	error = __put_user(kbuf.f_type, &buf->f_type);
687	error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
688	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
689	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
690	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
691	error |= __put_user(kbuf.f_files, &buf->f_files);
692	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
693
694	for (i = 0; i < 6; i++) {
695		error |= __put_user(0, &buf->f_fname[i]);
696		error |= __put_user(0, &buf->f_fpack[i]);
697	}
698
699out_f:
700	fput(file);
701out:
702	return error;
703}
704
705asmlinkage int irix_setpgrp(int flags)
706{
707	int error;
708
709#ifdef DEBUG_PROCGRPS
710	printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
711#endif
712	if(!flags)
713		error = process_group(current);
714	else
715		error = sys_setsid();
716#ifdef DEBUG_PROCGRPS
717	printk("returning %d\n", process_group(current));
718#endif
719
720	return error;
721}
722
723asmlinkage int irix_times(struct tms __user *tbuf)
724{
725	int err = 0;
726
727	if (tbuf) {
728		if (!access_ok(VERIFY_WRITE,tbuf,sizeof *tbuf))
729			return -EFAULT;
730
731		err = __put_user(current->utime, &tbuf->tms_utime);
732		err |= __put_user(current->stime, &tbuf->tms_stime);
733		err |= __put_user(current->signal->cutime, &tbuf->tms_cutime);
734		err |= __put_user(current->signal->cstime, &tbuf->tms_cstime);
735	}
736
737	return err;
738}
739
740asmlinkage int irix_exec(struct pt_regs *regs)
741{
742	int error, base = 0;
743	char *filename;
744
745	if(regs->regs[2] == 1000)
746		base = 1;
747	filename = getname((char __user *) (long)regs->regs[base + 4]);
748	error = PTR_ERR(filename);
749	if (IS_ERR(filename))
750		return error;
751
752	error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
753	                  NULL, regs);
754	putname(filename);
755
756	return error;
757}
758
759asmlinkage int irix_exece(struct pt_regs *regs)
760{
761	int error, base = 0;
762	char *filename;
763
764	if (regs->regs[2] == 1000)
765		base = 1;
766	filename = getname((char __user *) (long)regs->regs[base + 4]);
767	error = PTR_ERR(filename);
768	if (IS_ERR(filename))
769		return error;
770	error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
771	                  (char __user * __user *) (long)regs->regs[base + 6], regs);
772	putname(filename);
773
774	return error;
775}
776
777asmlinkage unsigned long irix_gethostid(void)
778{
779	printk("[%s:%d]: irix_gethostid() called...\n",
780	       current->comm, current->pid);
781
782	return -EINVAL;
783}
784
785asmlinkage unsigned long irix_sethostid(unsigned long val)
786{
787	printk("[%s:%d]: irix_sethostid(%08lx) called...\n",
788	       current->comm, current->pid, val);
789
790	return -EINVAL;
791}
792
793asmlinkage int irix_socket(int family, int type, int protocol)
794{
795	switch(type) {
796	case 1:
797		type = SOCK_DGRAM;
798		break;
799
800	case 2:
801		type = SOCK_STREAM;
802		break;
803
804	case 3:
805		type = 9; /* Invalid... */
806		break;
807
808	case 4:
809		type = SOCK_RAW;
810		break;
811
812	case 5:
813		type = SOCK_RDM;
814		break;
815
816	case 6:
817		type = SOCK_SEQPACKET;
818		break;
819
820	default:
821		break;
822	}
823
824	return sys_socket(family, type, protocol);
825}
826
827asmlinkage int irix_getdomainname(char __user *name, int len)
828{
829	int err;
830
831	down_read(&uts_sem);
832	if (len > __NEW_UTS_LEN)
833		len = __NEW_UTS_LEN;
834	err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0;
835	up_read(&uts_sem);
836
837	return err;
838}
839
840asmlinkage unsigned long irix_getpagesize(void)
841{
842	return PAGE_SIZE;
843}
844
845asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,
846			   unsigned long arg2, unsigned long arg3,
847			   unsigned long arg4)
848{
849	switch (opcode) {
850	case 0:
851		return sys_msgget((key_t) arg0, (int) arg1);
852	case 1:
853		return sys_msgctl((int) arg0, (int) arg1,
854		                  (struct msqid_ds __user *)arg2);
855	case 2:
856		return sys_msgrcv((int) arg0, (struct msgbuf __user *) arg1,
857				  (size_t) arg2, (long) arg3, (int) arg4);
858	case 3:
859		return sys_msgsnd((int) arg0, (struct msgbuf __user *) arg1,
860				  (size_t) arg2, (int) arg3);
861	default:
862		return -EINVAL;
863	}
864}
865
866asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,
867			   unsigned long arg2, unsigned long arg3)
868{
869	switch (opcode) {
870	case 0:
871		return do_shmat((int) arg0, (char __user *) arg1, (int) arg2,
872				 (unsigned long *) arg3);
873	case 1:
874		return sys_shmctl((int)arg0, (int)arg1,
875		                  (struct shmid_ds __user *)arg2);
876	case 2:
877		return sys_shmdt((char __user *)arg0);
878	case 3:
879		return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
880	default:
881		return -EINVAL;
882	}
883}
884
885asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,
886			   unsigned long arg2, int arg3)
887{
888	switch (opcode) {
889	case 0:
890		return sys_semctl((int) arg0, (int) arg1, (int) arg2,
891				  (union semun) arg3);
892	case 1:
893		return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
894	case 2:
895		return sys_semop((int) arg0, (struct sembuf __user *)arg1,
896				 (unsigned int) arg2);
897	default:
898		return -EINVAL;
899	}
900}
901
902static inline loff_t llseek(struct file *file, loff_t offset, int origin)
903{
904	loff_t (*fn)(struct file *, loff_t, int);
905	loff_t retval;
906
907	fn = default_llseek;
908	if (file->f_op && file->f_op->llseek)
909	fn = file->f_op->llseek;
910	lock_kernel();
911	retval = fn(file, offset, origin);
912	unlock_kernel();
913
914	return retval;
915}
916
917asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,
918                            int origin)
919{
920	struct file * file;
921	loff_t offset;
922	int retval;
923
924	retval = -EBADF;
925	file = fget(fd);
926	if (!file)
927		goto bad;
928	retval = -EINVAL;
929	if (origin > 2)
930		goto out_putf;
931
932	offset = llseek(file, ((loff_t) offhi << 32) | offlow, origin);
933	retval = (int) offset;
934
935out_putf:
936	fput(file);
937bad:
938	return retval;
939}
940
941asmlinkage int irix_sginap(int ticks)
942{
943	schedule_timeout_interruptible(ticks);
944	return 0;
945}
946
947asmlinkage int irix_sgikopt(char __user *istring, char __user *ostring, int len)
948{
949	return -EINVAL;
950}
951
952asmlinkage int irix_gettimeofday(struct timeval __user *tv)
953{
954	time_t sec;
955	long nsec, seq;
956	int err;
957
958	if (!access_ok(VERIFY_WRITE, tv, sizeof(struct timeval)))
959		return -EFAULT;
960
961	do {
962		seq = read_seqbegin(&xtime_lock);
963		sec = xtime.tv_sec;
964		nsec = xtime.tv_nsec;
965	} while (read_seqretry(&xtime_lock, seq));
966
967	err = __put_user(sec, &tv->tv_sec);
968	err |= __put_user((nsec / 1000), &tv->tv_usec);
969
970	return err;
971}
972
973#define IRIX_MAP_AUTOGROW 0x40
974
975asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
976				     int flags, int fd, off_t offset)
977{
978	struct file *file = NULL;
979	unsigned long retval;
980
981	if (!(flags & MAP_ANONYMOUS)) {
982		if (!(file = fget(fd)))
983			return -EBADF;
984
985		/* Ok, bad taste hack follows, try to think in something else
986		 * when reading this.  */
987		if (flags & IRIX_MAP_AUTOGROW) {
988			unsigned long old_pos;
989			long max_size = offset + len;
990
991			if (max_size > file->f_path.dentry->d_inode->i_size) {
992				old_pos = sys_lseek (fd, max_size - 1, 0);
993				sys_write (fd, (void __user *) "", 1);
994				sys_lseek (fd, old_pos, 0);
995			}
996		}
997	}
998
999	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1000
1001	down_write(&current->mm->mmap_sem);
1002	retval = do_mmap(file, addr, len, prot, flags, offset);
1003	up_write(&current->mm->mmap_sem);
1004	if (file)
1005		fput(file);
1006
1007	return retval;
1008}
1009
1010asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
1011{
1012	printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n",
1013	       current->comm, current->pid, addr, len, behavior);
1014
1015	return -EINVAL;
1016}
1017
1018asmlinkage int irix_pagelock(char __user *addr, int len, int op)
1019{
1020	printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
1021	       current->comm, current->pid, addr, len, op);
1022
1023	return -EINVAL;
1024}
1025
1026asmlinkage int irix_quotactl(struct pt_regs *regs)
1027{
1028	printk("[%s:%d] Wheee.. irix_quotactl()\n",
1029	       current->comm, current->pid);
1030
1031	return -EINVAL;
1032}
1033
1034asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
1035{
1036	int error;
1037
1038#ifdef DEBUG_PROCGRPS
1039	printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid,
1040	       pid, pgrp);
1041#endif
1042	if(!pid)
1043		pid = current->pid;
1044
1045	/* Wheee, weird sysv thing... */
1046	if ((pgrp == 0) && (pid == current->pid))
1047		error = sys_setsid();
1048	else
1049		error = sys_setpgid(pid, pgrp);
1050
1051#ifdef DEBUG_PROCGRPS
1052	printk("error = %d\n", error);
1053#endif
1054
1055	return error;
1056}
1057
1058asmlinkage int irix_systeminfo(int cmd, char __user *buf, int cnt)
1059{
1060	printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
1061	       current->comm, current->pid, cmd, buf, cnt);
1062
1063	return -EINVAL;
1064}
1065
1066struct iuname {
1067	char sysname[257], nodename[257], release[257];
1068	char version[257], machine[257];
1069	char m_type[257], base_rel[257];
1070	char _unused0[257], _unused1[257], _unused2[257];
1071	char _unused3[257], _unused4[257], _unused5[257];
1072};
1073
1074asmlinkage int irix_uname(struct iuname __user *buf)
1075{
1076	down_read(&uts_sem);
1077	if (copy_from_user(utsname()->sysname, buf->sysname, 65)
1078	    || copy_from_user(utsname()->nodename, buf->nodename, 65)
1079	    || copy_from_user(utsname()->release, buf->release, 65)
1080	    || copy_from_user(utsname()->version, buf->version, 65)
1081	    || copy_from_user(utsname()->machine, buf->machine, 65)) {
1082		return -EFAULT;
1083	}
1084	up_read(&uts_sem);
1085
1086	return 1;
1087}
1088
1089#undef DEBUG_XSTAT
1090
1091static int irix_xstat32_xlate(struct kstat *stat, void __user *ubuf)
1092{
1093	struct xstat32 {
1094		u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
1095		u32 st_rdev, st_pad2[2], st_size, st_pad3;
1096		u32 st_atime0, st_atime1;
1097		u32 st_mtime0, st_mtime1;
1098		u32 st_ctime0, st_ctime1;
1099		u32 st_blksize, st_blocks;
1100		char st_fstype[16];
1101		u32 st_pad4[8];
1102	} ub;
1103
1104	if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
1105		return -EOVERFLOW;
1106	ub.st_dev     = sysv_encode_dev(stat->dev);
1107	ub.st_ino     = stat->ino;
1108	ub.st_mode    = stat->mode;
1109	ub.st_nlink   = stat->nlink;
1110	SET_UID(ub.st_uid, stat->uid);
1111	SET_GID(ub.st_gid, stat->gid);
1112	ub.st_rdev    = sysv_encode_dev(stat->rdev);
1113#if BITS_PER_LONG == 32
1114	if (stat->size > MAX_NON_LFS)
1115		return -EOVERFLOW;
1116#endif
1117	ub.st_size    = stat->size;
1118	ub.st_atime0  = stat->atime.tv_sec;
1119	ub.st_atime1  = stat->atime.tv_nsec;
1120	ub.st_mtime0  = stat->mtime.tv_sec;
1121	ub.st_mtime1  = stat->atime.tv_nsec;
1122	ub.st_ctime0  = stat->ctime.tv_sec;
1123	ub.st_ctime1  = stat->atime.tv_nsec;
1124	ub.st_blksize = stat->blksize;
1125	ub.st_blocks  = stat->blocks;
1126	strcpy (ub.st_fstype, "efs");
1127
1128	return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
1129}
1130
1131static int irix_xstat64_xlate(struct kstat *stat, void __user *ubuf)
1132{
1133	struct xstat64 {
1134		u32 st_dev; s32 st_pad1[3];
1135		unsigned long long st_ino;
1136		u32 st_mode;
1137		u32 st_nlink; s32 st_uid; s32 st_gid; u32 st_rdev;
1138		s32 st_pad2[2];
1139		long long st_size;
1140		s32 st_pad3;
1141		struct { s32 tv_sec, tv_nsec; } st_atime, st_mtime, st_ctime;
1142		s32 st_blksize;
1143		long long  st_blocks;
1144		char st_fstype[16];
1145		s32 st_pad4[8];
1146	} ks;
1147
1148	if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
1149		return -EOVERFLOW;
1150
1151	ks.st_dev = sysv_encode_dev(stat->dev);
1152	ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
1153	ks.st_ino = (unsigned long long) stat->ino;
1154	ks.st_mode = (u32) stat->mode;
1155	ks.st_nlink = (u32) stat->nlink;
1156	ks.st_uid = (s32) stat->uid;
1157	ks.st_gid = (s32) stat->gid;
1158	ks.st_rdev = sysv_encode_dev (stat->rdev);
1159	ks.st_pad2[0] = ks.st_pad2[1] = 0;
1160	ks.st_size = (long long) stat->size;
1161	ks.st_pad3 = 0;
1162
1163	ks.st_atime.tv_sec = (s32) stat->atime.tv_sec;
1164	ks.st_atime.tv_nsec = stat->atime.tv_nsec;
1165	ks.st_mtime.tv_sec = (s32) stat->mtime.tv_sec;
1166	ks.st_mtime.tv_nsec = stat->mtime.tv_nsec;
1167	ks.st_ctime.tv_sec = (s32) stat->ctime.tv_sec;
1168	ks.st_ctime.tv_nsec = stat->ctime.tv_nsec;
1169
1170	ks.st_blksize = (s32) stat->blksize;
1171	ks.st_blocks = (long long) stat->blocks;
1172	memset(ks.st_fstype, 0, 16);
1173	ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0;
1174	ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
1175
1176	/* Now write it all back. */
1177	return copy_to_user(ubuf, &ks, sizeof(ks)) ? -EFAULT : 0;
1178}
1179
1180asmlinkage int irix_xstat(int version, char __user *filename, struct stat __user *statbuf)
1181{
1182	int retval;
1183	struct kstat stat;
1184
1185#ifdef DEBUG_XSTAT
1186	printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",
1187	       current->comm, current->pid, version, filename, statbuf);
1188#endif
1189
1190	retval = vfs_stat(filename, &stat);
1191	if (!retval) {
1192		switch(version) {
1193			case 2:
1194				retval = irix_xstat32_xlate(&stat, statbuf);
1195				break;
1196			case 3:
1197				retval = irix_xstat64_xlate(&stat, statbuf);
1198				break;
1199			default:
1200				retval = -EINVAL;
1201		}
1202	}
1203	return retval;
1204}
1205
1206asmlinkage int irix_lxstat(int version, char __user *filename, struct stat __user *statbuf)
1207{
1208	int error;
1209	struct kstat stat;
1210
1211#ifdef DEBUG_XSTAT
1212	printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",
1213	       current->comm, current->pid, version, filename, statbuf);
1214#endif
1215
1216	error = vfs_lstat(filename, &stat);
1217
1218	if (!error) {
1219		switch (version) {
1220			case 2:
1221				error = irix_xstat32_xlate(&stat, statbuf);
1222				break;
1223			case 3:
1224				error = irix_xstat64_xlate(&stat, statbuf);
1225				break;
1226			default:
1227				error = -EINVAL;
1228		}
1229	}
1230	return error;
1231}
1232
1233asmlinkage int irix_fxstat(int version, int fd, struct stat __user *statbuf)
1234{
1235	int error;
1236	struct kstat stat;
1237
1238#ifdef DEBUG_XSTAT
1239	printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",
1240	       current->comm, current->pid, version, fd, statbuf);
1241#endif
1242
1243	error = vfs_fstat(fd, &stat);
1244	if (!error) {
1245		switch (version) {
1246			case 2:
1247				error = irix_xstat32_xlate(&stat, statbuf);
1248				break;
1249			case 3:
1250				error = irix_xstat64_xlate(&stat, statbuf);
1251				break;
1252			default:
1253				error = -EINVAL;
1254		}
1255	}
1256	return error;
1257}
1258
1259asmlinkage int irix_xmknod(int ver, char __user *filename, int mode, unsigned dev)
1260{
1261	int retval;
1262	printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
1263	       current->comm, current->pid, ver, filename, mode, dev);
1264
1265	switch(ver) {
1266	case 2:
1267		/* shouldn't we convert here as well as on stat()? */
1268		retval = sys_mknod(filename, mode, dev);
1269		break;
1270
1271	default:
1272		retval = -EINVAL;
1273		break;
1274	};
1275
1276	return retval;
1277}
1278
1279asmlinkage int irix_swapctl(int cmd, char __user *arg)
1280{
1281	printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
1282	       current->comm, current->pid, cmd, arg);
1283
1284	return -EINVAL;
1285}
1286
1287struct irix_statvfs {
1288	u32 f_bsize; u32 f_frsize; u32 f_blocks;
1289	u32 f_bfree; u32 f_bavail; u32 f_files; u32 f_ffree; u32 f_favail;
1290	u32 f_fsid; char f_basetype[16];
1291	u32 f_flag; u32 f_namemax;
1292	char	f_fstr[32]; u32 f_filler[16];
1293};
1294
1295asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf)
1296{
1297	struct nameidata nd;
1298	struct kstatfs kbuf;
1299	int error, i;
1300
1301	printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
1302	       current->comm, current->pid, fname, buf);
1303	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
1304		return -EFAULT;
1305
1306	error = user_path_walk(fname, &nd);
1307	if (error)
1308		goto out;
1309	error = vfs_statfs(nd.dentry, &kbuf);
1310	if (error)
1311		goto dput_and_out;
1312
1313	error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
1314	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
1315	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
1316	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
1317	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);
1318	error |= __put_user(kbuf.f_files, &buf->f_files);
1319	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
1320	error |= __put_user(kbuf.f_ffree, &buf->f_favail);
1321#ifdef __MIPSEB__
1322	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1323#else
1324	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1325#endif
1326	for (i = 0; i < 16; i++)
1327		error |= __put_user(0, &buf->f_basetype[i]);
1328	error |= __put_user(0, &buf->f_flag);
1329	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
1330	for (i = 0; i < 32; i++)
1331		error |= __put_user(0, &buf->f_fstr[i]);
1332
1333dput_and_out:
1334	path_release(&nd);
1335out:
1336	return error;
1337}
1338
1339asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf)
1340{
1341	struct kstatfs kbuf;
1342	struct file *file;
1343	int error, i;
1344
1345	printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
1346	       current->comm, current->pid, fd, buf);
1347
1348	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
1349		return -EFAULT;
1350
1351	if (!(file = fget(fd))) {
1352		error = -EBADF;
1353		goto out;
1354	}
1355	error = vfs_statfs(file->f_path.dentry, &kbuf);
1356	if (error)
1357		goto out_f;
1358
1359	error = __put_user(kbuf.f_bsize, &buf->f_bsize);
1360	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
1361	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
1362	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
1363	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);
1364	error |= __put_user(kbuf.f_files, &buf->f_files);
1365	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
1366	error |= __put_user(kbuf.f_ffree, &buf->f_favail);
1367#ifdef __MIPSEB__
1368	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1369#else
1370	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1371#endif
1372	for(i = 0; i < 16; i++)
1373		error |= __put_user(0, &buf->f_basetype[i]);
1374	error |= __put_user(0, &buf->f_flag);
1375	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
1376	error |= __clear_user(&buf->f_fstr, sizeof(buf->f_fstr)) ? -EFAULT : 0;
1377
1378out_f:
1379	fput(file);
1380out:
1381	return error;
1382}
1383
1384asmlinkage int irix_priocntl(struct pt_regs *regs)
1385{
1386	printk("[%s:%d] Wheee.. irix_priocntl()\n",
1387	       current->comm, current->pid);
1388
1389	return -EINVAL;
1390}
1391
1392asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
1393{
1394	printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n",
1395	       current->comm, current->pid, pid, sig, code, val);
1396
1397	return -EINVAL;
1398}
1399
1400asmlinkage int irix_truncate64(char __user *name, int pad, int size1, int size2)
1401{
1402	int retval;
1403
1404	if (size1) {
1405		retval = -EINVAL;
1406		goto out;
1407	}
1408	retval = sys_truncate(name, size2);
1409
1410out:
1411	return retval;
1412}
1413
1414asmlinkage int irix_ftruncate64(int fd, int pad, int size1, int size2)
1415{
1416	int retval;
1417
1418	if (size1) {
1419		retval = -EINVAL;
1420		goto out;
1421	}
1422	retval = sys_ftruncate(fd, size2);
1423
1424out:
1425	return retval;
1426}
1427
1428asmlinkage int irix_mmap64(struct pt_regs *regs)
1429{
1430	int len, prot, flags, fd, off1, off2, error, base = 0;
1431	unsigned long addr, pgoff, *sp;
1432	struct file *file = NULL;
1433	int err;
1434
1435	if (regs->regs[2] == 1000)
1436		base = 1;
1437	sp = (unsigned long *) (regs->regs[29] + 16);
1438	addr = regs->regs[base + 4];
1439	len = regs->regs[base + 5];
1440	prot = regs->regs[base + 6];
1441	if (!base) {
1442		flags = regs->regs[base + 7];
1443		if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long))))
1444			return -EFAULT;
1445		fd = sp[0];
1446		err = __get_user(off1, &sp[1]);
1447		err |= __get_user(off2, &sp[2]);
1448	} else {
1449		if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long))))
1450			return -EFAULT;
1451		err = __get_user(flags, &sp[0]);
1452		err |= __get_user(fd, &sp[1]);
1453		err |= __get_user(off1, &sp[2]);
1454		err |= __get_user(off2, &sp[3]);
1455	}
1456
1457	if (err)
1458		return err;
1459
1460	if (off1 & PAGE_MASK)
1461		return -EOVERFLOW;
1462
1463	pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
1464
1465	if (!(flags & MAP_ANONYMOUS)) {
1466		if (!(file = fget(fd)))
1467			return -EBADF;
1468
1469		/* Ok, bad taste hack follows, try to think in something else
1470		   when reading this */
1471		if (flags & IRIX_MAP_AUTOGROW) {
1472			unsigned long old_pos;
1473			long max_size = off2 + len;
1474
1475			if (max_size > file->f_path.dentry->d_inode->i_size) {
1476				old_pos = sys_lseek (fd, max_size - 1, 0);
1477				sys_write (fd, (void __user *) "", 1);
1478				sys_lseek (fd, old_pos, 0);
1479			}
1480		}
1481	}
1482
1483	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1484
1485	down_write(&current->mm->mmap_sem);
1486	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1487	up_write(&current->mm->mmap_sem);
1488
1489	if (file)
1490		fput(file);
1491
1492	return error;
1493}
1494
1495asmlinkage int irix_dmi(struct pt_regs *regs)
1496{
1497	printk("[%s:%d] Wheee.. irix_dmi()\n",
1498	       current->comm, current->pid);
1499
1500	return -EINVAL;
1501}
1502
1503asmlinkage int irix_pread(int fd, char __user *buf, int cnt, int off64,
1504			  int off1, int off2)
1505{
1506	printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
1507	       current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
1508
1509	return -EINVAL;
1510}
1511
1512asmlinkage int irix_pwrite(int fd, char __user *buf, int cnt, int off64,
1513			   int off1, int off2)
1514{
1515	printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
1516	       current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
1517
1518	return -EINVAL;
1519}
1520
1521asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1,
1522				unsigned long arg2, unsigned long arg3,
1523				unsigned long arg4, unsigned long arg5)
1524{
1525	printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx,"
1526	       "%08lx,%08lx)\n",
1527	       current->comm, current->pid, cmd, arg0, arg1, arg2,
1528	       arg3, arg4, arg5);
1529
1530	return -EINVAL;
1531}
1532
1533struct irix_statvfs64 {
1534	u32  f_bsize; u32 f_frsize;
1535	u64  f_blocks; u64 f_bfree; u64 f_bavail;
1536	u64  f_files; u64 f_ffree; u64 f_favail;
1537	u32  f_fsid;
1538	char f_basetype[16];
1539	u32  f_flag; u32 f_namemax;
1540	char f_fstr[32];
1541	u32  f_filler[16];
1542};
1543
1544asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *buf)
1545{
1546	struct nameidata nd;
1547	struct kstatfs kbuf;
1548	int error, i;
1549
1550	printk("[%s:%d] Wheee.. irix_statvfs64(%s,%p)\n",
1551	       current->comm, current->pid, fname, buf);
1552	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64))) {
1553		error = -EFAULT;
1554		goto out;
1555	}
1556
1557	error = user_path_walk(fname, &nd);
1558	if (error)
1559		goto out;
1560	error = vfs_statfs(nd.dentry, &kbuf);
1561	if (error)
1562		goto dput_and_out;
1563
1564	error = __put_user(kbuf.f_bsize, &buf->f_bsize);
1565	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
1566	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
1567	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
1568	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);
1569	error |= __put_user(kbuf.f_files, &buf->f_files);
1570	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
1571	error |= __put_user(kbuf.f_ffree, &buf->f_favail);
1572#ifdef __MIPSEB__
1573	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1574#else
1575	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1576#endif
1577	for(i = 0; i < 16; i++)
1578		error |= __put_user(0, &buf->f_basetype[i]);
1579	error |= __put_user(0, &buf->f_flag);
1580	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
1581	for(i = 0; i < 32; i++)
1582		error |= __put_user(0, &buf->f_fstr[i]);
1583
1584dput_and_out:
1585	path_release(&nd);
1586out:
1587	return error;
1588}
1589
1590asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf)
1591{
1592	struct kstatfs kbuf;
1593	struct file *file;
1594	int error, i;
1595
1596	printk("[%s:%d] Wheee.. irix_fstatvfs64(%d,%p)\n",
1597	       current->comm, current->pid, fd, buf);
1598
1599	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
1600		error = -EFAULT;
1601		goto out;
1602	}
1603	if (!(file = fget(fd))) {
1604		error = -EBADF;
1605		goto out;
1606	}
1607	error = vfs_statfs(file->f_path.dentry, &kbuf);
1608	if (error)
1609		goto out_f;
1610
1611	error = __put_user(kbuf.f_bsize, &buf->f_bsize);
1612	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
1613	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
1614	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
1615	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);
1616	error |= __put_user(kbuf.f_files, &buf->f_files);
1617	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
1618	error |= __put_user(kbuf.f_ffree, &buf->f_favail);
1619#ifdef __MIPSEB__
1620	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1621#else
1622	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1623#endif
1624	for(i = 0; i < 16; i++)
1625		error |= __put_user(0, &buf->f_basetype[i]);
1626	error |= __put_user(0, &buf->f_flag);
1627	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
1628	error |= __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i])) ? -EFAULT : 0;
1629
1630out_f:
1631	fput(file);
1632out:
1633	return error;
1634}
1635
1636asmlinkage int irix_getmountid(char __user *fname, unsigned long __user *midbuf)
1637{
1638	int err;
1639
1640	printk("[%s:%d] irix_getmountid(%s, %p)\n",
1641	       current->comm, current->pid, fname, midbuf);
1642	if (!access_ok(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4)))
1643		return -EFAULT;
1644
1645	err = __put_user(0, &midbuf[0]);
1646	err |= __put_user(0, &midbuf[1]);
1647	err |= __put_user(0, &midbuf[2]);
1648	err |= __put_user(0, &midbuf[3]);
1649
1650	return err;
1651}
1652
1653asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask,
1654			   unsigned long arg, unsigned long sp, int slen)
1655{
1656	printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n",
1657	       current->comm, current->pid, entry, mask, arg, sp, slen);
1658
1659	return -EINVAL;
1660}
1661
1662#undef DEBUG_GETDENTS
1663
1664struct irix_dirent32 {
1665	u32  d_ino;
1666	u32  d_off;
1667	unsigned short  d_reclen;
1668	char d_name[1];
1669};
1670
1671struct irix_dirent32_callback {
1672	struct irix_dirent32 __user *current_dir;
1673	struct irix_dirent32 __user *previous;
1674	int count;
1675	int error;
1676};
1677
1678#define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))
1679#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1680
1681static int irix_filldir32(void *__buf, const char *name,
1682	int namlen, loff_t offset, u64 ino, unsigned int d_type)
1683{
1684	struct irix_dirent32 __user *dirent;
1685	struct irix_dirent32_callback *buf = __buf;
1686	unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
1687	int err = 0;
1688	u32 d_ino;
1689
1690#ifdef DEBUG_GETDENTS
1691	printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
1692	       reclen, namlen, buf->count);
1693#endif
1694	buf->error = -EINVAL;	/* only used if we fail.. */
1695	if (reclen > buf->count)
1696		return -EINVAL;
1697	d_ino = ino;
1698	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
1699		return -EOVERFLOW;
1700	dirent = buf->previous;
1701	if (dirent)
1702		err = __put_user(offset, &dirent->d_off);
1703	dirent = buf->current_dir;
1704	err |= __put_user(dirent, &buf->previous);
1705	err |= __put_user(d_ino, &dirent->d_ino);
1706	err |= __put_user(reclen, &dirent->d_reclen);
1707	err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;
1708	err |= __put_user(0, &dirent->d_name[namlen]);
1709	dirent = (struct irix_dirent32 __user *) ((char __user *) dirent + reclen);
1710
1711	buf->current_dir = dirent;
1712	buf->count -= reclen;
1713
1714	return err;
1715}
1716
1717asmlinkage int irix_ngetdents(unsigned int fd, void __user * dirent,
1718	unsigned int count, int __user *eob)
1719{
1720	struct file *file;
1721	struct irix_dirent32 __user *lastdirent;
1722	struct irix_dirent32_callback buf;
1723	int error;
1724
1725#ifdef DEBUG_GETDENTS
1726	printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm,
1727	       current->pid, fd, dirent, count, eob);
1728#endif
1729	error = -EBADF;
1730	file = fget(fd);
1731	if (!file)
1732		goto out;
1733
1734	buf.current_dir = (struct irix_dirent32 __user *) dirent;
1735	buf.previous = NULL;
1736	buf.count = count;
1737	buf.error = 0;
1738
1739	error = vfs_readdir(file, irix_filldir32, &buf);
1740	if (error < 0)
1741		goto out_putf;
1742
1743	error = buf.error;
1744	lastdirent = buf.previous;
1745	if (lastdirent) {
1746		put_user(file->f_pos, &lastdirent->d_off);
1747		error = count - buf.count;
1748	}
1749
1750	if (put_user(0, eob) < 0) {
1751		error = -EFAULT;
1752		goto out_putf;
1753	}
1754
1755#ifdef DEBUG_GETDENTS
1756	printk("eob=%d returning %d\n", *eob, count - buf.count);
1757#endif
1758	error = count - buf.count;
1759
1760out_putf:
1761	fput(file);
1762out:
1763	return error;
1764}
1765
1766struct irix_dirent64 {
1767	u64            d_ino;
1768	u64            d_off;
1769	unsigned short d_reclen;
1770	char           d_name[1];
1771};
1772
1773struct irix_dirent64_callback {
1774	struct irix_dirent64 __user *curr;
1775	struct irix_dirent64 __user *previous;
1776	int count;
1777	int error;
1778};
1779
1780#define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))
1781#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
1782
1783static int irix_filldir64(void *__buf, const char *name,
1784	int namlen, loff_t offset, u64 ino, unsigned int d_type)
1785{
1786	struct irix_dirent64 __user *dirent;
1787	struct irix_dirent64_callback * buf = __buf;
1788	unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
1789	int err = 0;
1790
1791	if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
1792		return -EFAULT;
1793
1794	if (__put_user(-EINVAL, &buf->error))	/* only used if we fail.. */
1795		return -EFAULT;
1796	if (reclen > buf->count)
1797		return -EINVAL;
1798	dirent = buf->previous;
1799	if (dirent)
1800		err = __put_user(offset, &dirent->d_off);
1801	dirent = buf->curr;
1802	buf->previous = dirent;
1803	err |= __put_user(ino, &dirent->d_ino);
1804	err |= __put_user(reclen, &dirent->d_reclen);
1805	err |= __copy_to_user((char __user *)dirent->d_name, name, namlen)
1806	       ? -EFAULT : 0;
1807	err |= __put_user(0, &dirent->d_name[namlen]);
1808
1809	dirent = (struct irix_dirent64 __user *) ((char __user *) dirent + reclen);
1810
1811	buf->curr = dirent;
1812	buf->count -= reclen;
1813
1814	return err;
1815}
1816
1817asmlinkage int irix_getdents64(int fd, void __user *dirent, int cnt)
1818{
1819	struct file *file;
1820	struct irix_dirent64 __user *lastdirent;
1821	struct irix_dirent64_callback buf;
1822	int error;
1823
1824#ifdef DEBUG_GETDENTS
1825	printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm,
1826	       current->pid, fd, dirent, cnt);
1827#endif
1828	error = -EBADF;
1829	if (!(file = fget(fd)))
1830		goto out;
1831
1832	error = -EFAULT;
1833	if (!access_ok(VERIFY_WRITE, dirent, cnt))
1834		goto out_f;
1835
1836	error = -EINVAL;
1837	if (cnt < (sizeof(struct irix_dirent64) + 255))
1838		goto out_f;
1839
1840	buf.curr = (struct irix_dirent64 __user *) dirent;
1841	buf.previous = NULL;
1842	buf.count = cnt;
1843	buf.error = 0;
1844	error = vfs_readdir(file, irix_filldir64, &buf);
1845	if (error < 0)
1846		goto out_f;
1847	lastdirent = buf.previous;
1848	if (!lastdirent) {
1849		error = buf.error;
1850		goto out_f;
1851	}
1852	if (put_user(file->f_pos, &lastdirent->d_off))
1853		return -EFAULT;
1854#ifdef DEBUG_GETDENTS
1855	printk("returning %d\n", cnt - buf.count);
1856#endif
1857	error = cnt - buf.count;
1858
1859out_f:
1860	fput(file);
1861out:
1862	return error;
1863}
1864
1865asmlinkage int irix_ngetdents64(int fd, void __user *dirent, int cnt, int *eob)
1866{
1867	struct file *file;
1868	struct irix_dirent64 __user *lastdirent;
1869	struct irix_dirent64_callback buf;
1870	int error;
1871
1872#ifdef DEBUG_GETDENTS
1873	printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm,
1874	       current->pid, fd, dirent, cnt);
1875#endif
1876	error = -EBADF;
1877	if (!(file = fget(fd)))
1878		goto out;
1879
1880	error = -EFAULT;
1881	if (!access_ok(VERIFY_WRITE, dirent, cnt) ||
1882	    !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
1883		goto out_f;
1884
1885	error = -EINVAL;
1886	if (cnt < (sizeof(struct irix_dirent64) + 255))
1887		goto out_f;
1888
1889	*eob = 0;
1890	buf.curr = (struct irix_dirent64 __user *) dirent;
1891	buf.previous = NULL;
1892	buf.count = cnt;
1893	buf.error = 0;
1894	error = vfs_readdir(file, irix_filldir64, &buf);
1895	if (error < 0)
1896		goto out_f;
1897	lastdirent = buf.previous;
1898	if (!lastdirent) {
1899		error = buf.error;
1900		goto out_f;
1901	}
1902	if (put_user(file->f_pos, &lastdirent->d_off))
1903		return -EFAULT;
1904#ifdef DEBUG_GETDENTS
1905	printk("eob=%d returning %d\n", *eob, cnt - buf.count);
1906#endif
1907	error = cnt - buf.count;
1908
1909out_f:
1910	fput(file);
1911out:
1912	return error;
1913}
1914
1915asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg)
1916{
1917	int retval;
1918
1919	switch (op) {
1920	case 1:
1921		/* Reboot */
1922		printk("[%s:%d] irix_uadmin: Wants to reboot...\n",
1923		       current->comm, current->pid);
1924		retval = -EINVAL;
1925		goto out;
1926
1927	case 2:
1928		/* Shutdown */
1929		printk("[%s:%d] irix_uadmin: Wants to shutdown...\n",
1930		       current->comm, current->pid);
1931		retval = -EINVAL;
1932		goto out;
1933
1934	case 4:
1935		/* Remount-root */
1936		printk("[%s:%d] irix_uadmin: Wants to remount root...\n",
1937		       current->comm, current->pid);
1938		retval = -EINVAL;
1939		goto out;
1940
1941	case 8:
1942		/* Kill all tasks. */
1943		printk("[%s:%d] irix_uadmin: Wants to kill all tasks...\n",
1944		       current->comm, current->pid);
1945		retval = -EINVAL;
1946		goto out;
1947
1948	case 256:
1949		/* Set magic mushrooms... */
1950		printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...\n",
1951		       current->comm, current->pid, (int) func);
1952		retval = -EINVAL;
1953		goto out;
1954
1955	default:
1956		printk("[%s:%d] irix_uadmin: Unknown operation [%d]...\n",
1957		       current->comm, current->pid, (int) op);
1958		retval = -EINVAL;
1959		goto out;
1960	};
1961
1962out:
1963	return retval;
1964}
1965
1966asmlinkage int irix_utssys(char __user *inbuf, int arg, int type, char __user *outbuf)
1967{
1968	int retval;
1969
1970	switch(type) {
1971	case 0:
1972		/* uname() */
1973		retval = irix_uname((struct iuname __user *)inbuf);
1974		goto out;
1975
1976	case 2:
1977		/* ustat() */
1978		printk("[%s:%d] irix_utssys: Wants to do ustat()\n",
1979		       current->comm, current->pid);
1980		retval = -EINVAL;
1981		goto out;
1982
1983	case 3:
1984		/* fusers() */
1985		printk("[%s:%d] irix_utssys: Wants to do fusers()\n",
1986		       current->comm, current->pid);
1987		retval = -EINVAL;
1988		goto out;
1989
1990	default:
1991		printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]\n",
1992		       current->comm, current->pid, (int) type);
1993		retval = -EINVAL;
1994		goto out;
1995	}
1996
1997out:
1998	return retval;
1999}
2000
2001#undef DEBUG_FCNTL
2002
2003#define IRIX_F_ALLOCSP 10
2004
2005asmlinkage int irix_fcntl(int fd, int cmd, int arg)
2006{
2007	int retval;
2008
2009#ifdef DEBUG_FCNTL
2010	printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm,
2011	       current->pid, fd, cmd, arg);
2012#endif
2013	if (cmd == IRIX_F_ALLOCSP){
2014		return 0;
2015	}
2016	retval = sys_fcntl(fd, cmd, arg);
2017#ifdef DEBUG_FCNTL
2018	printk("%d\n", retval);
2019#endif
2020	return retval;
2021}
2022
2023asmlinkage int irix_ulimit(int cmd, int arg)
2024{
2025	int retval;
2026
2027	switch(cmd) {
2028	case 1:
2029		printk("[%s:%d] irix_ulimit: Wants to get file size limit.\n",
2030		       current->comm, current->pid);
2031		retval = -EINVAL;
2032		goto out;
2033
2034	case 2:
2035		printk("[%s:%d] irix_ulimit: Wants to set file size limit.\n",
2036		       current->comm, current->pid);
2037		retval = -EINVAL;
2038		goto out;
2039
2040	case 3:
2041		printk("[%s:%d] irix_ulimit: Wants to get brk limit.\n",
2042		       current->comm, current->pid);
2043		retval = -EINVAL;
2044		goto out;
2045
2046	case 4:
2047		retval = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
2048		goto out;
2049
2050	case 5:
2051		printk("[%s:%d] irix_ulimit: Wants to get txt offset.\n",
2052		       current->comm, current->pid);
2053		retval = -EINVAL;
2054		goto out;
2055
2056	default:
2057		printk("[%s:%d] irix_ulimit: Unknown command [%d].\n",
2058		       current->comm, current->pid, cmd);
2059		retval = -EINVAL;
2060		goto out;
2061	}
2062out:
2063	return retval;
2064}
2065
2066asmlinkage int irix_unimp(struct pt_regs *regs)
2067{
2068	printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx "
2069	       "a3=%08lx\n", current->comm, current->pid,
2070	       (int) regs->regs[2], (int) regs->regs[3],
2071	       regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
2072
2073	return -ENOSYS;
2074}
2075