summary refs log tree commit diff
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-09-06 14:18:17 +0530
committerVineet Gupta <vgupta@synopsys.com>2013-11-06 10:41:40 +0530
commit0dafafc3ef42bad34fd446725cb9778c3bdd83a8 (patch)
tree2f61f879b892afe3001fdf7a5d93da40b4d532a8 /arch/arc/kernel
parent54c8bff14d604de23d0718eee59c5436a4703fe5 (diff)
downloadlinux-0dafafc3ef42bad34fd446725cb9778c3bdd83a8.tar.gz
ARC: Add support for irqflags tracing and lockdep
Lockdep required a small fix to stacktrace API which was incorrectly
unwindign out of __switch_to for the current call frame.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r--arch/arc/kernel/entry.S11
-rw-r--r--arch/arc/kernel/stacktrace.c4
2 files changed, 14 insertions, 1 deletions
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index daa0e7990270..47d09d07f093 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -250,6 +250,14 @@ ARC_ENTRY handle_interrupt_level1
 	lr  r0, [icause1]
 	and r0, r0, 0x1f
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+	; icause1 needs to be read early, before calling tracing, which
+	; can clobber scratch regs, hence use of stack to stash it
+	push r0
+	TRACE_ASM_IRQ_DISABLE
+	pop  r0
+#endif
+
 	bl.d  @arch_do_IRQ
 	mov r1, sp
 
@@ -570,6 +578,7 @@ resume_user_mode_begin:
 	; --- (Slow Path #2) pending signal  ---
 	mov r0, sp	; pt_regs for arg to do_signal()/do_notify_resume()
 
+	GET_CURR_THR_INFO_FLAGS   r9
 	bbit0  r9, TIF_SIGPENDING, .Lchk_notify_resume
 
 	; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs
@@ -635,6 +644,8 @@ resume_kernel_mode:
 
 restore_regs :
 
+	TRACE_ASM_IRQ_ENABLE
+
 	lr	r10, [status32]
 
 	; Restore REG File. In case multiple Events outstanding,
diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c
index f8b7d880304d..ab97b034922f 100644
--- a/arch/arc/kernel/stacktrace.c
+++ b/arch/arc/kernel/stacktrace.c
@@ -237,11 +237,13 @@ unsigned int get_wchan(struct task_struct *tsk)
  */
 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
+	/* Assumes @tsk is sleeping so unwinds from __switch_to */
 	arc_unwind_core(tsk, NULL, __collect_all_but_sched, trace);
 }
 
 void save_stack_trace(struct stack_trace *trace)
 {
-	arc_unwind_core(current, NULL, __collect_all, trace);
+	/* Pass NULL for task so it unwinds the current call frame */
+	arc_unwind_core(NULL, NULL, __collect_all, trace);
 }
 #endif