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
10 #include <linux/errno.h>
12 #include <asm/asmmacro.h>
13 #include <asm/irqflags.h>
14 #include <asm/mipsregs.h>
15 #include <asm/regdef.h>
16 #include <asm/stackframe.h>
17 #include <asm/isadep.h>
18 #include <asm/sysmips.h>
19 #include <asm/thread_info.h>
20 #include <asm/unistd.h>
22 #include <asm/asm-offsets.h>
24 /* Highest syscall used of any syscall flavour */
25 #define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls
28 NESTED(handle_sys, PT_SIZE, sp)
35 lw t1, PT_EPC(sp) # skip syscall on return
37 subu v0, v0, __NR_O32_Linux # check syscall number
38 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
39 addiu t1, 4 # skip to next instruction
41 beqz t0, illegal_syscall
46 lw t2, (t1) # syscall routine
47 lw t3, 4(t1) # >= 0 if we need stack arguments
48 beqz t2, illegal_syscall
50 sw a3, PT_R26(sp) # save a3 for syscall restarting
54 lw t0, TI_FLAGS($28) # syscall tracing enabled?
55 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
57 bnez t0, syscall_trace_entry # -> yes
59 jalr t2 # Do The Real Thing (TM)
61 li t0, -EMAXERRNO - 1 # error?
63 sw t0, PT_R7(sp) # set error flag
66 lw t1, PT_R2(sp) # syscall number
68 sw t1, PT_R0(sp) # save it for syscall restarting
69 1: sw v0, PT_R2(sp) # result
72 j syscall_exit_partial
74 /* ------------------------------------------------------------------------ */
80 jal syscall_trace_enter
84 lw a0, PT_R4(sp) # Restore argument registers
90 li t0, -EMAXERRNO - 1 # error?
92 sw t0, PT_R7(sp) # set error flag
95 lw t1, PT_R2(sp) # syscall number
97 sw t1, PT_R0(sp) # save it for syscall restarting
98 1: sw v0, PT_R2(sp) # result
102 /* ------------------------------------------------------------------------ */
105 * More than four arguments. Try to deal with it by copying the
106 * stack arguments from the user stack to the kernel stack.
110 lw t0, PT_R29(sp) # get old user stack pointer
113 * We intentionally keep the kernel stack a little below the top of
114 * userspace so we don't have to do a slower byte accurate check here.
116 lw t5, TI_ADDR_LIMIT($28)
119 bltz t5, bad_stack # -> sp is bad
121 /* Ok, copy the args from the luser stack to the kernel stack.
122 * t3 is the precomputed number of instruction bytes needed to
123 * load or store arguments 6-8.
126 la t1, 5f # load up to 3 arguments
128 1: lw t5, 16(t0) # argument #5 from usp
135 2: lw t8, 28(t0) # argument #8 from usp
136 3: lw t7, 24(t0) # argument #7 from usp
137 4: lw t6, 20(t0) # argument #6 from usp
139 sw t5, 16(sp) # argument #5 to ksp
141 sw t8, 28(sp) # argument #8 to ksp
142 sw t7, 24(sp) # argument #7 to ksp
143 sw t6, 20(sp) # argument #6 to ksp
144 6: j stack_done # go back
148 .section __ex_table,"a"
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
212 .macro fifty ptr, nargs, from=1, to=50
215 fifty \ptr,\nargs,"(\from+1)",\to
219 .macro mille ptr, nargs, from=1, to=20
222 mille \ptr,\nargs,"(\from+1)",\to
227 sys sys_syscall 8 /* 4000 */
232 sys sys_open 3 /* 4005 */
237 sys sys_unlink 1 /* 4010 */
242 sys sys_chmod 2 /* 4015 */
245 sys sys_ni_syscall 0 /* was sys_stat */
247 sys sys_getpid 0 /* 4020 */
252 sys sys_stime 1 /* 4025 */
255 sys sys_ni_syscall 0 /* was sys_fstat */
257 sys sys_utime 2 /* 4030 */
262 sys sys_ni_syscall 0 /* 4035 */
267 sys sys_rmdir 1 /* 4040 */
272 sys sys_brk 1 /* 4045 */
275 sys sys_ni_syscall 0 /* was signal(2) */
277 sys sys_getegid 0 /* 4050 */
282 sys sys_fcntl 3 /* 4055 */
287 sys sys_umask 1 /* 4060 */
292 sys sys_getpgrp 0 /* 4065 */
297 sys sys_setreuid 2 /* 4070 */
301 sys sys_sethostname 2
302 sys sys_setrlimit 2 /* 4075 */
305 sys sys_gettimeofday 2
306 sys sys_settimeofday 2
307 sys sys_getgroups 2 /* 4080 */
309 sys sys_ni_syscall 0 /* old_select */
311 sys sys_ni_syscall 0 /* was sys_lstat */
312 sys sys_readlink 3 /* 4085 */
316 sys sys_old_readdir 3
317 sys sys_mips_mmap 6 /* 4090 */
322 sys sys_fchown 3 /* 4095 */
323 sys sys_getpriority 2
324 sys sys_setpriority 3
327 sys sys_fstatfs 2 /* 4100 */
328 sys sys_ni_syscall 0 /* was ioperm(2) */
332 sys sys_getitimer 2 /* 4105 */
337 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
339 sys sys_ni_syscall 0 /* was sys_idle() */
340 sys sys_ni_syscall 0 /* was sys_vm86 */
342 sys sys_swapoff 1 /* 4115 */
347 sys sys_clone 0 /* 4120 */
348 sys sys_setdomainname 2
350 sys sys_ni_syscall 0 /* sys_modify_ldt */
352 sys sys_mprotect 3 /* 4125 */
353 sys sys_sigprocmask 3
354 sys sys_ni_syscall 0 /* was create_module */
355 sys sys_init_module 5
356 sys sys_delete_module 1
357 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
362 sys sys_sysfs 3 /* 4135 */
363 sys sys_personality 1
364 sys sys_ni_syscall 0 /* for afs_syscall */
367 sys sys_llseek 5 /* 4140 */
372 sys sys_readv 3 /* 4145 */
377 sys sys_ni_syscall 0 /* 4150 */
382 sys sys_munlock 2 /* 4155 */
385 sys sys_sched_setparam 2
386 sys sys_sched_getparam 2
387 sys sys_sched_setscheduler 3 /* 4160 */
388 sys sys_sched_getscheduler 1
389 sys sys_sched_yield 0
390 sys sys_sched_get_priority_max 1
391 sys sys_sched_get_priority_min 1
392 sys sys_sched_rr_get_interval 2 /* 4165 */
397 sys sys_connect 3 /* 4170 */
398 sys sys_getpeername 3
399 sys sys_getsockname 3
402 sys sys_recv 4 /* 4175 */
407 sys sys_sendto 6 /* 4180 */
412 sys sys_setresuid 3 /* 4185 */
414 sys sys_ni_syscall 0 /* was sys_query_module */
416 sys sys_ni_syscall 0 /* was nfsservctl */
417 sys sys_setresgid 3 /* 4190 */
420 sys sys_rt_sigreturn 0
421 sys sys_rt_sigaction 4
422 sys sys_rt_sigprocmask 4 /* 4195 */
423 sys sys_rt_sigpending 2
424 sys sys_rt_sigtimedwait 4
425 sys sys_rt_sigqueueinfo 3
426 sys sys_rt_sigsuspend 0
427 sys sys_pread64 6 /* 4200 */
432 sys sys_capset 2 /* 4205 */
433 sys sys_sigaltstack 0
437 sys sys_mips_mmap2 6 /* 4210 */
439 sys sys_ftruncate64 4
442 sys sys_fstat64 2 /* 4215 */
447 sys sys_fcntl64 3 /* 4220 */
452 sys sys_lsetxattr 5 /* 4225 */
457 sys sys_listxattr 3 /* 4230 */
460 sys sys_removexattr 2
461 sys sys_lremovexattr 2
462 sys sys_fremovexattr 2 /* 4235 */
466 #ifdef CONFIG_MIPS_MT_FPAFF
468 * For FPU affinity scheduling on MIPS MT processors, we need to
469 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
470 * in kernel/sched.c. Considered only temporary we only support these
471 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
473 sys mipsmt_sys_sched_setaffinity 3
474 sys mipsmt_sys_sched_getaffinity 3
476 sys sys_sched_setaffinity 3
477 sys sys_sched_getaffinity 3 /* 4240 */
478 #endif /* CONFIG_MIPS_MT_FPAFF */
481 sys sys_io_getevents 5
483 sys sys_io_cancel 3 /* 4245 */
485 sys sys_lookup_dcookie 4
486 sys sys_epoll_create 1
488 sys sys_epoll_wait 4 /* 4250 */
489 sys sys_remap_file_pages 5
490 sys sys_set_tid_address 1
491 sys sys_restart_syscall 0
492 sys sys_fadvise64_64 7
493 sys sys_statfs64 3 /* 4255 */
495 sys sys_timer_create 3
496 sys sys_timer_settime 4
497 sys sys_timer_gettime 2
498 sys sys_timer_getoverrun 1 /* 4260 */
499 sys sys_timer_delete 1
500 sys sys_clock_settime 2
501 sys sys_clock_gettime 2
502 sys sys_clock_getres 2
503 sys sys_clock_nanosleep 4 /* 4265 */
507 sys sys_ni_syscall 0 /* sys_get_mempolicy */
508 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
511 sys sys_mq_timedsend 5
512 sys sys_mq_timedreceive 5
513 sys sys_mq_notify 2 /* 4275 */
514 sys sys_mq_getsetattr 3
515 sys sys_ni_syscall 0 /* sys_vserver */
517 sys sys_ni_syscall 0 /* available, was setaltroot */
518 sys sys_add_key 5 /* 4280 */
519 sys sys_request_key 4
521 sys sys_set_thread_area 1
522 sys sys_inotify_init 0
523 sys sys_inotify_add_watch 3 /* 4285 */
524 sys sys_inotify_rm_watch 2
525 sys sys_migrate_pages 4
528 sys sys_mknodat 4 /* 4290 */
533 sys sys_renameat 4 /* 4295 */
538 sys sys_faccessat 3 /* 4300 */
543 sys sys_sync_file_range 7 /* 4305 */
547 sys sys_set_robust_list 2
548 sys sys_get_robust_list 3 /* 4310 */
551 sys sys_epoll_pwait 6
553 sys sys_ioprio_get 2 /* 4315 */
556 sys sys_ni_syscall 0 /* was timerfd */
558 sys sys_fallocate 6 /* 4320 */
559 sys sys_timerfd_create 2
560 sys sys_timerfd_gettime 2
561 sys sys_timerfd_settime 4
563 sys sys_eventfd2 2 /* 4325 */
564 sys sys_epoll_create1 1
567 sys sys_inotify_init1 1
568 sys sys_preadv 6 /* 4330 */
570 sys sys_rt_tgsigqueueinfo 4
571 sys sys_perf_event_open 5
573 sys sys_recvmmsg 5 /* 4335 */
574 sys sys_fanotify_init 2
575 sys sys_fanotify_mark 6
577 sys sys_name_to_handle_at 5
578 sys sys_open_by_handle_at 3 /* 4340 */
579 sys sys_clock_adjtime 2
583 sys sys_process_vm_readv 6 /* 4345 */
584 sys sys_process_vm_writev 6
586 sys sys_finit_module 3
589 /* We pre-compute the number of _instruction_ bytes needed to
590 load or store the arguments 6-8. Negative values are ignored. */
592 .macro sys function, nargs
594 LONG (\nargs << 2) - (5 << 2)
598 .type sys_call_table,@object
599 EXPORT(sys_call_table)
601 .size sys_call_table, . - sys_call_table