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 subu v0, v0, __NR_O32_Linux # check syscall number
38 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
39 addiu t1, 4 # skip to next instruction
41 beqz t0, illegal_syscall
46 lw t2, (t1) # syscall routine
47 lw t3, 4(t1) # >= 0 if we need stack arguments
48 beqz t2, illegal_syscall
50 sw a3, PT_R26(sp) # save a3 for syscall restarting
54 lw t0, TI_FLAGS($28) # syscall tracing enabled?
55 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
57 bnez t0, syscall_trace_entry # -> yes
59 jalr t2 # Do The Real Thing (TM)
61 li t0, -EMAXERRNO - 1 # error?
63 sw t0, PT_R7(sp) # set error flag
67 sw v0, PT_R0(sp) # set flag for syscall
69 1: sw v0, PT_R2(sp) # result
72 local_irq_disable # make sure need_resched and
73 # signals dont change between
75 lw a2, TI_FLAGS($28) # current->work
76 li t0, _TIF_ALLWORK_MASK
78 bnez t0, o32_syscall_exit_work
82 o32_syscall_exit_work:
83 j syscall_exit_work_partial
85 /* ------------------------------------------------------------------------ */
96 lw a0, PT_R4(sp) # Restore argument registers
102 li t0, -EMAXERRNO - 1 # error?
104 sw t0, PT_R7(sp) # set error flag
108 sw v0, PT_R0(sp) # set flag for syscall
110 1: sw v0, PT_R2(sp) # result
114 /* ------------------------------------------------------------------------ */
117 * More than four arguments. Try to deal with it by copying the
118 * stack arguments from the user stack to the kernel stack.
122 lw t0, PT_R29(sp) # get old user stack pointer
125 * We intentionally keep the kernel stack a little below the top of
126 * userspace so we don't have to do a slower byte accurate check here.
128 lw t5, TI_ADDR_LIMIT($28)
131 bltz t5, bad_stack # -> sp is bad
133 /* Ok, copy the args from the luser stack to the kernel stack.
134 * t3 is the precomputed number of instruction bytes needed to
135 * load or store arguments 6-8.
138 la t1, 5f # load up to 3 arguments
140 1: lw t5, 16(t0) # argument #5 from usp
147 2: lw t8, 28(t0) # argument #8 from usp
148 3: lw t7, 24(t0) # argument #7 from usp
149 4: lw t6, 20(t0) # argument #6 from usp
151 sw t5, 16(sp) # argument #5 to ksp
153 sw t8, 28(sp) # argument #8 to ksp
154 sw t7, 24(sp) # argument #7 to ksp
155 sw t6, 20(sp) # argument #6 to ksp
156 6: j stack_done # go back
160 .section __ex_table,"a"
168 * The stackpointer for a call with more than 4 arguments is bad.
169 * We probably should handle this case a bit more drastic.
175 li t0, 1 # set error flag
180 * The system call does not exist in this kernel
183 li v0, ENOSYS # error
185 li t0, 1 # set error flag
190 LEAF(mips_atomic_set)
191 andi v0, a1, 3 # must be word aligned
192 bnez v0, bad_alignment
194 lw v1, TI_ADDR_LIMIT($28) # in legal address range?
200 #ifdef CONFIG_CPU_HAS_LLSC
201 /* Ok, this is the ll/sc case. World is sane :-) */
211 .section __ex_table,"a"
228 * At this point the page should be readable and writable unless
229 * there was no more memory available.
234 .section __ex_table,"a"
240 sw zero, PT_R7(sp) # success
241 sw v0, PT_R2(sp) # result
243 j o32_syscall_exit # continue like a normal syscall
245 no_mem: li v0, -ENOMEM
258 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
263 subu t0, a0, __NR_O32_Linux # check syscall number
264 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
265 beqz t0, einval # do not recurse
268 lw t2, sys_call_table(t1) # syscall routine
270 /* Some syscalls like execve get their arguments from struct pt_regs
271 and claim zero arguments in the syscall table. Thus we have to
272 assume the worst case and shuffle around all potential arguments.
273 If you want performance, don't use indirect syscalls. */
275 move a0, a1 # shift argument registers
285 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
286 sw a1, PT_R5(sp) # syscalls expect them there
289 sw a3, PT_R26(sp) # update a3 for syscall restarting
293 einval: li v0, -ENOSYS
297 .macro fifty ptr, nargs, from=1, to=50
300 fifty \ptr,\nargs,"(\from+1)",\to
304 .macro mille ptr, nargs, from=1, to=20
307 mille \ptr,\nargs,"(\from+1)",\to
312 sys sys_syscall 8 /* 4000 */
317 sys sys_open 3 /* 4005 */
322 sys sys_unlink 1 /* 4010 */
327 sys sys_chmod 2 /* 4015 */
330 sys sys_ni_syscall 0 /* was sys_stat */
332 sys sys_getpid 0 /* 4020 */
337 sys sys_stime 1 /* 4025 */
340 sys sys_ni_syscall 0 /* was sys_fstat */
342 sys sys_utime 2 /* 4030 */
347 sys sys_ni_syscall 0 /* 4035 */
352 sys sys_rmdir 1 /* 4040 */
357 sys sys_brk 1 /* 4045 */
360 sys sys_ni_syscall 0 /* was signal(2) */
362 sys sys_getegid 0 /* 4050 */
367 sys sys_fcntl 3 /* 4055 */
372 sys sys_umask 1 /* 4060 */
377 sys sys_getpgrp 0 /* 4065 */
382 sys sys_setreuid 2 /* 4070 */
386 sys sys_sethostname 2
387 sys sys_setrlimit 2 /* 4075 */
390 sys sys_gettimeofday 2
391 sys sys_settimeofday 2
392 sys sys_getgroups 2 /* 4080 */
394 sys sys_ni_syscall 0 /* old_select */
396 sys sys_ni_syscall 0 /* was sys_lstat */
397 sys sys_readlink 3 /* 4085 */
401 sys sys_old_readdir 3
402 sys sys_mips_mmap 6 /* 4090 */
407 sys sys_fchown 3 /* 4095 */
408 sys sys_getpriority 2
409 sys sys_setpriority 3
412 sys sys_fstatfs 2 /* 4100 */
413 sys sys_ni_syscall 0 /* was ioperm(2) */
417 sys sys_getitimer 2 /* 4105 */
422 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
424 sys sys_ni_syscall 0 /* was sys_idle() */
425 sys sys_ni_syscall 0 /* was sys_vm86 */
427 sys sys_swapoff 1 /* 4115 */
432 sys sys_clone 0 /* 4120 */
433 sys sys_setdomainname 2
435 sys sys_ni_syscall 0 /* sys_modify_ldt */
437 sys sys_mprotect 3 /* 4125 */
438 sys sys_sigprocmask 3
439 sys sys_ni_syscall 0 /* was create_module */
440 sys sys_init_module 5
441 sys sys_delete_module 1
442 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
447 sys sys_sysfs 3 /* 4135 */
448 sys sys_personality 1
449 sys sys_ni_syscall 0 /* for afs_syscall */
452 sys sys_llseek 5 /* 4140 */
457 sys sys_readv 3 /* 4145 */
462 sys sys_ni_syscall 0 /* 4150 */
467 sys sys_munlock 2 /* 4155 */
470 sys sys_sched_setparam 2
471 sys sys_sched_getparam 2
472 sys sys_sched_setscheduler 3 /* 4160 */
473 sys sys_sched_getscheduler 1
474 sys sys_sched_yield 0
475 sys sys_sched_get_priority_max 1
476 sys sys_sched_get_priority_min 1
477 sys sys_sched_rr_get_interval 2 /* 4165 */
482 sys sys_connect 3 /* 4170 */
483 sys sys_getpeername 3
484 sys sys_getsockname 3
487 sys sys_recv 4 /* 4175 */
492 sys sys_sendto 6 /* 4180 */
497 sys sys_setresuid 3 /* 4185 */
499 sys sys_ni_syscall 0 /* was sys_query_module */
502 sys sys_setresgid 3 /* 4190 */
505 sys sys_rt_sigreturn 0
506 sys sys_rt_sigaction 4
507 sys sys_rt_sigprocmask 4 /* 4195 */
508 sys sys_rt_sigpending 2
509 sys sys_rt_sigtimedwait 4
510 sys sys_rt_sigqueueinfo 3
511 sys sys_rt_sigsuspend 0
512 sys sys_pread64 6 /* 4200 */
517 sys sys_capset 2 /* 4205 */
518 sys sys_sigaltstack 0
522 sys sys_mips_mmap2 6 /* 4210 */
524 sys sys_ftruncate64 4
527 sys sys_fstat64 2 /* 4215 */
532 sys sys_fcntl64 3 /* 4220 */
537 sys sys_lsetxattr 5 /* 4225 */
542 sys sys_listxattr 3 /* 4230 */
545 sys sys_removexattr 2
546 sys sys_lremovexattr 2
547 sys sys_fremovexattr 2 /* 4235 */
551 #ifdef CONFIG_MIPS_MT_FPAFF
553 * For FPU affinity scheduling on MIPS MT processors, we need to
554 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
555 * in kernel/sched.c. Considered only temporary we only support these
556 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
558 sys mipsmt_sys_sched_setaffinity 3
559 sys mipsmt_sys_sched_getaffinity 3
561 sys sys_sched_setaffinity 3
562 sys sys_sched_getaffinity 3 /* 4240 */
563 #endif /* CONFIG_MIPS_MT_FPAFF */
566 sys sys_io_getevents 5
568 sys sys_io_cancel 3 /* 4245 */
570 sys sys_lookup_dcookie 4
571 sys sys_epoll_create 1
573 sys sys_epoll_wait 3 /* 4250 */
574 sys sys_remap_file_pages 5
575 sys sys_set_tid_address 1
576 sys sys_restart_syscall 0
577 sys sys_fadvise64_64 7
578 sys sys_statfs64 3 /* 4255 */
580 sys sys_timer_create 3
581 sys sys_timer_settime 4
582 sys sys_timer_gettime 2
583 sys sys_timer_getoverrun 1 /* 4260 */
584 sys sys_timer_delete 1
585 sys sys_clock_settime 2
586 sys sys_clock_gettime 2
587 sys sys_clock_getres 2
588 sys sys_clock_nanosleep 4 /* 4265 */
592 sys sys_ni_syscall 0 /* sys_get_mempolicy */
593 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
596 sys sys_mq_timedsend 5
597 sys sys_mq_timedreceive 5
598 sys sys_mq_notify 2 /* 4275 */
599 sys sys_mq_getsetattr 3
600 sys sys_ni_syscall 0 /* sys_vserver */
602 sys sys_ni_syscall 0 /* available, was setaltroot */
603 sys sys_add_key 5 /* 4280 */
604 sys sys_request_key 4
606 sys sys_set_thread_area 1
607 sys sys_inotify_init 0
608 sys sys_inotify_add_watch 3 /* 4285 */
609 sys sys_inotify_rm_watch 2
610 sys sys_migrate_pages 4
613 sys sys_mknodat 4 /* 4290 */
618 sys sys_renameat 4 /* 4295 */
623 sys sys_faccessat 3 /* 4300 */
628 sys sys_sync_file_range 7 /* 4305 */
632 sys sys_set_robust_list 2
633 sys sys_get_robust_list 3 /* 4310 */
636 sys sys_epoll_pwait 6
638 sys sys_ioprio_get 2 /* 4315 */
643 sys sys_fallocate 6 /* 4320 */
644 sys sys_timerfd_create 2
645 sys sys_timerfd_gettime 2
646 sys sys_timerfd_settime 4
648 sys sys_eventfd2 2 /* 4325 */
649 sys sys_epoll_create1 1
652 sys sys_inotify_init1 1
653 sys sys_preadv 6 /* 4330 */
657 /* We pre-compute the number of _instruction_ bytes needed to
658 load or store the arguments 6-8. Negative values are ignored. */
660 .macro sys function, nargs
662 LONG (\nargs << 2) - (5 << 2)
666 .type sys_call_table,@object
667 EXPORT(sys_call_table)
669 .size sys_call_table, . - sys_call_table