summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/irixsig.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-03-27 04:47:53 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-03-27 04:47:53 +0000
commit36ea5120664550fae6d31f1c6f695e4f8975cb06 (patch)
tree7b985f066e6fa149027022366b9f3dd92506db24 /arch/mips/kernel/irixsig.c
parentf7f4aaffdad04eb69ab618c771df0416ad04a952 (diff)
o Speedup syscalls. Now 816ns per syscall. Yes, nanoseconds and goodbye
Pentium :-) o Little bit smarter handling of unimplemented exceptions. o Fix FPU context switches. o Fix reboot / halt. Powerdown in software still doesn't work. o Fix the fix for handling of return values of interrupted syscalls. o Handling of the Indy second level cache now works as spec'ed. Purely cosmentic, this was not causing any problems.
Diffstat (limited to 'arch/mips/kernel/irixsig.c')
-rw-r--r--arch/mips/kernel/irixsig.c59
1 files changed, 31 insertions, 28 deletions
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 88fca61f2..d0e286def 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -1,7 +1,9 @@
-/* $Id: irixsig.c,v 1.9 1998/03/17 00:59:35 ralf Exp $
+/*
* irixsig.c: WHEEE, IRIX signals! YOW, am I compatable or what?!?!
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * $Id: irixsig.c,v 1.11 1998/03/26 07:39:09 ralf Exp $
*/
#include <linux/kernel.h>
@@ -154,30 +156,27 @@ static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
}
}
-static inline void syscall_restart(unsigned long r0, unsigned long or2,
- unsigned long or7, struct pt_regs *regs,
- struct sigaction *sa)
+static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
{
- switch(r0) {
+ switch(regs->regs[0]) {
case ERESTARTNOHAND:
- no_system_call_restart:
- regs->regs[0] = regs->regs[2] = EINTR;
+ regs->regs[2] = EINTR;
break;
case ERESTARTSYS:
- if(!(sa->sa_flags & SA_RESTART))
- goto no_system_call_restart;
+ if(!(ka->sa.sa_flags & SA_RESTART)) {
+ regs->regs[2] = EINTR;
+ break;
+ }
/* fallthrough */
- case ERESTARTNOINTR:
- regs->regs[0] = regs->regs[2] = or2;
- regs->regs[7] = or7;
- regs->cp0_epc -= 8;
+ case ERESTARTNOINTR: /* Userland will reload $v0. */
+ regs->cp0_epc -= 8;
}
+
+ regs->regs[0] = 0; /* Don't deal with this again. */
}
asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
{
- unsigned long r0 = regs->regs[0];
- unsigned long r7 = regs->orig_reg7;
struct k_sigaction *ka;
siginfo_t info;
@@ -279,8 +278,8 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
}
}
- if (r0)
- syscall_restart(r0, regs->orig_reg2, r7, regs, &ka->sa);
+ if (regs->regs[0])
+ syscall_restart(regs, ka);
/* Whee! Actually deliver the signal. */
handle_signal(signr, ka, &info, oldset, regs);
return 1;
@@ -291,13 +290,12 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
* dies here!!! The li instruction, a single machine instruction,
* must directly be followed by the syscall instruction.
*/
- if (r0 &&
- (regs->regs[2] == ERESTARTNOHAND ||
- regs->regs[2] == ERESTARTSYS ||
- regs->regs[2] == ERESTARTNOINTR)) {
- regs->regs[0] = regs->regs[2] = regs->orig_reg2;
- regs->regs[7] = r7;
- regs->cp0_epc -= 8;
+ if (regs->regs[0]) {
+ if (regs->regs[2] == ERESTARTNOHAND ||
+ regs->regs[2] == ERESTARTSYS ||
+ regs->regs[2] == ERESTARTNOINTR) {
+ regs->cp0_epc -= 8;
+ }
}
return 0;
}
@@ -356,10 +354,15 @@ asmlinkage unsigned long irix_sigreturn(struct pt_regs *regs)
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
- regs->orig_reg2 = -1;
- __get_user(res, &context->regs[2]);
-
- return res;
+ /*
+ * Don't let your children do this ...
+ */
+ __asm__ __volatile__(
+ "move\t$29,%0\n\t"
+ "j\tret_from_sys_call"
+ :/* no outputs */
+ :"r" (&regs));
+ /* Unreached */
badframe:
lock_kernel();