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, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
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/mipsregs.h>
14 #include <asm/regdef.h>
15 #include <asm/stackframe.h>
16 #include <asm/isadep.h>
17 #include <asm/sysmips.h>
18 #include <asm/thread_info.h>
19 #include <asm/unistd.h>
21 #include <asm/asm-offsets.h>
23 /* Highest syscall used of any syscall flavour */
24 #define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls
27 NESTED(handle_sys, PT_SIZE, sp)
33 lw t1, PT_EPC(sp) # skip syscall on return
35 #if defined(CONFIG_BINFMT_IRIX)
36 sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
38 subu v0, v0, __NR_O32_Linux # check syscall number
39 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
41 addiu t1, 4 # skip to next instruction
43 beqz t0, illegal_syscall
48 lw t2, (t1) # syscall routine
49 lw t3, 4(t1) # >= 0 if we need stack arguments
50 beqz t2, illegal_syscall
52 sw a3, PT_R26(sp) # save a3 for syscall restarting
56 lw t0, TI_FLAGS($28) # syscall tracing enabled?
57 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
59 bnez t0, syscall_trace_entry # -> yes
61 jalr t2 # Do The Real Thing (TM)
63 li t0, -EMAXERRNO - 1 # error?
65 sw t0, PT_R7(sp) # set error flag
69 sw v0, PT_R0(sp) # set flag for syscall
71 1: sw v0, PT_R2(sp) # result
74 local_irq_disable # make sure need_resched and
75 # signals dont change between
77 lw a2, TI_FLAGS($28) # current->work
78 li t0, _TIF_ALLWORK_MASK
80 bnez t0, o32_syscall_exit_work
84 o32_syscall_exit_work:
85 j syscall_exit_work_partial
87 /* ------------------------------------------------------------------------ */
98 lw a0, PT_R4(sp) # Restore argument registers
104 li t0, -EMAXERRNO - 1 # error?
106 sw t0, PT_R7(sp) # set error flag
110 sw v0, PT_R0(sp) # set flag for syscall
112 1: sw v0, PT_R2(sp) # result
116 /* ------------------------------------------------------------------------ */
119 * More than four arguments. Try to deal with it by copying the
120 * stack arguments from the user stack to the kernel stack.
124 lw t0, PT_R29(sp) # get old user stack pointer
127 * We intentionally keep the kernel stack a little below the top of
128 * userspace so we don't have to do a slower byte accurate check here.
130 lw t5, TI_ADDR_LIMIT($28)
133 bltz t5, bad_stack # -> sp is bad
135 /* Ok, copy the args from the luser stack to the kernel stack.
136 * t3 is the precomputed number of instruction bytes needed to
137 * load or store arguments 6-8.
140 la t1, 5f # load up to 3 arguments
142 1: lw t5, 16(t0) # argument #5 from usp
149 2: lw t8, 28(t0) # argument #8 from usp
150 3: lw t7, 24(t0) # argument #7 from usp
151 4: lw t6, 20(t0) # argument #6 from usp
153 sw t5, 16(sp) # argument #5 to ksp
155 sw t8, 28(sp) # argument #8 to ksp
156 sw t7, 24(sp) # argument #7 to ksp
157 sw t6, 20(sp) # argument #6 to ksp
158 6: j stack_done # go back
162 .section __ex_table,"a"
170 * The stackpointer for a call with more than 4 arguments is bad.
171 * We probably should handle this case a bit more drastic.
177 li t0, 1 # set error flag
182 * The system call does not exist in this kernel
185 li v0, -ENOSYS # error
187 li t0, 1 # set error flag
192 LEAF(mips_atomic_set)
193 andi v0, a1, 3 # must be word aligned
194 bnez v0, bad_alignment
196 lw v1, TI_ADDR_LIMIT($28) # in legal address range?
202 #ifdef CONFIG_CPU_HAS_LLSC
203 /* Ok, this is the ll/sc case. World is sane :-) */
213 .section __ex_table,"a"
230 * At this point the page should be readable and writable unless
231 * there was no more memory available.
236 .section __ex_table,"a"
242 sw zero, PT_R7(sp) # success
243 sw v0, PT_R2(sp) # result
245 j o32_syscall_exit # continue like a normal syscall
247 no_mem: li v0, -ENOMEM
260 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
265 #if defined(CONFIG_BINFMT_IRIX)
266 sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
268 subu t0, a0, __NR_O32_Linux # check syscall number
269 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
274 lw t2, sys_call_table(t1) # syscall routine
276 #if defined(CONFIG_BINFMT_IRIX)
277 li v1, 4000 # nr of sys_syscall
279 li v1, 4000 - __NR_O32_Linux # index of sys_syscall
281 beq t0, v1, einval # do not recurse
283 /* Some syscalls like execve get their arguments from struct pt_regs
284 and claim zero arguments in the syscall table. Thus we have to
285 assume the worst case and shuffle around all potential arguments.
286 If you want performance, don't use indirect syscalls. */
288 move a0, a1 # shift argument registers
298 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
299 sw a1, PT_R5(sp) # syscalls expect them there
302 sw a3, PT_R26(sp) # update a3 for syscall restarting
306 einval: li v0, -EINVAL
310 .macro fifty ptr, nargs, from=1, to=50
313 fifty \ptr,\nargs,"(\from+1)",\to
317 .macro mille ptr, nargs, from=1, to=20
320 mille \ptr,\nargs,"(\from+1)",\to
325 #if defined(CONFIG_BINFMT_IRIX)
326 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
327 mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */
328 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
329 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
332 sys sys_syscall 8 /* 4000 */
337 sys sys_open 3 /* 4005 */
342 sys sys_unlink 1 /* 4010 */
347 sys sys_chmod 2 /* 4015 */
350 sys sys_ni_syscall 0 /* was sys_stat */
352 sys sys_getpid 0 /* 4020 */
357 sys sys_stime 1 /* 4025 */
360 sys sys_ni_syscall 0 /* was sys_fstat */
362 sys sys_utime 2 /* 4030 */
367 sys sys_ni_syscall 0 /* 4035 */
372 sys sys_rmdir 1 /* 4040 */
377 sys sys_brk 1 /* 4045 */
380 sys sys_ni_syscall 0 /* was signal(2) */
382 sys sys_getegid 0 /* 4050 */
387 sys sys_fcntl 3 /* 4055 */
392 sys sys_umask 1 /* 4060 */
397 sys sys_getpgrp 0 /* 4065 */
402 sys sys_setreuid 2 /* 4070 */
406 sys sys_sethostname 2
407 sys sys_setrlimit 2 /* 4075 */
410 sys sys_gettimeofday 2
411 sys sys_settimeofday 2
412 sys sys_getgroups 2 /* 4080 */
414 sys sys_ni_syscall 0 /* old_select */
416 sys sys_ni_syscall 0 /* was sys_lstat */
417 sys sys_readlink 3 /* 4085 */
422 sys old_mmap 6 /* 4090 */
427 sys sys_fchown 3 /* 4095 */
428 sys sys_getpriority 2
429 sys sys_setpriority 3
432 sys sys_fstatfs 2 /* 4100 */
433 sys sys_ni_syscall 0 /* was ioperm(2) */
437 sys sys_getitimer 2 /* 4105 */
442 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
444 sys sys_ni_syscall 0 /* was sys_idle() */
445 sys sys_ni_syscall 0 /* was sys_vm86 */
447 sys sys_swapoff 1 /* 4115 */
452 sys sys_clone 0 /* 4120 */
453 sys sys_setdomainname 2
455 sys sys_ni_syscall 0 /* sys_modify_ldt */
457 sys sys_mprotect 3 /* 4125 */
458 sys sys_sigprocmask 3
459 sys sys_ni_syscall 0 /* was create_module */
460 sys sys_init_module 5
461 sys sys_delete_module 1
462 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
467 sys sys_sysfs 3 /* 4135 */
468 sys sys_personality 1
469 sys sys_ni_syscall 0 /* for afs_syscall */
472 sys sys_llseek 5 /* 4140 */
477 sys sys_readv 3 /* 4145 */
482 sys sys_ni_syscall 0 /* 4150 */
487 sys sys_munlock 2 /* 4155 */
490 sys sys_sched_setparam 2
491 sys sys_sched_getparam 2
492 sys sys_sched_setscheduler 3 /* 4160 */
493 sys sys_sched_getscheduler 1
494 sys sys_sched_yield 0
495 sys sys_sched_get_priority_max 1
496 sys sys_sched_get_priority_min 1
497 sys sys_sched_rr_get_interval 2 /* 4165 */
502 sys sys_connect 3 /* 4170 */
503 sys sys_getpeername 3
504 sys sys_getsockname 3
507 sys sys_recv 4 /* 4175 */
512 sys sys_sendto 6 /* 4180 */
517 sys sys_setresuid 3 /* 4185 */
519 sys sys_ni_syscall 0 /* was sys_query_module */
522 sys sys_setresgid 3 /* 4190 */
525 sys sys_rt_sigreturn 0
526 sys sys_rt_sigaction 4
527 sys sys_rt_sigprocmask 4 /* 4195 */
528 sys sys_rt_sigpending 2
529 sys sys_rt_sigtimedwait 4
530 sys sys_rt_sigqueueinfo 3
531 sys sys_rt_sigsuspend 0
532 sys sys_pread64 6 /* 4200 */
537 sys sys_capset 2 /* 4205 */
538 sys sys_sigaltstack 0
542 sys sys_mmap2 6 /* 4210 */
544 sys sys_ftruncate64 4
547 sys sys_fstat64 2 /* 4215 */
552 sys sys_fcntl64 3 /* 4220 */
557 sys sys_lsetxattr 5 /* 4225 */
562 sys sys_listxattr 3 /* 4230 */
565 sys sys_removexattr 2
566 sys sys_lremovexattr 2
567 sys sys_fremovexattr 2 /* 4235 */
571 #ifdef CONFIG_MIPS_MT_FPAFF
573 * For FPU affinity scheduling on MIPS MT processors, we need to
574 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
575 * in kernel/sched.c. Considered only temporary we only support these
576 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
578 sys mipsmt_sys_sched_setaffinity 3
579 sys mipsmt_sys_sched_getaffinity 3
581 sys sys_sched_setaffinity 3
582 sys sys_sched_getaffinity 3 /* 4240 */
583 #endif /* CONFIG_MIPS_MT_FPAFF */
586 sys sys_io_getevents 5
588 sys sys_io_cancel 3 /* 4245 */
590 sys sys_lookup_dcookie 4
591 sys sys_epoll_create 1
593 sys sys_epoll_wait 3 /* 4250 */
594 sys sys_remap_file_pages 5
595 sys sys_set_tid_address 1
596 sys sys_restart_syscall 0
597 sys sys_fadvise64_64 7
598 sys sys_statfs64 3 /* 4255 */
600 sys sys_timer_create 3
601 sys sys_timer_settime 4
602 sys sys_timer_gettime 2
603 sys sys_timer_getoverrun 1 /* 4260 */
604 sys sys_timer_delete 1
605 sys sys_clock_settime 2
606 sys sys_clock_gettime 2
607 sys sys_clock_getres 2
608 sys sys_clock_nanosleep 4 /* 4265 */
612 sys sys_ni_syscall 0 /* sys_get_mempolicy */
613 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
616 sys sys_mq_timedsend 5
617 sys sys_mq_timedreceive 5
618 sys sys_mq_notify 2 /* 4275 */
619 sys sys_mq_getsetattr 3
620 sys sys_ni_syscall 0 /* sys_vserver */
622 sys sys_ni_syscall 0 /* available, was setaltroot */
623 sys sys_add_key 5 /* 4280 */
624 sys sys_request_key 4
626 sys sys_set_thread_area 1
627 sys sys_inotify_init 0
628 sys sys_inotify_add_watch 3 /* 4285 */
629 sys sys_inotify_rm_watch 2
630 sys sys_migrate_pages 4
633 sys sys_mknodat 4 /* 4290 */
638 sys sys_renameat 4 /* 4295 */
643 sys sys_faccessat 3 /* 4300 */
648 sys sys_sync_file_range 7 /* 4305 */
652 /* We pre-compute the number of _instruction_ bytes needed to
653 load or store the arguments 6-8. Negative values are ignored. */
655 .macro sys function, nargs
657 LONG (\nargs << 2) - (5 << 2)
661 .type sys_call_table,@object
662 EXPORT(sys_call_table)
664 .size sys_call_table, . - sys_call_table