From fe00f943e0ef98b4057abcc2940d631a975b43cd Mon Sep 17 00:00:00 2001
From: Ralf Baechle <ralf@linux-mips.org>
Date: Tue, 1 Mar 2005 19:22:29 +0000
Subject: Sparseify MIPS.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
 arch/mips/Makefile                |  15 ++
 arch/mips/kernel/i8259.c          |   2 +-
 arch/mips/kernel/irixelf.c        |  14 +-
 arch/mips/kernel/irixinv.c        |   7 +-
 arch/mips/kernel/irixsig.c        | 408 +++++++++++++++++---------------
 arch/mips/kernel/process.c        |   8 -
 arch/mips/kernel/ptrace.c         |   4 +-
 arch/mips/kernel/signal.c         |  14 +-
 arch/mips/kernel/sysirix.c        | 479 +++++++++++++++++++-------------------
 arch/mips/kernel/traps.c          |  21 +-
 arch/mips/kernel/unaligned.c      |  10 +-
 arch/mips/lib/csum_partial_copy.c |   2 +-
 arch/mips/mm/c-r4k.c              |   7 +-
 arch/mips/mm/cache.c              |   9 +-
 arch/mips/mm/fault.c              |   4 +-
 15 files changed, 516 insertions(+), 488 deletions(-)

(limited to 'arch')

diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 99da8a2850c..393c33c0faa 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -52,6 +52,21 @@ ifdef CONFIG_CROSSCOMPILE
 CROSS_COMPILE		:= $(tool-prefix)
 endif
 
+CHECKFLAGS-y				+= -D__linux__ -D__mips__ \
+					   -D_ABIO32=1 \
+					   -D_ABIN32=2 \
+					   -D_ABI64=3
+CHECKFLAGS-$(CONFIG_32BIT)		+= -D_MIPS_SIM=_ABIO32 \
+					   -D_MIPS_SZLONG=32 \
+					   -D__PTRDIFF_TYPE__=int
+CHECKFLAGS-$(CONFIG_64BIT)		+= -m64 -D_MIPS_SIM=_ABI64 \
+					   -D_MIPS_SZLONG=64 \
+					   -D__PTRDIFF_TYPE__="long int"
+CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN)	+= -D__MIPSEB__
+CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN)	+= -D__MIPSEL__
+
+CHECKFLAGS				= $(CHECKFLAGS-y)
+
 ifdef CONFIG_BUILD_ELF64
 gas-abi			= 64
 ld-emul			= $(64bit-emul)
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index bb31370cd39..a7d2aac46ee 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -321,7 +321,7 @@ void __init init_i8259_irqs (void)
 
 	for (i = 0; i < 16; i++) {
 		irq_desc[i].status = IRQ_DISABLED;
-		irq_desc[i].action = 0;
+		irq_desc[i].action = NULL;
 		irq_desc[i].depth = 1;
 		irq_desc[i].handler = &i8259A_irq_type;
 	}
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 881f125eecb..5aeacc1ffb2 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -147,7 +147,7 @@ static void padzero(unsigned long elf_bss)
 	nbyte = elf_bss & (PAGE_SIZE-1);
 	if (nbyte) {
 		nbyte = PAGE_SIZE - nbyte;
-		clear_user((void *) elf_bss, nbyte);
+		clear_user((void __user *) elf_bss, nbyte);
 	}
 }
 
@@ -878,10 +878,10 @@ static int load_irix_library(struct file *file)
  * phdrs there are in the USER_PHDRP array.  We return the vaddr the
  * first phdr was successfully mapped to.
  */
-unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
+unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt)
 {
 	unsigned long type, vaddr, filesz, offset, flags;
-	struct elf_phdr *hp;
+	struct elf_phdr __user *hp;
 	struct file *filp;
 	int i, retval;
 
@@ -968,9 +968,9 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
 /* These are the only things you should do on a core-file: use only these
  * functions to write out all the necessary info.
  */
-static int dump_write(struct file *file, const void *addr, int nr)
+static int dump_write(struct file *file, const void __user *addr, int nr)
 {
-	return file->f_op->write(file, (const char *) addr, nr, &file->f_pos) == nr;
+	return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr;
 }
 
 static int dump_seek(struct file *file, off_t off)
@@ -1204,7 +1204,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
 		len = current->mm->arg_end - current->mm->arg_start;
 		len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
 		(void *) copy_from_user(&psinfo.pr_psargs,
-			       (const char *)current->mm->arg_start, len);
+			       (const char __user *)current->mm->arg_start, len);
 		for (i = 0; i < len; i++)
 			if (psinfo.pr_psargs[i] == 0)
 				psinfo.pr_psargs[i] = ' ';
@@ -1301,7 +1301,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
 #ifdef DEBUG
 		printk("elf_core_dump: writing %08lx %lx\n", addr, len);
 #endif
-		DUMP_WRITE((void *)addr, len);
+		DUMP_WRITE((void __user *)addr, len);
 	}
 
 	if ((off_t) file->f_pos != offset) {
diff --git a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c
index 60aa98cd179..de8584f6231 100644
--- a/arch/mips/kernel/irixinv.c
+++ b/arch/mips/kernel/irixinv.c
@@ -30,10 +30,10 @@ void add_to_inventory (int class, int type, int controller, int unit, int state)
 	inventory_items++;
 }
 
-int dump_inventory_to_user (void *userbuf, int size)
+int dump_inventory_to_user (void __user *userbuf, int size)
 {
 	inventory_t *inv  = &inventory [0];
-	inventory_t *user = userbuf;
+	inventory_t __user *user = userbuf;
 	int v;
 
 	if (!access_ok(VERIFY_WRITE, userbuf, size))
@@ -41,7 +41,8 @@ int dump_inventory_to_user (void *userbuf, int size)
 
 	for (v = 0; v < inventory_items; v++){
 		inv = &inventory [v];
-		copy_to_user (user, inv, sizeof (inventory_t));
+		if (copy_to_user (user, inv, sizeof (inventory_t)))
+			return -EFAULT;
 		user++;
 	}
 	return inventory_items * sizeof (inventory_t);
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index eff89322ba5..908e6368420 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -76,36 +76,39 @@ static inline void dump_irix5_sigctx(struct sigctx_irix5 *c)
 }
 #endif
 
-static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
-			     int signr, sigset_t *oldmask)
+static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
+			    int signr, sigset_t *oldmask)
 {
+	struct sigctx_irix5 __user *ctx;
 	unsigned long sp;
-	struct sigctx_irix5 *ctx;
-	int i;
+	int error, i;
 
 	sp = regs->regs[29];
 	sp -= sizeof(struct sigctx_irix5);
 	sp &= ~(0xf);
-	ctx = (struct sigctx_irix5 *) sp;
+	ctx = (struct sigctx_irix5 __user *) sp;
 	if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
 		goto segv_and_exit;
 
-	__put_user(0, &ctx->weird_fpu_thing);
-	__put_user(~(0x00000001), &ctx->rmask);
-	__put_user(0, &ctx->regs[0]);
+	error = __put_user(0, &ctx->weird_fpu_thing);
+	error |= __put_user(~(0x00000001), &ctx->rmask);
+	error |= __put_user(0, &ctx->regs[0]);
 	for(i = 1; i < 32; i++)
-		__put_user((u64) regs->regs[i], &ctx->regs[i]);
+		error |= __put_user((u64) regs->regs[i], &ctx->regs[i]);
+
+	error |= __put_user((u64) regs->hi, &ctx->hi);
+	error |= __put_user((u64) regs->lo, &ctx->lo);
+	error |= __put_user((u64) regs->cp0_epc, &ctx->pc);
+	error |= __put_user(!!used_math(), &ctx->usedfp);
+	error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
+	error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
 
-	__put_user((u64) regs->hi, &ctx->hi);
-	__put_user((u64) regs->lo, &ctx->lo);
-	__put_user((u64) regs->cp0_epc, &ctx->pc);
-	__put_user(!!used_math(), &ctx->usedfp);
-	__put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
-	__put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
+	error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
 
-	__put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
+	error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0;
 
-	__copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t));
+	if (error)
+		goto segv_and_exit;
 
 #ifdef DEBUG_SIG
 	dump_irix5_sigctx(ctx);
