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
6 * Copyright (C) 1995-99, 2000- 02, 06 Ralf Baechle <ralf@linux-mips.org>
7 * Copyright (C) 2001 MIPS Technologies, Inc.
8 * Copyright (C) 2004 Thiemo Seufer
9 * Copyright (C) 2014 Imagination Technologies Ltd.
11 #include <linux/errno.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>
23 #include <asm/asm-offsets.h>
25 /* Highest syscall used of any syscall flavour */
26 #define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls
29 NESTED(handle_sys, PT_SIZE, sp)
36 lw t1, PT_EPC(sp) # skip syscall on return
38 subu v0, v0, __NR_O32_Linux # check syscall number
39 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
40 addiu t1, 4 # skip to next instruction
42 beqz t0, illegal_syscall
47 lw t2, (t1) # syscall routine
48 beqz t2, illegal_syscall
50 sw a3, PT_R26(sp) # save a3 for syscall restarting
53 * More than four arguments. Try to deal with it by copying the
54 * stack arguments from the user stack to the kernel stack.
57 lw t0, PT_R29(sp) # get old user stack pointer
60 * We intentionally keep the kernel stack a little below the top of
61 * userspace so we don't have to do a slower byte accurate check here.
63 lw t5, TI_ADDR_LIMIT($28)
66 bltz t5, bad_stack # -> sp is bad
69 * Ok, copy the args from the luser stack to the kernel stack.
70 * t3 is the precomputed number of instruction bytes needed to
71 * load or store arguments 6-8.
78 1: user_lw(t5, 16(t0)) # argument #5 from usp
79 4: user_lw(t6, 20(t0)) # argument #6 from usp
80 3: user_lw(t7, 24(t0)) # argument #7 from usp
81 2: user_lw(t8, 28(t0)) # argument #8 from usp
83 sw t5, 16(sp) # argument #5 to ksp
84 sw t6, 20(sp) # argument #6 to ksp
85 sw t7, 24(sp) # argument #7 to ksp
86 sw t8, 28(sp) # argument #8 to ksp
89 .section __ex_table,"a"
96 lw t0, TI_FLAGS($28) # syscall tracing enabled?
97 li t1, _TIF_WORK_SYSCALL_ENTRY
99 bnez t0, syscall_trace_entry # -> yes
101 jalr t2 # Do The Real Thing (TM)
103 li t0, -EMAXERRNO - 1 # error?
105 sw t0, PT_R7(sp) # set error flag
108 lw t1, PT_R2(sp) # syscall number
110 sw t1, PT_R0(sp) # save it for syscall restarting
111 1: sw v0, PT_R2(sp) # result
114 j syscall_exit_partial
116 /* ------------------------------------------------------------------------ */
124 * syscall number is in v0 unless we called syscall(__NR_###)
125 * where the real syscall number is in a0
127 addiu a1, v0, __NR_O32_Linux
128 bnez v0, 1f /* __NR_syscall at offset 0 */
131 1: jal syscall_trace_enter
133 bltz v0, 2f # seccomp failed? Skip syscall
137 lw a0, PT_R4(sp) # Restore argument registers
143 li t0, -EMAXERRNO - 1 # error?
145 sw t0, PT_R7(sp) # set error flag
148 lw t1, PT_R2(sp) # syscall number
150 sw t1, PT_R0(sp) # save it for syscall restarting
151 1: sw v0, PT_R2(sp) # result
155 /* ------------------------------------------------------------------------ */
158 * The stackpointer for a call with more than 4 arguments is bad.
159 * We probably should handle this case a bit more drastic.
164 li t0, 1 # set error flag
169 * The system call does not exist in this kernel
172 li v0, ENOSYS # error
174 li t0, 1 # set error flag
180 subu t0, a0, __NR_O32_Linux # check syscall number
181 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
182 beqz t0, einval # do not recurse
185 lw t2, sys_call_table(t1) # syscall routine
187 /* Some syscalls like execve get their arguments from struct pt_regs
188 and claim zero arguments in the syscall table. Thus we have to
189 assume the worst case and shuffle around all potential arguments.
190 If you want performance, don't use indirect syscalls. */
192 move a0, a1 # shift argument registers
202 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
203 sw a1, PT_R5(sp) # syscalls expect them there
206 sw a3, PT_R26(sp) # update a3 for syscall restarting
210 einval: li v0, -ENOSYS
215 .type sys_call_table, @object
216 EXPORT(sys_call_table)
217 PTR sys_syscall /* 4000 */
222 PTR sys_open /* 4005 */
227 PTR sys_unlink /* 4010 */
232 PTR sys_chmod /* 4015 */
235 PTR sys_ni_syscall /* was sys_stat */
237 PTR sys_getpid /* 4020 */
242 PTR sys_stime /* 4025 */
245 PTR sys_ni_syscall /* was sys_fstat */
247 PTR sys_utime /* 4030 */
252 PTR sys_ni_syscall /* 4035 */
257 PTR sys_rmdir /* 4040 */
262 PTR sys_brk /* 4045 */
265 PTR sys_ni_syscall /* was signal(2) */
267 PTR sys_getegid /* 4050 */
272 PTR sys_fcntl /* 4055 */
277 PTR sys_umask /* 4060 */
282 PTR sys_getpgrp /* 4065 */
287 PTR sys_setreuid /* 4070 */
292 PTR sys_setrlimit /* 4075 */
297 PTR sys_getgroups /* 4080 */
299 PTR sys_ni_syscall /* old_select */
301 PTR sys_ni_syscall /* was sys_lstat */
302 PTR sys_readlink /* 4085 */
307 PTR sys_mips_mmap /* 4090 */
312 PTR sys_fchown /* 4095 */
317 PTR sys_fstatfs /* 4100 */
318 PTR sys_ni_syscall /* was ioperm(2) */
322 PTR sys_getitimer /* 4105 */
327 PTR sys_ni_syscall /* 4110 was iopl(2) */
329 PTR sys_ni_syscall /* was sys_idle() */
330 PTR sys_ni_syscall /* was sys_vm86 */
332 PTR sys_swapoff /* 4115 */
337 PTR __sys_clone /* 4120 */
338 PTR sys_setdomainname
340 PTR sys_ni_syscall /* sys_modify_ldt */
342 PTR sys_mprotect /* 4125 */
344 PTR sys_ni_syscall /* was create_module */
346 PTR sys_delete_module
347 PTR sys_ni_syscall /* 4130 was get_kernel_syms */
352 PTR sys_sysfs /* 4135 */
354 PTR sys_ni_syscall /* for afs_syscall */
357 PTR sys_llseek /* 4140 */
362 PTR sys_readv /* 4145 */
367 PTR sys_ni_syscall /* 4150 */
372 PTR sys_munlock /* 4155 */
375 PTR sys_sched_setparam
376 PTR sys_sched_getparam
377 PTR sys_sched_setscheduler /* 4160 */
378 PTR sys_sched_getscheduler
380 PTR sys_sched_get_priority_max
381 PTR sys_sched_get_priority_min
382 PTR sys_sched_rr_get_interval /* 4165 */
387 PTR sys_connect /* 4170 */
392 PTR sys_recv /* 4175 */
397 PTR sys_sendto /* 4180 */
402 PTR sys_setresuid /* 4185 */
404 PTR sys_ni_syscall /* was sys_query_module */
406 PTR sys_ni_syscall /* was nfsservctl */
407 PTR sys_setresgid /* 4190 */
412 PTR sys_rt_sigprocmask /* 4195 */
413 PTR sys_rt_sigpending
414 PTR sys_rt_sigtimedwait
415 PTR sys_rt_sigqueueinfo
416 PTR sys_rt_sigsuspend
417 PTR sys_pread64 /* 4200 */
422 PTR sys_capset /* 4205 */
427 PTR sys_mips_mmap2 /* 4210 */
432 PTR sys_fstat64 /* 4215 */
437 PTR sys_fcntl64 /* 4220 */
442 PTR sys_lsetxattr /* 4225 */
447 PTR sys_listxattr /* 4230 */
452 PTR sys_fremovexattr /* 4235 */
456 #ifdef CONFIG_MIPS_MT_FPAFF
458 * For FPU affinity scheduling on MIPS MT processors, we need to
459 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
460 * in kernel/sched/core.c. Considered only temporary we only support
461 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
464 PTR mipsmt_sys_sched_setaffinity
465 PTR mipsmt_sys_sched_getaffinity
467 PTR sys_sched_setaffinity
468 PTR sys_sched_getaffinity /* 4240 */
469 #endif /* CONFIG_MIPS_MT_FPAFF */
474 PTR sys_io_cancel /* 4245 */
476 PTR sys_lookup_dcookie
479 PTR sys_epoll_wait /* 4250 */
480 PTR sys_remap_file_pages
481 PTR sys_set_tid_address
482 PTR sys_restart_syscall
484 PTR sys_statfs64 /* 4255 */
487 PTR sys_timer_settime
488 PTR sys_timer_gettime
489 PTR sys_timer_getoverrun /* 4260 */
491 PTR sys_clock_settime
492 PTR sys_clock_gettime
494 PTR sys_clock_nanosleep /* 4265 */
498 PTR sys_ni_syscall /* sys_get_mempolicy */
499 PTR sys_ni_syscall /* 4270 sys_set_mempolicy */
503 PTR sys_mq_timedreceive
504 PTR sys_mq_notify /* 4275 */
505 PTR sys_mq_getsetattr
506 PTR sys_ni_syscall /* sys_vserver */
508 PTR sys_ni_syscall /* available, was setaltroot */
509 PTR sys_add_key /* 4280 */
512 PTR sys_set_thread_area
514 PTR sys_inotify_add_watch /* 4285 */
515 PTR sys_inotify_rm_watch
516 PTR sys_migrate_pages
519 PTR sys_mknodat /* 4290 */
524 PTR sys_renameat /* 4295 */
529 PTR sys_faccessat /* 4300 */
534 PTR sys_sync_file_range /* 4305 */
538 PTR sys_set_robust_list
539 PTR sys_get_robust_list /* 4310 */
544 PTR sys_ioprio_get /* 4315 */
547 PTR sys_ni_syscall /* was timerfd */
549 PTR sys_fallocate /* 4320 */
550 PTR sys_timerfd_create
551 PTR sys_timerfd_gettime
552 PTR sys_timerfd_settime
554 PTR sys_eventfd2 /* 4325 */
555 PTR sys_epoll_create1
558 PTR sys_inotify_init1
559 PTR sys_preadv /* 4330 */
561 PTR sys_rt_tgsigqueueinfo
562 PTR sys_perf_event_open
564 PTR sys_recvmmsg /* 4335 */
565 PTR sys_fanotify_init
566 PTR sys_fanotify_mark
568 PTR sys_name_to_handle_at
569 PTR sys_open_by_handle_at /* 4340 */
570 PTR sys_clock_adjtime
574 PTR sys_process_vm_readv /* 4345 */
575 PTR sys_process_vm_writev
578 PTR sys_sched_setattr
579 PTR sys_sched_getattr /* 4350 */