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 #if defined(CONFIG_BINFMT_IRIX)
38 sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
40 subu v0, v0, __NR_O32_Linux # check syscall number
41 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
43 addiu t1, 4 # skip to next instruction
45 beqz t0, illegal_syscall
50 lw t2, (t1) # syscall routine
51 lw t3, 4(t1) # >= 0 if we need stack arguments
52 beqz t2, illegal_syscall
54 sw a3, PT_R26(sp) # save a3 for syscall restarting
58 lw t0, TI_FLAGS($28) # syscall tracing enabled?
59 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
61 bnez t0, syscall_trace_entry # -> yes
63 jalr t2 # Do The Real Thing (TM)
65 li t0, -EMAXERRNO - 1 # error?
67 sw t0, PT_R7(sp) # set error flag
71 sw v0, PT_R0(sp) # set flag for syscall
73 1: sw v0, PT_R2(sp) # result
76 local_irq_disable # make sure need_resched and
77 # signals dont change between
79 lw a2, TI_FLAGS($28) # current->work
80 li t0, _TIF_ALLWORK_MASK
82 bnez t0, o32_syscall_exit_work
86 o32_syscall_exit_work:
87 j syscall_exit_work_partial
89 /* ------------------------------------------------------------------------ */
100 lw a0, PT_R4(sp) # Restore argument registers
106 li t0, -EMAXERRNO - 1 # error?
108 sw t0, PT_R7(sp) # set error flag
112 sw v0, PT_R0(sp) # set flag for syscall
114 1: sw v0, PT_R2(sp) # result
118 /* ------------------------------------------------------------------------ */
121 * More than four arguments. Try to deal with it by copying the
122 * stack arguments from the user stack to the kernel stack.
126 lw t0, PT_R29(sp) # get old user stack pointer
129 * We intentionally keep the kernel stack a little below the top of
130 * userspace so we don't have to do a slower byte accurate check here.
132 lw t5, TI_ADDR_LIMIT($28)
135 bltz t5, bad_stack # -> sp is bad
137 /* Ok, copy the args from the luser stack to the kernel stack.
138 * t3 is the precomputed number of instruction bytes needed to
139 * load or store arguments 6-8.
142 la t1, 5f # load up to 3 arguments
144 1: lw t5, 16(t0) # argument #5 from usp
151 2: lw t8, 28(t0) # argument #8 from usp
152 3: lw t7, 24(t0) # argument #7 from usp
153 4: lw t6, 20(t0) # argument #6 from usp
155 sw t5, 16(sp) # argument #5 to ksp
157 sw t8, 28(sp) # argument #8 to ksp
158 sw t7, 24(sp) # argument #7 to ksp
159 sw t6, 20(sp) # argument #6 to ksp
160 6: j stack_done # go back
164 .section __ex_table,"a"
172 * The stackpointer for a call with more than 4 arguments is bad.
173 * We probably should handle this case a bit more drastic.
179 li t0, 1 # set error flag
184 * The system call does not exist in this kernel
187 li v0, -ENOSYS # error
189 li t0, 1 # set error flag
194 LEAF(mips_atomic_set)
195 andi v0, a1, 3 # must be word aligned
196 bnez v0, bad_alignment
198 lw v1, TI_ADDR_LIMIT($28) # in legal address range?
204 #ifdef CONFIG_CPU_HAS_LLSC
205 /* Ok, this is the ll/sc case. World is sane :-) */
215 .section __ex_table,"a"
232 * At this point the page should be readable and writable unless
233 * there was no more memory available.
238 .section __ex_table,"a"
244 sw zero, PT_R7(sp) # success
245 sw v0, PT_R2(sp) # result
247 j o32_syscall_exit # continue like a normal syscall
249 no_mem: li v0, -ENOMEM
262 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
267 #if defined(CONFIG_BINFMT_IRIX)
268 sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
270 subu t0, a0, __NR_O32_Linux # check syscall number
271 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
276 lw t2, sys_call_table(t1) # syscall routine
278 #if defined(CONFIG_BINFMT_IRIX)
279 li v1, 4000 # nr of sys_syscall
281 li v1, 4000 - __NR_O32_Linux # index of sys_syscall
283 beq t0, v1, einval # do not recurse
285 /* Some syscalls like execve get their arguments from struct pt_regs
286 and claim zero arguments in the syscall table. Thus we have to
287 assume the worst case and shuffle around all potential arguments.
288 If you want performance, don't use indirect syscalls. */
290 move a0, a1 # shift argument registers
300 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
301 sw a1, PT_R5(sp) # syscalls expect them there
304 sw a3, PT_R26(sp) # update a3 for syscall restarting
308 einval: li v0, -EINVAL
312 .macro fifty ptr, nargs, from=1, to=50
315 fifty \ptr,\nargs,"(\from+1)",\to
319 .macro mille ptr, nargs, from=1, to=20
322 mille \ptr,\nargs,"(\from+1)",\to
327 #if defined(CONFIG_BINFMT_IRIX)
328 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
329 mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */
330 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
331 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
334 sys sys_syscall 8 /* 4000 */
339 sys sys_open 3 /* 4005 */
344 sys sys_unlink 1 /* 4010 */
349 sys sys_chmod 2 /* 4015 */
352 sys sys_ni_syscall 0 /* was sys_stat */
354 sys sys_getpid 0 /* 4020 */
359 sys sys_stime 1 /* 4025 */
362 sys sys_ni_syscall 0 /* was sys_fstat */
364 sys sys_utime 2 /* 4030 */
369 sys sys_ni_syscall 0 /* 4035 */
374 sys sys_rmdir 1 /* 4040 */
379 sys sys_brk 1 /* 4045 */
382 sys sys_ni_syscall 0 /* was signal(2) */
384 sys sys_getegid 0 /* 4050 */
389 sys sys_fcntl 3 /* 4055 */
394 sys sys_umask 1 /* 4060 */
399 sys sys_getpgrp 0 /* 4065 */
404 sys sys_setreuid 2 /* 4070 */
408 sys sys_sethostname 2
409 sys sys_setrlimit 2 /* 4075 */
412 sys sys_gettimeofday 2
413 sys sys_settimeofday 2
414 sys sys_getgroups 2 /* 4080 */
416 sys sys_ni_syscall 0 /* old_select */
418 sys sys_ni_syscall 0 /* was sys_lstat */
419 sys sys_readlink 3 /* 4085 */
424 sys old_mmap 6 /* 4090 */
429 sys sys_fchown 3 /* 4095 */
430 sys sys_getpriority 2
431 sys sys_setpriority 3
434 sys sys_fstatfs 2 /* 4100 */
435 sys sys_ni_syscall 0 /* was ioperm(2) */
439 sys sys_getitimer 2 /* 4105 */
444 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
446 sys sys_ni_syscall 0 /* was sys_idle() */
447 sys sys_ni_syscall 0 /* was sys_vm86 */
449 sys sys_swapoff 1 /* 4115 */
454 sys sys_clone 0 /* 4120 */
455 sys sys_setdomainname 2
457 sys sys_ni_syscall 0 /* sys_modify_ldt */
459 sys sys_mprotect 3 /* 4125 */
460 sys sys_sigprocmask 3
461 sys sys_ni_syscall 0 /* was create_module */
462 sys sys_init_module 5
463 sys sys_delete_module 1
464 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
469 sys sys_sysfs 3 /* 4135 */
470 sys sys_personality 1
471 sys sys_ni_syscall 0 /* for afs_syscall */
474 sys sys_llseek 5 /* 4140 */
479 sys sys_readv 3 /* 4145 */
484 sys sys_ni_syscall 0 /* 4150 */
489 sys sys_munlock 2 /* 4155 */
492 sys sys_sched_setparam 2
493 sys sys_sched_getparam 2
494 sys sys_sched_setscheduler 3 /* 4160 */
495 sys sys_sched_getscheduler 1
496 sys sys_sched_yield 0
497 sys sys_sched_get_priority_max 1
498 sys sys_sched_get_priority_min 1
499 sys sys_sched_rr_get_interval 2 /* 4165 */
504 sys sys_connect 3 /* 4170 */
505 sys sys_getpeername 3
506 sys sys_getsockname 3
509 sys sys_recv 4 /* 4175 */
514 sys sys_sendto 6 /* 4180 */
519 sys sys_setresuid 3 /* 4185 */
521 sys sys_ni_syscall 0 /* was sys_query_module */
524 sys sys_setresgid 3 /* 4190 */
527 sys sys_rt_sigreturn 0
528 sys sys_rt_sigaction 4
529 sys sys_rt_sigprocmask 4 /* 4195 */
530 sys sys_rt_sigpending 2
531 sys sys_rt_sigtimedwait 4
532 sys sys_rt_sigqueueinfo 3
533 sys sys_rt_sigsuspend 0
534 sys sys_pread64 6 /* 4200 */
539 sys sys_capset 2 /* 4205 */
540 sys sys_sigaltstack 0
544 sys sys_mmap2 6 /* 4210 */
546 sys sys_ftruncate64 4
549 sys sys_fstat64 2 /* 4215 */
554 sys sys_fcntl64 3 /* 4220 */
559 sys sys_lsetxattr 5 /* 4225 */
564 sys sys_listxattr 3 /* 4230 */
567 sys sys_removexattr 2
568 sys sys_lremovexattr 2
569 sys sys_fremovexattr 2 /* 4235 */
573 #ifdef CONFIG_MIPS_MT_FPAFF
575 * For FPU affinity scheduling on MIPS MT processors, we need to
576 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
577 * in kernel/sched.c. Considered only temporary we only support these
578 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
580 sys mipsmt_sys_sched_setaffinity 3
581 sys mipsmt_sys_sched_getaffinity 3
583 sys sys_sched_setaffinity 3
584 sys sys_sched_getaffinity 3 /* 4240 */
585 #endif /* CONFIG_MIPS_MT_FPAFF */
588 sys sys_io_getevents 5
590 sys sys_io_cancel 3 /* 4245 */
592 sys sys_lookup_dcookie 4
593 sys sys_epoll_create 1
595 sys sys_epoll_wait 3 /* 4250 */
596 sys sys_remap_file_pages 5
597 sys sys_set_tid_address 1
598 sys sys_restart_syscall 0
599 sys sys_fadvise64_64 7
600 sys sys_statfs64 3 /* 4255 */
602 sys sys_timer_create 3
603 sys sys_timer_settime 4
604 sys sys_timer_gettime 2
605 sys sys_timer_getoverrun 1 /* 4260 */
606 sys sys_timer_delete 1
607 sys sys_clock_settime 2
608 sys sys_clock_gettime 2
609 sys sys_clock_getres 2
610 sys sys_clock_nanosleep 4 /* 4265 */
614 sys sys_ni_syscall 0 /* sys_get_mempolicy */
615 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
618 sys sys_mq_timedsend 5
619 sys sys_mq_timedreceive 5
620 sys sys_mq_notify 2 /* 4275 */
621 sys sys_mq_getsetattr 3
622 sys sys_ni_syscall 0 /* sys_vserver */
624 sys sys_ni_syscall 0 /* available, was setaltroot */
625 sys sys_add_key 5 /* 4280 */
626 sys sys_request_key 4
628 sys sys_set_thread_area 1
629 sys sys_inotify_init 0
630 sys sys_inotify_add_watch 3 /* 4285 */
631 sys sys_inotify_rm_watch 2
632 sys sys_migrate_pages 4
635 sys sys_mknodat 4 /* 4290 */
640 sys sys_renameat 4 /* 4295 */
645 sys sys_faccessat 3 /* 4300 */
650 sys sys_sync_file_range 7 /* 4305 */
654 sys sys_set_robust_list 2
655 sys sys_get_robust_list 3 /* 4310 */
658 sys sys_epoll_pwait 6
661 /* We pre-compute the number of _instruction_ bytes needed to
662 load or store the arguments 6-8. Negative values are ignored. */
664 .macro sys function, nargs
666 LONG (\nargs << 2) - (5 << 2)
670 .type sys_call_table,@object
671 EXPORT(sys_call_table)
673 .size sys_call_table, . - sys_call_table