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 #ifdef CONFIG_PRINT_SYSCALLS
61 move a0, sp # pass pointer to saved regs
68 lw a0, PT_R4(sp) # Restore argument registers
73 lw t0, TI_FLAGS($28) # syscall tracing enabled?
74 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
76 bnez t0, syscall_trace_entry # -> yes
78 jalr t2 # Do The Real Thing (TM)
80 li t0, -EMAXERRNO - 1 # error?
82 sw t0, PT_R7(sp) # set error flag
85 lw t1, PT_R2(sp) # syscall number
87 sw t1, PT_R0(sp) # save it for syscall restarting
88 1: sw v0, PT_R2(sp) # result
91 local_irq_disable # make sure need_resched and
92 # signals dont change between
94 lw a2, TI_FLAGS($28) # current->work
95 li t0, _TIF_ALLWORK_MASK
97 bnez t0, o32_syscall_exit_work
101 o32_syscall_exit_work:
102 j syscall_exit_work_partial
104 /* ------------------------------------------------------------------------ */
115 lw a0, PT_R4(sp) # Restore argument registers
121 li t0, -EMAXERRNO - 1 # error?
123 sw t0, PT_R7(sp) # set error flag
126 lw t1, PT_R2(sp) # syscall number
128 sw t1, PT_R0(sp) # save it for syscall restarting
129 1: sw v0, PT_R2(sp) # result
133 /* ------------------------------------------------------------------------ */
136 * More than four arguments. Try to deal with it by copying the
137 * stack arguments from the user stack to the kernel stack.
141 lw t0, PT_R29(sp) # get old user stack pointer
144 * We intentionally keep the kernel stack a little below the top of
145 * userspace so we don't have to do a slower byte accurate check here.
147 lw t5, TI_ADDR_LIMIT($28)
150 bltz t5, bad_stack # -> sp is bad
152 /* Ok, copy the args from the luser stack to the kernel stack.
153 * t3 is the precomputed number of instruction bytes needed to
154 * load or store arguments 6-8.
157 la t1, 5f # load up to 3 arguments
159 1: lw t5, 16(t0) # argument #5 from usp
166 2: lw t8, 28(t0) # argument #8 from usp
167 3: lw t7, 24(t0) # argument #7 from usp
168 4: lw t6, 20(t0) # argument #6 from usp
170 sw t5, 16(sp) # argument #5 to ksp
172 sw t8, 28(sp) # argument #8 to ksp
173 sw t7, 24(sp) # argument #7 to ksp
174 sw t6, 20(sp) # argument #6 to ksp
175 6: j stack_done # go back
179 .section __ex_table,"a"
187 * The stackpointer for a call with more than 4 arguments is bad.
188 * We probably should handle this case a bit more drastic.
193 li t0, 1 # set error flag
198 * The system call does not exist in this kernel
201 li v0, ENOSYS # error
203 li t0, 1 # set error flag
208 LEAF(mips_atomic_set)
209 andi v0, a1, 3 # must be word aligned
210 bnez v0, bad_alignment
212 lw v1, TI_ADDR_LIMIT($28) # in legal address range?
218 #ifdef CONFIG_CPU_HAS_LLSC
219 /* Ok, this is the ll/sc case. World is sane :-) */
229 .section __ex_table,"a"
246 * At this point the page should be readable and writable unless
247 * there was no more memory available.
252 .section __ex_table,"a"
258 sw zero, PT_R7(sp) # success
259 sw v0, PT_R2(sp) # result
261 j o32_syscall_exit # continue like a normal syscall
263 no_mem: li v0, -ENOMEM
276 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
281 #if defined(CONFIG_BINFMT_IRIX)
282 sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
284 subu t0, a0, __NR_O32_Linux # check syscall number
285 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
287 beqz t0, einval # do not recurse
290 lw t2, sys_call_table(t1) # syscall routine
292 /* Some syscalls like execve get their arguments from struct pt_regs
293 and claim zero arguments in the syscall table. Thus we have to
294 assume the worst case and shuffle around all potential arguments.
295 If you want performance, don't use indirect syscalls. */
297 move a0, a1 # shift argument registers
307 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
308 sw a1, PT_R5(sp) # syscalls expect them there
311 sw a3, PT_R26(sp) # update a3 for syscall restarting
315 einval: li v0, -ENOSYS
319 .macro fifty ptr, nargs, from=1, to=50
322 fifty \ptr,\nargs,"(\from+1)",\to
326 .macro mille ptr, nargs, from=1, to=20
329 mille \ptr,\nargs,"(\from+1)",\to
334 #if defined(CONFIG_BINFMT_IRIX)
335 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
336 mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */
337 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
338 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
341 sys sys_syscall 8 /* 4000 */
346 sys sys_open 3 /* 4005 */
351 sys sys_unlink 1 /* 4010 */
356 sys sys_chmod 2 /* 4015 */
359 sys sys_ni_syscall 0 /* was sys_stat */
361 sys sys_getpid 0 /* 4020 */
366 sys sys_stime 1 /* 4025 */
369 sys sys_ni_syscall 0 /* was sys_fstat */
371 sys sys_utime 2 /* 4030 */
376 sys sys_ni_syscall 0 /* 4035 */
381 sys sys_rmdir 1 /* 4040 */
386 sys sys_brk 1 /* 4045 */
389 sys sys_ni_syscall 0 /* was signal(2) */
391 sys sys_getegid 0 /* 4050 */
396 sys sys_fcntl 3 /* 4055 */
401 sys sys_umask 1 /* 4060 */
406 sys sys_getpgrp 0 /* 4065 */
411 sys sys_setreuid 2 /* 4070 */
415 sys sys_sethostname 2
416 sys sys_setrlimit 2 /* 4075 */
419 sys sys_gettimeofday 2
420 sys sys_settimeofday 2
421 sys sys_getgroups 2 /* 4080 */
423 sys sys_ni_syscall 0 /* old_select */
425 sys sys_ni_syscall 0 /* was sys_lstat */
426 sys sys_readlink 3 /* 4085 */
431 sys old_mmap 6 /* 4090 */
436 sys sys_fchown 3 /* 4095 */
437 sys sys_getpriority 2
438 sys sys_setpriority 3
441 sys sys_fstatfs 2 /* 4100 */
442 sys sys_ni_syscall 0 /* was ioperm(2) */
446 sys sys_getitimer 2 /* 4105 */
451 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
453 sys sys_ni_syscall 0 /* was sys_idle() */
454 sys sys_ni_syscall 0 /* was sys_vm86 */
456 sys sys_swapoff 1 /* 4115 */
461 sys sys_clone 0 /* 4120 */
462 sys sys_setdomainname 2
464 sys sys_ni_syscall 0 /* sys_modify_ldt */
466 sys sys_mprotect 3 /* 4125 */
467 sys sys_sigprocmask 3
468 sys sys_ni_syscall 0 /* was create_module */
469 sys sys_init_module 5
470 sys sys_delete_module 1
471 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
476 sys sys_sysfs 3 /* 4135 */
477 sys sys_personality 1
478 sys sys_ni_syscall 0 /* for afs_syscall */
481 sys sys_llseek 5 /* 4140 */
486 sys sys_readv 3 /* 4145 */
491 sys sys_ni_syscall 0 /* 4150 */
496 sys sys_munlock 2 /* 4155 */
499 sys sys_sched_setparam 2
500 sys sys_sched_getparam 2
501 sys sys_sched_setscheduler 3 /* 4160 */
502 sys sys_sched_getscheduler 1
503 sys sys_sched_yield 0
504 sys sys_sched_get_priority_max 1
505 sys sys_sched_get_priority_min 1
506 sys sys_sched_rr_get_interval 2 /* 4165 */
511 sys sys_connect 3 /* 4170 */
512 sys sys_getpeername 3
513 sys sys_getsockname 3
516 sys sys_recv 4 /* 4175 */
521 sys sys_sendto 6 /* 4180 */
526 sys sys_setresuid 3 /* 4185 */
528 sys sys_ni_syscall 0 /* was sys_query_module */
531 sys sys_setresgid 3 /* 4190 */
534 sys sys_rt_sigreturn 0
535 sys sys_rt_sigaction 4
536 sys sys_rt_sigprocmask 4 /* 4195 */
537 sys sys_rt_sigpending 2
538 sys sys_rt_sigtimedwait 4
539 sys sys_rt_sigqueueinfo 3
540 sys sys_rt_sigsuspend 0
541 sys sys_pread64 6 /* 4200 */
546 sys sys_capset 2 /* 4205 */
547 sys sys_sigaltstack 0
551 sys sys_mmap2 6 /* 4210 */
553 sys sys_ftruncate64 4
556 sys sys_fstat64 2 /* 4215 */
561 sys sys_fcntl64 3 /* 4220 */
566 sys sys_lsetxattr 5 /* 4225 */
571 sys sys_listxattr 3 /* 4230 */
574 sys sys_removexattr 2
575 sys sys_lremovexattr 2
576 sys sys_fremovexattr 2 /* 4235 */
580 #ifdef CONFIG_MIPS_MT_FPAFF
582 * For FPU affinity scheduling on MIPS MT processors, we need to
583 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
584 * in kernel/sched.c. Considered only temporary we only support these
585 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
587 sys mipsmt_sys_sched_setaffinity 3
588 sys mipsmt_sys_sched_getaffinity 3
590 sys sys_sched_setaffinity 3
591 sys sys_sched_getaffinity 3 /* 4240 */
592 #endif /* CONFIG_MIPS_MT_FPAFF */
595 sys sys_io_getevents 5
597 sys sys_io_cancel 3 /* 4245 */
599 sys sys_lookup_dcookie 4
600 sys sys_epoll_create 1
602 sys sys_epoll_wait 3 /* 4250 */
603 sys sys_remap_file_pages 5
604 sys sys_set_tid_address 1
605 sys sys_restart_syscall 0
606 sys sys_fadvise64_64 7
607 sys sys_statfs64 3 /* 4255 */
609 sys sys_timer_create 3
610 sys sys_timer_settime 4
611 sys sys_timer_gettime 2
612 sys sys_timer_getoverrun 1 /* 4260 */
613 sys sys_timer_delete 1
614 sys sys_clock_settime 2
615 sys sys_clock_gettime 2
616 sys sys_clock_getres 2
617 sys sys_clock_nanosleep 4 /* 4265 */
621 sys sys_ni_syscall 0 /* sys_get_mempolicy */
622 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
625 sys sys_mq_timedsend 5
626 sys sys_mq_timedreceive 5
627 sys sys_mq_notify 2 /* 4275 */
628 sys sys_mq_getsetattr 3
629 sys sys_ni_syscall 0 /* sys_vserver */
631 sys sys_ni_syscall 0 /* available, was setaltroot */
632 sys sys_add_key 5 /* 4280 */
633 sys sys_request_key 4
635 sys sys_set_thread_area 1
636 sys sys_inotify_init 0
637 sys sys_inotify_add_watch 3 /* 4285 */
638 sys sys_inotify_rm_watch 2
639 sys sys_migrate_pages 4
642 sys sys_mknodat 4 /* 4290 */
647 sys sys_renameat 4 /* 4295 */
652 sys sys_faccessat 3 /* 4300 */
657 sys sys_sync_file_range 7 /* 4305 */
661 sys sys_set_robust_list 2
662 sys sys_get_robust_list 3 /* 4310 */
665 sys sys_epoll_pwait 6
667 sys sys_ioprio_get 2 /* 4315 */
672 sys sys_ni_syscall 0 /* 4320 */
673 sys sys_timerfd_create 2
674 sys sys_timerfd_gettime 2
675 sys sys_timerfd_settime 4
678 /* We pre-compute the number of _instruction_ bytes needed to
679 load or store the arguments 6-8. Negative values are ignored. */
681 .macro sys function, nargs
683 LONG (\nargs << 2) - (5 << 2)
687 .type sys_call_table,@object
688 EXPORT(sys_call_table)
690 .size sys_call_table, . - sys_call_table