0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/errno.h>
0012 #include <asm/asm.h>
0013 #include <asm/asmmacro.h>
0014 #include <asm/irqflags.h>
0015 #include <asm/mipsregs.h>
0016 #include <asm/regdef.h>
0017 #include <asm/stackframe.h>
0018 #include <asm/isadep.h>
0019 #include <asm/sysmips.h>
0020 #include <asm/thread_info.h>
0021 #include <asm/unistd.h>
0022 #include <asm/asm-offsets.h>
0023
0024 .align 5
0025 NESTED(handle_sys, PT_SIZE, sp)
0026 .set noat
0027 SAVE_SOME
0028 TRACE_IRQS_ON_RELOAD
0029 STI
0030 .set at
0031
0032 lw t1, PT_EPC(sp) # skip syscall on return
0033
0034 addiu t1, 4 # skip to next instruction
0035 sw t1, PT_EPC(sp)
0036
0037 sw a3, PT_R26(sp) # save a3 for syscall restarting
0038
0039
0040
0041
0042
0043
0044 lw t0, PT_R29(sp) # get old user stack pointer
0045
0046
0047
0048
0049
0050 addu t4, t0, 32
0051 bltz t4, bad_stack # -> sp is bad
0052
0053
0054
0055
0056
0057 .set push
0058 .set noreorder
0059 .set nomacro
0060
0061 load_a4: user_lw(t5, 16(t0)) # argument #5 from usp
0062 load_a5: user_lw(t6, 20(t0)) # argument #6 from usp
0063 load_a6: user_lw(t7, 24(t0)) # argument #7 from usp
0064 load_a7: user_lw(t8, 28(t0)) # argument #8 from usp
0065 loads_done:
0066
0067 sw t5, 16(sp) # argument #5 to ksp
0068 sw t6, 20(sp) # argument #6 to ksp
0069 sw t7, 24(sp) # argument #7 to ksp
0070 sw t8, 28(sp) # argument #8 to ksp
0071 .set pop
0072
0073 .section __ex_table,"a"
0074 PTR_WD load_a4, bad_stack_a4
0075 PTR_WD load_a5, bad_stack_a5
0076 PTR_WD load_a6, bad_stack_a6
0077 PTR_WD load_a7, bad_stack_a7
0078 .previous
0079
0080 lw t0, TI_FLAGS($28) # syscall tracing enabled?
0081 li t1, _TIF_WORK_SYSCALL_ENTRY
0082 and t0, t1
0083 bnez t0, syscall_trace_entry # -> yes
0084 syscall_common:
0085 subu v0, v0, __NR_O32_Linux # check syscall number
0086 sltiu t0, v0, __NR_O32_Linux_syscalls
0087 beqz t0, illegal_syscall
0088
0089 sll t0, v0, 2
0090 la t1, sys_call_table
0091 addu t1, t0
0092 lw t2, (t1) # syscall routine
0093
0094 beqz t2, illegal_syscall
0095
0096 jalr t2 # Do The Real Thing (TM)
0097
0098 li t0, -EMAXERRNO - 1 # error?
0099 sltu t0, t0, v0
0100 sw t0, PT_R7(sp) # set error flag
0101 beqz t0, 1f
0102
0103 lw t1, PT_R2(sp) # syscall number
0104 negu v0 # error
0105 sw t1, PT_R0(sp) # save it for syscall restarting
0106 1: sw v0, PT_R2(sp) # result
0107
0108 o32_syscall_exit:
0109 j syscall_exit_partial
0110
0111
0112
0113 syscall_trace_entry:
0114 SAVE_STATIC
0115 move a0, sp
0116
0117
0118
0119
0120
0121 move a1, v0
0122 subu t2, v0, __NR_O32_Linux
0123 bnez t2, 1f
0124 lw a1, PT_R4(sp)
0125
0126 1: jal syscall_trace_enter
0127
0128 bltz v0, 1f # seccomp failed? Skip syscall
0129
0130 RESTORE_STATIC
0131 lw v0, PT_R2(sp) # Restore syscall (maybe modified)
0132 lw a0, PT_R4(sp) # Restore argument registers
0133 lw a1, PT_R5(sp)
0134 lw a2, PT_R6(sp)
0135 lw a3, PT_R7(sp)
0136 j syscall_common
0137
0138 1: j syscall_exit
0139
0140
0141
0142
0143
0144
0145
0146 bad_stack:
0147 li v0, EFAULT
0148 sw v0, PT_R2(sp)
0149 li t0, 1 # set error flag
0150 sw t0, PT_R7(sp)
0151 j o32_syscall_exit
0152
0153 bad_stack_a4:
0154 li t5, 0
0155 b load_a5
0156
0157 bad_stack_a5:
0158 li t6, 0
0159 b load_a6
0160
0161 bad_stack_a6:
0162 li t7, 0
0163 b load_a7
0164
0165 bad_stack_a7:
0166 li t8, 0
0167 b loads_done
0168
0169
0170
0171
0172 illegal_syscall:
0173 li v0, ENOSYS # error
0174 sw v0, PT_R2(sp)
0175 li t0, 1 # set error flag
0176 sw t0, PT_R7(sp)
0177 j o32_syscall_exit
0178 END(handle_sys)
0179
0180 LEAF(sys_syscall)
0181 subu t0, a0, __NR_O32_Linux # check syscall number
0182 sltiu v0, t0, __NR_O32_Linux_syscalls
0183 beqz t0, einval # do not recurse
0184 sll t1, t0, 2
0185 beqz v0, einval
0186 lw t2, sys_call_table(t1) # syscall routine
0187
0188 move a0, a1 # shift argument registers
0189 move a1, a2
0190 move a2, a3
0191 lw a3, 16(sp)
0192 lw t4, 20(sp)
0193 lw t5, 24(sp)
0194 lw t6, 28(sp)
0195 sw t4, 16(sp)
0196 sw t5, 20(sp)
0197 sw t6, 24(sp)
0198 jr t2
0199
0200
0201 einval: li v0, -ENOSYS
0202 jr ra
0203 END(sys_syscall)
0204
0205 #ifdef CONFIG_MIPS_MT_FPAFF
0206
0207
0208
0209
0210
0211
0212
0213 #define sys_sched_setaffinity mipsmt_sys_sched_setaffinity
0214 #define sys_sched_getaffinity mipsmt_sys_sched_getaffinity
0215 #endif
0216
0217 #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
0218 #define __SYSCALL(nr, entry) PTR_WD entry
0219 .align 2
0220 .type sys_call_table, @object
0221 EXPORT(sys_call_table)
0222 #include <asm/syscall_table_o32.h>