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 j o32_syscall_exit # continue like a normal syscall
246 no_mem: li v0, -ENOMEM
259 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
264 #if defined(CONFIG_BINFMT_IRIX)
265 sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
267 subu t0, a0, __NR_O32_Linux # check syscall number
268 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
273 lw t2, sys_call_table(t1) # syscall routine
275 #if defined(CONFIG_BINFMT_IRIX)
276 li v1, 4000 # nr of sys_syscall
278 li v1, 4000 - __NR_O32_Linux # index of sys_syscall
280 beq t0, v1, einval # do not recurse
282 /* Some syscalls like execve get their arguments from struct pt_regs
283 and claim zero arguments in the syscall table. Thus we have to
284 assume the worst case and shuffle around all potential arguments.
285 If you want performance, don't use indirect syscalls. */
287 move a0, a1 # shift argument registers
297 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
298 sw a1, PT_R5(sp) # syscalls expect them there
301 sw a3, PT_R26(sp) # update a3 for syscall restarting
305 einval: li v0, -EINVAL
309 .macro fifty ptr, nargs, from=1, to=50
312 fifty \ptr,\nargs,"(\from+1)",\to
316 .macro mille ptr, nargs, from=1, to=20
319 mille \ptr,\nargs,"(\from+1)",\to
324 #if defined(CONFIG_BINFMT_IRIX)
325 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
326 mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */
327 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
328 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
331 sys sys_syscall 8 /* 4000 */
336 sys sys_open 3 /* 4005 */
341 sys sys_unlink 1 /* 4010 */
346 sys sys_chmod 2 /* 4015 */
349 sys sys_ni_syscall 0 /* was sys_stat */
351 sys sys_getpid 0 /* 4020 */
356 sys sys_stime 1 /* 4025 */
359 sys sys_ni_syscall 0 /* was sys_fstat */
361 sys sys_utime 2 /* 4030 */
366 sys sys_ni_syscall 0 /* 4035 */
371 sys sys_rmdir 1 /* 4040 */
376 sys sys_brk 1 /* 4045 */
379 sys sys_ni_syscall 0 /* was signal(2) */
381 sys sys_getegid 0 /* 4050 */
386 sys sys_fcntl 3 /* 4055 */
391 sys sys_umask 1 /* 4060 */
396 sys sys_getpgrp 0 /* 4065 */
401 sys sys_setreuid 2 /* 4070 */
405 sys sys_sethostname 2
406 sys sys_setrlimit 2 /* 4075 */
409 sys sys_gettimeofday 2
410 sys sys_settimeofday 2
411 sys sys_getgroups 2 /* 4080 */
413 sys sys_ni_syscall 0 /* old_select */
415 sys sys_ni_syscall 0 /* was sys_lstat */
416 sys sys_readlink 3 /* 4085 */
421 sys old_mmap 6 /* 4090 */
426 sys sys_fchown 3 /* 4095 */
427 sys sys_getpriority 2
428 sys sys_setpriority 3
431 sys sys_fstatfs 2 /* 4100 */
432 sys sys_ni_syscall 0 /* was ioperm(2) */
436 sys sys_getitimer 2 /* 4105 */
441 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
443 sys sys_ni_syscall 0 /* was sys_idle() */
444 sys sys_ni_syscall 0 /* was sys_vm86 */
446 sys sys_swapoff 1 /* 4115 */
451 sys sys_clone 0 /* 4120 */
452 sys sys_setdomainname 2
454 sys sys_ni_syscall 0 /* sys_modify_ldt */
456 sys sys_mprotect 3 /* 4125 */
457 sys sys_sigprocmask 3
458 sys sys_ni_syscall 0 /* was create_module */
459 sys sys_init_module 5
460 sys sys_delete_module 1
461 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
466 sys sys_sysfs 3 /* 4135 */
467 sys sys_personality 1
468 sys sys_ni_syscall 0 /* for afs_syscall */
471 sys sys_llseek 5 /* 4140 */
476 sys sys_readv 3 /* 4145 */
481 sys sys_ni_syscall 0 /* 4150 */
486 sys sys_munlock 2 /* 4155 */
489 sys sys_sched_setparam 2
490 sys sys_sched_getparam 2
491 sys sys_sched_setscheduler 3 /* 4160 */
492 sys sys_sched_getscheduler 1
493 sys sys_sched_yield 0
494 sys sys_sched_get_priority_max 1
495 sys sys_sched_get_priority_min 1
496 sys sys_sched_rr_get_interval 2 /* 4165 */
501 sys sys_connect 3 /* 4170 */
502 sys sys_getpeername 3
503 sys sys_getsockname 3
506 sys sys_recv 4 /* 4175 */
511 sys sys_sendto 6 /* 4180 */
516 sys sys_setresuid 3 /* 4185 */
518 sys sys_ni_syscall 0 /* was sys_query_module */
521 sys sys_setresgid 3 /* 4190 */
524 sys sys_rt_sigreturn 0
525 sys sys_rt_sigaction 4
526 sys sys_rt_sigprocmask 4 /* 4195 */
527 sys sys_rt_sigpending 2
528 sys sys_rt_sigtimedwait 4
529 sys sys_rt_sigqueueinfo 3
530 sys sys_rt_sigsuspend 0
531 sys sys_pread64 6 /* 4200 */
536 sys sys_capset 2 /* 4205 */
537 sys sys_sigaltstack 0
541 sys sys_mmap2 6 /* 4210 */
543 sys sys_ftruncate64 4
546 sys sys_fstat64 2 /* 4215 */
551 sys sys_fcntl64 3 /* 4220 */
556 sys sys_lsetxattr 5 /* 4225 */
561 sys sys_listxattr 3 /* 4230 */
564 sys sys_removexattr 2
565 sys sys_lremovexattr 2
566 sys sys_fremovexattr 2 /* 4235 */
570 sys sys_sched_setaffinity 3
571 sys sys_sched_getaffinity 3 /* 4240 */
574 sys sys_io_getevents 5
576 sys sys_io_cancel 3 /* 4245 */
578 sys sys_lookup_dcookie 4
579 sys sys_epoll_create 1
581 sys sys_epoll_wait 3 /* 4250 */
582 sys sys_remap_file_pages 5
583 sys sys_set_tid_address 1
584 sys sys_restart_syscall 0
585 sys sys_fadvise64_64 7
586 sys sys_statfs64 3 /* 4255 */
588 sys sys_timer_create 3
589 sys sys_timer_settime 4
590 sys sys_timer_gettime 2
591 sys sys_timer_getoverrun 1 /* 4260 */
592 sys sys_timer_delete 1
593 sys sys_clock_settime 2
594 sys sys_clock_gettime 2
595 sys sys_clock_getres 2
596 sys sys_clock_nanosleep 4 /* 4265 */
600 sys sys_ni_syscall 0 /* sys_get_mempolicy */
601 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
604 sys sys_mq_timedsend 5
605 sys sys_mq_timedreceive 5
606 sys sys_mq_notify 2 /* 4275 */
607 sys sys_mq_getsetattr 3
608 sys sys_ni_syscall 0 /* sys_vserver */
610 sys sys_ni_syscall 0 /* available, was setaltroot */
611 sys sys_add_key 5 /* 4280 */
612 sys sys_request_key 4
614 sys sys_set_thread_area 1
615 sys sys_inotify_init 0
616 sys sys_inotify_add_watch 3 /* 4285 */
617 sys sys_inotify_rm_watch 2
620 /* We pre-compute the number of _instruction_ bytes needed to
621 load or store the arguments 6-8. Negative values are ignored. */
623 .macro sys function, nargs
625 LONG (\nargs << 2) - (5 << 2)
629 .type sys_call_table,@object
630 EXPORT(sys_call_table)
632 .size sys_call_table, . - sys_call_table