@@ -117,13 +120,14 @@ static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
 	regs->regs[7] = (unsigned long) ka->sa.sa_handler;
 	regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer;
 
-	return;
+	return 1;
 
 segv_and_exit:
 	force_sigsegv(signr, current);
+	return 0;
 }
 
-static void inline
+static int inline
 setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
                int signr, sigset_t *oldmask, siginfo_t *info)
 {
@@ -131,9 +135,11 @@ setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	do_exit(SIGSEGV);
 }
 
-static inline void handle_signal(unsigned long sig, siginfo_t *info,
+static inline int handle_signal(unsigned long sig, siginfo_t *info,
 	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
 {
+	int ret;
+
 	switch(regs->regs[0]) {
 	case ERESTARTNOHAND:
 		regs->regs[2] = EINTR;
@@ -151,9 +157,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
 	regs->regs[0] = 0;		/* Don't deal with this again.  */
 
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_irix_rt_frame(ka, regs, sig, oldset, info);
+		ret = setup_irix_rt_frame(ka, regs, sig, oldset, info);
 	else
-		setup_irix_frame(ka, regs, sig, oldset);
+		ret = setup_irix_frame(ka, regs, sig, oldset);
 
 	spin_lock_irq(&current->sighand->siglock);
 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -161,6 +167,8 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
 		sigaddset(&current->blocked,sig);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
+
+	return ret;
 }
 
 asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
@@ -184,10 +192,8 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-	if (signr > 0) {
-		handle_signal(signr, &info, &ka, oldset, regs);
-		return 1;
-	}
+	if (signr > 0)
+		return handle_signal(signr, &info, &ka, oldset, regs);
 
 no_signal:
 	/*
@@ -208,10 +214,11 @@ no_signal:
 asmlinkage void
 irix_sigreturn(struct pt_regs *regs)
 {
-	struct sigctx_irix5 *context, *magic;
+	struct sigctx_irix5 __user *context, *magic;
 	unsigned long umask, mask;
 	u64 *fregs;
-	int sig, i, base = 0;
+	u32 usedfp;
+	int error, sig, i, base = 0;
 	sigset_t blocked;
 
 	/* Always make any pending restarted system calls return -EINTR */
@@ -220,8 +227,8 @@ irix_sigreturn(struct pt_regs *regs)
 	if (regs->regs[2] == 1000)
 		base = 1;
 
-	context = (struct sigctx_irix5 *) regs->regs[base + 4];
-	magic = (struct sigctx_irix5 *) regs->regs[base + 5];
+	context = (struct sigctx_irix5 __user *) regs->regs[base + 4];
+	magic = (struct sigctx_irix5 __user *) regs->regs[base + 5];
 	sig = (int) regs->regs[base + 6];
 #ifdef DEBUG_SIG
 	printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n",
@@ -236,25 +243,31 @@ irix_sigreturn(struct pt_regs *regs)
 	dump_irix5_sigctx(context);
 #endif
 
-	__get_user(regs->cp0_epc, &context->pc);
-	umask = context->rmask; mask = 2;
+	error = __get_user(regs->cp0_epc, &context->pc);
+	error |= __get_user(umask, &context->rmask);
+
+	mask = 2;
 	for (i = 1; i < 32; i++, mask <<= 1) {
-		if(umask & mask)
-			__get_user(regs->regs[i], &context->regs[i]);
+		if (umask & mask)
+			error |= __get_user(regs->regs[i], &context->regs[i]);
 	}
-	__get_user(regs->hi, &context->hi);
-	__get_user(regs->lo, &context->lo);
+	error |= __get_user(regs->hi, &context->hi);
+	error |= __get_user(regs->lo, &context->lo);
 
-	if ((umask & 1) && context->usedfp) {
+	error |= __get_user(usedfp, &context->usedfp);
+	if ((umask & 1) && usedfp) {
 		fregs = (u64 *) &current->thread.fpu;
+
 		for(i = 0; i < 32; i++)
-			fregs[i] = (u64) context->fpregs[i];
-		__get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
+			error |= __get_user(fregs[i], &context->fpregs[i]);
+		error |= __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
 	}
 
 	/* XXX do sigstack crapola here... XXX */
 
-	if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked)))
+	error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0;
+
+	if (error)
 		goto badframe;
 
 	sigdelsetmask(&blocked, ~_BLOCKABLE);
@@ -296,8 +309,8 @@ static inline void dump_sigact_irix5(struct sigact_irix5 *p)
 #endif
 
 asmlinkage int
-irix_sigaction(int sig, const struct sigaction *act,
-	      struct sigaction *oact, void *trampoline)
+irix_sigaction(int sig, const struct sigaction __user *act,
+	      struct sigaction __user *oact, void __user *trampoline)
 {
 	struct k_sigaction new_ka, old_ka;
 	int ret;
@@ -311,12 +324,16 @@ irix_sigaction(int sig, const struct sigaction *act,
 #endif
 	if (act) {
 		sigset_t mask;
-		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
-		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-		    __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+		int err;
+
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 			return -EFAULT;
+		err = __get_user(new_ka.sa.sa_handler, &act->sa_handler);
+		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 
-		__copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
+		err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0;
+		if (err)
+			return err;
 
 		/*
 		 * Hmmm... methinks IRIX libc always passes a valid trampoline
@@ -330,30 +347,37 @@ irix_sigaction(int sig, const struct sigaction *act,
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
 	if (!ret && oact) {
-		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
-		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+		int err;
+
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+			return -EFAULT;
+
+		err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
+		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask,
+		               sizeof(sigset_t)) ? -EFAULT : 0;
+		if (err)
 			return -EFAULT;
-		__copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
-		               sizeof(sigset_t));
 	}
 
 	return ret;
 }
 
-asmlinkage int irix_sigpending(irix_sigset_t *set)
+asmlinkage int irix_sigpending(irix_sigset_t __user *set)
 {
 	return do_sigpending(set, sizeof(*set));
 }
 
-asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
+asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,
+	irix_sigset_t __user *old)
 {
 	sigset_t oldbits, newbits;
 
 	if (new) {
 		if (!access_ok(VERIFY_READ, new, sizeof(*new)))
 			return -EFAULT;
-		__copy_from_user(&newbits, new, sizeof(unsigned long)*4);
+		if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4))
+			return -EFAULT;
 		sigdelsetmask(&newbits, ~_BLOCKABLE);
 
 		spin_lock_irq(&current->sighand->siglock);
@@ -381,20 +405,19 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
 		recalc_sigpending();
 		spin_unlock_irq(&current->sighand->siglock);
 	}
-	if(old) {
-		if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
-			return -EFAULT;
-		__copy_to_user(old, &current->blocked, sizeof(unsigned long)*4);
-	}
+	if (old)
+		return copy_to_user(old, &current->blocked,
+		                  sizeof(unsigned long)*4) ? -EFAULT : 0;
 
 	return 0;
 }
 
 asmlinkage int irix_sigsuspend(struct pt_regs *regs)
 {
-	sigset_t *uset, saveset, newset;
+	sigset_t saveset, newset;
+	sigset_t __user *uset;
 
-	uset = (sigset_t *) regs->regs[4];
+	uset = (sigset_t __user *) regs->regs[4];
 	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -440,12 +463,13 @@ struct irix5_siginfo {
 	} stuff;
 };
 
-asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
-				struct timespec *tp)
+asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
+	struct irix5_siginfo __user *info, struct timespec __user *tp)
 {
 	long expire = MAX_SCHEDULE_TIMEOUT;
 	sigset_t kset;
 	int i, sig, error, timeo = 0;
+	struct timespec ktp;
 
 #ifdef DEBUG_SIG
 	printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n",
@@ -456,14 +480,8 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
 	if (!set)
 		return -EINVAL;
 
-	if (!access_ok(VERIFY_READ, set, sizeof(kset))) {
-		error = -EFAULT;
-		goto out;
-	}
-
-	__copy_from_user(&kset, set, sizeof(set));
-	if (error)
-		goto out;
+	if (copy_from_user(&kset, set, sizeof(set)))
+		return -EFAULT;
 
 	if (info && clear_user(info, sizeof(*info))) {
 		error = -EFAULT;
@@ -471,19 +489,21 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
 	}
 
 	if (tp) {
-		if (!access_ok(VERIFY_READ, tp, sizeof(*tp)))
+		if (copy_from_user(&ktp, tp, sizeof(*tp)))
 			return -EFAULT;
-		if (!tp->tv_sec && !tp->tv_nsec) {
-			error = -EINVAL;
-			goto out;
-		}
-		expire = timespec_to_jiffies(tp) + (tp->tv_sec||tp->tv_nsec);
+
+		if (!ktp.tv_sec && !ktp.tv_nsec)
+			return -EINVAL;
+
+		expire = timespec_to_jiffies(&ktp) +
+		         (ktp.tv_sec || ktp.tv_nsec);
 	}
 
 	while(1) {
 		long tmp = 0;
 
-		expire = schedule_timeout_interruptible(expire);
+		current->state = TASK_INTERRUPTIBLE;
+		expire = schedule_timeout(expire);
 
 		for (i=0; i<=4; i++)
 			tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
@@ -500,15 +520,14 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
 	if (timeo)
 		return -EAGAIN;
 
-	for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
+	for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
 		if (sigismember (&kset, sig))
 			continue;
 		if (sigismember (&current->pending.signal, sig)) {
 			/* XXX need more than this... */
 			if (info)
-				info->sig = sig;
-			error = 0;
-			goto out;
+				return copy_to_user(&info->sig, &sig, sizeof(sig));
+			return 0;
 		}
 	}
 
@@ -534,8 +553,9 @@ extern int getrusage(struct task_struct *, int, struct rusage __user *);
 
 #define W_MASK      (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)
 
-asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
-			    int options, struct rusage *ru)
+asmlinkage int irix_waitsys(int type, int pid,
+	struct irix5_siginfo __user *info, int options,
+	struct rusage __user *ru)
 {
 	int flag, retval;
 	DECLARE_WAITQUEUE(wait, current);
@@ -543,28 +563,22 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
 	struct task_struct *p;
 	struct list_head *_p;
 
-	if (!info) {
-		retval = -EINVAL;
-		goto out;
-	}
-	if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) {
-		retval = -EFAULT;
-		goto out;
-	}
-	if (ru) {
-		if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) {
-			retval = -EFAULT;
-			goto out;
-		}
-	}
-	if (options & ~(W_MASK)) {
-		retval = -EINVAL;
-		goto out;
-	}
-	if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) {
-		retval = -EINVAL;
-		goto out;
-	}
+	if (!info)
+		return -EINVAL;
+
+	if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
+		return -EFAULT;
+
+	if (ru)
+		if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)))
+			return -EFAULT;
+
+	if (options & ~W_MASK)
+		return -EINVAL;
+
+	if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL)
+		return -EINVAL;
+
 	add_wait_queue(&current->signal->wait_chldexit, &wait);
 repeat:
 	flag = 0;
