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 local_irq_disable # make sure need_resched and
73 # signals dont change between
75 lw a2, TI_FLAGS($28) # current->work
76 li t0, _TIF_ALLWORK_MASK
78 bnez t0, o32_syscall_exit_work
82 o32_syscall_exit_work:
83 j syscall_exit_work_partial
85 /* ------------------------------------------------------------------------ */
91 jal syscall_trace_enter
95 lw a0, PT_R4(sp) # Restore argument registers
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
113 /* ------------------------------------------------------------------------ */
116 * More than four arguments. Try to deal with it by copying the
117 * stack arguments from the user stack to the kernel stack.
121 lw t0, PT_R29(sp) # get old user stack pointer
124 * We intentionally keep the kernel stack a little below the top of
125 * userspace so we don't have to do a slower byte accurate check here.
127 lw t5, TI_ADDR_LIMIT($28)
130 bltz t5, bad_stack # -> sp is bad
132 /* Ok, copy the args from the luser stack to the kernel stack.
133 * t3 is the precomputed number of instruction bytes needed to
134 * load or store arguments 6-8.
137 la t1, 5f # load up to 3 arguments
139 1: lw t5, 16(t0) # argument #5 from usp
146 2: lw t8, 28(t0) # argument #8 from usp
147 3: lw t7, 24(t0) # argument #7 from usp
148 4: lw t6, 20(t0) # argument #6 from usp
150 sw t5, 16(sp) # argument #5 to ksp
152 sw t8, 28(sp) # argument #8 to ksp
153 sw t7, 24(sp) # argument #7 to ksp
154 sw t6, 20(sp) # argument #6 to ksp
155 6: j stack_done # go back
159 .section __ex_table,"a"
167 * The stackpointer for a call with more than 4 arguments is bad.
168 * We probably should handle this case a bit more drastic.
173 li t0, 1 # set error flag
178 * The system call does not exist in this kernel
181 li v0, ENOSYS # error
183 li t0, 1 # set error flag
189 subu t0, a0, __NR_O32_Linux # check syscall number
190 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
191 beqz t0, einval # do not recurse
194 lw t2, sys_call_table(t1) # syscall routine
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
223 .macro fifty ptr, nargs, from=1, to=50
226 fifty \ptr,\nargs,"(\from+1)",\to
230 .macro mille ptr, nargs, from=1, to=20
233 mille \ptr,\nargs,"(\from+1)",\to
238 sys sys_syscall 8 /* 4000 */
243 sys sys_open 3 /* 4005 */
248 sys sys_unlink 1 /* 4010 */
253 sys sys_chmod 2 /* 4015 */
256 sys sys_ni_syscall 0 /* was sys_stat */
258 sys sys_getpid 0 /* 4020 */
263 sys sys_stime 1 /* 4025 */
266 sys sys_ni_syscall 0 /* was sys_fstat */
268 sys sys_utime 2 /* 4030 */
273 sys sys_ni_syscall 0 /* 4035 */
278 sys sys_rmdir 1 /* 4040 */
283 sys sys_brk 1 /* 4045 */
286 sys sys_ni_syscall 0 /* was signal(2) */
288 sys sys_getegid 0 /* 4050 */
293 sys sys_fcntl 3 /* 4055 */
298 sys sys_umask 1 /* 4060 */
303 sys sys_getpgrp 0 /* 4065 */
308 sys sys_setreuid 2 /* 4070 */
312 sys sys_sethostname 2
313 sys sys_setrlimit 2 /* 4075 */
316 sys sys_gettimeofday 2
317 sys sys_settimeofday 2
318 sys sys_getgroups 2 /* 4080 */
320 sys sys_ni_syscall 0 /* old_select */
322 sys sys_ni_syscall 0 /* was sys_lstat */
323 sys sys_readlink 3 /* 4085 */
327 sys sys_old_readdir 3
328 sys sys_mips_mmap 6 /* 4090 */
333 sys sys_fchown 3 /* 4095 */
334 sys sys_getpriority 2
335 sys sys_setpriority 3
338 sys sys_fstatfs 2 /* 4100 */
339 sys sys_ni_syscall 0 /* was ioperm(2) */
343 sys sys_getitimer 2 /* 4105 */
348 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
350 sys sys_ni_syscall 0 /* was sys_idle() */
351 sys sys_ni_syscall 0 /* was sys_vm86 */
353 sys sys_swapoff 1 /* 4115 */
358 sys sys_clone 0 /* 4120 */
359 sys sys_setdomainname 2
361 sys sys_ni_syscall 0 /* sys_modify_ldt */
363 sys sys_mprotect 3 /* 4125 */
364 sys sys_sigprocmask 3
365 sys sys_ni_syscall 0 /* was create_module */
366 sys sys_init_module 5
367 sys sys_delete_module 1
368 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
373 sys sys_sysfs 3 /* 4135 */
374 sys sys_personality 1
375 sys sys_ni_syscall 0 /* for afs_syscall */
378 sys sys_llseek 5 /* 4140 */
383 sys sys_readv 3 /* 4145 */
388 sys sys_ni_syscall 0 /* 4150 */
393 sys sys_munlock 2 /* 4155 */
396 sys sys_sched_setparam 2
397 sys sys_sched_getparam 2
398 sys sys_sched_setscheduler 3 /* 4160 */
399 sys sys_sched_getscheduler 1
400 sys sys_sched_yield 0
401 sys sys_sched_get_priority_max 1
402 sys sys_sched_get_priority_min 1
403 sys sys_sched_rr_get_interval 2 /* 4165 */
408 sys sys_connect 3 /* 4170 */
409 sys sys_getpeername 3
410 sys sys_getsockname 3
413 sys sys_recv 4 /* 4175 */
418 sys sys_sendto 6 /* 4180 */
423 sys sys_setresuid 3 /* 4185 */
425 sys sys_ni_syscall 0 /* was sys_query_module */
428 sys sys_setresgid 3 /* 4190 */
431 sys sys_rt_sigreturn 0
432 sys sys_rt_sigaction 4
433 sys sys_rt_sigprocmask 4 /* 4195 */
434 sys sys_rt_sigpending 2
435 sys sys_rt_sigtimedwait 4
436 sys sys_rt_sigqueueinfo 3
437 sys sys_rt_sigsuspend 0
438 sys sys_pread64 6 /* 4200 */
443 sys sys_capset 2 /* 4205 */
444 sys sys_sigaltstack 0
448 sys sys_mips_mmap2 6 /* 4210 */
450 sys sys_ftruncate64 4
453 sys sys_fstat64 2 /* 4215 */
458 sys sys_fcntl64 3 /* 4220 */
463 sys sys_lsetxattr 5 /* 4225 */
468 sys sys_listxattr 3 /* 4230 */
471 sys sys_removexattr 2
472 sys sys_lremovexattr 2
473 sys sys_fremovexattr 2 /* 4235 */
477 #ifdef CONFIG_MIPS_MT_FPAFF
479 * For FPU affinity scheduling on MIPS MT processors, we need to
480 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
481 * in kernel/sched.c. Considered only temporary we only support these
482 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
484 sys mipsmt_sys_sched_setaffinity 3
485 sys mipsmt_sys_sched_getaffinity 3
487 sys sys_sched_setaffinity 3
488 sys sys_sched_getaffinity 3 /* 4240 */
489 #endif /* CONFIG_MIPS_MT_FPAFF */
492 sys sys_io_getevents 5
494 sys sys_io_cancel 3 /* 4245 */
496 sys sys_lookup_dcookie 4
497 sys sys_epoll_create 1
499 sys sys_epoll_wait 3 /* 4250 */
500 sys sys_remap_file_pages 5
501 sys sys_set_tid_address 1
502 sys sys_restart_syscall 0
503 sys sys_fadvise64_64 7
504 sys sys_statfs64 3 /* 4255 */
506 sys sys_timer_create 3
507 sys sys_timer_settime 4
508 sys sys_timer_gettime 2
509 sys sys_timer_getoverrun 1 /* 4260 */
510 sys sys_timer_delete 1
511 sys sys_clock_settime 2
512 sys sys_clock_gettime 2
513 sys sys_clock_getres 2
514 sys sys_clock_nanosleep 4 /* 4265 */
518 sys sys_ni_syscall 0 /* sys_get_mempolicy */
519 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
522 sys sys_mq_timedsend 5
523 sys sys_mq_timedreceive 5
524 sys sys_mq_notify 2 /* 4275 */
525 sys sys_mq_getsetattr 3
526 sys sys_ni_syscall 0 /* sys_vserver */
528 sys sys_ni_syscall 0 /* available, was setaltroot */
529 sys sys_add_key 5 /* 4280 */
530 sys sys_request_key 4
532 sys sys_set_thread_area 1
533 sys sys_inotify_init 0
534 sys sys_inotify_add_watch 3 /* 4285 */
535 sys sys_inotify_rm_watch 2
536 sys sys_migrate_pages 4
539 sys sys_mknodat 4 /* 4290 */
544 sys sys_renameat 4 /* 4295 */
549 sys sys_faccessat 3 /* 4300 */
554 sys sys_sync_file_range 7 /* 4305 */
558 sys sys_set_robust_list 2
559 sys sys_get_robust_list 3 /* 4310 */
562 sys sys_epoll_pwait 6
564 sys sys_ioprio_get 2 /* 4315 */
567 sys sys_ni_syscall 0 /* was timerfd */
569 sys sys_fallocate 6 /* 4320 */
570 sys sys_timerfd_create 2
571 sys sys_timerfd_gettime 2
572 sys sys_timerfd_settime 4
574 sys sys_eventfd2 2 /* 4325 */
575 sys sys_epoll_create1 1
578 sys sys_inotify_init1 1
579 sys sys_preadv 6 /* 4330 */
581 sys sys_rt_tgsigqueueinfo 4
582 sys sys_perf_event_open 5
584 sys sys_recvmmsg 5 /* 4335 */
585 sys sys_fanotify_init 2
586 sys sys_fanotify_mark 6
588 sys sys_name_to_handle_at 5
589 sys sys_open_by_handle_at 3 /* 4340 */
590 sys sys_clock_adjtime 2
594 /* We pre-compute the number of _instruction_ bytes needed to
595 load or store the arguments 6-8. Negative values are ignored. */
597 .macro sys function, nargs
599 LONG (\nargs << 2) - (5 << 2)
603 .type sys_call_table,@object
604 EXPORT(sys_call_table)
606 .size sys_call_table, . - sys_call_table