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)
31 #ifdef CONFIG_TRACE_IRQFLAGS
46 lw t1, PT_EPC(sp) # skip syscall on return
48 #if defined(CONFIG_BINFMT_IRIX)
49 sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
51 subu v0, v0, __NR_O32_Linux # check syscall number
52 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
54 addiu t1, 4 # skip to next instruction
56 beqz t0, illegal_syscall
61 lw t2, (t1) # syscall routine
62 lw t3, 4(t1) # >= 0 if we need stack arguments
63 beqz t2, illegal_syscall
65 sw a3, PT_R26(sp) # save a3 for syscall restarting
69 lw t0, TI_FLAGS($28) # syscall tracing enabled?
70 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
72 bnez t0, syscall_trace_entry # -> yes
74 jalr t2 # Do The Real Thing (TM)
76 li t0, -EMAXERRNO - 1 # error?
78 sw t0, PT_R7(sp) # set error flag
82 sw v0, PT_R0(sp) # set flag for syscall
84 1: sw v0, PT_R2(sp) # result
87 local_irq_disable # make sure need_resched and
88 # signals dont change between
90 lw a2, TI_FLAGS($28) # current->work
91 li t0, _TIF_ALLWORK_MASK
93 bnez t0, o32_syscall_exit_work
97 o32_syscall_exit_work:
98 j syscall_exit_work_partial
100 /* ------------------------------------------------------------------------ */
111 lw a0, PT_R4(sp) # Restore argument registers
117 li t0, -EMAXERRNO - 1 # error?
119 sw t0, PT_R7(sp) # set error flag
123 sw v0, PT_R0(sp) # set flag for syscall
125 1: sw v0, PT_R2(sp) # result
129 /* ------------------------------------------------------------------------ */
132 * More than four arguments. Try to deal with it by copying the
133 * stack arguments from the user stack to the kernel stack.
137 lw t0, PT_R29(sp) # get old user stack pointer
140 * We intentionally keep the kernel stack a little below the top of
141 * userspace so we don't have to do a slower byte accurate check here.
143 lw t5, TI_ADDR_LIMIT($28)
146 bltz t5, bad_stack # -> sp is bad
148 /* Ok, copy the args from the luser stack to the kernel stack.
149 * t3 is the precomputed number of instruction bytes needed to
150 * load or store arguments 6-8.
153 la t1, 5f # load up to 3 arguments
155 1: lw t5, 16(t0) # argument #5 from usp
162 2: lw t8, 28(t0) # argument #8 from usp
163 3: lw t7, 24(t0) # argument #7 from usp
164 4: lw t6, 20(t0) # argument #6 from usp
166 sw t5, 16(sp) # argument #5 to ksp
168 sw t8, 28(sp) # argument #8 to ksp
169 sw t7, 24(sp) # argument #7 to ksp
170 sw t6, 20(sp) # argument #6 to ksp
171 6: j stack_done # go back
175 .section __ex_table,"a"
183 * The stackpointer for a call with more than 4 arguments is bad.
184 * We probably should handle this case a bit more drastic.
190 li t0, 1 # set error flag
195 * The system call does not exist in this kernel
198 li v0, -ENOSYS # error
200 li t0, 1 # set error flag
205 LEAF(mips_atomic_set)
206 andi v0, a1, 3 # must be word aligned
207 bnez v0, bad_alignment
209 lw v1, TI_ADDR_LIMIT($28) # in legal address range?
215 #ifdef CONFIG_CPU_HAS_LLSC
216 /* Ok, this is the ll/sc case. World is sane :-) */
226 .section __ex_table,"a"
243 * At this point the page should be readable and writable unless
244 * there was no more memory available.
249 .section __ex_table,"a"
255 sw zero, PT_R7(sp) # success
256 sw v0, PT_R2(sp) # result
258 j o32_syscall_exit # continue like a normal syscall
260 no_mem: li v0, -ENOMEM
273 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
278 #if defined(CONFIG_BINFMT_IRIX)
279 sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
281 subu t0, a0, __NR_O32_Linux # check syscall number
282 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
287 lw t2, sys_call_table(t1) # syscall routine
289 #if defined(CONFIG_BINFMT_IRIX)
290 li v1, 4000 # nr of sys_syscall
292 li v1, 4000 - __NR_O32_Linux # index of sys_syscall
294 beq t0, v1, einval # do not recurse
296 /* Some syscalls like execve get their arguments from struct pt_regs
297 and claim zero arguments in the syscall table. Thus we have to
298 assume the worst case and shuffle around all potential arguments.
299 If you want performance, don't use indirect syscalls. */
301 move a0, a1 # shift argument registers
311 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
312 sw a1, PT_R5(sp) # syscalls expect them there
315 sw a3, PT_R26(sp) # update a3 for syscall restarting
319 einval: li v0, -EINVAL
323 .macro fifty ptr, nargs, from=1, to=50
326 fifty \ptr,\nargs,"(\from+1)",\to
330 .macro mille ptr, nargs, from=1, to=20
333 mille \ptr,\nargs,"(\from+1)",\to
338 #if defined(CONFIG_BINFMT_IRIX)
339 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
340 mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */
341 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
342 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
345 sys sys_syscall 8 /* 4000 */
350 sys sys_open 3 /* 4005 */
355 sys sys_unlink 1 /* 4010 */
360 sys sys_chmod 2 /* 4015 */
363 sys sys_ni_syscall 0 /* was sys_stat */
365 sys sys_getpid 0 /* 4020 */
370 sys sys_stime 1 /* 4025 */
373 sys sys_ni_syscall 0 /* was sys_fstat */
375 sys sys_utime 2 /* 4030 */
380 sys sys_ni_syscall 0 /* 4035 */
385 sys sys_rmdir 1 /* 4040 */
390 sys sys_brk 1 /* 4045 */
393 sys sys_ni_syscall 0 /* was signal(2) */
395 sys sys_getegid 0 /* 4050 */
400 sys sys_fcntl 3 /* 4055 */
405 sys sys_umask 1 /* 4060 */
410 sys sys_getpgrp 0 /* 4065 */
415 sys sys_setreuid 2 /* 4070 */
419 sys sys_sethostname 2
420 sys sys_setrlimit 2 /* 4075 */
423 sys sys_gettimeofday 2
424 sys sys_settimeofday 2
425 sys sys_getgroups 2 /* 4080 */
427 sys sys_ni_syscall 0 /* old_select */
429 sys sys_ni_syscall 0 /* was sys_lstat */
430 sys sys_readlink 3 /* 4085 */
435 sys old_mmap 6 /* 4090 */
440 sys sys_fchown 3 /* 4095 */
441 sys sys_getpriority 2
442 sys sys_setpriority 3
445 sys sys_fstatfs 2 /* 4100 */
446 sys sys_ni_syscall 0 /* was ioperm(2) */
450 sys sys_getitimer 2 /* 4105 */
455 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
457 sys sys_ni_syscall 0 /* was sys_idle() */
458 sys sys_ni_syscall 0 /* was sys_vm86 */
460 sys sys_swapoff 1 /* 4115 */
465 sys sys_clone 0 /* 4120 */
466 sys sys_setdomainname 2
468 sys sys_ni_syscall 0 /* sys_modify_ldt */
470 sys sys_mprotect 3 /* 4125 */
471 sys sys_sigprocmask 3
472 sys sys_ni_syscall 0 /* was create_module */
473 sys sys_init_module 5
474 sys sys_delete_module 1
475 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
480 sys sys_sysfs 3 /* 4135 */
481 sys sys_personality 1
482 sys sys_ni_syscall 0 /* for afs_syscall */
485 sys sys_llseek 5 /* 4140 */
490 sys sys_readv 3 /* 4145 */
495 sys sys_ni_syscall 0 /* 4150 */
500 sys sys_munlock 2 /* 4155 */
503 sys sys_sched_setparam 2
504 sys sys_sched_getparam 2
505 sys sys_sched_setscheduler 3 /* 4160 */
506 sys sys_sched_getscheduler 1
507 sys sys_sched_yield 0
508 sys sys_sched_get_priority_max 1
509 sys sys_sched_get_priority_min 1
510 sys sys_sched_rr_get_interval 2 /* 4165 */
515 sys sys_connect 3 /* 4170 */
516 sys sys_getpeername 3
517 sys sys_getsockname 3
520 sys sys_recv 4 /* 4175 */
525 sys sys_sendto 6 /* 4180 */
530 sys sys_setresuid 3 /* 4185 */
532 sys sys_ni_syscall 0 /* was sys_query_module */
535 sys sys_setresgid 3 /* 4190 */
538 sys sys_rt_sigreturn 0
539 sys sys_rt_sigaction 4
540 sys sys_rt_sigprocmask 4 /* 4195 */
541 sys sys_rt_sigpending 2
542 sys sys_rt_sigtimedwait 4
543 sys sys_rt_sigqueueinfo 3
544 sys sys_rt_sigsuspend 0
545 sys sys_pread64 6 /* 4200 */
550 sys sys_capset 2 /* 4205 */
551 sys sys_sigaltstack 0
555 sys sys_mmap2 6 /* 4210 */
557 sys sys_ftruncate64 4
560 sys sys_fstat64 2 /* 4215 */
565 sys sys_fcntl64 3 /* 4220 */
570 sys sys_lsetxattr 5 /* 4225 */
575 sys sys_listxattr 3 /* 4230 */
578 sys sys_removexattr 2
579 sys sys_lremovexattr 2
580 sys sys_fremovexattr 2 /* 4235 */
584 #ifdef CONFIG_MIPS_MT_FPAFF
586 * For FPU affinity scheduling on MIPS MT processors, we need to
587 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
588 * in kernel/sched.c. Considered only temporary we only support these
589 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
591 sys mipsmt_sys_sched_setaffinity 3
592 sys mipsmt_sys_sched_getaffinity 3
594 sys sys_sched_setaffinity 3
595 sys sys_sched_getaffinity 3 /* 4240 */
596 #endif /* CONFIG_MIPS_MT_FPAFF */
599 sys sys_io_getevents 5
601 sys sys_io_cancel 3 /* 4245 */
603 sys sys_lookup_dcookie 4
604 sys sys_epoll_create 1
606 sys sys_epoll_wait 3 /* 4250 */
607 sys sys_remap_file_pages 5
608 sys sys_set_tid_address 1
609 sys sys_restart_syscall 0
610 sys sys_fadvise64_64 7
611 sys sys_statfs64 3 /* 4255 */
613 sys sys_timer_create 3
614 sys sys_timer_settime 4
615 sys sys_timer_gettime 2
616 sys sys_timer_getoverrun 1 /* 4260 */
617 sys sys_timer_delete 1
618 sys sys_clock_settime 2
619 sys sys_clock_gettime 2
620 sys sys_clock_getres 2
621 sys sys_clock_nanosleep 4 /* 4265 */
625 sys sys_ni_syscall 0 /* sys_get_mempolicy */
626 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
629 sys sys_mq_timedsend 5
630 sys sys_mq_timedreceive 5
631 sys sys_mq_notify 2 /* 4275 */
632 sys sys_mq_getsetattr 3
633 sys sys_ni_syscall 0 /* sys_vserver */
635 sys sys_ni_syscall 0 /* available, was setaltroot */
636 sys sys_add_key 5 /* 4280 */
637 sys sys_request_key 4
639 sys sys_set_thread_area 1
640 sys sys_inotify_init 0
641 sys sys_inotify_add_watch 3 /* 4285 */
642 sys sys_inotify_rm_watch 2
643 sys sys_migrate_pages 4
646 sys sys_mknodat 4 /* 4290 */
651 sys sys_renameat 4 /* 4295 */
656 sys sys_faccessat 3 /* 4300 */
661 sys sys_sync_file_range 7 /* 4305 */
667 /* We pre-compute the number of _instruction_ bytes needed to
668 load or store the arguments 6-8. Negative values are ignored. */
670 .macro sys function, nargs
672 LONG (\nargs << 2) - (5 << 2)
676 .type sys_call_table,@object
677 EXPORT(sys_call_table)
679 .size sys_call_table, . - sys_call_table