@@ -595,18 +609,20 @@ repeat:
 			add_parent(p, p->parent);
 			write_unlock_irq(&tasklist_lock);
 			retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
-			if (!retval && ru) {
-				retval |= __put_user(SIGCHLD, &info->sig);
-				retval |= __put_user(0, &info->code);
-				retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
-				retval |= __put_user((p->exit_code >> 8) & 0xff,
-				           &info->stuff.procinfo.procdata.child.status);
-				retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
-				retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
-			}
-			if (!retval) {
-				p->exit_code = 0;
-			}
+			if (retval)
+				goto end_waitsys;
+
+			retval = __put_user(SIGCHLD, &info->sig);
+			retval |= __put_user(0, &info->code);
+			retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
+			retval |= __put_user((p->exit_code >> 8) & 0xff,
+			           &info->stuff.procinfo.procdata.child.status);
+			retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
+			retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
+			if (retval)
+				goto end_waitsys;
+
+			p->exit_code = 0;
 			goto end_waitsys;
 
 		case EXIT_ZOMBIE:
@@ -614,16 +630,18 @@ repeat:
 			current->signal->cstime += p->stime + p->signal->cstime;
 			if (ru != NULL)
 				getrusage(p, RUSAGE_BOTH, ru);
-			__put_user(SIGCHLD, &info->sig);
-			__put_user(1, &info->code);      /* CLD_EXITED */
-			__put_user(p->pid, &info->stuff.procinfo.pid);
-			__put_user((p->exit_code >> 8) & 0xff,
+			retval = __put_user(SIGCHLD, &info->sig);
+			retval |= __put_user(1, &info->code);      /* CLD_EXITED */
+			retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
+			retval |= __put_user((p->exit_code >> 8) & 0xff,
 			           &info->stuff.procinfo.procdata.child.status);
-			__put_user(p->utime,
+			retval |= __put_user(p->utime,
 			           &info->stuff.procinfo.procdata.child.utime);
-			__put_user(p->stime,
+			retval |= __put_user(p->stime,
 			           &info->stuff.procinfo.procdata.child.stime);
-			retval = 0;
+			if (retval)
+				return retval;
+
 			if (p->real_parent != p->parent) {
 				write_lock_irq(&tasklist_lock);
 				remove_parent(p);
@@ -656,7 +674,6 @@ end_waitsys:
 	current->state = TASK_RUNNING;
 	remove_wait_queue(&current->signal->wait_chldexit, &wait);
 
-out:
 	return retval;
 }
 
@@ -675,39 +692,39 @@ struct irix5_context {
 
 asmlinkage int irix_getcontext(struct pt_regs *regs)
 {
-	int i, base = 0;
-	struct irix5_context *ctx;
+	int error, i, base = 0;
+	struct irix5_context __user *ctx;
 	unsigned long flags;
 
 	if (regs->regs[2] == 1000)
 		base = 1;
-	ctx = (struct irix5_context *) regs->regs[base + 4];
+	ctx = (struct irix5_context __user *) regs->regs[base + 4];
 
 #ifdef DEBUG_SIG
 	printk("[%s:%d] irix_getcontext(%p)\n",
 	       current->comm, current->pid, ctx);
 #endif
 
-	if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
+	if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)));
 		return -EFAULT;
 
-	__put_user(current->thread.irix_oldctx, &ctx->link);
+	error = __put_user(current->thread.irix_oldctx, &ctx->link);
 
-	__copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t));
+	error |= __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0;
 
 	/* XXX Do sigstack stuff someday... */
-	__put_user(0, &ctx->stack.sp);
-	__put_user(0, &ctx->stack.size);
-	__put_user(0, &ctx->stack.flags);
+	error |= __put_user(0, &ctx->stack.sp);
+	error |= __put_user(0, &ctx->stack.size);
+	error |= __put_user(0, &ctx->stack.flags);
 
-	__put_user(0, &ctx->weird_graphics_thing);
-	__put_user(0, &ctx->regs[0]);
+	error |= __put_user(0, &ctx->weird_graphics_thing);
+	error |= __put_user(0, &ctx->regs[0]);
 	for (i = 1; i < 32; i++)
-		__put_user(regs->regs[i], &ctx->regs[i]);
-	__put_user(regs->lo, &ctx->regs[32]);
-	__put_user(regs->hi, &ctx->regs[33]);
-	__put_user(regs->cp0_cause, &ctx->regs[34]);
-	__put_user(regs->cp0_epc, &ctx->regs[35]);
+		error |= __put_user(regs->regs[i], &ctx->regs[i]);
+	error |= __put_user(regs->lo, &ctx->regs[32]);
+	error |= __put_user(regs->hi, &ctx->regs[33]);
+	error |= __put_user(regs->cp0_cause, &ctx->regs[34]);
+	error |= __put_user(regs->cp0_epc, &ctx->regs[35]);
 
 	flags = 0x0f;
 	if (!used_math()) {
@@ -716,119 +733,124 @@ asmlinkage int irix_getcontext(struct pt_regs *regs)
 		/* XXX wheee... */
 		printk("Wheee, no code for saving IRIX FPU context yet.\n");
 	}
-	__put_user(flags, &ctx->flags);
+	error |= __put_user(flags, &ctx->flags);
 
-	return 0;
+	return error;
 }
 
