blob: b1b2e106f71184eddcea4b4cc031b857340bf755 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
Ralf Baechle192ef362006-07-07 14:07:18 +01006 * Copyright (C) 1995-99, 2000- 02, 06 Ralf Baechle <ralf@linux-mips.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 * Copyright (C) 2001 MIPS Technologies, Inc.
8 * Copyright (C) 2004 Thiemo Seufer
Markos Chandras86bdb272013-12-04 14:35:28 +00009 * Copyright (C) 2014 Imagination Technologies Ltd.
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <linux/errno.h>
12#include <asm/asm.h>
13#include <asm/asmmacro.h>
Ralf Baechle192ef362006-07-07 14:07:18 +010014#include <asm/irqflags.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#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/war.h>
Sam Ravnborg048eb582005-09-09 22:32:31 +020023#include <asm/asm-offsets.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
Ralf Baechle70342282013-01-22 12:59:30 +010025 .align 5
Linus Torvalds1da177e2005-04-16 15:20:36 -070026NESTED(handle_sys, PT_SIZE, sp)
27 .set noat
28 SAVE_SOME
Atsushi Nemotoeae6c0d2006-09-26 23:43:40 +090029 TRACE_IRQS_ON_RELOAD
Linus Torvalds1da177e2005-04-16 15:20:36 -070030 STI
31 .set at
32
33 lw t1, PT_EPC(sp) # skip syscall on return
34
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 addiu t1, 4 # skip to next instruction
36 sw t1, PT_EPC(sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
38 sw a3, PT_R26(sp) # save a3 for syscall restarting
Linus Torvalds1da177e2005-04-16 15:20:36 -070039
Ralf Baechle46e12c02012-07-14 09:22:05 +020040 /*
41 * More than four arguments. Try to deal with it by copying the
42 * stack arguments from the user stack to the kernel stack.
43 * This Sucks (TM).
44 */
45 lw t0, PT_R29(sp) # get old user stack pointer
46
47 /*
48 * We intentionally keep the kernel stack a little below the top of
49 * userspace so we don't have to do a slower byte accurate check here.
50 */
Ralf Baechle46e12c02012-07-14 09:22:05 +020051 addu t4, t0, 32
Thomas Bogendoerfer04324f42021-04-01 14:56:37 +020052 bltz t4, bad_stack # -> sp is bad
Ralf Baechle46e12c02012-07-14 09:22:05 +020053
54 /*
55 * Ok, copy the args from the luser stack to the kernel stack.
Ralf Baechle46e12c02012-07-14 09:22:05 +020056 */
57
58 .set push
59 .set noreorder
60 .set nomacro
61
Ralf Baechle7928eb02015-07-08 04:49:10 +020062load_a4: user_lw(t5, 16(t0)) # argument #5 from usp
63load_a5: user_lw(t6, 20(t0)) # argument #6 from usp
64load_a6: user_lw(t7, 24(t0)) # argument #7 from usp
65load_a7: user_lw(t8, 28(t0)) # argument #8 from usp
66loads_done:
Ralf Baechle46e12c02012-07-14 09:22:05 +020067
68 sw t5, 16(sp) # argument #5 to ksp
69 sw t6, 20(sp) # argument #6 to ksp
70 sw t7, 24(sp) # argument #7 to ksp
71 sw t8, 28(sp) # argument #8 to ksp
72 .set pop
73
74 .section __ex_table,"a"
Ralf Baechle7928eb02015-07-08 04:49:10 +020075 PTR load_a4, bad_stack_a4
76 PTR load_a5, bad_stack_a5
77 PTR load_a6, bad_stack_a6
78 PTR load_a7, bad_stack_a7
Ralf Baechle46e12c02012-07-14 09:22:05 +020079 .previous
80
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 lw t0, TI_FLAGS($28) # syscall tracing enabled?
Ralf Baechlee7f3b482013-05-29 01:02:18 +020082 li t1, _TIF_WORK_SYSCALL_ENTRY
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 and t0, t1
Ralf Baechle70342282013-01-22 12:59:30 +010084 bnez t0, syscall_trace_entry # -> yes
Markos Chandrasd218af72015-09-25 08:17:42 +010085syscall_common:
Matt Redfearna400bed2016-03-29 09:35:31 +010086 subu v0, v0, __NR_O32_Linux # check syscall number
Firoz Khanbe856432018-12-13 14:37:36 +053087 sltiu t0, v0, __NR_O32_Linux_syscalls
Markos Chandrasd218af72015-09-25 08:17:42 +010088 beqz t0, illegal_syscall
89
90 sll t0, v0, 2
91 la t1, sys_call_table
92 addu t1, t0
93 lw t2, (t1) # syscall routine
94
95 beqz t2, illegal_syscall
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
97 jalr t2 # Do The Real Thing (TM)
98
99 li t0, -EMAXERRNO - 1 # error?
100 sltu t0, t0, v0
101 sw t0, PT_R7(sp) # set error flag
102 beqz t0, 1f
103
Al Viro8f5a00eb2010-09-28 18:50:37 +0100104 lw t1, PT_R2(sp) # syscall number
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 negu v0 # error
Al Viro8f5a00eb2010-09-28 18:50:37 +0100106 sw t1, PT_R0(sp) # save it for syscall restarting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071: sw v0, PT_R2(sp) # result
108
109o32_syscall_exit:
Al Viro02f884e2012-05-05 16:11:35 -0400110 j syscall_exit_partial
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
112/* ------------------------------------------------------------------------ */
113
114syscall_trace_entry:
115 SAVE_STATIC
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 move a0, sp
Markos Chandras4c21b8f2014-01-22 14:40:03 +0000117
118 /*
119 * syscall number is in v0 unless we called syscall(__NR_###)
120 * where the real syscall number is in a0
121 */
Matt Redfearna400bed2016-03-29 09:35:31 +0100122 move a1, v0
123 subu t2, v0, __NR_O32_Linux
124 bnez t2, 1f /* __NR_syscall at offset 0 */
Markos Chandras4c21b8f2014-01-22 14:40:03 +0000125 lw a1, PT_R4(sp)
126
1271: jal syscall_trace_enter
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
Markos Chandrasd218af72015-09-25 08:17:42 +0100129 bltz v0, 1f # seccomp failed? Skip syscall
Markos Chandras9d37c402014-01-22 14:40:02 +0000130
Ralf Baechle04a70522005-11-30 16:24:57 +0000131 RESTORE_STATIC
Matt Redfearna400bed2016-03-29 09:35:31 +0100132 lw v0, PT_R2(sp) # Restore syscall (maybe modified)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 lw a0, PT_R4(sp) # Restore argument registers
134 lw a1, PT_R5(sp)
135 lw a2, PT_R6(sp)
136 lw a3, PT_R7(sp)
Markos Chandrasd218af72015-09-25 08:17:42 +0100137 j syscall_common
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
Markos Chandrasd218af72015-09-25 08:17:42 +01001391: j syscall_exit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
141/* ------------------------------------------------------------------------ */
142
143 /*
Ralf Baechle7928eb02015-07-08 04:49:10 +0200144 * Our open-coded access area sanity test for the stack pointer
145 * failed. We probably should handle this case a bit more drastic.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 */
147bad_stack:
Al Viro5b89c002010-09-28 18:50:47 +0100148 li v0, EFAULT
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 sw v0, PT_R2(sp)
150 li t0, 1 # set error flag
151 sw t0, PT_R7(sp)
152 j o32_syscall_exit
153
Ralf Baechle7928eb02015-07-08 04:49:10 +0200154bad_stack_a4:
155 li t5, 0
156 b load_a5
157
158bad_stack_a5:
159 li t6, 0
160 b load_a6
161
162bad_stack_a6:
163 li t7, 0
164 b load_a7
165
166bad_stack_a7:
167 li t8, 0
168 b loads_done
169
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 /*
171 * The system call does not exist in this kernel
172 */
173illegal_syscall:
Atsushi Nemotobda82292008-10-25 01:17:22 +0900174 li v0, ENOSYS # error
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 sw v0, PT_R2(sp)
176 li t0, 1 # set error flag
177 sw t0, PT_R7(sp)
178 j o32_syscall_exit
179 END(handle_sys)
180
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 LEAF(sys_syscall)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 subu t0, a0, __NR_O32_Linux # check syscall number
Firoz Khanbe856432018-12-13 14:37:36 +0530183 sltiu v0, t0, __NR_O32_Linux_syscalls
Vlad Malove807f952008-11-18 15:05:46 -0800184 beqz t0, einval # do not recurse
Ralf Baechle46e12c02012-07-14 09:22:05 +0200185 sll t1, t0, 2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 beqz v0, einval
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 lw t2, sys_call_table(t1) # syscall routine
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188
189 move a0, a1 # shift argument registers
190 move a1, a2
191 move a2, a3
192 lw a3, 16(sp)
193 lw t4, 20(sp)
194 lw t5, 24(sp)
195 lw t6, 28(sp)
196 sw t4, 16(sp)
197 sw t5, 20(sp)
198 sw t6, 24(sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199 jr t2
200 /* Unreached */
201
Ralf Baechle70342282013-01-22 12:59:30 +0100202einval: li v0, -ENOSYS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 jr ra
204 END(sys_syscall)
205
Firoz Khan6a00cb62018-12-13 14:37:37 +0530206#ifdef CONFIG_MIPS_MT_FPAFF
207 /*
208 * For FPU affinity scheduling on MIPS MT processors, we need to
209 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
210 * in kernel/sched/core.c. Considered only temporary we only support
211 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
212 * atm.
213 */
214#define sys_sched_setaffinity mipsmt_sys_sched_setaffinity
215#define sys_sched_getaffinity mipsmt_sys_sched_getaffinity
216#endif /* CONFIG_MIPS_MT_FPAFF */
217
Masahiro Yamadaecbba302021-03-01 23:48:24 +0900218#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
Firoz Khandc7077f2019-01-02 20:26:17 +0530219#define __SYSCALL(nr, entry) PTR entry
Ralf Baechle46e12c02012-07-14 09:22:05 +0200220 .align 2
221 .type sys_call_table, @object
222EXPORT(sys_call_table)
Masahiro Yamadaecbba302021-03-01 23:48:24 +0900223#include <asm/syscall_table_o32.h>