Loading...
1/*
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
4 * for more details.
5 *
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
9 */
10#include <linux/errno.h>
11#include <asm/asm.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>
21#include <asm/war.h>
22#include <asm/asm-offsets.h>
23
24/* Highest syscall used of any syscall flavour */
25#define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls
26
27 .align 5
28NESTED(handle_sys, PT_SIZE, sp)
29 .set noat
30 SAVE_SOME
31 TRACE_IRQS_ON_RELOAD
32 STI
33 .set at
34
35 lw t1, PT_EPC(sp) # skip syscall on return
36
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
40 sw t1, PT_EPC(sp)
41 beqz t0, illegal_syscall
42
43 sll t0, v0, 3
44 la t1, sys_call_table
45 addu t1, t0
46 lw t2, (t1) # syscall routine
47 lw t3, 4(t1) # >= 0 if we need stack arguments
48 beqz t2, illegal_syscall
49
50 sw a3, PT_R26(sp) # save a3 for syscall restarting
51 bgez t3, stackargs
52
53stack_done:
54 lw t0, TI_FLAGS($28) # syscall tracing enabled?
55 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
56 and t0, t1
57 bnez t0, syscall_trace_entry # -> yes
58
59 jalr t2 # Do The Real Thing (TM)
60
61 li t0, -EMAXERRNO - 1 # error?
62 sltu t0, t0, v0
63 sw t0, PT_R7(sp) # set error flag
64 beqz t0, 1f
65
66 lw t1, PT_R2(sp) # syscall number
67 negu v0 # error
68 sw t1, PT_R0(sp) # save it for syscall restarting
691: sw v0, PT_R2(sp) # result
70
71o32_syscall_exit:
72 local_irq_disable # make sure need_resched and
73 # signals dont change between
74 # sampling and return
75 lw a2, TI_FLAGS($28) # current->work
76 li t0, _TIF_ALLWORK_MASK
77 and t0, a2
78 bnez t0, o32_syscall_exit_work
79
80 j restore_partial
81
82o32_syscall_exit_work:
83 j syscall_exit_work_partial
84
85/* ------------------------------------------------------------------------ */
86
87syscall_trace_entry:
88 SAVE_STATIC
89 move s0, t2
90 move a0, sp
91 jal syscall_trace_enter
92
93 move t0, s0
94 RESTORE_STATIC
95 lw a0, PT_R4(sp) # Restore argument registers
96 lw a1, PT_R5(sp)
97 lw a2, PT_R6(sp)
98 lw a3, PT_R7(sp)
99 jalr t0
100
101 li t0, -EMAXERRNO - 1 # error?
102 sltu t0, t0, v0
103 sw t0, PT_R7(sp) # set error flag
104 beqz t0, 1f
105
106 lw t1, PT_R2(sp) # syscall number
107 negu v0 # error
108 sw t1, PT_R0(sp) # save it for syscall restarting
1091: sw v0, PT_R2(sp) # result
110
111 j syscall_exit
112
113/* ------------------------------------------------------------------------ */
114
115 /*
116 * More than four arguments. Try to deal with it by copying the
117 * stack arguments from the user stack to the kernel stack.
118 * This Sucks (TM).
119 */
120stackargs:
121 lw t0, PT_R29(sp) # get old user stack pointer
122
123 /*
124 * We intentionally keep the kernel stack a little below the top of
125 * userspace so we don't have to do a slower byte accurate check here.
126 */
127 lw t5, TI_ADDR_LIMIT($28)
128 addu t4, t0, 32
129 and t5, t4
130 bltz t5, bad_stack # -> sp is bad
131
132 /* Ok, copy the args from the luser stack to the kernel stack.
133 * t3 is the precomputed number of instruction bytes needed to
134 * load or store arguments 6-8.
135 */
136
137 la t1, 5f # load up to 3 arguments
138 subu t1, t3
1391: lw t5, 16(t0) # argument #5 from usp
140 .set push
141 .set noreorder
142 .set nomacro
143 jr t1
144 addiu t1, 6f - 5f
145
1462: lw t8, 28(t0) # argument #8 from usp
1473: lw t7, 24(t0) # argument #7 from usp
1484: lw t6, 20(t0) # argument #6 from usp
1495: jr t1
150 sw t5, 16(sp) # argument #5 to ksp
151
152 sw t8, 28(sp) # argument #8 to ksp
153 sw t7, 24(sp) # argument #7 to ksp
154 sw t6, 20(sp) # argument #6 to ksp
1556: j stack_done # go back
156 nop
157 .set pop
158
159 .section __ex_table,"a"
160 PTR 1b,bad_stack
161 PTR 2b,bad_stack
162 PTR 3b,bad_stack
163 PTR 4b,bad_stack
164 .previous
165
166 /*
167 * The stackpointer for a call with more than 4 arguments is bad.
168 * We probably should handle this case a bit more drastic.
169 */
170bad_stack:
171 li v0, EFAULT
172 sw v0, PT_R2(sp)
173 li t0, 1 # set error flag
174 sw t0, PT_R7(sp)
175 j o32_syscall_exit
176
177 /*
178 * The system call does not exist in this kernel
179 */
180illegal_syscall:
181 li v0, ENOSYS # error
182 sw v0, PT_R2(sp)
183 li t0, 1 # set error flag
184 sw t0, PT_R7(sp)
185 j o32_syscall_exit
186 END(handle_sys)
187
188 LEAF(sys_syscall)
189 subu t0, a0, __NR_O32_Linux # check syscall number
190 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
191 beqz t0, einval # do not recurse
192 sll t1, t0, 3
193 beqz v0, einval
194 lw t2, sys_call_table(t1) # syscall routine
195
196 /* Some syscalls like execve get their arguments from struct pt_regs
197 and claim zero arguments in the syscall table. Thus we have to
198 assume the worst case and shuffle around all potential arguments.
199 If you want performance, don't use indirect syscalls. */
200
201 move a0, a1 # shift argument registers
202 move a1, a2
203 move a2, a3
204 lw a3, 16(sp)
205 lw t4, 20(sp)
206 lw t5, 24(sp)
207 lw t6, 28(sp)
208 sw t4, 16(sp)
209 sw t5, 20(sp)
210 sw t6, 24(sp)
211 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
212 sw a1, PT_R5(sp) # syscalls expect them there
213 sw a2, PT_R6(sp)
214 sw a3, PT_R7(sp)
215 sw a3, PT_R26(sp) # update a3 for syscall restarting
216 jr t2
217 /* Unreached */
218
219einval: li v0, -ENOSYS
220 jr ra
221 END(sys_syscall)
222
223 .macro fifty ptr, nargs, from=1, to=50
224 sys \ptr \nargs
225 .if \to-\from
226 fifty \ptr,\nargs,"(\from+1)",\to
227 .endif
228 .endm
229
230 .macro mille ptr, nargs, from=1, to=20
231 fifty \ptr,\nargs
232 .if \to-\from
233 mille \ptr,\nargs,"(\from+1)",\to
234 .endif
235 .endm
236
237 .macro syscalltable
238 sys sys_syscall 8 /* 4000 */
239 sys sys_exit 1
240 sys sys_fork 0
241 sys sys_read 3
242 sys sys_write 3
243 sys sys_open 3 /* 4005 */
244 sys sys_close 1
245 sys sys_waitpid 3
246 sys sys_creat 2
247 sys sys_link 2
248 sys sys_unlink 1 /* 4010 */
249 sys sys_execve 0
250 sys sys_chdir 1
251 sys sys_time 1
252 sys sys_mknod 3
253 sys sys_chmod 2 /* 4015 */
254 sys sys_lchown 3
255 sys sys_ni_syscall 0
256 sys sys_ni_syscall 0 /* was sys_stat */
257 sys sys_lseek 3
258 sys sys_getpid 0 /* 4020 */
259 sys sys_mount 5
260 sys sys_oldumount 1
261 sys sys_setuid 1
262 sys sys_getuid 0
263 sys sys_stime 1 /* 4025 */
264 sys sys_ptrace 4
265 sys sys_alarm 1
266 sys sys_ni_syscall 0 /* was sys_fstat */
267 sys sys_pause 0
268 sys sys_utime 2 /* 4030 */
269 sys sys_ni_syscall 0
270 sys sys_ni_syscall 0
271 sys sys_access 2
272 sys sys_nice 1
273 sys sys_ni_syscall 0 /* 4035 */
274 sys sys_sync 0
275 sys sys_kill 2
276 sys sys_rename 2
277 sys sys_mkdir 2
278 sys sys_rmdir 1 /* 4040 */
279 sys sys_dup 1
280 sys sysm_pipe 0
281 sys sys_times 1
282 sys sys_ni_syscall 0
283 sys sys_brk 1 /* 4045 */
284 sys sys_setgid 1
285 sys sys_getgid 0
286 sys sys_ni_syscall 0 /* was signal(2) */
287 sys sys_geteuid 0
288 sys sys_getegid 0 /* 4050 */
289 sys sys_acct 1
290 sys sys_umount 2
291 sys sys_ni_syscall 0
292 sys sys_ioctl 3
293 sys sys_fcntl 3 /* 4055 */
294 sys sys_ni_syscall 2
295 sys sys_setpgid 2
296 sys sys_ni_syscall 0
297 sys sys_olduname 1
298 sys sys_umask 1 /* 4060 */
299 sys sys_chroot 1
300 sys sys_ustat 2
301 sys sys_dup2 2
302 sys sys_getppid 0
303 sys sys_getpgrp 0 /* 4065 */
304 sys sys_setsid 0
305 sys sys_sigaction 3
306 sys sys_sgetmask 0
307 sys sys_ssetmask 1
308 sys sys_setreuid 2 /* 4070 */
309 sys sys_setregid 2
310 sys sys_sigsuspend 0
311 sys sys_sigpending 1
312 sys sys_sethostname 2
313 sys sys_setrlimit 2 /* 4075 */
314 sys sys_getrlimit 2
315 sys sys_getrusage 2
316 sys sys_gettimeofday 2
317 sys sys_settimeofday 2
318 sys sys_getgroups 2 /* 4080 */
319 sys sys_setgroups 2
320 sys sys_ni_syscall 0 /* old_select */
321 sys sys_symlink 2
322 sys sys_ni_syscall 0 /* was sys_lstat */
323 sys sys_readlink 3 /* 4085 */
324 sys sys_uselib 1
325 sys sys_swapon 2
326 sys sys_reboot 3
327 sys sys_old_readdir 3
328 sys sys_mips_mmap 6 /* 4090 */
329 sys sys_munmap 2
330 sys sys_truncate 2
331 sys sys_ftruncate 2
332 sys sys_fchmod 2
333 sys sys_fchown 3 /* 4095 */
334 sys sys_getpriority 2
335 sys sys_setpriority 3
336 sys sys_ni_syscall 0
337 sys sys_statfs 2
338 sys sys_fstatfs 2 /* 4100 */
339 sys sys_ni_syscall 0 /* was ioperm(2) */
340 sys sys_socketcall 2
341 sys sys_syslog 3
342 sys sys_setitimer 3
343 sys sys_getitimer 2 /* 4105 */
344 sys sys_newstat 2
345 sys sys_newlstat 2
346 sys sys_newfstat 2
347 sys sys_uname 1
348 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
349 sys sys_vhangup 0
350 sys sys_ni_syscall 0 /* was sys_idle() */
351 sys sys_ni_syscall 0 /* was sys_vm86 */
352 sys sys_wait4 4
353 sys sys_swapoff 1 /* 4115 */
354 sys sys_sysinfo 1
355 sys sys_ipc 6
356 sys sys_fsync 1
357 sys sys_sigreturn 0
358 sys sys_clone 0 /* 4120 */
359 sys sys_setdomainname 2
360 sys sys_newuname 1
361 sys sys_ni_syscall 0 /* sys_modify_ldt */
362 sys sys_adjtimex 1
363 sys sys_mprotect 3 /* 4125 */
364 sys sys_sigprocmask 3
365 sys sys_ni_syscall 0 /* was create_module */
366 sys sys_init_module 5
367 sys sys_delete_module 1
368 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
369 sys sys_quotactl 4
370 sys sys_getpgid 1
371 sys sys_fchdir 1
372 sys sys_bdflush 2
373 sys sys_sysfs 3 /* 4135 */
374 sys sys_personality 1
375 sys sys_ni_syscall 0 /* for afs_syscall */
376 sys sys_setfsuid 1
377 sys sys_setfsgid 1
378 sys sys_llseek 5 /* 4140 */
379 sys sys_getdents 3
380 sys sys_select 5
381 sys sys_flock 2
382 sys sys_msync 3
383 sys sys_readv 3 /* 4145 */
384 sys sys_writev 3
385 sys sys_cacheflush 3
386 sys sys_cachectl 3
387 sys sys_sysmips 4
388 sys sys_ni_syscall 0 /* 4150 */
389 sys sys_getsid 1
390 sys sys_fdatasync 1
391 sys sys_sysctl 1
392 sys sys_mlock 2
393 sys sys_munlock 2 /* 4155 */
394 sys sys_mlockall 1
395 sys sys_munlockall 0
396 sys sys_sched_setparam 2
397 sys sys_sched_getparam 2
398 sys sys_sched_setscheduler 3 /* 4160 */
399 sys sys_sched_getscheduler 1
400 sys sys_sched_yield 0
401 sys sys_sched_get_priority_max 1
402 sys sys_sched_get_priority_min 1
403 sys sys_sched_rr_get_interval 2 /* 4165 */
404 sys sys_nanosleep, 2
405 sys sys_mremap, 5
406 sys sys_accept 3
407 sys sys_bind 3
408 sys sys_connect 3 /* 4170 */
409 sys sys_getpeername 3
410 sys sys_getsockname 3
411 sys sys_getsockopt 5
412 sys sys_listen 2
413 sys sys_recv 4 /* 4175 */
414 sys sys_recvfrom 6
415 sys sys_recvmsg 3
416 sys sys_send 4
417 sys sys_sendmsg 3
418 sys sys_sendto 6 /* 4180 */
419 sys sys_setsockopt 5
420 sys sys_shutdown 2
421 sys sys_socket 3
422 sys sys_socketpair 4
423 sys sys_setresuid 3 /* 4185 */
424 sys sys_getresuid 3
425 sys sys_ni_syscall 0 /* was sys_query_module */
426 sys sys_poll 3
427 sys sys_ni_syscall 0 /* was nfsservctl */
428 sys sys_setresgid 3 /* 4190 */
429 sys sys_getresgid 3
430 sys sys_prctl 5
431 sys sys_rt_sigreturn 0
432 sys sys_rt_sigaction 4
433 sys sys_rt_sigprocmask 4 /* 4195 */
434 sys sys_rt_sigpending 2
435 sys sys_rt_sigtimedwait 4
436 sys sys_rt_sigqueueinfo 3
437 sys sys_rt_sigsuspend 0
438 sys sys_pread64 6 /* 4200 */
439 sys sys_pwrite64 6
440 sys sys_chown 3
441 sys sys_getcwd 2
442 sys sys_capget 2
443 sys sys_capset 2 /* 4205 */
444 sys sys_sigaltstack 0
445 sys sys_sendfile 4
446 sys sys_ni_syscall 0
447 sys sys_ni_syscall 0
448 sys sys_mips_mmap2 6 /* 4210 */
449 sys sys_truncate64 4
450 sys sys_ftruncate64 4
451 sys sys_stat64 2
452 sys sys_lstat64 2
453 sys sys_fstat64 2 /* 4215 */
454 sys sys_pivot_root 2
455 sys sys_mincore 3
456 sys sys_madvise 3
457 sys sys_getdents64 3
458 sys sys_fcntl64 3 /* 4220 */
459 sys sys_ni_syscall 0
460 sys sys_gettid 0
461 sys sys_readahead 5
462 sys sys_setxattr 5
463 sys sys_lsetxattr 5 /* 4225 */
464 sys sys_fsetxattr 5
465 sys sys_getxattr 4
466 sys sys_lgetxattr 4
467 sys sys_fgetxattr 4
468 sys sys_listxattr 3 /* 4230 */
469 sys sys_llistxattr 3
470 sys sys_flistxattr 3
471 sys sys_removexattr 2
472 sys sys_lremovexattr 2
473 sys sys_fremovexattr 2 /* 4235 */
474 sys sys_tkill 2
475 sys sys_sendfile64 5
476 sys sys_futex 6
477#ifdef CONFIG_MIPS_MT_FPAFF
478 /*
479 * For FPU affinity scheduling on MIPS MT processors, we need to
480 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
481 * in kernel/sched.c. Considered only temporary we only support these
482 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
483 */
484 sys mipsmt_sys_sched_setaffinity 3
485 sys mipsmt_sys_sched_getaffinity 3
486#else
487 sys sys_sched_setaffinity 3
488 sys sys_sched_getaffinity 3 /* 4240 */
489#endif /* CONFIG_MIPS_MT_FPAFF */
490 sys sys_io_setup 2
491 sys sys_io_destroy 1
492 sys sys_io_getevents 5
493 sys sys_io_submit 3
494 sys sys_io_cancel 3 /* 4245 */
495 sys sys_exit_group 1
496 sys sys_lookup_dcookie 4
497 sys sys_epoll_create 1
498 sys sys_epoll_ctl 4
499 sys sys_epoll_wait 3 /* 4250 */
500 sys sys_remap_file_pages 5
501 sys sys_set_tid_address 1
502 sys sys_restart_syscall 0
503 sys sys_fadvise64_64 7
504 sys sys_statfs64 3 /* 4255 */
505 sys sys_fstatfs64 2
506 sys sys_timer_create 3
507 sys sys_timer_settime 4
508 sys sys_timer_gettime 2
509 sys sys_timer_getoverrun 1 /* 4260 */
510 sys sys_timer_delete 1
511 sys sys_clock_settime 2
512 sys sys_clock_gettime 2
513 sys sys_clock_getres 2
514 sys sys_clock_nanosleep 4 /* 4265 */
515 sys sys_tgkill 3
516 sys sys_utimes 2
517 sys sys_mbind 4
518 sys sys_ni_syscall 0 /* sys_get_mempolicy */
519 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
520 sys sys_mq_open 4
521 sys sys_mq_unlink 1
522 sys sys_mq_timedsend 5
523 sys sys_mq_timedreceive 5
524 sys sys_mq_notify 2 /* 4275 */
525 sys sys_mq_getsetattr 3
526 sys sys_ni_syscall 0 /* sys_vserver */
527 sys sys_waitid 5
528 sys sys_ni_syscall 0 /* available, was setaltroot */
529 sys sys_add_key 5 /* 4280 */
530 sys sys_request_key 4
531 sys sys_keyctl 5
532 sys sys_set_thread_area 1
533 sys sys_inotify_init 0
534 sys sys_inotify_add_watch 3 /* 4285 */
535 sys sys_inotify_rm_watch 2
536 sys sys_migrate_pages 4
537 sys sys_openat 4
538 sys sys_mkdirat 3
539 sys sys_mknodat 4 /* 4290 */
540 sys sys_fchownat 5
541 sys sys_futimesat 3
542 sys sys_fstatat64 4
543 sys sys_unlinkat 3
544 sys sys_renameat 4 /* 4295 */
545 sys sys_linkat 5
546 sys sys_symlinkat 3
547 sys sys_readlinkat 4
548 sys sys_fchmodat 3
549 sys sys_faccessat 3 /* 4300 */
550 sys sys_pselect6 6
551 sys sys_ppoll 5
552 sys sys_unshare 1
553 sys sys_splice 6
554 sys sys_sync_file_range 7 /* 4305 */
555 sys sys_tee 4
556 sys sys_vmsplice 4
557 sys sys_move_pages 6
558 sys sys_set_robust_list 2
559 sys sys_get_robust_list 3 /* 4310 */
560 sys sys_kexec_load 4
561 sys sys_getcpu 3
562 sys sys_epoll_pwait 6
563 sys sys_ioprio_set 3
564 sys sys_ioprio_get 2 /* 4315 */
565 sys sys_utimensat 4
566 sys sys_signalfd 3
567 sys sys_ni_syscall 0 /* was timerfd */
568 sys sys_eventfd 1
569 sys sys_fallocate 6 /* 4320 */
570 sys sys_timerfd_create 2
571 sys sys_timerfd_gettime 2
572 sys sys_timerfd_settime 4
573 sys sys_signalfd4 4
574 sys sys_eventfd2 2 /* 4325 */
575 sys sys_epoll_create1 1
576 sys sys_dup3 3
577 sys sys_pipe2 2
578 sys sys_inotify_init1 1
579 sys sys_preadv 6 /* 4330 */
580 sys sys_pwritev 6
581 sys sys_rt_tgsigqueueinfo 4
582 sys sys_perf_event_open 5
583 sys sys_accept4 4
584 sys sys_recvmmsg 5 /* 4335 */
585 sys sys_fanotify_init 2
586 sys sys_fanotify_mark 6
587 sys sys_prlimit64 4
588 sys sys_name_to_handle_at 5
589 sys sys_open_by_handle_at 3 /* 4340 */
590 sys sys_clock_adjtime 2
591 sys sys_syncfs 1
592 sys sys_sendmmsg 4
593 sys sys_setns 2
594 .endm
595
596 /* We pre-compute the number of _instruction_ bytes needed to
597 load or store the arguments 6-8. Negative values are ignored. */
598
599 .macro sys function, nargs
600 PTR \function
601 LONG (\nargs << 2) - (5 << 2)
602 .endm
603
604 .align 3
605 .type sys_call_table,@object
606EXPORT(sys_call_table)
607 syscalltable
608 .size sys_call_table, . - sys_call_table
1/*
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
4 * for more details.
5 *
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
9 * Copyright (C) 2014 Imagination Technologies Ltd.
10 */
11#include <linux/errno.h>
12#include <asm/asm.h>
13#include <asm/asmmacro.h>
14#include <asm/irqflags.h>
15#include <asm/mipsregs.h>
16#include <asm/regdef.h>
17#include <asm/stackframe.h>
18#include <asm/isadep.h>
19#include <asm/sysmips.h>
20#include <asm/thread_info.h>
21#include <asm/unistd.h>
22#include <asm/asm-offsets.h>
23
24 .align 5
25NESTED(handle_sys, PT_SIZE, sp)
26 .set noat
27 SAVE_SOME
28 TRACE_IRQS_ON_RELOAD
29 STI
30 .set at
31
32 lw t1, PT_EPC(sp) # skip syscall on return
33
34 addiu t1, 4 # skip to next instruction
35 sw t1, PT_EPC(sp)
36
37 sw a3, PT_R26(sp) # save a3 for syscall restarting
38
39 /*
40 * More than four arguments. Try to deal with it by copying the
41 * stack arguments from the user stack to the kernel stack.
42 * This Sucks (TM).
43 */
44 lw t0, PT_R29(sp) # get old user stack pointer
45
46 /*
47 * We intentionally keep the kernel stack a little below the top of
48 * userspace so we don't have to do a slower byte accurate check here.
49 */
50 addu t4, t0, 32
51 bltz t4, bad_stack # -> sp is bad
52
53 /*
54 * Ok, copy the args from the luser stack to the kernel stack.
55 */
56
57 .set push
58 .set noreorder
59 .set nomacro
60
61load_a4: user_lw(t5, 16(t0)) # argument #5 from usp
62load_a5: user_lw(t6, 20(t0)) # argument #6 from usp
63load_a6: user_lw(t7, 24(t0)) # argument #7 from usp
64load_a7: user_lw(t8, 28(t0)) # argument #8 from usp
65loads_done:
66
67 sw t5, 16(sp) # argument #5 to ksp
68 sw t6, 20(sp) # argument #6 to ksp
69 sw t7, 24(sp) # argument #7 to ksp
70 sw t8, 28(sp) # argument #8 to ksp
71 .set pop
72
73 .section __ex_table,"a"
74 PTR_WD load_a4, bad_stack_a4
75 PTR_WD load_a5, bad_stack_a5
76 PTR_WD load_a6, bad_stack_a6
77 PTR_WD load_a7, bad_stack_a7
78 .previous
79
80 lw t0, TI_FLAGS($28) # syscall tracing enabled?
81 li t1, _TIF_WORK_SYSCALL_ENTRY
82 and t0, t1
83 bnez t0, syscall_trace_entry # -> yes
84syscall_common:
85 subu v0, v0, __NR_O32_Linux # check syscall number
86 sltiu t0, v0, __NR_O32_Linux_syscalls
87 beqz t0, illegal_syscall
88
89 sll t0, v0, 2
90 la t1, sys_call_table
91 addu t1, t0
92 lw t2, (t1) # syscall routine
93
94 beqz t2, illegal_syscall
95
96 jalr t2 # Do The Real Thing (TM)
97
98 li t0, -EMAXERRNO - 1 # error?
99 sltu t0, t0, v0
100 sw t0, PT_R7(sp) # set error flag
101 beqz t0, 1f
102
103 lw t1, PT_R2(sp) # syscall number
104 negu v0 # error
105 sw t1, PT_R0(sp) # save it for syscall restarting
1061: sw v0, PT_R2(sp) # result
107
108o32_syscall_exit:
109 j syscall_exit_partial
110
111/* ------------------------------------------------------------------------ */
112
113syscall_trace_entry:
114 SAVE_STATIC
115 move a0, sp
116
117 /*
118 * syscall number is in v0 unless we called syscall(__NR_###)
119 * where the real syscall number is in a0
120 */
121 move a1, v0
122 subu t2, v0, __NR_O32_Linux
123 bnez t2, 1f /* __NR_syscall at offset 0 */
124 lw a1, PT_R4(sp)
125
1261: jal syscall_trace_enter
127
128 bltz v0, 1f # seccomp failed? Skip syscall
129
130 RESTORE_STATIC
131 lw v0, PT_R2(sp) # Restore syscall (maybe modified)
132 lw a0, PT_R4(sp) # Restore argument registers
133 lw a1, PT_R5(sp)
134 lw a2, PT_R6(sp)
135 lw a3, PT_R7(sp)
136 j syscall_common
137
1381: j syscall_exit
139
140/* ------------------------------------------------------------------------ */
141
142 /*
143 * Our open-coded access area sanity test for the stack pointer
144 * failed. We probably should handle this case a bit more drastic.
145 */
146bad_stack:
147 li v0, EFAULT
148 sw v0, PT_R2(sp)
149 li t0, 1 # set error flag
150 sw t0, PT_R7(sp)
151 j o32_syscall_exit
152
153bad_stack_a4:
154 li t5, 0
155 b load_a5
156
157bad_stack_a5:
158 li t6, 0
159 b load_a6
160
161bad_stack_a6:
162 li t7, 0
163 b load_a7
164
165bad_stack_a7:
166 li t8, 0
167 b loads_done
168
169 /*
170 * The system call does not exist in this kernel
171 */
172illegal_syscall:
173 li v0, ENOSYS # error
174 sw v0, PT_R2(sp)
175 li t0, 1 # set error flag
176 sw t0, PT_R7(sp)
177 j o32_syscall_exit
178 END(handle_sys)
179
180 LEAF(sys_syscall)
181 subu t0, a0, __NR_O32_Linux # check syscall number
182 sltiu v0, t0, __NR_O32_Linux_syscalls
183 beqz t0, einval # do not recurse
184 sll t1, t0, 2
185 beqz v0, einval
186 lw t2, sys_call_table(t1) # syscall routine
187
188 move a0, a1 # shift argument registers
189 move a1, a2
190 move a2, a3
191 lw a3, 16(sp)
192 lw t4, 20(sp)
193 lw t5, 24(sp)
194 lw t6, 28(sp)
195 sw t4, 16(sp)
196 sw t5, 20(sp)
197 sw t6, 24(sp)
198 jr t2
199 /* Unreached */
200
201einval: li v0, -ENOSYS
202 jr ra
203 END(sys_syscall)
204
205#ifdef CONFIG_MIPS_MT_FPAFF
206 /*
207 * For FPU affinity scheduling on MIPS MT processors, we need to
208 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
209 * in kernel/sched/core.c. Considered only temporary we only support
210 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
211 * atm.
212 */
213#define sys_sched_setaffinity mipsmt_sys_sched_setaffinity
214#define sys_sched_getaffinity mipsmt_sys_sched_getaffinity
215#endif /* CONFIG_MIPS_MT_FPAFF */
216
217#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
218#define __SYSCALL(nr, entry) PTR_WD entry
219 .align 2
220 .type sys_call_table, @object
221EXPORT(sys_call_table)
222#include <asm/syscall_table_o32.h>