-asmlinkage unsigned long irix_setcontext(struct pt_regs *regs)
+asmlinkage void irix_setcontext(struct pt_regs *regs)
 {
-	int error, base = 0;
-	struct irix5_context *ctx;
+	struct irix5_context __user *ctx;
+	int err, base = 0;
+	u32 flags;
 
-	if(regs->regs[2] == 1000)
+	if (regs->regs[2] == 1000)
 		base = 1;
-	ctx = (struct irix5_context *) regs->regs[base + 4];
+	ctx = (struct irix5_context __user *) regs->regs[base + 4];
 
 #ifdef DEBUG_SIG
 	printk("[%s:%d] irix_setcontext(%p)\n",
 	       current->comm, current->pid, ctx);
 #endif
 
-	if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) {
-		error = -EFAULT;
-		goto out;
-	}
+	if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)))
+		goto segv_and_exit;
 
-	if (ctx->flags & 0x02) {
+	err = __get_user(flags, &ctx->flags);
+	if (flags & 0x02) {
 		/* XXX sigstack garbage, todo... */
 		printk("Wheee, cannot do sigstack stuff in setcontext\n");
 	}
 
-	if (ctx->flags & 0x04) {
+	if (flags & 0x04) {
 		int i;
 
 		/* XXX extra control block stuff... todo... */
-		for(i = 1; i < 32; i++)
-			regs->regs[i] = ctx->regs[i];
-		regs->lo = ctx->regs[32];
-		regs->hi = ctx->regs[33];
-		regs->cp0_epc = ctx->regs[35];
+		for (i = 1; i < 32; i++)
+			err |= __get_user(regs->regs[i], &ctx->regs[i]);
+		err |= __get_user(regs->lo, &ctx->regs[32]);
+		err |= __get_user(regs->hi, &ctx->regs[33]);
+		err |= __get_user(regs->cp0_epc, &ctx->regs[35]);
 	}
 
-	if (ctx->flags & 0x08) {
+	if (flags & 0x08)
 		/* XXX fpu context, blah... */
-		printk("Wheee, cannot restore FPU context yet...\n");
-	}
-	current->thread.irix_oldctx = ctx->link;
-	error = regs->regs[2];
+		printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n");
 
-out:
-	return error;
+	err |= __get_user(current->thread.irix_oldctx, &ctx->link);
+	if (err)
+		goto segv_and_exit;
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
+		do_syscall_trace(regs, 1);
+	__asm__ __volatile__(
+		"move\t$29,%0\n\t"
+		"j\tsyscall_exit"
+		:/* no outputs */
+		:"r" (&regs));
+		/* Unreached */
+
+segv_and_exit:
+	force_sigsegv(SIGSEGV, current);
 }
 
-struct irix_sigstack { unsigned long sp; int status; };
+struct irix_sigstack {
+	unsigned long sp;
+	int status;
+};
 
-asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old)
+asmlinkage int irix_sigstack(struct irix_sigstack __user *new,
+	struct irix_sigstack __user *old)
 {
-	int error = -EFAULT;
-
 #ifdef DEBUG_SIG
 	printk("[%s:%d] irix_sigstack(%p,%p)\n",
 	       current->comm, current->pid, new, old);
 #endif
-	if(new) {
+	if (new) {
 		if (!access_ok(VERIFY_READ, new, sizeof(*new)))
-			goto out;
+			return -EFAULT;
 	}
 
-	if(old) {
+	if (old) {
 		if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
-			goto out;
+			return -EFAULT;
 	}
-	error = 0;
 
-out:
-	return error;
+	return 0;
 }
 
 struct irix_sigaltstack { unsigned long sp; int size; int status; };
 
-asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new,
-				struct irix_sigaltstack *old)
+asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new,
+				struct irix_sigaltstack __user *old)
 {
-	int error = -EFAULT;
-
 #ifdef DEBUG_SIG
 	printk("[%s:%d] irix_sigaltstack(%p,%p)\n",
 	       current->comm, current->pid, new, old);
 #endif
-	if (new) {
+	if (new)
 		if (!access_ok(VERIFY_READ, new, sizeof(*new)))
-			goto out;
-	}
+			return -EFAULT;
 
 	if (old) {
 		if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
-			goto out;
+			return -EFAULT;
 	}
-	error = 0;
-
-out:
-	error = 0;
 
-	return error;
+	return 0;
 }
 
 struct irix_procset {
 	int cmd, ltype, lid, rtype, rid;
 };
 
-asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig)
+asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig)
 {
 	if (!access_ok(VERIFY_READ, pset, sizeof(*pset)))
 		return -EFAULT;
-
 #ifdef DEBUG_SIG
 	printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n",
 	       current->comm, current->pid,
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index f99efce556e..5223c4450e4 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -38,14 +38,6 @@
 #include <asm/isadep.h>
 #include <asm/inst.h>
 
-/*
- * We use this if we don't have any better idle routine..
- * (This to kill: kernel/platform.c.
- */
-void default_idle (void)
-{
-}
-
 /*
  * The idle thread. There's no useful work to be done, so just try to conserve
  * power and have a low exit latency (ie sit in a loop waiting for somebody to
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 0b571a5b4b8..2c7fc7472fb 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -103,7 +103,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
 		ret = -EIO;
 		if (copied != sizeof(tmp))
 			break;
-		ret = put_user(tmp,(unsigned long *) data);
+		ret = put_user(tmp,(unsigned long __user *) data);
 		break;
 	}
 
@@ -180,7 +180,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
 			ret = -EIO;
 			goto out_tsk;
 		}
-		ret = put_user(tmp, (unsigned long *) data);
+		ret = put_user(tmp, (unsigned long __user *) data);
 		break;
 	}
 
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 0209c1dd142..eb127230cc9 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -47,9 +47,10 @@ save_static_function(sys_sigsuspend);
 __attribute_used__ noinline static int
 _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-	sigset_t *uset, saveset, newset;
+	sigset_t saveset, newset;
+	sigset_t __user *uset;
 
-	uset = (sigset_t *) regs.regs[4];
+	uset = (sigset_t __user *) regs.regs[4];
 	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -75,7 +76,8 @@ save_static_function(sys_rt_sigsuspend);
 __attribute_used__ noinline static int
 _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-	sigset_t *unewset, saveset, newset;
+	sigset_t saveset, newset;
+	sigset_t __user *unewset;
 	size_t sigsetsize;
 
 	/* XXX Don't preclude handling different sized sigset_t's.  */
@@ -83,7 +85,7 @@ _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 	if (sigsetsize != sizeof(sigset_t))
 		return -EINVAL;
 
-	unewset = (sigset_t *) regs.regs[4];
+	unewset = (sigset_t __user *) regs.regs[4];
 	if (copy_from_user(&newset, unewset, sizeof(newset)))
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -147,8 +149,8 @@ asmlinkage int sys_sigaction(int sig, const struct sigaction *act,
 
 asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
 {
-	const stack_t *uss = (const stack_t *) regs.regs[4];
-	stack_t *uoss = (stack_t *) regs.regs[5];
+	const stack_t __user *uss = (const stack_t __user *) regs.regs[4];
+	stack_t __user *uoss = (stack_t __user *) regs.regs[5];
 	unsigned long usp = regs.regs[29];
 
 	return do_sigaltstack(uss, uoss, usp);
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index ed7c0e3c2f8..52924f8ce23 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -233,7 +233,7 @@ asmlinkage int irix_prctl(unsigned option, ...)
 
 #undef DEBUG_PROCGRPS
 
-extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
+extern unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt);
 extern int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
 extern char *prom_getenv(char *name);
 extern long prom_setenv(char *name, char *value);
@@ -270,23 +270,19 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
 	cmd = regs->regs[base + 4];
 	switch(cmd) {
 	case SGI_SYSID: {
-		char *buf = (char *) regs->regs[base + 5];
+		char __user *buf = (char __user *) regs->regs[base + 5];
 
 		/* XXX Use ethernet addr.... */
-		retval = clear_user(buf, 64);
+		retval = clear_user(buf, 64) ? -EFAULT : 0;
 		break;
 	}
 #if 0
 	case SGI_RDNAME: {
 		int pid = (int) regs->regs[base + 5];
-		char *buf = (char *) regs->regs[base + 6];
+		char __user *buf = (char __user *) regs->regs[base + 6];
 		struct task_struct *p;
 		char tcomm[sizeof(current->comm)];
 
-		if (!access_ok(VERIFY_WRITE, buf, sizeof(tcomm))) {
-			retval = -EFAULT;
-			break;
-		}
 		read_lock(&tasklist_lock);
 		p = find_task_by_pid(pid);
 		if (!p) {
@@ -298,34 +294,28 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
 		read_unlock(&tasklist_lock);
 
 		/* XXX Need to check sizes. */
-		copy_to_user(buf, tcomm, sizeof(tcomm));
-		retval = 0;
+		retval = copy_to_user(buf, tcomm, sizeof(tcomm)) ? -EFAULT : 0;
 		break;
 	}
 
 	case SGI_GETNVRAM: {
-		char *name = (char *) regs->regs[base+5];
-		char *buf = (char *) regs->regs[base+6];
+		char __user *name = (char __user *) regs->regs[base+5];
+		char __user *buf = (char __user *) regs->regs[base+6];
 		char *value;
 		return -EINVAL;	/* til I fix it */
-		if (!access_ok(VERIFY_WRITE, buf, 128)) {
-			retval = -EFAULT;
-			break;
-		}
 		value = prom_getenv(name);	/* PROM lock?  */
 		if (!value) {
 			retval = -EINVAL;
 			break;
 		}
 		/* Do I strlen() for the length? */
-		copy_to_user(buf, value, 128);
-		retval = 0;
+		retval = copy_to_user(buf, value, 128) ? -EFAULT : 0;
 		break;
 	}
 
 	case SGI_SETNVRAM: {
-		char *name = (char *) regs->regs[base+5];
-		char *value = (char *) regs->regs[base+6];
+		char __user *name = (char __user *) regs->regs[base+5];
+		char __user *value = (char __user *) regs->regs[base+6];
 		return -EINVAL;	/* til I fix it */
 		retval = prom_setenv(name, value);
 		/* XXX make sure retval conforms to syssgi(2) */
@@ -401,16 +391,16 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
 
 	case SGI_SETGROUPS:
 		retval = sys_setgroups((int) regs->regs[base + 5],
-		                       (gid_t *) regs->regs[base + 6]);
+		                       (gid_t __user *) regs->regs[base + 6]);
 		break;
 
 	case SGI_GETGROUPS:
 		retval = sys_getgroups((int) regs->regs[base + 5],
-		                       (gid_t *) regs->regs[base + 6]);
+		                       (gid_t __user *) regs->regs[base + 6]);
 		break;
 
 	case SGI_RUSAGE: {
-		struct rusage *ru = (struct rusage *) regs->regs[base + 6];
+		struct rusage __user *ru = (struct rusage __user *) regs->regs[base + 6];
 
 		switch((int) regs->regs[base + 5]) {
 		case 0:
@@ -447,7 +437,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
 
 	case SGI_ELFMAP:
 		retval = irix_mapelf((int) regs->regs[base + 5],
-				     (struct elf_phdr *) regs->regs[base + 6],
+				     (struct elf_phdr __user *) regs->regs[base + 6],
 				     (int) regs->regs[base + 7]);
 		break;
 
@@ -462,24 +452,24 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
 
 	case SGI_PHYSP: {
 		unsigned long addr = regs->regs[base + 5];
-		int *pageno = (int *) (regs->regs[base + 6]);
+		int __user *pageno = (int __user *) (regs->regs[base + 6]);
 		struct mm_struct *mm = current->mm;
 		pgd_t *pgdp;
+		pud_t *pudp;
 		pmd_t *pmdp;
 		pte_t *ptep;
 
-		if (!access_ok(VERIFY_WRITE, pageno, sizeof(int)))
-			return -EFAULT;
-
 		down_read(&mm->mmap_sem);
 		pgdp = pgd_offset(mm, addr);
-		pmdp = pmd_offset(pgdp, addr);
+		pudp = pud_offset(pgdp, addr);
+		pmdp = pmd_offset(pudp, addr);
 		ptep = pte_offset(pmdp, addr);
 		retval = -EINVAL;
 		if (ptep) {
 			pte_t pte = *ptep;
 
 			if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) {
+				/* b0rked on 64-bit */
 				retval =  put_user((pte_val(pte) & PAGE_MASK) >>
 				                   PAGE_SHIFT, pageno);
 			}
@@ -490,7 +480,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
 
 	case SGI_INVENT: {
 		int  arg1    = (int)    regs->regs [base + 5];
-		void *buffer = (void *) regs->regs [base + 6];
+		void __user *buffer = (void __user *) regs->regs [base + 6];
 		int  count   = (int)    regs->regs [base + 7];
 
 		switch (arg1) {
@@ -686,8 +676,8 @@ asmlinkage int irix_pause(void)
 }
 
 /* XXX need more than this... */
-asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
-			  char *type, void *data, int datalen)
+asmlinkage int irix_mount(char __user *dev_name, char __user *dir_name,
+	unsigned long flags, char __user *type, void __user *data, int datalen)
 {
 	printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
 	       current->comm, current->pid,
@@ -702,8 +692,8 @@ struct irix_statfs {
 	char  f_fname[6], f_fpack[6];
 };
 
-asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
-			   int len, int fs_type)
+asmlinkage int irix_statfs(const char __user *path,
+	struct irix_statfs __user *buf, int len, int fs_type)
 {
 	struct nameidata nd;
 	struct kstatfs kbuf;
@@ -718,6 +708,7 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
 		error = -EFAULT;
 		goto out;
 	}
+
 	error = user_path_walk(path, &nd);
 	if (error)
 		goto out;
@@ -726,18 +717,17 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
 	if (error)
 		goto dput_and_out;
 
-	__put_user(kbuf.f_type, &buf->f_type);
-	__put_user(kbuf.f_bsize, &buf->f_bsize);
-	__put_user(kbuf.f_frsize, &buf->f_frsize);
-	__put_user(kbuf.f_blocks, &buf->f_blocks);
-	__put_user(kbuf.f_bfree, &buf->f_bfree);
-	__put_user(kbuf.f_files, &buf->f_files);
-	__put_user(kbuf.f_ffree, &buf->f_ffree);
+	error = __put_user(kbuf.f_type, &buf->f_type);
+	error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
+	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+	error |= __put_user(kbuf.f_files, &buf->f_files);
+	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
 	for (i = 0; i < 6; i++) {
-		__put_user(0, &buf->f_fname[i]);
-		__put_user(0, &buf->f_fpack[i]);
+		error |= __put_user(0, &buf->f_fname[i]);
+		error |= __put_user(0, &buf->f_fpack[i]);
 	}
-	error = 0;
 
 dput_and_out:
 	path_release(&nd);
@@ -745,7 +735,7 @@ out:
 	return error;
 }
 
-asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
+asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf)
 {
 	struct kstatfs kbuf;
 	struct file *file;
@@ -755,6 +745,7 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
 		error = -EFAULT;
 		goto out;
 	}
+
 	if (!(file = fget(fd))) {
 		error = -EBADF;
 		goto out;
@@ -764,16 +755,17 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
 	if (error)
 		goto out_f;
 
-	__put_user(kbuf.f_type, &buf->f_type);
-	__put_user(kbuf.f_bsize, &buf->f_bsize);
-	__put_user(kbuf.f_frsize, &buf->f_frsize);
-	__put_user(kbuf.f_blocks, &buf->f_blocks);
-	__put_user(kbuf.f_bfree, &buf->f_bfree);
-	__put_user(kbuf.f_files, &buf->f_files);
-	__put_user(kbuf.f_ffree, &buf->f_ffree);
-	for(i = 0; i < 6; i++) {
-		__put_user(0, &buf->f_fname[i]);
-		__put_user(0, &buf->f_fpack[i]);
+	error = __put_user(kbuf.f_type, &buf->f_type);
+	error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
+	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+	error |= __put_user(kbuf.f_files, &buf->f_files);
+	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+
+	for (i = 0; i < 6; i++) {
+		error |= __put_user(0, &buf->f_fname[i]);
+		error |= __put_user(0, &buf->f_fpack[i]);
 	}
 
 out_f:
@@ -800,14 +792,15 @@ asmlinkage int irix_setpgrp(int flags)
 	return error;
 }
 
-asmlinkage int irix_times(struct tms * tbuf)
+asmlinkage int irix_times(struct tms __user *tbuf)
 {
 	int err = 0;
 
 	if (tbuf) {
 		if (!access_ok(VERIFY_WRITE,tbuf,sizeof *tbuf))
 			return -EFAULT;
-		err |= __put_user(current->utime, &tbuf->tms_utime);
+
+		err = __put_user(current->utime, &tbuf->tms_utime);
 		err |= __put_user(current->stime, &tbuf->tms_stime);
 		err |= __put_user(current->signal->cutime, &tbuf->tms_cutime);
 		err |= __put_user(current->signal->cstime, &tbuf->tms_cstime);
@@ -823,13 +816,13 @@ asmlinkage int irix_exec(struct pt_regs *regs)
 
 	if(regs->regs[2] == 1000)
 		base = 1;
-	filename = getname((char *) (long)regs->regs[base + 4]);
+	filename = getname((char __user *) (long)regs->regs[base + 4]);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
 		return error;
 
-	error = do_execve(filename, (char **) (long)regs->regs[base + 5],
-	                  (char **) 0, regs);
+	error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
+	                  NULL, regs);
 	putname(filename);
 
 	return error;
@@ -842,12 +835,12 @@ asmlinkage int irix_exece(struct pt_regs *regs)
 
 	if (regs->regs[2] == 1000)
 		base = 1;
-	filename = getname((char *) (long)regs->regs[base + 4]);
+	filename = getname((char __user *) (long)regs->regs[base + 4]);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
 		return error;
-	error = do_execve(filename, (char **) (long)regs->regs[base + 5],
-	                  (char **) (long)regs->regs[base + 6], regs);
+	error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
+	                  (char __user * __user *) (long)regs->regs[base + 6], regs);
 	putname(filename);
 
 	return error;
@@ -903,22 +896,17 @@ asmlinkage int irix_socket(int family, int type, int protocol)
 	return sys_socket(family, type, protocol);
 }
 
-asmlinkage int irix_getdomainname(char *name, int len)
+asmlinkage int irix_getdomainname(char __user *name, int len)
 {
-	int error;
-
-	if (!access_ok(VERIFY_WRITE, name, len))
-		return -EFAULT;
+	int err;
 
 	down_read(&uts_sem);
 	if (len > __NEW_UTS_LEN)
 		len = __NEW_UTS_LEN;
-	error = 0;
-	if (copy_to_user(name, system_utsname.domainname, len))
-		error = -EFAULT;
+	err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0;
 	up_read(&uts_sem);
 
-	return error;
+	return err;
 }
 
 asmlinkage unsigned long irix_getpagesize(void)
@@ -934,12 +922,13 @@ asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,
 	case 0:
 		return sys_msgget((key_t) arg0, (int) arg1);
 	case 1:
-		return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds *)arg2);
+		return sys_msgctl((int) arg0, (int) arg1,
+		                  (struct msqid_ds __user *)arg2);
 	case 2:
-		return sys_msgrcv((int) arg0, (struct msgbuf *) arg1,
+		return sys_msgrcv((int) arg0, (struct msgbuf __user *) arg1,
 				  (size_t) arg2, (long) arg3, (int) arg4);
 	case 3:
-		return sys_msgsnd((int) arg0, (struct msgbuf *) arg1,
+		return sys_msgsnd((int) arg0, (struct msgbuf __user *) arg1,
 				  (size_t) arg2, (int) arg3);
 	default:
 		return -EINVAL;
@@ -951,12 +940,13 @@ asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,
 {
 	switch (opcode) {
 	case 0:
-		return do_shmat((int) arg0, (char *)arg1, (int) arg2,
+		return do_shmat((int) arg0, (char __user *) arg1, (int) arg2,
 				 (unsigned long *) arg3);
 	case 1:
-		return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds *)arg2);
+		return sys_shmctl((int)arg0, (int)arg1,
+		                  (struct shmid_ds __user *)arg2);
 	case 2:
-		return sys_shmdt((char *)arg0);
+		return sys_shmdt((char __user *)arg0);
 	case 3:
 		return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
 	default:
@@ -974,7 +964,7 @@ asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,
 	case 1:
 		return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
 	case 2:
-		return sys_semop((int) arg0, (struct sembuf *)arg1,
+		return sys_semop((int) arg0, (struct sembuf __user *)arg1,
 				 (unsigned int) arg2);
 	default:
 		return -EINVAL;
@@ -992,15 +982,16 @@ static inline loff_t llseek(struct file *file, loff_t offset, int origin)
 	lock_kernel();
 	retval = fn(file, offset, origin);
 	unlock_kernel();
+
 	return retval;
 }
 
 asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,
                             int origin)
 {
-	int retval;
 	struct file * file;
 	loff_t offset;
+	int retval;
 
 	retval = -EBADF;
 	file = fget(fd);
@@ -1025,12 +1016,12 @@ asmlinkage int irix_sginap(int ticks)
 	return 0;
 }
 
-asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)
+asmlinkage int irix_sgikopt(char __user *istring, char __user *ostring, int len)
 {
 	return -EINVAL;
 }
 
-asmlinkage int irix_gettimeofday(struct timeval *tv)
+asmlinkage int irix_gettimeofday(struct timeval __user *tv)
 {
 	time_t sec;
 	long nsec, seq;
@@ -1071,7 +1062,7 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
 
 			if (max_size > file->f_dentry->d_inode->i_size) {
 				old_pos = sys_lseek (fd, max_size - 1, 0);
-				sys_write (fd, "", 1);
+				sys_write (fd, (void __user *) "", 1);
 				sys_lseek (fd, old_pos, 0);
 			}
 		}
@@ -1096,7 +1087,7 @@ asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
 	return -EINVAL;
 }
 
-asmlinkage int irix_pagelock(char *addr, int len, int op)
+asmlinkage int irix_pagelock(char __user *addr, int len, int op)
 {
 	printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
 	       current->comm, current->pid, addr, len, op);
@@ -1136,7 +1127,7 @@ asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
 	return error;
 }
 
-asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
+asmlinkage int irix_systeminfo(int cmd, char __user *buf, int cnt)
 {
 	printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
 	       current->comm, current->pid, cmd, buf, cnt);
@@ -1152,14 +1143,14 @@ struct iuname {
 	char _unused3[257], _unused4[257], _unused5[257];
 };
 
-asmlinkage int irix_uname(struct iuname *buf)
+asmlinkage int irix_uname(struct iuname __user *buf)
 {
 	down_read(&uts_sem);
-	if (copy_to_user(system_utsname.sysname, buf->sysname, 65)
-	    || copy_to_user(system_utsname.nodename, buf->nodename, 65)
-	    || copy_to_user(system_utsname.release, buf->release, 65)
-	    || copy_to_user(system_utsname.version, buf->version, 65)
-	    || copy_to_user(system_utsname.machine, buf->machine, 65)) {
+	if (copy_from_user(system_utsname.sysname, buf->sysname, 65)
+	    || copy_from_user(system_utsname.nodename, buf->nodename, 65)
+	    || copy_from_user(system_utsname.release, buf->release, 65)
+	    || copy_from_user(system_utsname.version, buf->version, 65)
+	    || copy_from_user(system_utsname.machine, buf->machine, 65)) {
 		return -EFAULT;
 	}
 	up_read(&uts_sem);
@@ -1169,7 +1160,7 @@ asmlinkage int irix_uname(struct iuname *buf)
 
 #undef DEBUG_XSTAT
 
-static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
+static int irix_xstat32_xlate(struct kstat *stat, void __user *ubuf)
 {
 	struct xstat32 {
 		u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
@@ -1209,7 +1200,7 @@ static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
 	return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
 }
 
-static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
+static int irix_xstat64_xlate(struct kstat *stat, void __user *ubuf)
 {
 	struct xstat64 {
 		u32 st_dev; s32 st_pad1[3];
@@ -1259,7 +1250,7 @@ static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
 	return copy_to_user(ubuf, &ks, sizeof(ks)) ? -EFAULT : 0;
 }
 
-asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
+asmlinkage int irix_xstat(int version, char __user *filename, struct stat __user *statbuf)
 {
 	int retval;
 	struct kstat stat;
@@ -1285,7 +1276,7 @@ asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
 	return retval;
 }
 
-asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
+asmlinkage int irix_lxstat(int version, char __user *filename, struct stat __user *statbuf)
 {
 	int error;
 	struct kstat stat;
@@ -1312,7 +1303,7 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
 	return error;
 }
 
-asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
+asmlinkage int irix_fxstat(int version, int fd, struct stat __user *statbuf)
 {
 	int error;
 	struct kstat stat;
@@ -1338,7 +1329,7 @@ asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
 	return error;
 }
 
-asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
+asmlinkage int irix_xmknod(int ver, char __user *filename, int mode, unsigned dev)
 {
 	int retval;
 	printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
@@ -1358,7 +1349,7 @@ asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
 	return retval;
 }
 
-asmlinkage int irix_swapctl(int cmd, char *arg)
+asmlinkage int irix_swapctl(int cmd, char __user *arg)
 {
 	printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
 	       current->comm, current->pid, cmd, arg);
@@ -1374,7 +1365,7 @@ struct irix_statvfs {
 	char	f_fstr[32]; u32 f_filler[16];
 };
 
-asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
+asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf)
 {
 	struct nameidata nd;
 	struct kstatfs kbuf;
@@ -1382,10 +1373,9 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
 
 	printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
 	       current->comm, current->pid, fname, buf);
-	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
-		error = -EFAULT;
-		goto out;
-	}
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
+		return -EFAULT;
+
 	error = user_path_walk(fname, &nd);
 	if (error)
 		goto out;
@@ -1393,27 +1383,25 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
 	if (error)
 		goto dput_and_out;
 
-	__put_user(kbuf.f_bsize, &buf->f_bsize);
-	__put_user(kbuf.f_frsize, &buf->f_frsize);
-	__put_user(kbuf.f_blocks, &buf->f_blocks);
-	__put_user(kbuf.f_bfree, &buf->f_bfree);
-	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
-	__put_user(kbuf.f_files, &buf->f_files);
-	__put_user(kbuf.f_ffree, &buf->f_ffree);
-	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
+	error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
+	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
+	error |= __put_user(kbuf.f_files, &buf->f_files);
+	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+	error |= __put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
 #ifdef __MIPSEB__
-	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
 #else
-	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
 #endif
 	for (i = 0; i < 16; i++)
-		__put_user(0, &buf->f_basetype[i]);
-	__put_user(0, &buf->f_flag);
-	__put_user(kbuf.f_namelen, &buf->f_namemax);
+		error |= __put_user(0, &buf->f_basetype[i]);
+	error |= __put_user(0, &buf->f_flag);
+	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
 	for (i = 0; i < 32; i++)
-		__put_user(0, &buf->f_fstr[i]);
-
-	error = 0;
+		error |= __put_user(0, &buf->f_fstr[i]);
 
 dput_and_out:
 	path_release(&nd);
@@ -1421,7 +1409,7 @@ out:
 	return error;
 }
 
-asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
+asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf)
 {
 	struct kstatfs kbuf;
 	struct file *file;
@@ -1430,10 +1418,9 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
 	printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
 	       current->comm, current->pid, fd, buf);
 
-	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
-		error = -EFAULT;
-		goto out;
-	}
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
+		return -EFAULT;
+
 	if (!(file = fget(fd))) {
 		error = -EBADF;
 		goto out;
@@ -1442,24 +1429,24 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
 	if (error)
 		goto out_f;
 
-	__put_user(kbuf.f_bsize, &buf->f_bsize);
-	__put_user(kbuf.f_frsize, &buf->f_frsize);
-	__put_user(kbuf.f_blocks, &buf->f_blocks);
-	__put_user(kbuf.f_bfree, &buf->f_bfree);
-	__put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
-	__put_user(kbuf.f_files, &buf->f_files);
-	__put_user(kbuf.f_ffree, &buf->f_ffree);
-	__put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+	error = __put_user(kbuf.f_bsize, &buf->f_bsize);
+	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+	error |= __put_user(kbuf.f_files, &buf->f_files);
+	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+	error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
 #ifdef __MIPSEB__
-	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
 #else
-	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
 #endif
 	for(i = 0; i < 16; i++)
-		__put_user(0, &buf->f_basetype[i]);
-	__put_user(0, &buf->f_flag);
-	__put_user(kbuf.f_namelen, &buf->f_namemax);
-	__clear_user(&buf->f_fstr, sizeof(buf->f_fstr));
+		error |= __put_user(0, &buf->f_basetype[i]);
+	error |= __put_user(0, &buf->f_flag);
+	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
+	error |= __clear_user(&buf->f_fstr, sizeof(buf->f_fstr)) ? -EFAULT : 0;
 
 out_f:
 	fput(file);
@@ -1483,7 +1470,7 @@ asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
 	return -EINVAL;
 }
 
