]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/mips/kernel/scall32-o32.S
MIPS: Fix error values in case of bad_stack
[net-next-2.6.git] / arch / mips / kernel / scall32-o32.S
CommitLineData
1da177e4
LT
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 *
192ef366 6 * Copyright (C) 1995-99, 2000- 02, 06 Ralf Baechle <ralf@linux-mips.org>
1da177e4
LT
7 * Copyright (C) 2001 MIPS Technologies, Inc.
8 * Copyright (C) 2004 Thiemo Seufer
9 */
1da177e4
LT
10#include <linux/errno.h>
11#include <asm/asm.h>
12#include <asm/asmmacro.h>
192ef366 13#include <asm/irqflags.h>
1da177e4
LT
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>
048eb582 22#include <asm/asm-offsets.h>
1da177e4
LT
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
eae6c0da 31 TRACE_IRQS_ON_RELOAD
1da177e4
LT
32 STI
33 .set at
34
35 lw t1, PT_EPC(sp) # skip syscall on return
36
1da177e4
LT
37 subu v0, v0, __NR_O32_Linux # check syscall number
38 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
1da177e4
LT
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
8f5a00eb 66 lw t1, PT_R2(sp) # syscall number
1da177e4 67 negu v0 # error
8f5a00eb 68 sw t1, PT_R0(sp) # save it for syscall restarting
1da177e4
LT
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 li a1, 0
92 jal do_syscall_trace
93
04a7052c
RB
94 move t0, s0
95 RESTORE_STATIC
1da177e4
LT
96 lw a0, PT_R4(sp) # Restore argument registers
97 lw a1, PT_R5(sp)
98 lw a2, PT_R6(sp)
99 lw a3, PT_R7(sp)
04a7052c 100 jalr t0
1da177e4
LT
101
102 li t0, -EMAXERRNO - 1 # error?
103 sltu t0, t0, v0
104 sw t0, PT_R7(sp) # set error flag
105 beqz t0, 1f
106
8f5a00eb 107 lw t1, PT_R2(sp) # syscall number
1da177e4 108 negu v0 # error
8f5a00eb 109 sw t1, PT_R0(sp) # save it for syscall restarting
1da177e4
LT
1101: sw v0, PT_R2(sp) # result
111
112 j syscall_exit
113
114/* ------------------------------------------------------------------------ */
115
116 /*
117 * More than four arguments. Try to deal with it by copying the
118 * stack arguments from the user stack to the kernel stack.
119 * This Sucks (TM).
120 */
121stackargs:
122 lw t0, PT_R29(sp) # get old user stack pointer
123
124 /*
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.
127 */
128 lw t5, TI_ADDR_LIMIT($28)
129 addu t4, t0, 32
130 and t5, t4
131 bltz t5, bad_stack # -> sp is bad
132
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.
136 */
137
138 la t1, 5f # load up to 3 arguments
139 subu t1, t3
1401: lw t5, 16(t0) # argument #5 from usp
141 .set push
142 .set noreorder
143 .set nomacro
144 jr t1
145 addiu t1, 6f - 5f
146
1472: lw t8, 28(t0) # argument #8 from usp
1483: lw t7, 24(t0) # argument #7 from usp
1494: lw t6, 20(t0) # argument #6 from usp
1505: jr t1
151 sw t5, 16(sp) # argument #5 to ksp
152
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
1566: j stack_done # go back
157 nop
158 .set pop
159
160 .section __ex_table,"a"
161 PTR 1b,bad_stack
162 PTR 2b,bad_stack
163 PTR 3b,bad_stack
164 PTR 4b,bad_stack
165 .previous
166
167 /*
168 * The stackpointer for a call with more than 4 arguments is bad.
169 * We probably should handle this case a bit more drastic.
170 */
171bad_stack:
5b89c004 172 li v0, EFAULT
1da177e4
LT
173 sw v0, PT_R2(sp)
174 li t0, 1 # set error flag
175 sw t0, PT_R7(sp)
176 j o32_syscall_exit
177
178 /*
179 * The system call does not exist in this kernel
180 */
181illegal_syscall:
bda8229b 182 li v0, ENOSYS # error
1da177e4
LT
183 sw v0, PT_R2(sp)
184 li t0, 1 # set error flag
185 sw t0, PT_R7(sp)
186 j o32_syscall_exit
187 END(handle_sys)
188
1da177e4 189 LEAF(sys_syscall)
1da177e4
LT
190 subu t0, a0, __NR_O32_Linux # check syscall number
191 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
e807f957 192 beqz t0, einval # do not recurse
1da177e4
LT
193 sll t1, t0, 3
194 beqz v0, einval
1da177e4
LT
195 lw t2, sys_call_table(t1) # syscall routine
196
1da177e4
LT
197 /* Some syscalls like execve get their arguments from struct pt_regs
198 and claim zero arguments in the syscall table. Thus we have to
199 assume the worst case and shuffle around all potential arguments.
200 If you want performance, don't use indirect syscalls. */
201
202 move a0, a1 # shift argument registers
203 move a1, a2
204 move a2, a3
205 lw a3, 16(sp)
206 lw t4, 20(sp)
207 lw t5, 24(sp)
208 lw t6, 28(sp)
209 sw t4, 16(sp)
210 sw t5, 20(sp)
211 sw t6, 24(sp)
212 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
213 sw a1, PT_R5(sp) # syscalls expect them there
214 sw a2, PT_R6(sp)
215 sw a3, PT_R7(sp)
216 sw a3, PT_R26(sp) # update a3 for syscall restarting
217 jr t2
218 /* Unreached */
219
fb498e25 220einval: li v0, -ENOSYS
1da177e4
LT
221 jr ra
222 END(sys_syscall)
223
224 .macro fifty ptr, nargs, from=1, to=50
225 sys \ptr \nargs
226 .if \to-\from
227 fifty \ptr,\nargs,"(\from+1)",\to
228 .endif
229 .endm
230
231 .macro mille ptr, nargs, from=1, to=20
232 fifty \ptr,\nargs
233 .if \to-\from
234 mille \ptr,\nargs,"(\from+1)",\to
235 .endif
236 .endm
237
238 .macro syscalltable
1da177e4
LT
239 sys sys_syscall 8 /* 4000 */
240 sys sys_exit 1
241 sys sys_fork 0
242 sys sys_read 3
243 sys sys_write 3
244 sys sys_open 3 /* 4005 */
245 sys sys_close 1
246 sys sys_waitpid 3
247 sys sys_creat 2
248 sys sys_link 2
249 sys sys_unlink 1 /* 4010 */
250 sys sys_execve 0
251 sys sys_chdir 1
252 sys sys_time 1
253 sys sys_mknod 3
254 sys sys_chmod 2 /* 4015 */
255 sys sys_lchown 3
256 sys sys_ni_syscall 0
257 sys sys_ni_syscall 0 /* was sys_stat */
258 sys sys_lseek 3
259 sys sys_getpid 0 /* 4020 */
260 sys sys_mount 5
261 sys sys_oldumount 1
262 sys sys_setuid 1
263 sys sys_getuid 0
264 sys sys_stime 1 /* 4025 */
265 sys sys_ptrace 4
266 sys sys_alarm 1
267 sys sys_ni_syscall 0 /* was sys_fstat */
268 sys sys_pause 0
269 sys sys_utime 2 /* 4030 */
270 sys sys_ni_syscall 0
271 sys sys_ni_syscall 0
272 sys sys_access 2
273 sys sys_nice 1
274 sys sys_ni_syscall 0 /* 4035 */
275 sys sys_sync 0
276 sys sys_kill 2
277 sys sys_rename 2
278 sys sys_mkdir 2
279 sys sys_rmdir 1 /* 4040 */
280 sys sys_dup 1
8213bbf9 281 sys sysm_pipe 0
1da177e4
LT
282 sys sys_times 1
283 sys sys_ni_syscall 0
284 sys sys_brk 1 /* 4045 */
285 sys sys_setgid 1
286 sys sys_getgid 0
287 sys sys_ni_syscall 0 /* was signal(2) */
288 sys sys_geteuid 0
289 sys sys_getegid 0 /* 4050 */
290 sys sys_acct 1
291 sys sys_umount 2
292 sys sys_ni_syscall 0
293 sys sys_ioctl 3
294 sys sys_fcntl 3 /* 4055 */
295 sys sys_ni_syscall 2
296 sys sys_setpgid 2
297 sys sys_ni_syscall 0
298 sys sys_olduname 1
299 sys sys_umask 1 /* 4060 */
300 sys sys_chroot 1
301 sys sys_ustat 2
302 sys sys_dup2 2
303 sys sys_getppid 0
304 sys sys_getpgrp 0 /* 4065 */
305 sys sys_setsid 0
306 sys sys_sigaction 3
307 sys sys_sgetmask 0
308 sys sys_ssetmask 1
309 sys sys_setreuid 2 /* 4070 */
310 sys sys_setregid 2
311 sys sys_sigsuspend 0
312 sys sys_sigpending 1
313 sys sys_sethostname 2
314 sys sys_setrlimit 2 /* 4075 */
315 sys sys_getrlimit 2
316 sys sys_getrusage 2
317 sys sys_gettimeofday 2
318 sys sys_settimeofday 2
319 sys sys_getgroups 2 /* 4080 */
320 sys sys_setgroups 2
321 sys sys_ni_syscall 0 /* old_select */
322 sys sys_symlink 2
323 sys sys_ni_syscall 0 /* was sys_lstat */
324 sys sys_readlink 3 /* 4085 */
325 sys sys_uselib 1
326 sys sys_swapon 2
327 sys sys_reboot 3
e55380ed 328 sys sys_old_readdir 3
dbda6ac0 329 sys sys_mips_mmap 6 /* 4090 */
1da177e4
LT
330 sys sys_munmap 2
331 sys sys_truncate 2
332 sys sys_ftruncate 2
333 sys sys_fchmod 2
334 sys sys_fchown 3 /* 4095 */
335 sys sys_getpriority 2
336 sys sys_setpriority 3
337 sys sys_ni_syscall 0
338 sys sys_statfs 2
339 sys sys_fstatfs 2 /* 4100 */
340 sys sys_ni_syscall 0 /* was ioperm(2) */
341 sys sys_socketcall 2
342 sys sys_syslog 3
343 sys sys_setitimer 3
344 sys sys_getitimer 2 /* 4105 */
345 sys sys_newstat 2
346 sys sys_newlstat 2
347 sys sys_newfstat 2
348 sys sys_uname 1
349 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
350 sys sys_vhangup 0
351 sys sys_ni_syscall 0 /* was sys_idle() */
352 sys sys_ni_syscall 0 /* was sys_vm86 */
353 sys sys_wait4 4
354 sys sys_swapoff 1 /* 4115 */
355 sys sys_sysinfo 1
356 sys sys_ipc 6
357 sys sys_fsync 1
358 sys sys_sigreturn 0
359 sys sys_clone 0 /* 4120 */
360 sys sys_setdomainname 2
361 sys sys_newuname 1
362 sys sys_ni_syscall 0 /* sys_modify_ldt */
363 sys sys_adjtimex 1
364 sys sys_mprotect 3 /* 4125 */
365 sys sys_sigprocmask 3
366 sys sys_ni_syscall 0 /* was create_module */
367 sys sys_init_module 5
368 sys sys_delete_module 1
369 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
370 sys sys_quotactl 4
371 sys sys_getpgid 1
372 sys sys_fchdir 1
373 sys sys_bdflush 2
374 sys sys_sysfs 3 /* 4135 */
375 sys sys_personality 1
376 sys sys_ni_syscall 0 /* for afs_syscall */
377 sys sys_setfsuid 1
378 sys sys_setfsgid 1
379 sys sys_llseek 5 /* 4140 */
380 sys sys_getdents 3
381 sys sys_select 5
382 sys sys_flock 2
383 sys sys_msync 3
384 sys sys_readv 3 /* 4145 */
385 sys sys_writev 3
386 sys sys_cacheflush 3
387 sys sys_cachectl 3
388 sys sys_sysmips 4
389 sys sys_ni_syscall 0 /* 4150 */
390 sys sys_getsid 1
391 sys sys_fdatasync 1
392 sys sys_sysctl 1
393 sys sys_mlock 2
394 sys sys_munlock 2 /* 4155 */
395 sys sys_mlockall 1
396 sys sys_munlockall 0
397 sys sys_sched_setparam 2
398 sys sys_sched_getparam 2
399 sys sys_sched_setscheduler 3 /* 4160 */
400 sys sys_sched_getscheduler 1
401 sys sys_sched_yield 0
402 sys sys_sched_get_priority_max 1
403 sys sys_sched_get_priority_min 1
404 sys sys_sched_rr_get_interval 2 /* 4165 */
405 sys sys_nanosleep, 2
7dbdf43c 406 sys sys_mremap, 5
1da177e4
LT
407 sys sys_accept 3
408 sys sys_bind 3
409 sys sys_connect 3 /* 4170 */
410 sys sys_getpeername 3
411 sys sys_getsockname 3
412 sys sys_getsockopt 5
413 sys sys_listen 2
414 sys sys_recv 4 /* 4175 */
415 sys sys_recvfrom 6
416 sys sys_recvmsg 3
417 sys sys_send 4
418 sys sys_sendmsg 3
419 sys sys_sendto 6 /* 4180 */
420 sys sys_setsockopt 5
421 sys sys_shutdown 2
422 sys sys_socket 3
423 sys sys_socketpair 4
424 sys sys_setresuid 3 /* 4185 */
425 sys sys_getresuid 3
426 sys sys_ni_syscall 0 /* was sys_query_module */
427 sys sys_poll 3
428 sys sys_nfsservctl 3
429 sys sys_setresgid 3 /* 4190 */
430 sys sys_getresgid 3
431 sys sys_prctl 5
432 sys sys_rt_sigreturn 0
433 sys sys_rt_sigaction 4
434 sys sys_rt_sigprocmask 4 /* 4195 */
435 sys sys_rt_sigpending 2
436 sys sys_rt_sigtimedwait 4
437 sys sys_rt_sigqueueinfo 3
438 sys sys_rt_sigsuspend 0
439 sys sys_pread64 6 /* 4200 */
440 sys sys_pwrite64 6
441 sys sys_chown 3
442 sys sys_getcwd 2
443 sys sys_capget 2
444 sys sys_capset 2 /* 4205 */
445 sys sys_sigaltstack 0
446 sys sys_sendfile 4
447 sys sys_ni_syscall 0
448 sys sys_ni_syscall 0
dbda6ac0 449 sys sys_mips_mmap2 6 /* 4210 */
1da177e4
LT
450 sys sys_truncate64 4
451 sys sys_ftruncate64 4
452 sys sys_stat64 2
453 sys sys_lstat64 2
454 sys sys_fstat64 2 /* 4215 */
455 sys sys_pivot_root 2
456 sys sys_mincore 3
457 sys sys_madvise 3
458 sys sys_getdents64 3
459 sys sys_fcntl64 3 /* 4220 */
460 sys sys_ni_syscall 0
461 sys sys_gettid 0
462 sys sys_readahead 5
463 sys sys_setxattr 5
464 sys sys_lsetxattr 5 /* 4225 */
465 sys sys_fsetxattr 5
466 sys sys_getxattr 4
467 sys sys_lgetxattr 4
468 sys sys_fgetxattr 4
469 sys sys_listxattr 3 /* 4230 */
470 sys sys_llistxattr 3
471 sys sys_flistxattr 3
472 sys sys_removexattr 2
473 sys sys_lremovexattr 2
474 sys sys_fremovexattr 2 /* 4235 */
475 sys sys_tkill 2
476 sys sys_sendfile64 5
90a67b59 477 sys sys_futex 6
f088fc84
RB
478#ifdef CONFIG_MIPS_MT_FPAFF
479 /*
480 * For FPU affinity scheduling on MIPS MT processors, we need to
481 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
482 * in kernel/sched.c. Considered only temporary we only support these
483 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
484 */
485 sys mipsmt_sys_sched_setaffinity 3
486 sys mipsmt_sys_sched_getaffinity 3
487#else
1da177e4
LT
488 sys sys_sched_setaffinity 3
489 sys sys_sched_getaffinity 3 /* 4240 */
f088fc84 490#endif /* CONFIG_MIPS_MT_FPAFF */
1da177e4
LT
491 sys sys_io_setup 2
492 sys sys_io_destroy 1
493 sys sys_io_getevents 5
494 sys sys_io_submit 3
495 sys sys_io_cancel 3 /* 4245 */
496 sys sys_exit_group 1
0d507d61 497 sys sys_lookup_dcookie 4
1da177e4
LT
498 sys sys_epoll_create 1
499 sys sys_epoll_ctl 4
500 sys sys_epoll_wait 3 /* 4250 */
501 sys sys_remap_file_pages 5
502 sys sys_set_tid_address 1
503 sys sys_restart_syscall 0
504 sys sys_fadvise64_64 7
505 sys sys_statfs64 3 /* 4255 */
506 sys sys_fstatfs64 2
507 sys sys_timer_create 3
508 sys sys_timer_settime 4
509 sys sys_timer_gettime 2
510 sys sys_timer_getoverrun 1 /* 4260 */
511 sys sys_timer_delete 1
512 sys sys_clock_settime 2
513 sys sys_clock_gettime 2
514 sys sys_clock_getres 2
515 sys sys_clock_nanosleep 4 /* 4265 */
516 sys sys_tgkill 3
517 sys sys_utimes 2
518 sys sys_mbind 4
519 sys sys_ni_syscall 0 /* sys_get_mempolicy */
520 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
521 sys sys_mq_open 4
522 sys sys_mq_unlink 1
523 sys sys_mq_timedsend 5
524 sys sys_mq_timedreceive 5
525 sys sys_mq_notify 2 /* 4275 */
526 sys sys_mq_getsetattr 3
527 sys sys_ni_syscall 0 /* sys_vserver */
a19050f3 528 sys sys_waitid 5
1da177e4 529 sys sys_ni_syscall 0 /* available, was setaltroot */
e50c0a8f 530 sys sys_add_key 5 /* 4280 */
1da177e4
LT
531 sys sys_request_key 4
532 sys sys_keyctl 5
3c37026d 533 sys sys_set_thread_area 1
7db36c85
RB
534 sys sys_inotify_init 0
535 sys sys_inotify_add_watch 3 /* 4285 */
536 sys sys_inotify_rm_watch 2
72bf8914
RB
537 sys sys_migrate_pages 4
538 sys sys_openat 4
539 sys sys_mkdirat 3
540 sys sys_mknodat 4 /* 4290 */
541 sys sys_fchownat 5
542 sys sys_futimesat 3
326a6257 543 sys sys_fstatat64 4
72bf8914
RB
544 sys sys_unlinkat 3
545 sys sys_renameat 4 /* 4295 */
c04030e1 546 sys sys_linkat 5
72bf8914
RB
547 sys sys_symlinkat 3
548 sys sys_readlinkat 4
549 sys sys_fchmodat 3
550 sys sys_faccessat 3 /* 4300 */
551 sys sys_pselect6 6
552 sys sys_ppoll 5
553 sys sys_unshare 1
08d30879 554 sys sys_splice 6
a8d587a7 555 sys sys_sync_file_range 7 /* 4305 */
136d47d3 556 sys sys_tee 4
722cfd90
RB
557 sys sys_vmsplice 4
558 sys sys_move_pages 6
7fdeb048 559 sys sys_set_robust_list 2
d2bcf87d 560 sys sys_get_robust_list 3 /* 4310 */
583bb86f 561 sys sys_kexec_load 4
991ea26d
RB
562 sys sys_getcpu 3
563 sys sys_epoll_pwait 6
08253b39 564 sys sys_ioprio_set 3
7a6d4f38
AN
565 sys sys_ioprio_get 2 /* 4315 */
566 sys sys_utimensat 4
567 sys sys_signalfd 3
4d672e7a 568 sys sys_ni_syscall 0
7a6d4f38 569 sys sys_eventfd 1
4dc46775 570 sys sys_fallocate 6 /* 4320 */
6783fe62
DV
571 sys sys_timerfd_create 2
572 sys sys_timerfd_gettime 2
573 sys sys_timerfd_settime 4
3885b71b
RB
574 sys sys_signalfd4 4
575 sys sys_eventfd2 2 /* 4325 */
576 sys sys_epoll_create1 1
577 sys sys_dup3 3
578 sys sys_pipe2 2
579 sys sys_inotify_init1 1
ddd9e91b
RB
580 sys sys_preadv 6 /* 4330 */
581 sys sys_pwritev 6
69f16c9a 582 sys sys_rt_tgsigqueueinfo 4
cdd6c482 583 sys sys_perf_event_open 5
54822de7 584 sys sys_accept4 4
a2e27255 585 sys sys_recvmmsg 5
1da177e4
LT
586 .endm
587
588 /* We pre-compute the number of _instruction_ bytes needed to
589 load or store the arguments 6-8. Negative values are ignored. */
590
591 .macro sys function, nargs
592 PTR \function
593 LONG (\nargs << 2) - (5 << 2)
594 .endm
595
596 .align 3
597 .type sys_call_table,@object
598EXPORT(sys_call_table)
599 syscalltable
600 .size sys_call_table, . - sys_call_table