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 addiu t1, 4 # skip to next instruction
41 sw a3, PT_R26(sp) # save a3 for syscall restarting
44 * More than four arguments. Try to deal with it by copying the
45 * stack arguments from the user stack to the kernel stack.
48 lw t0, PT_R29(sp) # get old user stack pointer
51 * We intentionally keep the kernel stack a little below the top of
52 * userspace so we don't have to do a slower byte accurate check here.
54 lw t5, TI_ADDR_LIMIT($28)
57 bltz t5, bad_stack # -> sp is bad
60 * Ok, copy the args from the luser stack to the kernel stack.
67 load_a4: user_lw(t5, 16(t0)) # argument #5 from usp
68 load_a5: user_lw(t6, 20(t0)) # argument #6 from usp
69 load_a6: user_lw(t7, 24(t0)) # argument #7 from usp
70 load_a7: user_lw(t8, 28(t0)) # argument #8 from usp
73 sw t5, 16(sp) # argument #5 to ksp
74 sw t6, 20(sp) # argument #6 to ksp
75 sw t7, 24(sp) # argument #7 to ksp
76 sw t8, 28(sp) # argument #8 to ksp
79 .section __ex_table,"a"
80 PTR load_a4, bad_stack_a4
81 PTR load_a5, bad_stack_a5
82 PTR load_a6, bad_stack_a6
83 PTR load_a7, bad_stack_a7
86 lw t0, TI_FLAGS($28) # syscall tracing enabled?
87 li t1, _TIF_WORK_SYSCALL_ENTRY
89 bnez t0, syscall_trace_entry # -> yes
91 subu v0, v0, __NR_O32_Linux # check syscall number
92 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
93 beqz t0, illegal_syscall
98 lw t2, (t1) # syscall routine
100 beqz t2, illegal_syscall
102 jalr t2 # Do The Real Thing (TM)
104 li t0, -EMAXERRNO - 1 # error?
106 sw t0, PT_R7(sp) # set error flag
109 lw t1, PT_R2(sp) # syscall number
111 sw t1, PT_R0(sp) # save it for syscall restarting
112 1: sw v0, PT_R2(sp) # result
115 j syscall_exit_partial
117 /* ------------------------------------------------------------------------ */
124 * syscall number is in v0 unless we called syscall(__NR_###)
125 * where the real syscall number is in a0
128 subu t2, v0, __NR_O32_Linux
129 bnez t2, 1f /* __NR_syscall at offset 0 */
132 1: jal syscall_trace_enter
134 bltz v0, 1f # seccomp failed? Skip syscall
137 lw v0, PT_R2(sp) # Restore syscall (maybe modified)
138 lw a0, PT_R4(sp) # Restore argument registers
146 /* ------------------------------------------------------------------------ */
149 * Our open-coded access area sanity test for the stack pointer
150 * failed. We probably should handle this case a bit more drastic.
155 li t0, 1 # set error flag
176 * The system call does not exist in this kernel
179 li v0, ENOSYS # error
181 li t0, 1 # set error flag
187 subu t0, a0, __NR_O32_Linux # check syscall number
188 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
189 beqz t0, einval # do not recurse
192 lw t2, sys_call_table(t1) # syscall routine
193 sw a0, PT_R2(sp) # call routine directly on restart
195 /* Some syscalls like execve get their arguments from struct pt_regs
196 and claim zero arguments in the syscall table. Thus we have to
197 assume the worst case and shuffle around all potential arguments.
198 If you want performance, don't use indirect syscalls. */
200 move a0, a1 # shift argument registers
210 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
211 sw a1, PT_R5(sp) # syscalls expect them there
214 sw a3, PT_R26(sp) # update a3 for syscall restarting
218 einval: li v0, -ENOSYS
223 .type sys_call_table, @object
224 EXPORT(sys_call_table)
225 PTR sys_syscall /* 4000 */
230 PTR sys_open /* 4005 */
235 PTR sys_unlink /* 4010 */
240 PTR sys_chmod /* 4015 */
243 PTR sys_ni_syscall /* was sys_stat */
245 PTR sys_getpid /* 4020 */
250 PTR sys_stime /* 4025 */
253 PTR sys_ni_syscall /* was sys_fstat */
255 PTR sys_utime /* 4030 */
260 PTR sys_ni_syscall /* 4035 */
265 PTR sys_rmdir /* 4040 */
270 PTR sys_brk /* 4045 */
273 PTR sys_ni_syscall /* was signal(2) */
275 PTR sys_getegid /* 4050 */
280 PTR sys_fcntl /* 4055 */
285 PTR sys_umask /* 4060 */
290 PTR sys_getpgrp /* 4065 */
295 PTR sys_setreuid /* 4070 */
300 PTR sys_setrlimit /* 4075 */
305 PTR sys_getgroups /* 4080 */
307 PTR sys_ni_syscall /* old_select */
309 PTR sys_ni_syscall /* was sys_lstat */
310 PTR sys_readlink /* 4085 */
315 PTR sys_mips_mmap /* 4090 */
320 PTR sys_fchown /* 4095 */
325 PTR sys_fstatfs /* 4100 */
326 PTR sys_ni_syscall /* was ioperm(2) */
330 PTR sys_getitimer /* 4105 */
335 PTR sys_ni_syscall /* 4110 was iopl(2) */
337 PTR sys_ni_syscall /* was sys_idle() */
338 PTR sys_ni_syscall /* was sys_vm86 */
340 PTR sys_swapoff /* 4115 */
345 PTR __sys_clone /* 4120 */
346 PTR sys_setdomainname
348 PTR sys_ni_syscall /* sys_modify_ldt */
350 PTR sys_mprotect /* 4125 */
352 PTR sys_ni_syscall /* was create_module */
354 PTR sys_delete_module
355 PTR sys_ni_syscall /* 4130 was get_kernel_syms */
360 PTR sys_sysfs /* 4135 */
362 PTR sys_ni_syscall /* for afs_syscall */
365 PTR sys_llseek /* 4140 */
370 PTR sys_readv /* 4145 */
375 PTR sys_ni_syscall /* 4150 */
380 PTR sys_munlock /* 4155 */
383 PTR sys_sched_setparam
384 PTR sys_sched_getparam
385 PTR sys_sched_setscheduler /* 4160 */
386 PTR sys_sched_getscheduler
388 PTR sys_sched_get_priority_max
389 PTR sys_sched_get_priority_min
390 PTR sys_sched_rr_get_interval /* 4165 */
395 PTR sys_connect /* 4170 */
400 PTR sys_recv /* 4175 */
405 PTR sys_sendto /* 4180 */
410 PTR sys_setresuid /* 4185 */
412 PTR sys_ni_syscall /* was sys_query_module */
414 PTR sys_ni_syscall /* was nfsservctl */
415 PTR sys_setresgid /* 4190 */
420 PTR sys_rt_sigprocmask /* 4195 */
421 PTR sys_rt_sigpending
422 PTR sys_rt_sigtimedwait
423 PTR sys_rt_sigqueueinfo
424 PTR sys_rt_sigsuspend
425 PTR sys_pread64 /* 4200 */
430 PTR sys_capset /* 4205 */
435 PTR sys_mips_mmap2 /* 4210 */
440 PTR sys_fstat64 /* 4215 */
445 PTR sys_fcntl64 /* 4220 */
450 PTR sys_lsetxattr /* 4225 */
455 PTR sys_listxattr /* 4230 */
460 PTR sys_fremovexattr /* 4235 */
464 #ifdef CONFIG_MIPS_MT_FPAFF
466 * For FPU affinity scheduling on MIPS MT processors, we need to
467 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
468 * in kernel/sched/core.c. Considered only temporary we only support
469 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
472 PTR mipsmt_sys_sched_setaffinity
473 PTR mipsmt_sys_sched_getaffinity
475 PTR sys_sched_setaffinity
476 PTR sys_sched_getaffinity /* 4240 */
477 #endif /* CONFIG_MIPS_MT_FPAFF */
482 PTR sys_io_cancel /* 4245 */
484 PTR sys_lookup_dcookie
487 PTR sys_epoll_wait /* 4250 */
488 PTR sys_remap_file_pages
489 PTR sys_set_tid_address
490 PTR sys_restart_syscall
492 PTR sys_statfs64 /* 4255 */
495 PTR sys_timer_settime
496 PTR sys_timer_gettime
497 PTR sys_timer_getoverrun /* 4260 */
499 PTR sys_clock_settime
500 PTR sys_clock_gettime
502 PTR sys_clock_nanosleep /* 4265 */
506 PTR sys_get_mempolicy
507 PTR sys_set_mempolicy /* 4270 */
511 PTR sys_mq_timedreceive
512 PTR sys_mq_notify /* 4275 */
513 PTR sys_mq_getsetattr
514 PTR sys_ni_syscall /* sys_vserver */
516 PTR sys_ni_syscall /* available, was setaltroot */
517 PTR sys_add_key /* 4280 */
520 PTR sys_set_thread_area
522 PTR sys_inotify_add_watch /* 4285 */
523 PTR sys_inotify_rm_watch
524 PTR sys_migrate_pages
527 PTR sys_mknodat /* 4290 */
532 PTR sys_renameat /* 4295 */
537 PTR sys_faccessat /* 4300 */
542 PTR sys_sync_file_range /* 4305 */
546 PTR sys_set_robust_list
547 PTR sys_get_robust_list /* 4310 */
552 PTR sys_ioprio_get /* 4315 */
555 PTR sys_ni_syscall /* was timerfd */
557 PTR sys_fallocate /* 4320 */
558 PTR sys_timerfd_create
559 PTR sys_timerfd_gettime
560 PTR sys_timerfd_settime
562 PTR sys_eventfd2 /* 4325 */
563 PTR sys_epoll_create1
566 PTR sys_inotify_init1
567 PTR sys_preadv /* 4330 */
569 PTR sys_rt_tgsigqueueinfo
570 PTR sys_perf_event_open
572 PTR sys_recvmmsg /* 4335 */
573 PTR sys_fanotify_init
574 PTR sys_fanotify_mark
576 PTR sys_name_to_handle_at
577 PTR sys_open_by_handle_at /* 4340 */
578 PTR sys_clock_adjtime
582 PTR sys_process_vm_readv /* 4345 */
583 PTR sys_process_vm_writev
586 PTR sys_sched_setattr
587 PTR sys_sched_getattr /* 4350 */
592 PTR sys_bpf /* 4355 */
597 PTR sys_copy_file_range /* 4360 */