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/config.h> 17#include <linux/errno.h> 18#include <asm/asm.h> 19#include <asm/asmmacro.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 28NESTED(handle_sys, PT_SIZE, sp) 29 .set noat 30 SAVE_SOME 31 STI 32 .set at 33 ld t1, PT_EPC(sp) # skip syscall on return 34 35 dsubu t0, v0, __NR_O32_Linux # check syscall number 36 sltiu t0, t0, __NR_O32_Linux_syscalls + 1 37 daddiu t1, 4 # skip to next instruction 38 sd t1, PT_EPC(sp) 39 beqz t0, not_o32_scall 40#if 0 41 SAVE_ALL 42 move a1, v0 43 PRINT("Scall %ld\n") 44 RESTORE_ALL 45#endif 46 47 /* We don't want to stumble over broken sign extensions from 48 userland. O32 does never use the upper half. */ 49 sll a0, a0, 0 50 sll a1, a1, 0 51 sll a2, a2, 0 52 sll a3, a3, 0 53 54 dsll t0, v0, 3 # offset into table 55 ld t2, (sys_call_table - (__NR_O32_Linux * 8))(t0) 56 57 sd a3, PT_R26(sp) # save a3 for syscall restarting 58 59 /* 60 * More than four arguments. Try to deal with it by copying the 61 * stack arguments from the user stack to the kernel stack. 62 * This Sucks (TM). 63 * 64 * We intentionally keep the kernel stack a little below the top of 65 * userspace so we don't have to do a slower byte accurate check here. 66 */ 67 ld t0, PT_R29(sp) # get old user stack pointer 68 daddu t1, t0, 32 69 bltz t1, bad_stack 70 711: lw a4, 16(t0) # argument #5 from usp 722: lw a5, 20(t0) # argument #6 from usp 733: lw a6, 24(t0) # argument #7 from usp 744: lw a7, 28(t0) # argument #8 from usp (for indirect syscalls) 75 76 .section __ex_table,"a" 77 PTR 1b, bad_stack 78 PTR 2b, bad_stack 79 PTR 3b, bad_stack 80 PTR 4b, bad_stack 81 .previous 82 83 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT 84 LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? 85 and t0, t1, t0 86 bnez t0, trace_a_syscall 87 88 jalr t2 # Do The Real Thing (TM) 89 90 li t0, -EMAXERRNO - 1 # error? 91 sltu t0, t0, v0 92 sd t0, PT_R7(sp) # set error flag 93 beqz t0, 1f 94 95 dnegu v0 # error 96 sd v0, PT_R0(sp) # flag for syscall restarting 971: sd v0, PT_R2(sp) # result 98 99o32_syscall_exit: 100 local_irq_disable # make need_resched and 101 # signals dont change between 102 # sampling and return 103 LONG_L a2, TI_FLAGS($28) 104 li t0, _TIF_ALLWORK_MASK 105 and t0, a2, t0 106 bnez t0, o32_syscall_exit_work 107 108 j restore_partial 109 110o32_syscall_exit_work: 111 j syscall_exit_work_partial 112 113/* ------------------------------------------------------------------------ */ 114 115trace_a_syscall: 116 SAVE_STATIC 117 sd a4, PT_R8(sp) # Save argument registers 118 sd a5, PT_R9(sp) 119 sd a6, PT_R10(sp) 120 sd a7, PT_R11(sp) # For indirect syscalls 121 122 move s0, t2 # Save syscall pointer 123 move a0, sp 124 li a1, 0 125 jal do_syscall_trace 126 127 ld a0, PT_R4(sp) # Restore argument registers 128 ld a1, PT_R5(sp) 129 ld a2, PT_R6(sp) 130 ld a3, PT_R7(sp) 131 ld a4, PT_R8(sp) 132 ld a5, PT_R9(sp) 133 ld a6, PT_R10(sp) 134 ld a7, PT_R11(sp) # For indirect syscalls 135 jalr s0 136 137 li t0, -EMAXERRNO - 1 # error? 138 sltu t0, t0, v0 139 sd t0, PT_R7(sp) # set error flag 140 beqz t0, 1f 141 142 dnegu v0 # error 143 sd v0, PT_R0(sp) # set flag for syscall restarting 1441: sd v0, PT_R2(sp) # result 145 146 j syscall_exit 147 148/* ------------------------------------------------------------------------ */ 149 150 /* 151 * The stackpointer for a call with more than 4 arguments is bad. 152 */ 153bad_stack: 154 dnegu v0 # error 155 sd v0, PT_R0(sp) 156 sd v0, PT_R2(sp) 157 li t0, 1 # set error flag 158 sd t0, PT_R7(sp) 159 j o32_syscall_exit 160 161not_o32_scall: 162 /* 163 * This is not an o32 compatibility syscall, pass it on 164 * to the 64-bit syscall handlers. 165 */ 166#ifdef CONFIG_MIPS32_N32 167 j handle_sysn32 168#else 169 j handle_sys64 170#endif 171 END(handle_sys) 172 173LEAF(sys32_syscall) 174 sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1 175 beqz v0, einval 176 177 dsll v0, a0, 3 178 ld t2, (sys_call_table - (__NR_O32_Linux * 8))(v0) 179 180 li v1, 4000 # indirect syscall number 181 beq a0, v1, einval # do not recurse 182 183 move a0, a1 # shift argument registers 184 move a1, a2 185 move a2, a3 186 move a3, a4 187 move a4, a5 188 move a5, a6 189 move a6, a7 190 sd a0, PT_R4(sp) # ... and push back a0 - a3, some 191 sd a1, PT_R5(sp) # syscalls expect them there 192 sd a2, PT_R6(sp) 193 sd a3, PT_R7(sp) 194 sd a3, PT_R26(sp) # update a3 for syscall restarting 195 jr t2 196 /* Unreached */ 197 198einval: li v0, -EINVAL 199 jr ra 200 END(sys32_syscall) 201 202 .align 3 203 .type sys_call_table,@object 204sys_call_table: 205 PTR sys32_syscall /* 4000 */ 206 PTR sys_exit 207 PTR sys_fork 208 PTR sys_read 209 PTR sys_write 210 PTR sys_open /* 4005 */ 211 PTR sys_close 212 PTR sys_waitpid 213 PTR sys_creat 214 PTR sys_link 215 PTR sys_unlink /* 4010 */ 216 PTR sys32_execve 217 PTR sys_chdir 218 PTR compat_sys_time 219 PTR sys_mknod 220 PTR sys_chmod /* 4015 */ 221 PTR sys_lchown 222 PTR sys_ni_syscall 223 PTR sys_ni_syscall /* was sys_stat */ 224 PTR sys_lseek 225 PTR sys_getpid /* 4020 */ 226 PTR sys_mount 227 PTR sys_oldumount 228 PTR sys_setuid 229 PTR sys_getuid 230 PTR compat_sys_stime /* 4025 */ 231 PTR sys32_ptrace 232 PTR sys_alarm 233 PTR sys_ni_syscall /* was sys_fstat */ 234 PTR sys_pause 235 PTR compat_sys_utime /* 4030 */ 236 PTR sys_ni_syscall 237 PTR sys_ni_syscall 238 PTR sys_access 239 PTR sys_nice 240 PTR sys_ni_syscall /* 4035 */ 241 PTR sys_sync 242 PTR sys_kill 243 PTR sys_rename 244 PTR sys_mkdir 245 PTR sys_rmdir /* 4040 */ 246 PTR sys_dup 247 PTR sys_pipe 248 PTR compat_sys_times 249 PTR sys_ni_syscall 250 PTR sys_brk /* 4045 */ 251 PTR sys_setgid 252 PTR sys_getgid 253 PTR sys_ni_syscall /* was signal 2 */ 254 PTR sys_geteuid 255 PTR sys_getegid /* 4050 */ 256 PTR sys_acct 257 PTR sys_umount 258 PTR sys_ni_syscall 259 PTR compat_sys_ioctl 260 PTR compat_sys_fcntl /* 4055 */ 261 PTR sys_ni_syscall 262 PTR sys_setpgid 263 PTR sys_ni_syscall 264 PTR sys_olduname 265 PTR sys_umask /* 4060 */ 266 PTR sys_chroot 267 PTR sys32_ustat 268 PTR sys_dup2 269 PTR sys_getppid 270 PTR sys_getpgrp /* 4065 */ 271 PTR sys_setsid 272 PTR sys32_sigaction 273 PTR sys_sgetmask 274 PTR sys_ssetmask 275 PTR sys_setreuid /* 4070 */ 276 PTR sys_setregid 277 PTR sys32_sigsuspend 278 PTR compat_sys_sigpending 279 PTR sys_sethostname 280 PTR compat_sys_setrlimit /* 4075 */ 281 PTR compat_sys_getrlimit 282 PTR compat_sys_getrusage 283 PTR sys32_gettimeofday 284 PTR sys32_settimeofday 285 PTR sys_getgroups /* 4080 */ 286 PTR sys_setgroups 287 PTR sys_ni_syscall /* old_select */ 288 PTR sys_symlink 289 PTR sys_ni_syscall /* was sys_lstat */ 290 PTR sys_readlink /* 4085 */ 291 PTR sys_uselib 292 PTR sys_swapon 293 PTR sys_reboot 294 PTR sys32_readdir 295 PTR old_mmap /* 4090 */ 296 PTR sys_munmap 297 PTR sys_truncate 298 PTR sys_ftruncate 299 PTR sys_fchmod 300 PTR sys_fchown /* 4095 */ 301 PTR sys_getpriority 302 PTR sys_setpriority 303 PTR sys_ni_syscall 304 PTR compat_sys_statfs 305 PTR compat_sys_fstatfs /* 4100 */ 306 PTR sys_ni_syscall /* sys_ioperm */ 307 PTR sys32_socketcall 308 PTR sys_syslog 309 PTR compat_sys_setitimer 310 PTR compat_sys_getitimer /* 4105 */ 311 PTR compat_sys_newstat 312 PTR compat_sys_newlstat 313 PTR compat_sys_newfstat 314 PTR sys_uname 315 PTR sys_ni_syscall /* sys_ioperm *//* 4110 */ 316 PTR sys_vhangup 317 PTR sys_ni_syscall /* was sys_idle */ 318 PTR sys_ni_syscall /* sys_vm86 */ 319 PTR sys32_wait4 320 PTR sys_swapoff /* 4115 */ 321 PTR sys32_sysinfo 322 PTR sys32_ipc 323 PTR sys_fsync 324 PTR sys32_sigreturn 325 PTR sys_clone /* 4120 */ 326 PTR sys_setdomainname 327 PTR sys32_newuname 328 PTR sys_ni_syscall /* sys_modify_ldt */ 329 PTR sys32_adjtimex 330 PTR sys_mprotect /* 4125 */ 331 PTR compat_sys_sigprocmask 332 PTR sys_ni_syscall /* was creat_module */ 333 PTR sys_init_module 334 PTR sys_delete_module 335 PTR sys_ni_syscall /* 4130, get_kernel_syms */ 336 PTR sys_quotactl 337 PTR sys_getpgid 338 PTR sys_fchdir 339 PTR sys_bdflush 340 PTR sys_sysfs /* 4135 */ 341 PTR sys32_personality 342 PTR sys_ni_syscall /* for afs_syscall */ 343 PTR sys_setfsuid 344 PTR sys_setfsgid 345 PTR sys32_llseek /* 4140 */ 346 PTR sys32_getdents 347 PTR compat_sys_select 348 PTR sys_flock 349 PTR sys_msync 350 PTR compat_sys_readv /* 4145 */ 351 PTR compat_sys_writev 352 PTR sys_cacheflush 353 PTR sys_cachectl 354 PTR sys_sysmips 355 PTR sys_ni_syscall /* 4150 */ 356 PTR sys_getsid 357 PTR sys_fdatasync 358 PTR sys32_sysctl 359 PTR sys_mlock 360 PTR sys_munlock /* 4155 */ 361 PTR sys_mlockall 362 PTR sys_munlockall 363 PTR sys_sched_setparam 364 PTR sys_sched_getparam 365 PTR sys_sched_setscheduler /* 4160 */ 366 PTR sys_sched_getscheduler 367 PTR sys_sched_yield 368 PTR sys_sched_get_priority_max 369 PTR sys_sched_get_priority_min 370 PTR sys32_sched_rr_get_interval /* 4165 */ 371 PTR compat_sys_nanosleep 372 PTR sys_mremap 373 PTR sys_accept 374 PTR sys_bind 375 PTR sys_connect /* 4170 */ 376 PTR sys_getpeername 377 PTR sys_getsockname 378 PTR sys_getsockopt 379 PTR sys_listen 380 PTR sys_recv /* 4175 */ 381 PTR sys_recvfrom 382 PTR compat_sys_recvmsg 383 PTR sys_send 384 PTR compat_sys_sendmsg 385 PTR sys_sendto /* 4180 */ 386 PTR compat_sys_setsockopt 387 PTR sys_shutdown 388 PTR sys_socket 389 PTR sys_socketpair 390 PTR sys_setresuid /* 4185 */ 391 PTR sys_getresuid 392 PTR sys_ni_syscall /* was query_module */ 393 PTR sys_poll 394 PTR sys_nfsservctl 395 PTR sys_setresgid /* 4190 */ 396 PTR sys_getresgid 397 PTR sys_prctl 398 PTR sys32_rt_sigreturn 399 PTR sys32_rt_sigaction 400 PTR sys32_rt_sigprocmask /* 4195 */ 401 PTR sys32_rt_sigpending 402 PTR compat_sys_rt_sigtimedwait 403 PTR sys32_rt_sigqueueinfo 404 PTR sys32_rt_sigsuspend 405 PTR sys32_pread /* 4200 */ 406 PTR sys32_pwrite 407 PTR sys_chown 408 PTR sys_getcwd 409 PTR sys_capget 410 PTR sys_capset /* 4205 */ 411 PTR sys32_sigaltstack 412 PTR sys32_sendfile 413 PTR sys_ni_syscall 414 PTR sys_ni_syscall 415 PTR sys32_mmap2 /* 4210 */ 416 PTR sys32_truncate64 417 PTR sys32_ftruncate64 418 PTR sys_newstat 419 PTR sys_newlstat 420 PTR sys_newfstat /* 4215 */ 421 PTR sys_pivot_root 422 PTR sys_mincore 423 PTR sys_madvise 424 PTR sys_getdents64 425 PTR compat_sys_fcntl64 /* 4220 */ 426 PTR sys_ni_syscall 427 PTR sys_gettid 428 PTR sys32_readahead 429 PTR sys_setxattr 430 PTR sys_lsetxattr /* 4225 */ 431 PTR sys_fsetxattr 432 PTR sys_getxattr 433 PTR sys_lgetxattr 434 PTR sys_fgetxattr 435 PTR sys_listxattr /* 4230 */ 436 PTR sys_llistxattr 437 PTR sys_flistxattr 438 PTR sys_removexattr 439 PTR sys_lremovexattr 440 PTR sys_fremovexattr /* 4235 */ 441 PTR sys_tkill 442 PTR sys_sendfile64 443 PTR compat_sys_futex 444 PTR compat_sys_sched_setaffinity 445 PTR compat_sys_sched_getaffinity /* 4240 */ 446 PTR sys_io_setup 447 PTR sys_io_destroy 448 PTR sys_io_getevents 449 PTR sys_io_submit 450 PTR sys_io_cancel /* 4245 */ 451 PTR sys_exit_group 452 PTR sys_lookup_dcookie 453 PTR sys_epoll_create 454 PTR sys_epoll_ctl 455 PTR sys_epoll_wait /* 4250 */ 456 PTR sys_remap_file_pages 457 PTR sys_set_tid_address 458 PTR sys_restart_syscall 459 PTR sys_fadvise64_64 460 PTR compat_sys_statfs64 /* 4255 */ 461 PTR compat_sys_fstatfs64 462 PTR sys_timer_create 463 PTR compat_sys_timer_settime 464 PTR compat_sys_timer_gettime 465 PTR sys_timer_getoverrun /* 4260 */ 466 PTR sys_timer_delete 467 PTR compat_sys_clock_settime 468 PTR compat_sys_clock_gettime 469 PTR compat_sys_clock_getres 470 PTR compat_sys_clock_nanosleep /* 4265 */ 471 PTR sys_tgkill 472 PTR compat_sys_utimes 473 PTR sys_ni_syscall /* sys_mbind */ 474 PTR sys_ni_syscall /* sys_get_mempolicy */ 475 PTR sys_ni_syscall /* 4270 sys_set_mempolicy */ 476 PTR compat_sys_mq_open 477 PTR sys_mq_unlink 478 PTR compat_sys_mq_timedsend 479 PTR compat_sys_mq_timedreceive 480 PTR compat_sys_mq_notify /* 4275 */ 481 PTR compat_sys_mq_getsetattr 482 PTR sys_ni_syscall /* sys_vserver */ 483 PTR sys_waitid 484 PTR sys_ni_syscall /* available, was setaltroot */ 485 PTR sys_add_key /* 4280 */ 486 PTR sys_request_key 487 PTR sys_keyctl 488 .size sys_call_table,.-sys_call_table 489