diff options
-rw-r--r-- | arch/arc/Kconfig | 6 | ||||
-rw-r--r-- | arch/arc/include/asm/irqflags.h | 22 | ||||
-rw-r--r-- | arch/arc/kernel/entry.S | 11 | ||||
-rw-r--r-- | arch/arc/kernel/stacktrace.c | 4 |
4 files changed, 42 insertions, 1 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 91dbb2757afd..524e6fce2c89 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig | |||
@@ -35,6 +35,12 @@ config ARC | |||
35 | select PERF_USE_VMALLOC | 35 | select PERF_USE_VMALLOC |
36 | select HAVE_DEBUG_STACKOVERFLOW | 36 | select HAVE_DEBUG_STACKOVERFLOW |
37 | 37 | ||
38 | config TRACE_IRQFLAGS_SUPPORT | ||
39 | def_bool y | ||
40 | |||
41 | config LOCKDEP_SUPPORT | ||
42 | def_bool y | ||
43 | |||
38 | config SCHED_OMIT_FRAME_POINTER | 44 | config SCHED_OMIT_FRAME_POINTER |
39 | def_bool y | 45 | def_bool y |
40 | 46 | ||
diff --git a/arch/arc/include/asm/irqflags.h b/arch/arc/include/asm/irqflags.h index b68b53f458d1..cb7efc29f16f 100644 --- a/arch/arc/include/asm/irqflags.h +++ b/arch/arc/include/asm/irqflags.h | |||
@@ -151,16 +151,38 @@ static inline void arch_unmask_irq(unsigned int irq) | |||
151 | 151 | ||
152 | #else | 152 | #else |
153 | 153 | ||
154 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
155 | |||
156 | .macro TRACE_ASM_IRQ_DISABLE | ||
157 | bl trace_hardirqs_off | ||
158 | .endm | ||
159 | |||
160 | .macro TRACE_ASM_IRQ_ENABLE | ||
161 | bl trace_hardirqs_on | ||
162 | .endm | ||
163 | |||
164 | #else | ||
165 | |||
166 | .macro TRACE_ASM_IRQ_DISABLE | ||
167 | .endm | ||
168 | |||
169 | .macro TRACE_ASM_IRQ_ENABLE | ||
170 | .endm | ||
171 | |||
172 | #endif | ||
173 | |||
154 | .macro IRQ_DISABLE scratch | 174 | .macro IRQ_DISABLE scratch |
155 | lr \scratch, [status32] | 175 | lr \scratch, [status32] |
156 | bic \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) | 176 | bic \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) |
157 | flag \scratch | 177 | flag \scratch |
178 | TRACE_ASM_IRQ_DISABLE | ||
158 | .endm | 179 | .endm |
159 | 180 | ||
160 | .macro IRQ_ENABLE scratch | 181 | .macro IRQ_ENABLE scratch |
161 | lr \scratch, [status32] | 182 | lr \scratch, [status32] |
162 | or \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) | 183 | or \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) |
163 | flag \scratch | 184 | flag \scratch |
185 | TRACE_ASM_IRQ_ENABLE | ||
164 | .endm | 186 | .endm |
165 | 187 | ||
166 | #endif /* __ASSEMBLY__ */ | 188 | #endif /* __ASSEMBLY__ */ |
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 | |||
250 | lr r0, [icause1] | 250 | lr r0, [icause1] |
251 | and r0, r0, 0x1f | 251 | and r0, r0, 0x1f |
252 | 252 | ||
253 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
254 | ; icause1 needs to be read early, before calling tracing, which | ||
255 | ; can clobber scratch regs, hence use of stack to stash it | ||
256 | push r0 | ||
257 | TRACE_ASM_IRQ_DISABLE | ||
258 | pop r0 | ||
259 | #endif | ||
260 | |||
253 | bl.d @arch_do_IRQ | 261 | bl.d @arch_do_IRQ |
254 | mov r1, sp | 262 | mov r1, sp |
255 | 263 | ||
@@ -570,6 +578,7 @@ resume_user_mode_begin: | |||
570 | ; --- (Slow Path #2) pending signal --- | 578 | ; --- (Slow Path #2) pending signal --- |
571 | mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() | 579 | mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() |
572 | 580 | ||
581 | GET_CURR_THR_INFO_FLAGS r9 | ||
573 | bbit0 r9, TIF_SIGPENDING, .Lchk_notify_resume | 582 | bbit0 r9, TIF_SIGPENDING, .Lchk_notify_resume |
574 | 583 | ||
575 | ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs | 584 | ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs |
@@ -635,6 +644,8 @@ resume_kernel_mode: | |||
635 | 644 | ||
636 | restore_regs : | 645 | restore_regs : |
637 | 646 | ||
647 | TRACE_ASM_IRQ_ENABLE | ||
648 | |||
638 | lr r10, [status32] | 649 | lr r10, [status32] |
639 | 650 | ||
640 | ; Restore REG File. In case multiple Events outstanding, | 651 | ; 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) | |||
237 | */ | 237 | */ |
238 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | 238 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) |
239 | { | 239 | { |
240 | /* Assumes @tsk is sleeping so unwinds from __switch_to */ | ||
240 | arc_unwind_core(tsk, NULL, __collect_all_but_sched, trace); | 241 | arc_unwind_core(tsk, NULL, __collect_all_but_sched, trace); |
241 | } | 242 | } |
242 | 243 | ||
243 | void save_stack_trace(struct stack_trace *trace) | 244 | void save_stack_trace(struct stack_trace *trace) |
244 | { | 245 | { |
245 | arc_unwind_core(current, NULL, __collect_all, trace); | 246 | /* Pass NULL for task so it unwinds the current call frame */ |
247 | arc_unwind_core(NULL, NULL, __collect_all, trace); | ||
246 | } | 248 | } |
247 | #endif | 249 | #endif |