diff options
-rw-r--r-- | arch/arc/kernel/entry-arcv2.S | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S index cbfec79137bf..b17830294706 100644 --- a/arch/arc/kernel/entry-arcv2.S +++ b/arch/arc/kernel/entry-arcv2.S | |||
@@ -211,7 +211,11 @@ debug_marker_syscall: | |||
211 | ; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig | 211 | ; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig |
212 | ; entry was via Exception in DS which got preempted in kernel). | 212 | ; entry was via Exception in DS which got preempted in kernel). |
213 | ; | 213 | ; |
214 | ; IRQ RTIE won't reliably restore DE bit and/or BTA, needs handling | 214 | ; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround |
215 | ; | ||
216 | ; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline | ||
217 | ; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly | ||
218 | |||
215 | .Lintr_ret_to_delay_slot: | 219 | .Lintr_ret_to_delay_slot: |
216 | debug_marker_ds: | 220 | debug_marker_ds: |
217 | 221 | ||
@@ -222,18 +226,23 @@ debug_marker_ds: | |||
222 | ld r2, [sp, PT_ret] | 226 | ld r2, [sp, PT_ret] |
223 | ld r3, [sp, PT_status32] | 227 | ld r3, [sp, PT_status32] |
224 | 228 | ||
229 | ; STAT32 for Int return created from scratch | ||
230 | ; (No delay dlot, disable Further intr in trampoline) | ||
231 | |||
225 | bic r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK | 232 | bic r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK |
226 | st r0, [sp, PT_status32] | 233 | st r0, [sp, PT_status32] |
227 | 234 | ||
228 | mov r1, .Lintr_ret_to_delay_slot_2 | 235 | mov r1, .Lintr_ret_to_delay_slot_2 |
229 | st r1, [sp, PT_ret] | 236 | st r1, [sp, PT_ret] |
230 | 237 | ||
238 | ; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots | ||
231 | st r2, [sp, 0] | 239 | st r2, [sp, 0] |
232 | st r3, [sp, 4] | 240 | st r3, [sp, 4] |
233 | 241 | ||
234 | b .Lisr_ret_fast_path | 242 | b .Lisr_ret_fast_path |
235 | 243 | ||
236 | .Lintr_ret_to_delay_slot_2: | 244 | .Lintr_ret_to_delay_slot_2: |
245 | ; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP | ||
237 | sub sp, sp, SZ_PT_REGS | 246 | sub sp, sp, SZ_PT_REGS |
238 | st r9, [sp, -4] | 247 | st r9, [sp, -4] |
239 | 248 | ||
@@ -243,11 +252,19 @@ debug_marker_ds: | |||
243 | ld r9, [sp, 4] | 252 | ld r9, [sp, 4] |
244 | sr r9, [erstatus] | 253 | sr r9, [erstatus] |
245 | 254 | ||
255 | ; restore AUX_USER_SP if returning to U mode | ||
256 | bbit0 r9, STATUS_U_BIT, 1f | ||
257 | ld r9, [sp, PT_sp] | ||
258 | sr r9, [AUX_USER_SP] | ||
259 | |||
260 | 1: | ||
246 | ld r9, [sp, 8] | 261 | ld r9, [sp, 8] |
247 | sr r9, [erbta] | 262 | sr r9, [erbta] |
248 | 263 | ||
249 | ld r9, [sp, -4] | 264 | ld r9, [sp, -4] |
250 | add sp, sp, SZ_PT_REGS | 265 | add sp, sp, SZ_PT_REGS |
266 | |||
267 | ; return from pure kernel mode to delay slot | ||
251 | rtie | 268 | rtie |
252 | 269 | ||
253 | END(ret_from_exception) | 270 | END(ret_from_exception) |