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