aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2015-07-15 23:18:46 -0400
committerMax Filippov <jcmvbkbc@gmail.com>2015-08-17 00:33:34 -0400
commit7d5f6a9a2496c6e4f2a3b5db7743ff4e3a99738e (patch)
tree50649451d8f300910a632205be4df863093533b9
parent18bc5b85aac08d35eeca174abc73238a4d5deb0b (diff)
xtensa: reorganize irq flags tracing
entry.s only disables IRQs on hardware IRQ, move trace_hardirqs_off call into do_interrupt. Check actual intlevel that will be restored on return from exception handler to decide if trace_hardirqs_on should be called. Annotate IRQ on/off points in the TIF_* handling loop on return from exception handler. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r--arch/xtensa/kernel/entry.S39
-rw-r--r--arch/xtensa/kernel/traps.c5
2 files changed, 18 insertions, 26 deletions
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index e955f6098f64..5e492aec7b47 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -399,21 +399,6 @@ common_exception:
399 399
400 save_xtregs_opt a1 a3 a4 a5 a6 a7 PT_XTREGS_OPT 400 save_xtregs_opt a1 a3 a4 a5 a6 a7 PT_XTREGS_OPT
401 401
402#ifdef CONFIG_TRACE_IRQFLAGS
403 l32i a4, a1, PT_DEPC
404 /* Double exception means we came here with an exception
405 * while PS.EXCM was set, i.e. interrupts disabled.
406 */
407 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
408 bnei a2, EXCCAUSE_LEVEL1_INTERRUPT, 1f
409 /* We came here with an interrupt means interrupts were enabled
410 * and we've just disabled them.
411 */
412 movi a4, trace_hardirqs_off
413 callx4 a4
4141:
415#endif
416
417 /* Go to second-level dispatcher. Set up parameters to pass to the 402 /* Go to second-level dispatcher. Set up parameters to pass to the
418 * exception handler and call the exception handler. 403 * exception handler and call the exception handler.
419 */ 404 */
@@ -434,6 +419,10 @@ common_exception_return:
434 419
4351: 4201:
436 rsil a2, LOCKLEVEL 421 rsil a2, LOCKLEVEL
422#ifdef CONFIG_TRACE_IRQFLAGS
423 movi a4, trace_hardirqs_off
424 callx4 a4
425#endif
437 426
438 /* Jump if we are returning from kernel exceptions. */ 427 /* Jump if we are returning from kernel exceptions. */
439 428
@@ -458,6 +447,10 @@ common_exception_return:
458 447
459 /* Call do_signal() */ 448 /* Call do_signal() */
460 449
450#ifdef CONFIG_TRACE_IRQFLAGS
451 movi a4, trace_hardirqs_on
452 callx4 a4
453#endif
461 rsil a2, 0 454 rsil a2, 0
462 movi a4, do_notify_resume # int do_notify_resume(struct pt_regs*) 455 movi a4, do_notify_resume # int do_notify_resume(struct pt_regs*)
463 mov a6, a1 456 mov a6, a1
@@ -466,6 +459,10 @@ common_exception_return:
466 459
4673: /* Reschedule */ 4603: /* Reschedule */
468 461
462#ifdef CONFIG_TRACE_IRQFLAGS
463 movi a4, trace_hardirqs_on
464 callx4 a4
465#endif
469 rsil a2, 0 466 rsil a2, 0
470 movi a4, schedule # void schedule (void) 467 movi a4, schedule # void schedule (void)
471 callx4 a4 468 callx4 a4
@@ -494,16 +491,8 @@ common_exception_return:
4946: 4916:
4954: 4924:
496#ifdef CONFIG_TRACE_IRQFLAGS 493#ifdef CONFIG_TRACE_IRQFLAGS
497 l32i a4, a1, PT_DEPC 494 extui a4, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH
498 /* Double exception means we came here with an exception 495 bgei a4, LOCKLEVEL, 1f
499 * while PS.EXCM was set, i.e. interrupts disabled.
500 */
501 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
502 l32i a4, a1, PT_EXCCAUSE
503 bnei a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
504 /* We came here with an interrupt means interrupts were enabled
505 * and we'll reenable them on return.
506 */
507 movi a4, trace_hardirqs_on 496 movi a4, trace_hardirqs_on
508 callx4 a4 497 callx4 a4
5091: 4981:
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 9d2f45f010ef..a1b5bd237c71 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -211,8 +211,11 @@ void do_interrupt(struct pt_regs *regs)
211 XCHAL_INTLEVEL6_MASK, 211 XCHAL_INTLEVEL6_MASK,
212 XCHAL_INTLEVEL7_MASK, 212 XCHAL_INTLEVEL7_MASK,
213 }; 213 };
214 struct pt_regs *old_regs = set_irq_regs(regs); 214 struct pt_regs *old_regs;
215 215
216 trace_hardirqs_off();
217
218 old_regs = set_irq_regs(regs);
216 irq_enter(); 219 irq_enter();
217 220
218 for (;;) { 221 for (;;) {