-asmlinkage int irix_truncate64(char *name, int pad, int size1, int size2)
+asmlinkage int irix_truncate64(char __user *name, int pad, int size1, int size2)
 {
 	int retval;
 
@@ -1516,6 +1503,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
 	int len, prot, flags, fd, off1, off2, error, base = 0;
 	unsigned long addr, pgoff, *sp;
 	struct file *file = NULL;
+	int err;
 
 	if (regs->regs[2] == 1000)
 		base = 1;
@@ -1525,36 +1513,31 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
 	prot = regs->regs[base + 6];
 	if (!base) {
 		flags = regs->regs[base + 7];
-		if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long)))) {
-			error = -EFAULT;
-			goto out;
-		}
+		if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long))))
+			return -EFAULT;
 		fd = sp[0];
-		__get_user(off1, &sp[1]);
-		__get_user(off2, &sp[2]);
+		err = __get_user(off1, &sp[1]);
+		err |= __get_user(off2, &sp[2]);
 	} else {
-		if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long)))) {
-			error = -EFAULT;
-			goto out;
-		}
-		__get_user(flags, &sp[0]);
-		__get_user(fd, &sp[1]);
-		__get_user(off1, &sp[2]);
-		__get_user(off2, &sp[3]);
+		if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long))))
+			return -EFAULT;
+		err = __get_user(flags, &sp[0]);
+		err |= __get_user(fd, &sp[1]);
+		err |= __get_user(off1, &sp[2]);
+		err |= __get_user(off2, &sp[3]);
 	}
 
