aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2016-01-08 01:59:10 -0500
committerVineet Gupta <vgupta@synopsys.com>2016-01-22 06:55:03 -0500
commitcbfe74a753e877b49dc54e9b04d5d42230ca0aed (patch)
tree44a68deb843b381bb776ee0af5a6275af467e3e5
parentafd2ff9b7e1b367172f18ba7f693dfb62bdcb2dc (diff)
ARCv2: STAR 9000950267: Handle return from intr to Delay Slot #2
Returning to delay slot, riding an interrupti, had one loose end. AUX_USER_SP used for restoring user mode SP upon RTIE was not being setup from orig task's saved value, causing task to use wrong SP, leading to ProtV errors. The reason being: - INTERRUPT_EPILOGUE returns to a kernel trampoline, thus not expected to restore it - EXCEPTION_EPILOGUE is not used at all Fix that by restoring AUX_USER_SP explicitly in the trampoline. This was broken in the original workaround, but the error scenarios got reduced considerably since v3.14 due to following: 1. The Linuxthreads.old based userspace at the time caused many more exceptions in delay slot than the current NPTL based one. Infact with current userspace the error doesn't happen at all. 2. Return from interrupt (delay slot or otherwise) doesn't get exercised much after commit 4de0e52867d8 ("Really Re-enable interrupts to avoid deadlocks") since IRQ_ACTIVE.active being clear means most returns are as if from pure kernel (even for active interrupts) Infact the issue only happened in an experimental branch where I was tinkering with reverted 4de0e52867d8 Cc: stable@kernel.org # v4.2+ Fixes: 4255b07f2c9c ("ARCv2: STAR 9000793984: Handle return from intr to Delay Slot") Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r--arch/arc/kernel/entry-arcv2.S19
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:
216debug_marker_ds: 220debug_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
2601:
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
253END(ret_from_exception) 270END(ret_from_exception)