MIPS: scall64-o32: Fix indirect syscall detection
[deliverable/linux.git] / arch / mips / kernel / scall64-o32.S
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 - 2000, 2001 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2001 MIPS Technologies, Inc.
9 * Copyright (C) 2004 Thiemo Seufer
10 *
11 * Hairy, the userspace application uses a different argument passing
12 * convention than the kernel, so we have to translate things from o32
13 * to ABI64 calling convention. 64-bit syscalls are also processed
14 * here for now.
15 */
16 #include <linux/errno.h>
17 #include <asm/asm.h>
18 #include <asm/asmmacro.h>
19 #include <asm/irqflags.h>
20 #include <asm/mipsregs.h>
21 #include <asm/regdef.h>
22 #include <asm/stackframe.h>
23 #include <asm/thread_info.h>
24 #include <asm/unistd.h>
25 #include <asm/sysmips.h>
26
27 .align 5
28 NESTED(handle_sys, PT_SIZE, sp)
29 .set noat
30 SAVE_SOME
31 TRACE_IRQS_ON_RELOAD
32 STI
33 .set at
34 ld t1, PT_EPC(sp) # skip syscall on return
35
36 dsubu t0, v0, __NR_O32_Linux # check syscall number
37 sltiu t0, t0, __NR_O32_Linux_syscalls + 1
38 daddiu t1, 4 # skip to next instruction
39 sd t1, PT_EPC(sp)
40 beqz t0, not_o32_scall
41 #if 0
42 SAVE_ALL
43 move a1, v0
44 PRINT("Scall %ld\n")
45 RESTORE_ALL
46 #endif
47
48 /* We don't want to stumble over broken sign extensions from
49 userland. O32 does never use the upper half. */
50 sll a0, a0, 0
51 sll a1, a1, 0
52 sll a2, a2, 0
53 sll a3, a3, 0
54
55 dsll t0, v0, 3 # offset into table
56 ld t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
57
58 sd a3, PT_R26(sp) # save a3 for syscall restarting
59
60 /*
61 * More than four arguments. Try to deal with it by copying the
62 * stack arguments from the user stack to the kernel stack.
63 * This Sucks (TM).
64 *
65 * We intentionally keep the kernel stack a little below the top of
66 * userspace so we don't have to do a slower byte accurate check here.
67 */
68 ld t0, PT_R29(sp) # get old user stack pointer
69 daddu t1, t0, 32
70 bltz t1, bad_stack
71
72 1: lw a4, 16(t0) # argument #5 from usp
73 2: lw a5, 20(t0) # argument #6 from usp
74 3: lw a6, 24(t0) # argument #7 from usp
75 4: lw a7, 28(t0) # argument #8 from usp (for indirect syscalls)
76
77 .section __ex_table,"a"
78 PTR 1b, bad_stack
79 PTR 2b, bad_stack
80 PTR 3b, bad_stack
81 PTR 4b, bad_stack
82 .previous
83
84 li t1, _TIF_WORK_SYSCALL_ENTRY
85 LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
86 and t0, t1, t0
87 bnez t0, trace_a_syscall
88
89 jalr t2 # Do The Real Thing (TM)
90
91 li t0, -EMAXERRNO - 1 # error?
92 sltu t0, t0, v0
93 sd t0, PT_R7(sp) # set error flag
94 beqz t0, 1f
95
96 ld t1, PT_R2(sp) # syscall number
97 dnegu v0 # error
98 sd t1, PT_R0(sp) # save it for syscall restarting
99 1: sd v0, PT_R2(sp) # result
100
101 o32_syscall_exit:
102 j syscall_exit_partial
103
104 /* ------------------------------------------------------------------------ */
105
106 trace_a_syscall:
107 SAVE_STATIC
108 sd a4, PT_R8(sp) # Save argument registers
109 sd a5, PT_R9(sp)
110 sd a6, PT_R10(sp)
111 sd a7, PT_R11(sp) # For indirect syscalls
112
113 move s0, t2 # Save syscall pointer
114 move a0, sp
115 /*
116 * absolute syscall number is in v0 unless we called syscall(__NR_###)
117 * where the real syscall number is in a0
118 * note: NR_syscall is the first O32 syscall but the macro is
119 * only defined when compiling with -mabi=32 (CONFIG_32BIT)
120 * therefore __NR_O32_Linux is used (4000)
121 */
122 .set push
123 .set reorder
124 subu t1, v0, __NR_O32_Linux
125 move a1, v0
126 bnez t1, 1f /* __NR_syscall at offset 0 */
127 lw a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
128 .set pop
129
130 1: jal syscall_trace_enter
131
132 bltz v0, 2f # seccomp failed? Skip syscall
133
134 move t0, s0
135 RESTORE_STATIC
136 ld a0, PT_R4(sp) # Restore argument registers
137 ld a1, PT_R5(sp)
138 ld a2, PT_R6(sp)
139 ld a3, PT_R7(sp)
140 ld a4, PT_R8(sp)
141 ld a5, PT_R9(sp)
142 ld a6, PT_R10(sp)
143 ld a7, PT_R11(sp) # For indirect syscalls
144 jalr t0
145
146 li t0, -EMAXERRNO - 1 # error?
147 sltu t0, t0, v0
148 sd t0, PT_R7(sp) # set error flag
149 beqz t0, 1f
150
151 ld t1, PT_R2(sp) # syscall number
152 dnegu v0 # error
153 sd t1, PT_R0(sp) # save it for syscall restarting
154 1: sd v0, PT_R2(sp) # result
155
156 2: j syscall_exit
157
158 /* ------------------------------------------------------------------------ */
159
160 /*
161 * The stackpointer for a call with more than 4 arguments is bad.
162 */
163 bad_stack:
164 li v0, EFAULT
165 sd v0, PT_R2(sp)
166 li t0, 1 # set error flag
167 sd t0, PT_R7(sp)
168 j o32_syscall_exit
169
170 not_o32_scall:
171 /*
172 * This is not an o32 compatibility syscall, pass it on
173 * to the 64-bit syscall handlers.
174 */
175 #ifdef CONFIG_MIPS32_N32
176 j handle_sysn32
177 #else
178 j handle_sys64
179 #endif
180 END(handle_sys)
181
182 LEAF(sys32_syscall)
183 subu t0, a0, __NR_O32_Linux # check syscall number
184 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
185 beqz t0, einval # do not recurse
186 dsll t1, t0, 3
187 beqz v0, einval
188 ld t2, sys32_call_table(t1) # syscall routine
189
190 move a0, a1 # shift argument registers
191 move a1, a2
192 move a2, a3
193 move a3, a4
194 move a4, a5
195 move a5, a6
196 move a6, a7
197 sd a0, PT_R4(sp) # ... and push back a0 - a3, some
198 sd a1, PT_R5(sp) # syscalls expect them there
199 sd a2, PT_R6(sp)
200 sd a3, PT_R7(sp)
201 sd a3, PT_R26(sp) # update a3 for syscall restarting
202 jr t2
203 /* Unreached */
204
205 einval: li v0, -ENOSYS
206 jr ra
207 END(sys32_syscall)
208
209 .align 3
210 .type sys32_call_table,@object
211 EXPORT(sys32_call_table)
212 PTR sys32_syscall /* 4000 */
213 PTR sys_exit
214 PTR __sys_fork
215 PTR sys_read
216 PTR sys_write
217 PTR compat_sys_open /* 4005 */
218 PTR sys_close
219 PTR sys_waitpid
220 PTR sys_creat
221 PTR sys_link
222 PTR sys_unlink /* 4010 */
223 PTR compat_sys_execve
224 PTR sys_chdir
225 PTR compat_sys_time
226 PTR sys_mknod
227 PTR sys_chmod /* 4015 */
228 PTR sys_lchown
229 PTR sys_ni_syscall
230 PTR sys_ni_syscall /* was sys_stat */
231 PTR sys_lseek
232 PTR sys_getpid /* 4020 */
233 PTR compat_sys_mount
234 PTR sys_oldumount
235 PTR sys_setuid
236 PTR sys_getuid
237 PTR compat_sys_stime /* 4025 */
238 PTR compat_sys_ptrace
239 PTR sys_alarm
240 PTR sys_ni_syscall /* was sys_fstat */
241 PTR sys_pause
242 PTR compat_sys_utime /* 4030 */
243 PTR sys_ni_syscall
244 PTR sys_ni_syscall
245 PTR sys_access
246 PTR sys_nice
247 PTR sys_ni_syscall /* 4035 */
248 PTR sys_sync
249 PTR sys_kill
250 PTR sys_rename
251 PTR sys_mkdir
252 PTR sys_rmdir /* 4040 */
253 PTR sys_dup
254 PTR sysm_pipe
255 PTR compat_sys_times
256 PTR sys_ni_syscall
257 PTR sys_brk /* 4045 */
258 PTR sys_setgid
259 PTR sys_getgid
260 PTR sys_ni_syscall /* was signal 2 */
261 PTR sys_geteuid
262 PTR sys_getegid /* 4050 */
263 PTR sys_acct
264 PTR sys_umount
265 PTR sys_ni_syscall
266 PTR compat_sys_ioctl
267 PTR compat_sys_fcntl /* 4055 */
268 PTR sys_ni_syscall
269 PTR sys_setpgid
270 PTR sys_ni_syscall
271 PTR sys_olduname
272 PTR sys_umask /* 4060 */
273 PTR sys_chroot
274 PTR compat_sys_ustat
275 PTR sys_dup2
276 PTR sys_getppid
277 PTR sys_getpgrp /* 4065 */
278 PTR sys_setsid
279 PTR sys_32_sigaction
280 PTR sys_sgetmask
281 PTR sys_ssetmask
282 PTR sys_setreuid /* 4070 */
283 PTR sys_setregid
284 PTR sys32_sigsuspend
285 PTR compat_sys_sigpending
286 PTR sys_sethostname
287 PTR compat_sys_setrlimit /* 4075 */
288 PTR compat_sys_getrlimit
289 PTR compat_sys_getrusage
290 PTR compat_sys_gettimeofday
291 PTR compat_sys_settimeofday
292 PTR sys_getgroups /* 4080 */
293 PTR sys_setgroups
294 PTR sys_ni_syscall /* old_select */
295 PTR sys_symlink
296 PTR sys_ni_syscall /* was sys_lstat */
297 PTR sys_readlink /* 4085 */
298 PTR sys_uselib
299 PTR sys_swapon
300 PTR sys_reboot
301 PTR compat_sys_old_readdir
302 PTR sys_mips_mmap /* 4090 */
303 PTR sys_munmap
304 PTR compat_sys_truncate
305 PTR compat_sys_ftruncate
306 PTR sys_fchmod
307 PTR sys_fchown /* 4095 */
308 PTR sys_getpriority
309 PTR sys_setpriority
310 PTR sys_ni_syscall
311 PTR compat_sys_statfs
312 PTR compat_sys_fstatfs /* 4100 */
313 PTR sys_ni_syscall /* sys_ioperm */
314 PTR compat_sys_socketcall
315 PTR sys_syslog
316 PTR compat_sys_setitimer
317 PTR compat_sys_getitimer /* 4105 */
318 PTR compat_sys_newstat
319 PTR compat_sys_newlstat
320 PTR compat_sys_newfstat
321 PTR sys_uname
322 PTR sys_ni_syscall /* sys_ioperm *//* 4110 */
323 PTR sys_vhangup
324 PTR sys_ni_syscall /* was sys_idle */
325 PTR sys_ni_syscall /* sys_vm86 */
326 PTR compat_sys_wait4
327 PTR sys_swapoff /* 4115 */
328 PTR compat_sys_sysinfo
329 PTR compat_sys_ipc
330 PTR sys_fsync
331 PTR sys32_sigreturn
332 PTR __sys_clone /* 4120 */
333 PTR sys_setdomainname
334 PTR sys_newuname
335 PTR sys_ni_syscall /* sys_modify_ldt */
336 PTR compat_sys_adjtimex
337 PTR sys_mprotect /* 4125 */
338 PTR compat_sys_sigprocmask
339 PTR sys_ni_syscall /* was creat_module */
340 PTR sys_init_module
341 PTR sys_delete_module
342 PTR sys_ni_syscall /* 4130, get_kernel_syms */
343 PTR sys_quotactl
344 PTR sys_getpgid
345 PTR sys_fchdir
346 PTR sys_bdflush
347 PTR sys_sysfs /* 4135 */
348 PTR sys_32_personality
349 PTR sys_ni_syscall /* for afs_syscall */
350 PTR sys_setfsuid
351 PTR sys_setfsgid
352 PTR sys_32_llseek /* 4140 */
353 PTR compat_sys_getdents
354 PTR compat_sys_select
355 PTR sys_flock
356 PTR sys_msync
357 PTR compat_sys_readv /* 4145 */
358 PTR compat_sys_writev
359 PTR sys_cacheflush
360 PTR sys_cachectl
361 PTR sys_sysmips
362 PTR sys_ni_syscall /* 4150 */
363 PTR sys_getsid
364 PTR sys_fdatasync
365 PTR compat_sys_sysctl
366 PTR sys_mlock
367 PTR sys_munlock /* 4155 */
368 PTR sys_mlockall
369 PTR sys_munlockall
370 PTR sys_sched_setparam
371 PTR sys_sched_getparam
372 PTR sys_sched_setscheduler /* 4160 */
373 PTR sys_sched_getscheduler
374 PTR sys_sched_yield
375 PTR sys_sched_get_priority_max
376 PTR sys_sched_get_priority_min
377 PTR compat_sys_sched_rr_get_interval /* 4165 */
378 PTR compat_sys_nanosleep
379 PTR sys_mremap
380 PTR sys_accept
381 PTR sys_bind
382 PTR sys_connect /* 4170 */
383 PTR sys_getpeername
384 PTR sys_getsockname
385 PTR sys_getsockopt
386 PTR sys_listen
387 PTR compat_sys_recv /* 4175 */
388 PTR compat_sys_recvfrom
389 PTR compat_sys_recvmsg
390 PTR sys_send
391 PTR compat_sys_sendmsg
392 PTR sys_sendto /* 4180 */
393 PTR compat_sys_setsockopt
394 PTR sys_shutdown
395 PTR sys_socket
396 PTR sys_socketpair
397 PTR sys_setresuid /* 4185 */
398 PTR sys_getresuid
399 PTR sys_ni_syscall /* was query_module */
400 PTR sys_poll
401 PTR sys_ni_syscall /* was nfsservctl */
402 PTR sys_setresgid /* 4190 */
403 PTR sys_getresgid
404 PTR sys_prctl
405 PTR sys32_rt_sigreturn
406 PTR compat_sys_rt_sigaction
407 PTR compat_sys_rt_sigprocmask /* 4195 */
408 PTR compat_sys_rt_sigpending
409 PTR compat_sys_rt_sigtimedwait
410 PTR compat_sys_rt_sigqueueinfo
411 PTR compat_sys_rt_sigsuspend
412 PTR sys_32_pread /* 4200 */
413 PTR sys_32_pwrite
414 PTR sys_chown
415 PTR sys_getcwd
416 PTR sys_capget
417 PTR sys_capset /* 4205 */
418 PTR compat_sys_sigaltstack
419 PTR compat_sys_sendfile
420 PTR sys_ni_syscall
421 PTR sys_ni_syscall
422 PTR sys_mips_mmap2 /* 4210 */
423 PTR sys_32_truncate64
424 PTR sys_32_ftruncate64
425 PTR sys_newstat
426 PTR sys_newlstat
427 PTR sys_newfstat /* 4215 */
428 PTR sys_pivot_root
429 PTR sys_mincore
430 PTR sys_madvise
431 PTR sys_getdents64
432 PTR compat_sys_fcntl64 /* 4220 */
433 PTR sys_ni_syscall
434 PTR sys_gettid
435 PTR sys32_readahead
436 PTR sys_setxattr
437 PTR sys_lsetxattr /* 4225 */
438 PTR sys_fsetxattr
439 PTR sys_getxattr
440 PTR sys_lgetxattr
441 PTR sys_fgetxattr
442 PTR sys_listxattr /* 4230 */
443 PTR sys_llistxattr
444 PTR sys_flistxattr
445 PTR sys_removexattr
446 PTR sys_lremovexattr
447 PTR sys_fremovexattr /* 4235 */
448 PTR sys_tkill
449 PTR sys_sendfile64
450 PTR compat_sys_futex
451 PTR compat_sys_sched_setaffinity
452 PTR compat_sys_sched_getaffinity /* 4240 */
453 PTR compat_sys_io_setup
454 PTR sys_io_destroy
455 PTR compat_sys_io_getevents
456 PTR compat_sys_io_submit
457 PTR sys_io_cancel /* 4245 */
458 PTR sys_exit_group
459 PTR compat_sys_lookup_dcookie
460 PTR sys_epoll_create
461 PTR sys_epoll_ctl
462 PTR sys_epoll_wait /* 4250 */
463 PTR sys_remap_file_pages
464 PTR sys_set_tid_address
465 PTR sys_restart_syscall
466 PTR sys32_fadvise64_64
467 PTR compat_sys_statfs64 /* 4255 */
468 PTR compat_sys_fstatfs64
469 PTR compat_sys_timer_create
470 PTR compat_sys_timer_settime
471 PTR compat_sys_timer_gettime
472 PTR sys_timer_getoverrun /* 4260 */
473 PTR sys_timer_delete
474 PTR compat_sys_clock_settime
475 PTR compat_sys_clock_gettime
476 PTR compat_sys_clock_getres
477 PTR compat_sys_clock_nanosleep /* 4265 */
478 PTR sys_tgkill
479 PTR compat_sys_utimes
480 PTR compat_sys_mbind
481 PTR compat_sys_get_mempolicy
482 PTR compat_sys_set_mempolicy /* 4270 */
483 PTR compat_sys_mq_open
484 PTR sys_mq_unlink
485 PTR compat_sys_mq_timedsend
486 PTR compat_sys_mq_timedreceive
487 PTR compat_sys_mq_notify /* 4275 */
488 PTR compat_sys_mq_getsetattr
489 PTR sys_ni_syscall /* sys_vserver */
490 PTR compat_sys_waitid
491 PTR sys_ni_syscall /* available, was setaltroot */
492 PTR sys_add_key /* 4280 */
493 PTR sys_request_key
494 PTR sys_keyctl
495 PTR sys_set_thread_area
496 PTR sys_inotify_init
497 PTR sys_inotify_add_watch /* 4285 */
498 PTR sys_inotify_rm_watch
499 PTR compat_sys_migrate_pages
500 PTR compat_sys_openat
501 PTR sys_mkdirat
502 PTR sys_mknodat /* 4290 */
503 PTR sys_fchownat
504 PTR compat_sys_futimesat
505 PTR sys_newfstatat
506 PTR sys_unlinkat
507 PTR sys_renameat /* 4295 */
508 PTR sys_linkat
509 PTR sys_symlinkat
510 PTR sys_readlinkat
511 PTR sys_fchmodat
512 PTR sys_faccessat /* 4300 */
513 PTR compat_sys_pselect6
514 PTR compat_sys_ppoll
515 PTR sys_unshare
516 PTR sys_splice
517 PTR sys32_sync_file_range /* 4305 */
518 PTR sys_tee
519 PTR compat_sys_vmsplice
520 PTR compat_sys_move_pages
521 PTR compat_sys_set_robust_list
522 PTR compat_sys_get_robust_list /* 4310 */
523 PTR compat_sys_kexec_load
524 PTR sys_getcpu
525 PTR compat_sys_epoll_pwait
526 PTR sys_ioprio_set
527 PTR sys_ioprio_get /* 4315 */
528 PTR compat_sys_utimensat
529 PTR compat_sys_signalfd
530 PTR sys_ni_syscall /* was timerfd */
531 PTR sys_eventfd
532 PTR sys32_fallocate /* 4320 */
533 PTR sys_timerfd_create
534 PTR compat_sys_timerfd_gettime
535 PTR compat_sys_timerfd_settime
536 PTR compat_sys_signalfd4
537 PTR sys_eventfd2 /* 4325 */
538 PTR sys_epoll_create1
539 PTR sys_dup3
540 PTR sys_pipe2
541 PTR sys_inotify_init1
542 PTR compat_sys_preadv /* 4330 */
543 PTR compat_sys_pwritev
544 PTR compat_sys_rt_tgsigqueueinfo
545 PTR sys_perf_event_open
546 PTR sys_accept4
547 PTR compat_sys_recvmmsg /* 4335 */
548 PTR sys_fanotify_init
549 PTR compat_sys_fanotify_mark
550 PTR sys_prlimit64
551 PTR sys_name_to_handle_at
552 PTR compat_sys_open_by_handle_at /* 4340 */
553 PTR compat_sys_clock_adjtime
554 PTR sys_syncfs
555 PTR compat_sys_sendmmsg
556 PTR sys_setns
557 PTR compat_sys_process_vm_readv /* 4345 */
558 PTR compat_sys_process_vm_writev
559 PTR sys_kcmp
560 PTR sys_finit_module
561 PTR sys_sched_setattr
562 PTR sys_sched_getattr /* 4350 */
563 PTR sys_renameat2
564 PTR sys_seccomp
565 .size sys32_call_table,.-sys32_call_table
This page took 0.04602 seconds and 5 git commands to generate.