-	if (off1 & PAGE_MASK) {
-		error = -EOVERFLOW;
-		goto out;
-	}
+	if (err)
+		return err;
+
+	if (off1 & PAGE_MASK)
+		return -EOVERFLOW;
 
 	pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
 
 	if (!(flags & MAP_ANONYMOUS)) {
-		if (!(file = fget(fd))) {
-			error = -EBADF;
-			goto out;
-		}
+		if (!(file = fget(fd)))
+			return -EBADF;
 
 		/* Ok, bad taste hack follows, try to think in something else
 		   when reading this */
@@ -1564,7 +1547,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
 
 			if (max_size > file->f_dentry->d_inode->i_size) {
 				old_pos = sys_lseek (fd, max_size - 1, 0);
-				sys_write (fd, "", 1);
+				sys_write (fd, (void __user *) "", 1);
 				sys_lseek (fd, old_pos, 0);
 			}
 		}
@@ -1579,7 +1562,6 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
 	if (file)
 		fput(file);
 
-out:
 	return error;
 }
 
@@ -1591,7 +1573,7 @@ asmlinkage int irix_dmi(struct pt_regs *regs)
 	return -EINVAL;
 }
 
-asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
+asmlinkage int irix_pread(int fd, char __user *buf, int cnt, int off64,
 			  int off1, int off2)
 {
 	printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
@@ -1600,7 +1582,7 @@ asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
 	return -EINVAL;
 }
 
-asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
+asmlinkage int irix_pwrite(int fd, char __user *buf, int cnt, int off64,
 			   int off1, int off2)
 {
 	printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
@@ -1632,7 +1614,7 @@ struct irix_statvfs64 {
 	u32  f_filler[16];
 };
 
-asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
+asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *buf)
 {
 	struct nameidata nd;
 	struct kstatfs kbuf;
@@ -1644,6 +1626,7 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
 		error = -EFAULT;
 		goto out;
 	}
+
 	error = user_path_walk(fname, &nd);
 	if (error)
 		goto out;
@@ -1651,27 +1634,25 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
 	if (error)
 		goto dput_and_out;
 
