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/config.h>
11 #include <linux/errno.h>
13 #include <asm/asmmacro.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)
34 lw t1, PT_EPC(sp) # skip syscall on return
36 #if defined(CONFIG_BINFMT_IRIX)
37 sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
39 subu v0, v0, __NR_O32_Linux # check syscall number
40 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
42 addiu t1, 4 # skip to next instruction
44 beqz t0, illegal_syscall
49 lw t2, (t1) # syscall routine
50 lw t3, 4(t1) # >= 0 if we need stack arguments
51 beqz t2, illegal_syscall
53 sw a3, PT_R26(sp) # save a3 for syscall restarting
57 lw t0, TI_FLAGS($28) # syscall tracing enabled?
58 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
60 bnez t0, syscall_trace_entry # -> yes
62 jalr t2 # Do The Real Thing (TM)
64 li t0, -EMAXERRNO - 1 # error?
66 sw t0, PT_R7(sp) # set error flag
70 sw v0, PT_R0(sp) # set flag for syscall
72 1: sw v0, PT_R2(sp) # result
75 local_irq_disable # make sure need_resched and
76 # signals dont change between
78 lw a2, TI_FLAGS($28) # current->work
79 li t0, _TIF_ALLWORK_MASK
81 bnez t0, o32_syscall_exit_work
85 o32_syscall_exit_work:
86 j syscall_exit_work_partial
88 /* ------------------------------------------------------------------------ */
97 lw a0, PT_R4(sp) # Restore argument registers
103 li t0, -EMAXERRNO - 1 # error?
105 sw t0, PT_R7(sp) # set error flag
109 sw v0, PT_R0(sp) # set flag for syscall
111 1: sw v0, PT_R2(sp) # result
115 /* ------------------------------------------------------------------------ */
118 * More than four arguments. Try to deal with it by copying the
119 * stack arguments from the user stack to the kernel stack.
123 lw t0, PT_R29(sp) # get old user stack pointer
126 * We intentionally keep the kernel stack a little below the top of
127 * userspace so we don't have to do a slower byte accurate check here.
129 lw t5, TI_ADDR_LIMIT($28)
132 bltz t5, bad_stack # -> sp is bad
134 /* Ok, copy the args from the luser stack to the kernel stack.
135 * t3 is the precomputed number of instruction bytes needed to
136 * load or store arguments 6-8.
139 la t1, 5f # load up to 3 arguments
141 1: lw t5, 16(t0) # argument #5 from usp
148 2: lw t8, 28(t0) # argument #8 from usp
149 3: lw t7, 24(t0) # argument #7 from usp
150 4: lw t6, 20(t0) # argument #6 from usp
152 sw t5, 16(sp) # argument #5 to ksp
154 sw t8, 28(sp) # argument #8 to ksp
155 sw t7, 24(sp) # argument #7 to ksp
156 sw t6, 20(sp) # argument #6 to ksp
157 6: j stack_done # go back
161 .section __ex_table,"a"
169 * The stackpointer for a call with more than 4 arguments is bad.
170 * We probably should handle this case a bit more drastic.
176 li t0, 1 # set error flag
181 * The system call does not exist in this kernel
184 li v0, -ENOSYS # error
186 li t0, 1 # set error flag
191 LEAF(mips_atomic_set)
192 andi v0, a1, 3 # must be word aligned
193 bnez v0, bad_alignment
195 lw v1, TI_ADDR_LIMIT($28) # in legal address range?
201 #ifdef CONFIG_CPU_HAS_LLSC
202 /* Ok, this is the ll/sc case. World is sane :-) */
212 .section __ex_table,"a"
229 * At this point the page should be readable and writable unless
230 * there was no more memory available.
235 .section __ex_table,"a"
241 sw zero, PT_R7(sp) # success
242 sw v0, PT_R2(sp) # result
244 /* Success, so skip usual error handling garbage. */
245 lw a2, TI_FLAGS($28) # syscall tracing enabled?
246 li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
258 no_mem: li v0, -ENOMEM
271 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
276 #if defined(CONFIG_BINFMT_IRIX)
277 sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
279 subu t0, a0, __NR_O32_Linux # check syscall number
280 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
285 lw t2, sys_call_table(t1) # syscall routine
287 #if defined(CONFIG_BINFMT_IRIX)
288 li v1, 4000 # nr of sys_syscall
290 li v1, 4000 - __NR_O32_Linux # index of sys_syscall
292 beq t0, v1, einval # do not recurse
294 /* Some syscalls like execve get their arguments from struct pt_regs
295 and claim zero arguments in the syscall table. Thus we have to
296 assume the worst case and shuffle around all potential arguments.
297 If you want performance, don't use indirect syscalls. */
299 move a0, a1 # shift argument registers
309 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
310 sw a1, PT_R5(sp) # syscalls expect them there
313 sw a3, PT_R26(sp) # update a3 for syscall restarting
317 einval: li v0, -EINVAL
321 .macro fifty ptr, nargs, from=1, to=50
324 fifty \ptr,\nargs,"(\from+1)",\to
328 .macro mille ptr, nargs, from=1, to=20
331 mille \ptr,\nargs,"(\from+1)",\to
336 #if defined(CONFIG_BINFMT_IRIX)
337 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
338 mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */
339 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
340 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
343 sys sys_syscall 8 /* 4000 */
348 sys sys_open 3 /* 4005 */
353 sys sys_unlink 1 /* 4010 */
358 sys sys_chmod 2 /* 4015 */
361 sys sys_ni_syscall 0 /* was sys_stat */
363 sys sys_getpid 0 /* 4020 */
368 sys sys_stime 1 /* 4025 */
371 sys sys_ni_syscall 0 /* was sys_fstat */
373 sys sys_utime 2 /* 4030 */
378 sys sys_ni_syscall 0 /* 4035 */
383 sys sys_rmdir 1 /* 4040 */
388 sys sys_brk 1 /* 4045 */
391 sys sys_ni_syscall 0 /* was signal(2) */
393 sys sys_getegid 0 /* 4050 */
398 sys sys_fcntl 3 /* 4055 */
403 sys sys_umask 1 /* 4060 */
408 sys sys_getpgrp 0 /* 4065 */
413 sys sys_setreuid 2 /* 4070 */
417 sys sys_sethostname 2
418 sys sys_setrlimit 2 /* 4075 */
421 sys sys_gettimeofday 2
422 sys sys_settimeofday 2
423 sys sys_getgroups 2 /* 4080 */
425 sys sys_ni_syscall 0 /* old_select */
427 sys sys_ni_syscall 0 /* was sys_lstat */
428 sys sys_readlink 3 /* 4085 */
433 sys old_mmap 6 /* 4090 */
438 sys sys_fchown 3 /* 4095 */
439 sys sys_getpriority 2
440 sys sys_setpriority 3
443 sys sys_fstatfs 2 /* 4100 */
444 sys sys_ni_syscall 0 /* was ioperm(2) */
448 sys sys_getitimer 2 /* 4105 */
453 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
455 sys sys_ni_syscall 0 /* was sys_idle() */
456 sys sys_ni_syscall 0 /* was sys_vm86 */
458 sys sys_swapoff 1 /* 4115 */
463 sys sys_clone 0 /* 4120 */
464 sys sys_setdomainname 2
466 sys sys_ni_syscall 0 /* sys_modify_ldt */
468 sys sys_mprotect 3 /* 4125 */
469 sys sys_sigprocmask 3
470 sys sys_ni_syscall 0 /* was create_module */
471 sys sys_init_module 5
472 sys sys_delete_module 1
473 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
478 sys sys_sysfs 3 /* 4135 */
479 sys sys_personality 1
480 sys sys_ni_syscall 0 /* for afs_syscall */
483 sys sys_llseek 5 /* 4140 */
488 sys sys_readv 3 /* 4145 */
493 sys sys_ni_syscall 0 /* 4150 */
498 sys sys_munlock 2 /* 4155 */
501 sys sys_sched_setparam 2
502 sys sys_sched_getparam 2
503 sys sys_sched_setscheduler 3 /* 4160 */
504 sys sys_sched_getscheduler 1
505 sys sys_sched_yield 0
506 sys sys_sched_get_priority_max 1
507 sys sys_sched_get_priority_min 1
508 sys sys_sched_rr_get_interval 2 /* 4165 */
513 sys sys_connect 3 /* 4170 */
514 sys sys_getpeername 3
515 sys sys_getsockname 3
518 sys sys_recv 4 /* 4175 */
523 sys sys_sendto 6 /* 4180 */
528 sys sys_setresuid 3 /* 4185 */
530 sys sys_ni_syscall 0 /* was sys_query_module */
533 sys sys_setresgid 3 /* 4190 */
536 sys sys_rt_sigreturn 0
537 sys sys_rt_sigaction 4
538 sys sys_rt_sigprocmask 4 /* 4195 */
539 sys sys_rt_sigpending 2
540 sys sys_rt_sigtimedwait 4
541 sys sys_rt_sigqueueinfo 3
542 sys sys_rt_sigsuspend 0
543 sys sys_pread64 6 /* 4200 */
548 sys sys_capset 2 /* 4205 */
549 sys sys_sigaltstack 0
553 sys sys_mmap2 6 /* 4210 */
555 sys sys_ftruncate64 4
558 sys sys_fstat64 2 /* 4215 */
563 sys sys_fcntl64 3 /* 4220 */
568 sys sys_lsetxattr 5 /* 4225 */
573 sys sys_listxattr 3 /* 4230 */
576 sys sys_removexattr 2
577 sys sys_lremovexattr 2
578 sys sys_fremovexattr 2 /* 4235 */
582 sys sys_sched_setaffinity 3
583 sys sys_sched_getaffinity 3 /* 4240 */
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
632 /* We pre-compute the number of _instruction_ bytes needed to
633 load or store the arguments 6-8. Negative values are ignored. */
635 .macro sys function, nargs
637 LONG (\nargs << 2) - (5 << 2)
641 .type sys_call_table,@object
642 EXPORT(sys_call_table)
644 .size sys_call_table, . - sys_call_table