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.
76 1: user_lw(t5, 16(t0)) # argument #5 from usp
77 4: user_lw(t6, 20(t0)) # argument #6 from usp
78 3: user_lw(t7, 24(t0)) # argument #7 from usp
79 2: user_lw(t8, 28(t0)) # argument #8 from usp
81 sw t5, 16(sp) # argument #5 to ksp
82 sw t6, 20(sp) # argument #6 to ksp
83 sw t7, 24(sp) # argument #7 to ksp
84 sw t8, 28(sp) # argument #8 to ksp
87 .section __ex_table,"a"
94 lw t0, TI_FLAGS($28) # syscall tracing enabled?
95 li t1, _TIF_WORK_SYSCALL_ENTRY
97 bnez t0, syscall_trace_entry # -> yes
99 jalr t2 # Do The Real Thing (TM)
101 li t0, -EMAXERRNO - 1 # error?
103 sw t0, PT_R7(sp) # set error flag
106 lw t1, PT_R2(sp) # syscall number
108 sw t1, PT_R0(sp) # save it for syscall restarting
109 1: sw v0, PT_R2(sp) # result
112 j syscall_exit_partial
114 /* ------------------------------------------------------------------------ */
122 * syscall number is in v0 unless we called syscall(__NR_###)
123 * where the real syscall number is in a0
125 addiu a1, v0, __NR_O32_Linux
126 bnez v0, 1f /* __NR_syscall at offset 0 */
129 1: jal syscall_trace_enter
131 bltz v0, 2f # seccomp failed? Skip syscall
135 lw a0, PT_R4(sp) # Restore argument registers
141 li t0, -EMAXERRNO - 1 # error?
143 sw t0, PT_R7(sp) # set error flag
146 lw t1, PT_R2(sp) # syscall number
148 sw t1, PT_R0(sp) # save it for syscall restarting
149 1: sw v0, PT_R2(sp) # result
153 /* ------------------------------------------------------------------------ */
156 * The stackpointer for a call with more than 4 arguments is bad.
157 * We probably should handle this case a bit more drastic.
162 li t0, 1 # set error flag
167 * The system call does not exist in this kernel
170 li v0, ENOSYS # error
172 li t0, 1 # set error flag
178 subu t0, a0, __NR_O32_Linux # check syscall number
179 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
180 beqz t0, einval # do not recurse
183 lw t2, sys_call_table(t1) # syscall routine
185 /* Some syscalls like execve get their arguments from struct pt_regs
186 and claim zero arguments in the syscall table. Thus we have to
187 assume the worst case and shuffle around all potential arguments.
188 If you want performance, don't use indirect syscalls. */
190 move a0, a1 # shift argument registers
200 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
201 sw a1, PT_R5(sp) # syscalls expect them there
204 sw a3, PT_R26(sp) # update a3 for syscall restarting
208 einval: li v0, -ENOSYS
213 .type sys_call_table, @object
214 EXPORT(sys_call_table)
215 PTR sys_syscall /* 4000 */
220 PTR sys_open /* 4005 */
225 PTR sys_unlink /* 4010 */
230 PTR sys_chmod /* 4015 */
233 PTR sys_ni_syscall /* was sys_stat */
235 PTR sys_getpid /* 4020 */
240 PTR sys_stime /* 4025 */
243 PTR sys_ni_syscall /* was sys_fstat */
245 PTR sys_utime /* 4030 */
250 PTR sys_ni_syscall /* 4035 */
255 PTR sys_rmdir /* 4040 */
260 PTR sys_brk /* 4045 */
263 PTR sys_ni_syscall /* was signal(2) */
265 PTR sys_getegid /* 4050 */
270 PTR sys_fcntl /* 4055 */
275 PTR sys_umask /* 4060 */
280 PTR sys_getpgrp /* 4065 */
285 PTR sys_setreuid /* 4070 */
290 PTR sys_setrlimit /* 4075 */
295 PTR sys_getgroups /* 4080 */
297 PTR sys_ni_syscall /* old_select */
299 PTR sys_ni_syscall /* was sys_lstat */
300 PTR sys_readlink /* 4085 */
305 PTR sys_mips_mmap /* 4090 */
310 PTR sys_fchown /* 4095 */
315 PTR sys_fstatfs /* 4100 */
316 PTR sys_ni_syscall /* was ioperm(2) */
320 PTR sys_getitimer /* 4105 */
325 PTR sys_ni_syscall /* 4110 was iopl(2) */
327 PTR sys_ni_syscall /* was sys_idle() */
328 PTR sys_ni_syscall /* was sys_vm86 */
330 PTR sys_swapoff /* 4115 */
335 PTR __sys_clone /* 4120 */
336 PTR sys_setdomainname
338 PTR sys_ni_syscall /* sys_modify_ldt */
340 PTR sys_mprotect /* 4125 */
342 PTR sys_ni_syscall /* was create_module */
344 PTR sys_delete_module
345 PTR sys_ni_syscall /* 4130 was get_kernel_syms */
350 PTR sys_sysfs /* 4135 */
352 PTR sys_ni_syscall /* for afs_syscall */
355 PTR sys_llseek /* 4140 */
360 PTR sys_readv /* 4145 */
365 PTR sys_ni_syscall /* 4150 */
370 PTR sys_munlock /* 4155 */
373 PTR sys_sched_setparam
374 PTR sys_sched_getparam
375 PTR sys_sched_setscheduler /* 4160 */
376 PTR sys_sched_getscheduler
378 PTR sys_sched_get_priority_max
379 PTR sys_sched_get_priority_min
380 PTR sys_sched_rr_get_interval /* 4165 */
385 PTR sys_connect /* 4170 */
390 PTR sys_recv /* 4175 */
395 PTR sys_sendto /* 4180 */
400 PTR sys_setresuid /* 4185 */
402 PTR sys_ni_syscall /* was sys_query_module */
404 PTR sys_ni_syscall /* was nfsservctl */
405 PTR sys_setresgid /* 4190 */
410 PTR sys_rt_sigprocmask /* 4195 */
411 PTR sys_rt_sigpending
412 PTR sys_rt_sigtimedwait
413 PTR sys_rt_sigqueueinfo
414 PTR sys_rt_sigsuspend
415 PTR sys_pread64 /* 4200 */
420 PTR sys_capset /* 4205 */
425 PTR sys_mips_mmap2 /* 4210 */
430 PTR sys_fstat64 /* 4215 */
435 PTR sys_fcntl64 /* 4220 */
440 PTR sys_lsetxattr /* 4225 */
445 PTR sys_listxattr /* 4230 */
450 PTR sys_fremovexattr /* 4235 */
454 #ifdef CONFIG_MIPS_MT_FPAFF
456 * For FPU affinity scheduling on MIPS MT processors, we need to
457 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
458 * in kernel/sched/core.c. Considered only temporary we only support
459 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
462 PTR mipsmt_sys_sched_setaffinity
463 PTR mipsmt_sys_sched_getaffinity
465 PTR sys_sched_setaffinity
466 PTR sys_sched_getaffinity /* 4240 */
467 #endif /* CONFIG_MIPS_MT_FPAFF */
472 PTR sys_io_cancel /* 4245 */
474 PTR sys_lookup_dcookie
477 PTR sys_epoll_wait /* 4250 */
478 PTR sys_remap_file_pages
479 PTR sys_set_tid_address
480 PTR sys_restart_syscall
482 PTR sys_statfs64 /* 4255 */
485 PTR sys_timer_settime
486 PTR sys_timer_gettime
487 PTR sys_timer_getoverrun /* 4260 */
489 PTR sys_clock_settime
490 PTR sys_clock_gettime
492 PTR sys_clock_nanosleep /* 4265 */
496 PTR sys_get_mempolicy
497 PTR sys_set_mempolicy /* 4270 */
501 PTR sys_mq_timedreceive
502 PTR sys_mq_notify /* 4275 */
503 PTR sys_mq_getsetattr
504 PTR sys_ni_syscall /* sys_vserver */
506 PTR sys_ni_syscall /* available, was setaltroot */
507 PTR sys_add_key /* 4280 */
510 PTR sys_set_thread_area
512 PTR sys_inotify_add_watch /* 4285 */
513 PTR sys_inotify_rm_watch
514 PTR sys_migrate_pages
517 PTR sys_mknodat /* 4290 */
522 PTR sys_renameat /* 4295 */
527 PTR sys_faccessat /* 4300 */
532 PTR sys_sync_file_range /* 4305 */
536 PTR sys_set_robust_list
537 PTR sys_get_robust_list /* 4310 */
542 PTR sys_ioprio_get /* 4315 */
545 PTR sys_ni_syscall /* was timerfd */
547 PTR sys_fallocate /* 4320 */
548 PTR sys_timerfd_create
549 PTR sys_timerfd_gettime
550 PTR sys_timerfd_settime
552 PTR sys_eventfd2 /* 4325 */
553 PTR sys_epoll_create1
556 PTR sys_inotify_init1
557 PTR sys_preadv /* 4330 */
559 PTR sys_rt_tgsigqueueinfo
560 PTR sys_perf_event_open
562 PTR sys_recvmmsg /* 4335 */
563 PTR sys_fanotify_init
564 PTR sys_fanotify_mark
566 PTR sys_name_to_handle_at
567 PTR sys_open_by_handle_at /* 4340 */
568 PTR sys_clock_adjtime
572 PTR sys_process_vm_readv /* 4345 */
573 PTR sys_process_vm_writev
576 PTR sys_sched_setattr
577 PTR sys_sched_getattr /* 4350 */