scall64-o32.S 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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/errno.h>
  17. #include <asm/asm.h>
  18. #include <asm/asmmacro.h>
  19. #include <asm/irqflags.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. .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. ld t1, PT_EPC(sp) # skip syscall on return
  34. dsubu t0, v0, __NR_O32_Linux # check syscall number
  35. sltiu t0, t0, __NR_O32_Linux_syscalls
  36. daddiu t1, 4 # skip to next instruction
  37. sd t1, PT_EPC(sp)
  38. beqz t0, not_o32_scall
  39. #if 0
  40. SAVE_ALL
  41. move a1, v0
  42. ASM_PRINT("Scall %ld\n")
  43. RESTORE_ALL
  44. #endif
  45. /* We don't want to stumble over broken sign extensions from
  46. userland. O32 does never use the upper half. */
  47. sll a0, a0, 0
  48. sll a1, a1, 0
  49. sll a2, a2, 0
  50. sll a3, a3, 0
  51. sd a3, PT_R26(sp) # save a3 for syscall restarting
  52. /*
  53. * More than four arguments. Try to deal with it by copying the
  54. * stack arguments from the user stack to the kernel stack.
  55. * This Sucks (TM).
  56. *
  57. * We intentionally keep the kernel stack a little below the top of
  58. * userspace so we don't have to do a slower byte accurate check here.
  59. */
  60. ld t0, PT_R29(sp) # get old user stack pointer
  61. daddu t1, t0, 32
  62. bltz t1, bad_stack
  63. load_a4: lw a4, 16(t0) # argument #5 from usp
  64. load_a5: lw a5, 20(t0) # argument #6 from usp
  65. load_a6: lw a6, 24(t0) # argument #7 from usp
  66. load_a7: lw a7, 28(t0) # argument #8 from usp
  67. loads_done:
  68. .section __ex_table,"a"
  69. PTR_WD load_a4, bad_stack_a4
  70. PTR_WD load_a5, bad_stack_a5
  71. PTR_WD load_a6, bad_stack_a6
  72. PTR_WD load_a7, bad_stack_a7
  73. .previous
  74. li t1, _TIF_WORK_SYSCALL_ENTRY
  75. LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
  76. and t0, t1, t0
  77. bnez t0, trace_a_syscall
  78. syscall_common:
  79. dsll t0, v0, 3 # offset into table
  80. ld t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
  81. jalr t2 # Do The Real Thing (TM)
  82. li t0, -EMAXERRNO - 1 # error?
  83. sltu t0, t0, v0
  84. sd t0, PT_R7(sp) # set error flag
  85. beqz t0, 1f
  86. ld t1, PT_R2(sp) # syscall number
  87. dnegu v0 # error
  88. sd t1, PT_R0(sp) # save it for syscall restarting
  89. 1: sd v0, PT_R2(sp) # result
  90. o32_syscall_exit:
  91. j syscall_exit_partial
  92. /* ------------------------------------------------------------------------ */
  93. trace_a_syscall:
  94. SAVE_STATIC
  95. sd a4, PT_R8(sp) # Save argument registers
  96. sd a5, PT_R9(sp)
  97. sd a6, PT_R10(sp)
  98. sd a7, PT_R11(sp) # For indirect syscalls
  99. move a0, sp
  100. /*
  101. * absolute syscall number is in v0 unless we called syscall(__NR_###)
  102. * where the real syscall number is in a0
  103. * note: NR_syscall is the first O32 syscall but the macro is
  104. * only defined when compiling with -mabi=32 (CONFIG_32BIT)
  105. * therefore __NR_O32_Linux is used (4000)
  106. */
  107. .set push
  108. .set reorder
  109. subu t1, v0, __NR_O32_Linux
  110. move a1, v0
  111. bnez t1, 1f /* __NR_syscall at offset 0 */
  112. ld a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
  113. .set pop
  114. 1: jal syscall_trace_enter
  115. bltz v0, 1f # seccomp failed? Skip syscall
  116. RESTORE_STATIC
  117. ld v0, PT_R2(sp) # Restore syscall (maybe modified)
  118. ld a0, PT_R4(sp) # Restore argument registers
  119. ld a1, PT_R5(sp)
  120. ld a2, PT_R6(sp)
  121. ld a3, PT_R7(sp)
  122. ld a4, PT_R8(sp)
  123. ld a5, PT_R9(sp)
  124. ld a6, PT_R10(sp)
  125. ld a7, PT_R11(sp) # For indirect syscalls
  126. dsubu t0, v0, __NR_O32_Linux # check (new) syscall number
  127. sltiu t0, t0, __NR_O32_Linux_syscalls
  128. beqz t0, not_o32_scall
  129. j syscall_common
  130. 1: j syscall_exit
  131. /* ------------------------------------------------------------------------ */
  132. /*
  133. * The stackpointer for a call with more than 4 arguments is bad.
  134. */
  135. bad_stack:
  136. li v0, EFAULT
  137. sd v0, PT_R2(sp)
  138. li t0, 1 # set error flag
  139. sd t0, PT_R7(sp)
  140. j o32_syscall_exit
  141. bad_stack_a4:
  142. li a4, 0
  143. b load_a5
  144. bad_stack_a5:
  145. li a5, 0
  146. b load_a6
  147. bad_stack_a6:
  148. li a6, 0
  149. b load_a7
  150. bad_stack_a7:
  151. li a7, 0
  152. b loads_done
  153. not_o32_scall:
  154. /*
  155. * This is not an o32 compatibility syscall, pass it on
  156. * to the 64-bit syscall handlers.
  157. */
  158. #ifdef CONFIG_MIPS32_N32
  159. j handle_sysn32
  160. #else
  161. j handle_sys64
  162. #endif
  163. END(handle_sys)
  164. LEAF(sys32_syscall)
  165. subu t0, a0, __NR_O32_Linux # check syscall number
  166. sltiu v0, t0, __NR_O32_Linux_syscalls
  167. beqz t0, einval # do not recurse
  168. dsll t1, t0, 3
  169. beqz v0, einval
  170. ld t2, sys32_call_table(t1) # syscall routine
  171. move a0, a1 # shift argument registers
  172. move a1, a2
  173. move a2, a3
  174. move a3, a4
  175. move a4, a5
  176. move a5, a6
  177. move a6, a7
  178. jr t2
  179. /* Unreached */
  180. einval: li v0, -ENOSYS
  181. jr ra
  182. END(sys32_syscall)
  183. #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat)
  184. #define __SYSCALL(nr, entry) PTR_WD entry
  185. .align 3
  186. .type sys32_call_table,@object
  187. EXPORT(sys32_call_table)
  188. #include <asm/syscall_table_o32.h>