diff options
Diffstat (limited to 'arch/mips/kernel/scall_o32.S')
-rw-r--r-- | arch/mips/kernel/scall_o32.S | 98 |
1 files changed, 60 insertions, 38 deletions
diff --git a/arch/mips/kernel/scall_o32.S b/arch/mips/kernel/scall_o32.S index eb25c34e5..6c46dedda 100644 --- a/arch/mips/kernel/scall_o32.S +++ b/arch/mips/kernel/scall_o32.S @@ -1,9 +1,13 @@ /* - * Handle ABI O32 style syscalls. + * arch/mips/kernel/scall_o32.S + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * * Copyright (C) 1997, 1998 by Ralf Baechle * - * $Id: scall_o32.S,v 1.1 1998/03/12 19:06:20 ralf Exp $ + * $Id: scall_o32.S,v 1.3 1998/03/26 07:39:10 ralf Exp $ */ #include <asm/asm.h> #include <linux/errno.h> @@ -25,18 +29,11 @@ .align 5 NESTED(handle_sys, PT_SIZE, sp) .set noat - SAVE_ALL + SAVE_SOME STI .set at - /* - * By convention "li v0,<syscallno>" is always preceeding - * the syscall instruction. So if we're in a delay slot - * userland is screwed up. - */ - lw t0, PT_CAUSE(sp) # delay slot? lw t1, PT_EPC(sp) # skip syscall on return - bltz t0, sigill_and_out sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number addiu t1, 4 # skip to next instruction @@ -45,18 +42,19 @@ NESTED(handle_sys, PT_SIZE, sp) /* XXX Put both in one cacheline, should save a bit. */ sll t0, v0, 2 - lw s0, sys_call_table(t0) # syscall routine - lbu s1, sys_narg_table(v0) # number of arguments - beqz s0, illegal_syscall; + lw t2, sys_call_table(t0) # syscall routine + lbu t3, sys_narg_table(v0) # number of arguments + beqz t2, illegal_syscall; - subu t0, s1, 5 # 5 or more arguments? - bgezal t0, stackargs + subu t0, t3, 5 # 5 or more arguments? + bgez t0, stackargs - lw s3, TASK_FLAGS($28) # syscall tracing enabled? - andi s3, PF_TRACESYS - bnez s3, trace_a_syscall +stack_done: + lw t0, TASK_FLAGS($28) # syscall tracing enabled? + andi t0, PF_TRACESYS + bnez t0, trace_a_syscall - jalr s0 # Do The Real Thing (TM) + jalr t2 # Do The Real Thing (TM) li t0, -EMAXERRNO - 1 # error? sltu t0, t0, v0 @@ -66,14 +64,49 @@ NESTED(handle_sys, PT_SIZE, sp) negu v0 # error sw v0, PT_R0(sp) # set flag for syscall restarting 1: sw v0, PT_R2(sp) # result - j ret_from_sys_call + +EXPORT(o32_ret_from_sys_call) + lw t0,bh_mask + lw t1,bh_active # unused delay slot + and t0,t1 + bnez t0,o32_handle_bottom_half + +9: lw t0,PT_STATUS(sp) # returning to kernel mode? + andi t1, t0, 0x10 + lw t2, need_resched + beqz t1, o32_return # -> yes + bnez t2, o32_reschedule + lw v0, TASK_SIGPENDING($28) + move a0, zero + beqz v0, o32_return + move a1, sp + SAVE_STATIC + jal do_signal + +o32_return: + RESTORE_SOME + RESTORE_SP + .set mips3 + eret + .set mips0 + +o32_handle_bottom_half: + jal do_bottom_half + b 9b +o32_reschedule: + SAVE_STATIC + jal schedule + b o32_ret_from_sys_call /* ------------------------------------------------------------------------ */ trace_a_syscall: + SAVE_STATIC + sw t2,PT_R1(sp) jal syscall_trace + sw t2,PT_R1(sp) - jalr s0 # Do The Real Thing (TM) + jalr t2 # Do The Real Thing (TM) li t0, -EMAXERRNO - 1 # error? sltu t0, t0, v0 @@ -95,20 +128,18 @@ trace_a_syscall: * This Sucks (TM). */ stackargs: - move s3, ra # save return address - lw t0, PT_R29(sp) # get old user stack pointer - subu s2, s1, 4 - sll t1, s2, 2 # stack valid? + subu t3, 4 + sll t1, t3, 2 # stack valid? addu t1, t0 # end address - or t2, t0, t1 + or t0, t1 bltz t0, bad_stack # -> sp is bad lw t0, PT_R29(sp) # get old user stack pointer la t1, 3f # copy 1 to 2 arguments - sll s2, s2, 3 - subu t1, s2 + sll t3, t3, 3 + subu t1, t3 jr t1 /* Ok, copy the args from the luser stack to the kernel stack */ @@ -117,7 +148,7 @@ stackargs: 2: lw t1, 16(t0) # argument #5 from usp sw t1, 16(sp) -3: jr s3 # go back +3: j stack_done # go back .section __ex_table,"a" PTR 1b,bad_stack @@ -144,12 +175,3 @@ illegal_syscall: li t0, 1 # set error flag sw t0, PT_R7(sp) j ret_from_sys_call - -sigill_and_out: - li t0, -1 # not a sys call - REG_S t0, PT_OR2(sp) - li a0, SIGILL - move a2, $28 - jal force_sig - j ret_from_sys_call - END(handle_sys) |