scall32-o32.S 14 KB

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