entry.S 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Common Low Level Interrupts/Traps/Exceptions(non-TLB) Handling for ARC
  4. * (included from entry-<isa>.S
  5. *
  6. * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
  7. * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  8. */
  9. /*------------------------------------------------------------------
  10. * Function ABI
  11. *------------------------------------------------------------------
  12. *
  13. * Arguments r0 - r7
  14. * Caller Saved Registers r0 - r12
  15. * Callee Saved Registers r13- r25
  16. * Global Pointer (gp) r26
  17. * Frame Pointer (fp) r27
  18. * Stack Pointer (sp) r28
  19. * Branch link register (blink) r31
  20. *------------------------------------------------------------------
  21. */
  22. ;################### Special Sys Call Wrappers ##########################
  23. ENTRY(sys_clone_wrapper)
  24. SAVE_CALLEE_SAVED_USER
  25. bl @sys_clone
  26. DISCARD_CALLEE_SAVED_USER
  27. GET_CURR_THR_INFO_FLAGS r10
  28. and.f 0, r10, _TIF_SYSCALL_WORK
  29. bnz tracesys_exit
  30. b .Lret_from_system_call
  31. END(sys_clone_wrapper)
  32. ENTRY(sys_clone3_wrapper)
  33. SAVE_CALLEE_SAVED_USER
  34. bl @sys_clone3
  35. DISCARD_CALLEE_SAVED_USER
  36. GET_CURR_THR_INFO_FLAGS r10
  37. and.f 0, r10, _TIF_SYSCALL_WORK
  38. bnz tracesys_exit
  39. b .Lret_from_system_call
  40. END(sys_clone3_wrapper)
  41. ENTRY(ret_from_fork)
  42. ; when the forked child comes here from the __switch_to function
  43. ; r0 has the last task pointer.
  44. ; put last task in scheduler queue
  45. jl @schedule_tail
  46. ld r9, [sp, PT_status32]
  47. brne r9, 0, 1f
  48. jl.d [r14] ; kernel thread entry point
  49. mov r0, r13 ; (see PF_KTHREAD block in copy_thread)
  50. 1:
  51. ; Return to user space
  52. ; 1. Any forked task (Reach here via BRne above)
  53. ; 2. First ever init task (Reach here via return from JL above)
  54. ; This is the historic "kernel_execve" use-case, to return to init
  55. ; user mode, in a round about way since that is always done from
  56. ; a kernel thread which is executed via JL above but always returns
  57. ; out whenever kernel_execve (now inline do_fork()) is involved
  58. b ret_from_exception
  59. END(ret_from_fork)
  60. ;################### Non TLB Exception Handling #############################
  61. ; ---------------------------------------------
  62. ; Instruction Error Exception Handler
  63. ; ---------------------------------------------
  64. ENTRY(instr_service)
  65. EXCEPTION_PROLOGUE
  66. lr r0, [efa]
  67. mov r1, sp
  68. FAKE_RET_FROM_EXCPN
  69. bl do_insterror_or_kprobe
  70. b ret_from_exception
  71. END(instr_service)
  72. ; ---------------------------------------------
  73. ; Machine Check Exception Handler
  74. ; ---------------------------------------------
  75. ENTRY(EV_MachineCheck)
  76. EXCEPTION_PROLOGUE
  77. lr r2, [ecr]
  78. lr r0, [efa]
  79. mov r1, sp
  80. ; MC excpetions disable MMU
  81. ARC_MMU_REENABLE r3
  82. lsr r3, r2, 8
  83. bmsk r3, r3, 7
  84. brne r3, ECR_C_MCHK_DUP_TLB, 1f
  85. bl do_tlb_overlap_fault
  86. b ret_from_exception
  87. 1:
  88. ; DEAD END: can't do much, display Regs and HALT
  89. SAVE_CALLEE_SAVED_USER
  90. GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
  91. st sp, [r10, THREAD_CALLEE_REG]
  92. j do_machine_check_fault
  93. END(EV_MachineCheck)
  94. ; ---------------------------------------------
  95. ; Privilege Violation Exception Handler
  96. ; ---------------------------------------------
  97. ENTRY(EV_PrivilegeV)
  98. EXCEPTION_PROLOGUE
  99. lr r0, [efa]
  100. mov r1, sp
  101. FAKE_RET_FROM_EXCPN
  102. bl do_privilege_fault
  103. b ret_from_exception
  104. END(EV_PrivilegeV)
  105. ; ---------------------------------------------
  106. ; Extension Instruction Exception Handler
  107. ; ---------------------------------------------
  108. ENTRY(EV_Extension)
  109. EXCEPTION_PROLOGUE
  110. lr r0, [efa]
  111. mov r1, sp
  112. FAKE_RET_FROM_EXCPN
  113. bl do_extension_fault
  114. b ret_from_exception
  115. END(EV_Extension)
  116. ;################ Trap Handling (Syscall, Breakpoint) ##################
  117. ; ---------------------------------------------
  118. ; syscall Tracing
  119. ; ---------------------------------------------
  120. tracesys:
  121. ; save EFA in case tracer wants the PC of traced task
  122. ; using ERET won't work since next-PC has already committed
  123. GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11
  124. st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address
  125. ; PRE Sys Call Ptrace hook
  126. mov r0, sp ; pt_regs needed
  127. bl @syscall_trace_entry
  128. ; Tracing code now returns the syscall num (orig or modif)
  129. mov r8, r0
  130. ; Do the Sys Call as we normally would.
  131. ; Validate the Sys Call number
  132. cmp r8, NR_syscalls - 1
  133. mov.hi r0, -ENOSYS
  134. bhi tracesys_exit
  135. ; Restore the sys-call args. Mere invocation of the hook abv could have
  136. ; clobbered them (since they are in scratch regs). The tracer could also
  137. ; have deliberately changed the syscall args: r0-r7
  138. ld r0, [sp, PT_r0]
  139. ld r1, [sp, PT_r1]
  140. ld r2, [sp, PT_r2]
  141. ld r3, [sp, PT_r3]
  142. ld r4, [sp, PT_r4]
  143. ld r5, [sp, PT_r5]
  144. ld r6, [sp, PT_r6]
  145. ld r7, [sp, PT_r7]
  146. ld.as r9, [sys_call_table, r8]
  147. jl [r9] ; Entry into Sys Call Handler
  148. tracesys_exit:
  149. st r0, [sp, PT_r0] ; sys call return value in pt_regs
  150. ;POST Sys Call Ptrace Hook
  151. mov r0, sp ; pt_regs needed
  152. bl @syscall_trace_exit
  153. b ret_from_exception ; NOT ret_from_system_call at is saves r0 which
  154. ; we'd done before calling post hook above
  155. ; ---------------------------------------------
  156. ; Breakpoint TRAP
  157. ; ---------------------------------------------
  158. trap_with_param:
  159. mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc
  160. mov r1, sp
  161. ; Save callee regs in case gdb wants to have a look
  162. ; SP will grow up by size of CALLEE Reg-File
  163. ; NOTE: clobbers r12
  164. SAVE_CALLEE_SAVED_USER
  165. ; save location of saved Callee Regs @ thread_struct->pc
  166. GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
  167. st sp, [r10, THREAD_CALLEE_REG]
  168. ; Call the trap handler
  169. bl do_non_swi_trap
  170. ; unwind stack to discard Callee saved Regs
  171. DISCARD_CALLEE_SAVED_USER
  172. b ret_from_exception
  173. ; ---------------------------------------------
  174. ; syscall TRAP
  175. ; ABI: (r0-r7) upto 8 args, (r8) syscall number
  176. ; ---------------------------------------------
  177. ENTRY(EV_Trap)
  178. EXCEPTION_PROLOGUE
  179. lr r12, [efa]
  180. FAKE_RET_FROM_EXCPN
  181. ;============ TRAP 1 :breakpoints
  182. ; Check ECR for trap with arg (PROLOGUE ensures r10 has ECR)
  183. bmsk.f 0, r10, 7
  184. bnz trap_with_param
  185. ;============ TRAP (no param): syscall top level
  186. ; If syscall tracing ongoing, invoke pre-post-hooks
  187. GET_CURR_THR_INFO_FLAGS r10
  188. and.f 0, r10, _TIF_SYSCALL_WORK
  189. bnz tracesys ; this never comes back
  190. ;============ Normal syscall case
  191. ; syscall num shd not exceed the total system calls avail
  192. cmp r8, NR_syscalls - 1
  193. mov.hi r0, -ENOSYS
  194. bhi .Lret_from_system_call
  195. ; Offset into the syscall_table and call handler
  196. ld.as r9,[sys_call_table, r8]
  197. jl [r9] ; Entry into Sys Call Handler
  198. .Lret_from_system_call:
  199. st r0, [sp, PT_r0] ; sys call return value in pt_regs
  200. ; fall through to ret_from_exception
  201. END(EV_Trap)
  202. ;############# Return from Intr/Excp/Trap (Linux Specifics) ##############
  203. ;
  204. ; If ret to user mode do we need to handle signals, schedule() et al.
  205. ENTRY(ret_from_exception)
  206. ; Pre-{IRQ,Trap,Exception} K/U mode from pt_regs->status32
  207. ld r8, [sp, PT_status32] ; returning to User/Kernel Mode
  208. bbit0 r8, STATUS_U_BIT, resume_kernel_mode
  209. ; Before returning to User mode check-for-and-complete any pending work
  210. ; such as rescheduling/signal-delivery etc.
  211. resume_user_mode_begin:
  212. ; Disable IRQs to ensures that chk for pending work itself is atomic
  213. ; (and we don't end up missing a NEED_RESCHED/SIGPENDING due to an
  214. ; interim IRQ).
  215. IRQ_DISABLE r10
  216. ; Fast Path return to user mode if no pending work
  217. GET_CURR_THR_INFO_FLAGS r9
  218. and.f 0, r9, _TIF_WORK_MASK
  219. bz .Lrestore_regs
  220. ; --- (Slow Path #1) task preemption ---
  221. bbit0 r9, TIF_NEED_RESCHED, .Lchk_pend_signals
  222. mov blink, resume_user_mode_begin ; tail-call to U mode ret chks
  223. j @schedule ; BTST+Bnz causes relo error in link
  224. .Lchk_pend_signals:
  225. IRQ_ENABLE r10
  226. ; --- (Slow Path #2) pending signal ---
  227. mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume()
  228. GET_CURR_THR_INFO_FLAGS r9
  229. and.f 0, r9, _TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL
  230. bz .Lchk_notify_resume
  231. ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs
  232. ; in pt_reg since the "C" ABI (kernel code) will automatically
  233. ; save/restore callee-saved regs.
  234. ;
  235. ; However, here we need to explicitly save callee regs because
  236. ; (i) If this signal causes coredump - full regfile needed
  237. ; (ii) If signal is SIGTRAP/SIGSTOP, task is being traced thus
  238. ; tracer might call PEEKUSR(CALLEE reg)
  239. ;
  240. ; NOTE: SP will grow up by size of CALLEE Reg-File
  241. SAVE_CALLEE_SAVED_USER ; clobbers r12
  242. ; save location of saved Callee Regs @ thread_struct->callee
  243. GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
  244. st sp, [r10, THREAD_CALLEE_REG]
  245. bl @do_signal
  246. ; Ideally we want to discard the Callee reg above, however if this was
  247. ; a tracing signal, tracer could have done a POKEUSR(CALLEE reg)
  248. RESTORE_CALLEE_SAVED_USER
  249. b resume_user_mode_begin ; loop back to start of U mode ret
  250. ; --- (Slow Path #3) notify_resume ---
  251. .Lchk_notify_resume:
  252. btst r9, TIF_NOTIFY_RESUME
  253. blnz @do_notify_resume
  254. b resume_user_mode_begin ; unconditionally back to U mode ret chks
  255. ; for single exit point from this block
  256. resume_kernel_mode:
  257. ; Disable Interrupts from this point on
  258. ; CONFIG_PREEMPTION: This is a must for preempt_schedule_irq()
  259. ; !CONFIG_PREEMPTION: To ensure restore_regs is intr safe
  260. IRQ_DISABLE r9
  261. #ifdef CONFIG_PREEMPTION
  262. ; Can't preempt if preemption disabled
  263. GET_CURR_THR_INFO_FROM_SP r10
  264. ld r8, [r10, THREAD_INFO_PREEMPT_COUNT]
  265. brne r8, 0, .Lrestore_regs
  266. ; check if this task's NEED_RESCHED flag set
  267. ld r9, [r10, THREAD_INFO_FLAGS]
  268. bbit0 r9, TIF_NEED_RESCHED, .Lrestore_regs
  269. ; Invoke PREEMPTION
  270. jl preempt_schedule_irq
  271. ; preempt_schedule_irq() always returns with IRQ disabled
  272. #endif
  273. b .Lrestore_regs
  274. ##### DONT ADD CODE HERE - .Lrestore_regs actually follows in entry-<isa>.S