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