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 addiu t1, 4 # skip to next instruction
42 sw a3, PT_R26(sp) # save a3 for syscall restarting
45 * More than four arguments. Try to deal with it by copying the
46 * stack arguments from the user stack to the kernel stack.
49 lw t0, PT_R29(sp) # get old user stack pointer
52 * We intentionally keep the kernel stack a little below the top of
53 * userspace so we don't have to do a slower byte accurate check here.
55 lw t5, TI_ADDR_LIMIT($28)
58 bltz t5, bad_stack # -> sp is bad
61 * Ok, copy the args from the luser stack to the kernel stack.
68 load_a4: user_lw(t5, 16(t0)) # argument #5 from usp
69 load_a5: user_lw(t6, 20(t0)) # argument #6 from usp
70 load_a6: user_lw(t7, 24(t0)) # argument #7 from usp
71 load_a7: user_lw(t8, 28(t0)) # argument #8 from usp
74 sw t5, 16(sp) # argument #5 to ksp
75 sw t6, 20(sp) # argument #6 to ksp
76 sw t7, 24(sp) # argument #7 to ksp
77 sw t8, 28(sp) # argument #8 to ksp
80 .section __ex_table,"a"
81 PTR load_a4, bad_stack_a4
82 PTR load_a5, bad_stack_a5
83 PTR load_a6, bad_stack_a6
84 PTR load_a7, bad_stack_a7
87 lw t0, TI_FLAGS($28) # syscall tracing enabled?
88 li t1, _TIF_WORK_SYSCALL_ENTRY
90 bnez t0, syscall_trace_entry # -> yes
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 /* ------------------------------------------------------------------------ */
125 * syscall number is in v0 unless we called syscall(__NR_###)
126 * where the real syscall number is in a0
128 addiu a1, v0, __NR_O32_Linux
129 bnez v0, 1f /* __NR_syscall at offset 0 */
132 1: jal syscall_trace_enter
134 bltz v0, 1f # seccomp failed? Skip syscall
136 move v0, s0 # restore syscall
139 lw a0, PT_R4(sp) # Restore argument registers
147 /* ------------------------------------------------------------------------ */
150 * Our open-coded access area sanity test for the stack pointer
151 * failed. We probably should handle this case a bit more drastic.
156 li t0, 1 # set error flag
177 * The system call does not exist in this kernel
180 li v0, ENOSYS # error
182 li t0, 1 # set error flag
188 subu t0, a0, __NR_O32_Linux # check syscall number
189 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
190 beqz t0, einval # do not recurse
193 lw t2, sys_call_table(t1) # syscall routine
194 sw a0, PT_R2(sp) # call routine directly on restart
196 /* Some syscalls like execve get their arguments from struct pt_regs
197 and claim zero arguments in the syscall table. Thus we have to
198 assume the worst case and shuffle around all potential arguments.
199 If you want performance, don't use indirect syscalls. */
201 move a0, a1 # shift argument registers
211 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
212 sw a1, PT_R5(sp) # syscalls expect them there
215 sw a3, PT_R26(sp) # update a3 for syscall restarting
219 einval: li v0, -ENOSYS
224 .type sys_call_table, @object
225 EXPORT(sys_call_table)
226 PTR sys_syscall /* 4000 */
231 PTR sys_open /* 4005 */
236 PTR sys_unlink /* 4010 */
241 PTR sys_chmod /* 4015 */
244 PTR sys_ni_syscall /* was sys_stat */
246 PTR sys_getpid /* 4020 */
251 PTR sys_stime /* 4025 */
254 PTR sys_ni_syscall /* was sys_fstat */
256 PTR sys_utime /* 4030 */
261 PTR sys_ni_syscall /* 4035 */
266 PTR sys_rmdir /* 4040 */
271 PTR sys_brk /* 4045 */
274 PTR sys_ni_syscall /* was signal(2) */
276 PTR sys_getegid /* 4050 */
281 PTR sys_fcntl /* 4055 */
286 PTR sys_umask /* 4060 */
291 PTR sys_getpgrp /* 4065 */
296 PTR sys_setreuid /* 4070 */
301 PTR sys_setrlimit /* 4075 */
306 PTR sys_getgroups /* 4080 */
308 PTR sys_ni_syscall /* old_select */
310 PTR sys_ni_syscall /* was sys_lstat */
311 PTR sys_readlink /* 4085 */
316 PTR sys_mips_mmap /* 4090 */
321 PTR sys_fchown /* 4095 */
326 PTR sys_fstatfs /* 4100 */
327 PTR sys_ni_syscall /* was ioperm(2) */
331 PTR sys_getitimer /* 4105 */
336 PTR sys_ni_syscall /* 4110 was iopl(2) */
338 PTR sys_ni_syscall /* was sys_idle() */
339 PTR sys_ni_syscall /* was sys_vm86 */
341 PTR sys_swapoff /* 4115 */
346 PTR __sys_clone /* 4120 */
347 PTR sys_setdomainname
349 PTR sys_ni_syscall /* sys_modify_ldt */
351 PTR sys_mprotect /* 4125 */
353 PTR sys_ni_syscall /* was create_module */
355 PTR sys_delete_module
356 PTR sys_ni_syscall /* 4130 was get_kernel_syms */
361 PTR sys_sysfs /* 4135 */
363 PTR sys_ni_syscall /* for afs_syscall */
366 PTR sys_llseek /* 4140 */
371 PTR sys_readv /* 4145 */
376 PTR sys_ni_syscall /* 4150 */
381 PTR sys_munlock /* 4155 */
384 PTR sys_sched_setparam
385 PTR sys_sched_getparam
386 PTR sys_sched_setscheduler /* 4160 */
387 PTR sys_sched_getscheduler
389 PTR sys_sched_get_priority_max
390 PTR sys_sched_get_priority_min
391 PTR sys_sched_rr_get_interval /* 4165 */
396 PTR sys_connect /* 4170 */
401 PTR sys_recv /* 4175 */
406 PTR sys_sendto /* 4180 */
411 PTR sys_setresuid /* 4185 */
413 PTR sys_ni_syscall /* was sys_query_module */
415 PTR sys_ni_syscall /* was nfsservctl */
416 PTR sys_setresgid /* 4190 */
421 PTR sys_rt_sigprocmask /* 4195 */
422 PTR sys_rt_sigpending
423 PTR sys_rt_sigtimedwait
424 PTR sys_rt_sigqueueinfo
425 PTR sys_rt_sigsuspend
426 PTR sys_pread64 /* 4200 */
431 PTR sys_capset /* 4205 */
436 PTR sys_mips_mmap2 /* 4210 */
441 PTR sys_fstat64 /* 4215 */
446 PTR sys_fcntl64 /* 4220 */
451 PTR sys_lsetxattr /* 4225 */
456 PTR sys_listxattr /* 4230 */
461 PTR sys_fremovexattr /* 4235 */
465 #ifdef CONFIG_MIPS_MT_FPAFF
467 * For FPU affinity scheduling on MIPS MT processors, we need to
468 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
469 * in kernel/sched/core.c. Considered only temporary we only support
470 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
473 PTR mipsmt_sys_sched_setaffinity
474 PTR mipsmt_sys_sched_getaffinity
476 PTR sys_sched_setaffinity
477 PTR sys_sched_getaffinity /* 4240 */
478 #endif /* CONFIG_MIPS_MT_FPAFF */
483 PTR sys_io_cancel /* 4245 */
485 PTR sys_lookup_dcookie
488 PTR sys_epoll_wait /* 4250 */
489 PTR sys_remap_file_pages
490 PTR sys_set_tid_address
491 PTR sys_restart_syscall
493 PTR sys_statfs64 /* 4255 */
496 PTR sys_timer_settime
497 PTR sys_timer_gettime
498 PTR sys_timer_getoverrun /* 4260 */
500 PTR sys_clock_settime
501 PTR sys_clock_gettime
503 PTR sys_clock_nanosleep /* 4265 */
507 PTR sys_get_mempolicy
508 PTR sys_set_mempolicy /* 4270 */
512 PTR sys_mq_timedreceive
513 PTR sys_mq_notify /* 4275 */
514 PTR sys_mq_getsetattr
515 PTR sys_ni_syscall /* sys_vserver */
517 PTR sys_ni_syscall /* available, was setaltroot */
518 PTR sys_add_key /* 4280 */
521 PTR sys_set_thread_area
523 PTR sys_inotify_add_watch /* 4285 */
524 PTR sys_inotify_rm_watch
525 PTR sys_migrate_pages
528 PTR sys_mknodat /* 4290 */
533 PTR sys_renameat /* 4295 */
538 PTR sys_faccessat /* 4300 */
543 PTR sys_sync_file_range /* 4305 */
547 PTR sys_set_robust_list
548 PTR sys_get_robust_list /* 4310 */
553 PTR sys_ioprio_get /* 4315 */
556 PTR sys_ni_syscall /* was timerfd */
558 PTR sys_fallocate /* 4320 */
559 PTR sys_timerfd_create
560 PTR sys_timerfd_gettime
561 PTR sys_timerfd_settime
563 PTR sys_eventfd2 /* 4325 */
564 PTR sys_epoll_create1
567 PTR sys_inotify_init1
568 PTR sys_preadv /* 4330 */
570 PTR sys_rt_tgsigqueueinfo
571 PTR sys_perf_event_open
573 PTR sys_recvmmsg /* 4335 */
574 PTR sys_fanotify_init
575 PTR sys_fanotify_mark
577 PTR sys_name_to_handle_at
578 PTR sys_open_by_handle_at /* 4340 */
579 PTR sys_clock_adjtime
583 PTR sys_process_vm_readv /* 4345 */
584 PTR sys_process_vm_writev
587 PTR sys_sched_setattr
588 PTR sys_sched_getattr /* 4350 */
593 PTR sys_bpf /* 4355 */