-	__put_user(kbuf.f_bsize, &buf->f_bsize);
-	__put_user(kbuf.f_frsize, &buf->f_frsize);
-	__put_user(kbuf.f_blocks, &buf->f_blocks);
-	__put_user(kbuf.f_bfree, &buf->f_bfree);
-	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
-	__put_user(kbuf.f_files, &buf->f_files);
-	__put_user(kbuf.f_ffree, &buf->f_ffree);
-	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
+	error = __put_user(kbuf.f_bsize, &buf->f_bsize);
+	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
+	error |= __put_user(kbuf.f_files, &buf->f_files);
+	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+	error |= __put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
 #ifdef __MIPSEB__
-	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
 #else
-	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
 #endif
 	for(i = 0; i < 16; i++)
-		__put_user(0, &buf->f_basetype[i]);
-	__put_user(0, &buf->f_flag);
-	__put_user(kbuf.f_namelen, &buf->f_namemax);
+		error |= __put_user(0, &buf->f_basetype[i]);
+	error |= __put_user(0, &buf->f_flag);
+	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
 	for(i = 0; i < 32; i++)
-		__put_user(0, &buf->f_fstr[i]);
-
-	error = 0;
+		error |= __put_user(0, &buf->f_fstr[i]);
 
 dput_and_out:
 	path_release(&nd);
@@ -1679,7 +1660,7 @@ out:
 	return error;
 }
 
-asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
+asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf)
 {
 	struct kstatfs kbuf;
 	struct file *file;
@@ -1700,24 +1681,24 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
 	if (error)
 		goto out_f;
 
-	__put_user(kbuf.f_bsize, &buf->f_bsize);
-	__put_user(kbuf.f_frsize, &buf->f_frsize);
-	__put_user(kbuf.f_blocks, &buf->f_blocks);
-	__put_user(kbuf.f_bfree, &buf->f_bfree);
-	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
-	__put_user(kbuf.f_files, &buf->f_files);
-	__put_user(kbuf.f_ffree, &buf->f_ffree);
-	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
+	error = __put_user(kbuf.f_bsize, &buf->f_bsize);
+	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
+	error |= __put_user(kbuf.f_files, &buf->f_files);
+	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+	error |= __put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
 #ifdef __MIPSEB__
-	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
 #else
-	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
 #endif
 	for(i = 0; i < 16; i++)
-		__put_user(0, &buf->f_basetype[i]);
-	__put_user(0, &buf->f_flag);
-	__put_user(kbuf.f_namelen, &buf->f_namemax);
-	__clear_user(buf->f_fstr, sizeof(buf->f_fstr[i]));
+		error |= __put_user(0, &buf->f_basetype[i]);
+	error |= __put_user(0, &buf->f_flag);
+	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
+	error |= __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i])) ? -EFAULT : 0;
 
 out_f:
 	fput(file);
@@ -1725,9 +1706,9 @@ out:
 	return error;
 }
 
-asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
+asmlinkage int irix_getmountid(char __user *fname, unsigned long __user *midbuf)
 {
-	int err = 0;
+	int err;
 
 	printk("[%s:%d] irix_getmountid(%s, %p)\n",
 	       current->comm, current->pid, fname, midbuf);
@@ -1740,7 +1721,7 @@ asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
 	 * fsid of the filesystem to try and make the right decision, but
 	 * we don't have this so for now. XXX
 	 */
-	err |= __put_user(0, &midbuf[0]);
+	err = __put_user(0, &midbuf[0]);
 	err |= __put_user(0, &midbuf[1]);
 	err |= __put_user(0, &midbuf[2]);
 	err |= __put_user(0, &midbuf[3]);
@@ -1767,8 +1748,8 @@ struct irix_dirent32 {
 };
 
 struct irix_dirent32_callback {
-	struct irix_dirent32 *current_dir;
-	struct irix_dirent32 *previous;
+	struct irix_dirent32 __user *current_dir;
+	struct irix_dirent32 __user *previous;
 	int count;
 	int error;
 };
@@ -1776,13 +1757,13 @@ struct irix_dirent32_callback {
 #define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))
 #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
 
-static int irix_filldir32(void *__buf, const char *name, int namlen,
-                          loff_t offset, ino_t ino, unsigned int d_type)
+static int irix_filldir32(void *__buf, const char *name,
+	int namlen, loff_t offset, ino_t ino, unsigned int d_type)
 {
-	struct irix_dirent32 *dirent;
-	struct irix_dirent32_callback *buf =
-		 (struct irix_dirent32_callback *)__buf;
+	struct irix_dirent32 __user *dirent;
+	struct irix_dirent32_callback *buf = __buf;
 	unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
+	int err = 0;
 
 #ifdef DEBUG_GETDENTS
 	printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
@@ -1793,25 +1774,26 @@ static int irix_filldir32(void *__buf, const char *name, int namlen,
 		return -EINVAL;
 	dirent = buf->previous;
 	if (dirent)
-		__put_user(offset, &dirent->d_off);
+		err = __put_user(offset, &dirent->d_off);
 	dirent = buf->current_dir;
-	buf->previous = dirent;
-	__put_user(ino, &dirent->d_ino);
-	__put_user(reclen, &dirent->d_reclen);
-	copy_to_user(dirent->d_name, name, namlen);
-	__put_user(0, &dirent->d_name[namlen]);
-	((char *) dirent) += reclen;
+	err |= __put_user(dirent, &buf->previous);
+	err |= __put_user(ino, &dirent->d_ino);
+	err |= __put_user(reclen, &dirent->d_reclen);
+	err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;
+	err |= __put_user(0, &dirent->d_name[namlen]);
+	dirent = (struct irix_dirent32 __user *) ((char __user *) dirent + reclen);
+
 	buf->current_dir = dirent;
 	buf->count -= reclen;
 
-	return 0;
+	return err;
 }
 
-asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
-	unsigned int count, int *eob)
+asmlinkage int irix_ngetdents(unsigned int fd, void __user * dirent,
+	unsigned int count, int __user *eob)
 {
 	struct file *file;
-	struct irix_dirent32 *lastdirent;
+	struct irix_dirent32 __user *lastdirent;
 	struct irix_dirent32_callback buf;
 	int error;
 
@@ -1824,7 +1806,7 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
 	if (!file)
 		goto out;
 
-	buf.current_dir = (struct irix_dirent32 *) dirent;
+	buf.current_dir = (struct irix_dirent32 __user *) dirent;
 	buf.previous = NULL;
 	buf.count = count;
 	buf.error = 0;
@@ -1864,8 +1846,8 @@ struct irix_dirent64 {
 };
 
 struct irix_dirent64_callback {
-	struct irix_dirent64 *curr;
-	struct irix_dirent64 *previous;
+	struct irix_dirent64 __user *curr;
+	struct irix_dirent64 __user *previous;
 	int count;
 	int error;
 };
@@ -1873,37 +1855,44 @@ struct irix_dirent64_callback {
 #define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))
 #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
 
-static int irix_filldir64(void * __buf, const char * name, int namlen,
-			  loff_t offset, ino_t ino, unsigned int d_type)
+static int irix_filldir64(void *__buf, const char *name,
+	int namlen, loff_t offset, ino_t ino, unsigned int d_type)
 {
-	struct irix_dirent64 *dirent;
-	struct irix_dirent64_callback * buf =
-		(struct irix_dirent64_callback *) __buf;
+	struct irix_dirent64 __user *dirent;
+	struct irix_dirent64_callback * buf = __buf;
 	unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
+	int err = 0;
 
-	buf->error = -EINVAL;	/* only used if we fail.. */
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
+		return -EFAULT;
+
+	if (__put_user(-EINVAL, &buf->error))	/* only used if we fail.. */
+		return -EFAULT;
 	if (reclen > buf->count)
 		return -EINVAL;
 	dirent = buf->previous;
 	if (dirent)
-		__put_user(offset, &dirent->d_off);
+		err = __put_user(offset, &dirent->d_off);
 	dirent = buf->curr;
 	buf->previous = dirent;
-	__put_user(ino, &dirent->d_ino);
-	__put_user(reclen, &dirent->d_reclen);
-	__copy_to_user(dirent->d_name, name, namlen);
-	__put_user(0, &dirent->d_name[namlen]);
-	((char *) dirent) += reclen;
+	err |= __put_user(ino, &dirent->d_ino);
+	err |= __put_user(reclen, &dirent->d_reclen);
+	err |= __copy_to_user((char __user *)dir