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