1 /* 2 * This file is subject to the terms and condi 3 * License. See the file "COPYING" in the mai 4 * for more details. 5 * 6 * Copyright (C) 1995-99, 2000- 02, 06 Ralf Ba< 7 * Copyright (C) 2001 MIPS Technologies, Inc. 8 * Copyright (C) 2004 Thiemo Seufer 9 * Copyright (C) 2014 Imagination Technologies 10 */ 11 #include <linux/errno.h> 12 #include <asm/asm.h> 13 #include <asm/asmmacro.h> 14 #include <asm/irqflags.h> 15 #include <asm/mipsregs.h> 16 #include <asm/regdef.h> 17 #include <asm/stackframe.h> 18 #include <asm/isadep.h> 19 #include <asm/sysmips.h> 20 #include <asm/thread_info.h> 21 #include <asm/unistd.h> 22 #include <asm/asm-offsets.h> 23 24 .align 5 25 NESTED(handle_sys, PT_SIZE, sp) 26 .set noat 27 SAVE_SOME 28 TRACE_IRQS_ON_RELOAD 29 STI 30 .set at 31 32 lw t1, PT_EPC(sp) # skip 33 34 addiu t1, 4 # skip 35 sw t1, PT_EPC(sp) 36 37 sw a3, PT_R26(sp) # save 38 39 /* 40 * More than four arguments. Try to d 41 * stack arguments from the user stack 42 * This Sucks (TM). 43 */ 44 lw t0, PT_R29(sp) # get 45 46 /* 47 * We intentionally keep the kernel st 48 * userspace so we don't have to do a 49 */ 50 addu t4, t0, 32 51 bltz t4, bad_stack # -> s 52 53 /* 54 * Ok, copy the args from the luser st 55 */ 56 57 .set push 58 .set noreorder 59 .set nomacro 60 61 load_a4: user_lw(t5, 16(t0)) # argu 62 load_a5: user_lw(t6, 20(t0)) # argu 63 load_a6: user_lw(t7, 24(t0)) # argu 64 load_a7: user_lw(t8, 28(t0)) # argu 65 loads_done: 66 67 sw t5, 16(sp) # argu 68 sw t6, 20(sp) # argu 69 sw t7, 24(sp) # argu 70 sw t8, 28(sp) # argu 71 .set pop 72 73 .section __ex_table,"a" 74 PTR_WD load_a4, bad_stack_a4 75 PTR_WD load_a5, bad_stack_a5 76 PTR_WD load_a6, bad_stack_a6 77 PTR_WD load_a7, bad_stack_a7 78 .previous 79 80 /* 81 * syscall number is in v0 unless we c 82 * where the real syscall number is in 83 */ 84 subu t2, v0, __NR_O32_Linux 85 bnez t2, 1f /* __NR_syscall at offs 86 LONG_S a0, TI_SYSCALL($28) # Save 87 b 2f 88 1: 89 LONG_S v0, TI_SYSCALL($28) # Save 90 2: 91 92 lw t0, TI_FLAGS($28) # sysc 93 li t1, _TIF_WORK_SYSCALL_ENTRY 94 and t0, t1 95 bnez t0, syscall_trace_entry # -> y 96 syscall_common: 97 subu v0, v0, __NR_O32_Linux # chec 98 sltiu t0, v0, __NR_O32_Linux_syscall 99 beqz t0, illegal_syscall 100 101 sll t0, v0, 2 102 la t1, sys_call_table 103 addu t1, t0 104 lw t2, (t1) # sysc 105 106 beqz t2, illegal_syscall 107 108 jalr t2 # Do T 109 110 li t0, -EMAXERRNO - 1 # erro 111 sltu t0, t0, v0 112 sw t0, PT_R7(sp) # set 113 beqz t0, 1f 114 115 lw t1, PT_R2(sp) # sysc 116 negu v0 # erro 117 sw t1, PT_R0(sp) # save 118 1: sw v0, PT_R2(sp) # resu 119 120 o32_syscall_exit: 121 j syscall_exit_partial 122 123 /* ------------------------------------------- 124 125 syscall_trace_entry: 126 SAVE_STATIC 127 move a0, sp 128 129 jal syscall_trace_enter 130 131 bltz v0, 1f # secc 132 133 RESTORE_STATIC 134 lw v0, PT_R2(sp) # Rest 135 lw a0, PT_R4(sp) # Rest 136 lw a1, PT_R5(sp) 137 lw a2, PT_R6(sp) 138 lw a3, PT_R7(sp) 139 j syscall_common 140 141 1: j syscall_exit 142 143 /* ------------------------------------------- 144 145 /* 146 * Our open-coded access area sanity t 147 * failed. We probably should handle t 148 */ 149 bad_stack: 150 li v0, EFAULT 151 sw v0, PT_R2(sp) 152 li t0, 1 153 sw t0, PT_R7(sp) 154 j o32_syscall_exit 155 156 bad_stack_a4: 157 li t5, 0 158 b load_a5 159 160 bad_stack_a5: 161 li t6, 0 162 b load_a6 163 164 bad_stack_a6: 165 li t7, 0 166 b load_a7 167 168 bad_stack_a7: 169 li t8, 0 170 b loads_done 171 172 /* 173 * The system call does not exist in t 174 */ 175 illegal_syscall: 176 li v0, ENOSYS 177 sw v0, PT_R2(sp) 178 li t0, 1 179 sw t0, PT_R7(sp) 180 j o32_syscall_exit 181 END(handle_sys) 182 183 LEAF(sys_syscall) 184 subu t0, a0, __NR_O32_Linux # chec 185 sltiu v0, t0, __NR_O32_Linux_syscall 186 beqz t0, einval # do n 187 sll t1, t0, 2 188 beqz v0, einval 189 lw t2, sys_call_table(t1) 190 191 move a0, a1 192 move a1, a2 193 move a2, a3 194 lw a3, 16(sp) 195 lw t4, 20(sp) 196 lw t5, 24(sp) 197 lw t6, 28(sp) 198 sw t4, 16(sp) 199 sw t5, 20(sp) 200 sw t6, 24(sp) 201 jr t2 202 /* Unreached */ 203 204 einval: li v0, -ENOSYS 205 jr ra 206 END(sys_syscall) 207 208 #ifdef CONFIG_MIPS_MT_FPAFF 209 /* 210 * For FPU affinity scheduling on MIPS 211 * intercept sys_sched_xxxaffinity() c 212 * in kernel/sched/core.c. Considered 213 * these hooks for the 32-bit kernel - 214 * atm. 215 */ 216 #define sys_sched_setaffinity mipsmt_sys_sch 217 #define sys_sched_getaffinity mipsmt_sys_sch 218 #endif /* CONFIG_MIPS_MT_FPAFF */ 219 220 #define __SYSCALL_WITH_COMPAT(nr, native, comp 221 #define __SYSCALL(nr, entry) PTR_WD entry 222 .align 2 223 .type sys_call_table, @object 224 EXPORT(sys_call_table) 225 #include <asm/syscall_table_o32.h>
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.