aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2007-03-02 10:01:36 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-04-21 15:34:34 -0400
commit7ab3f8d595a1b1e5cf8d726b72fd476fe0d0226c (patch)
treed37cf7290d5df5927ff870bfbb40673bead8f00d /arch/arm/kernel
parent46fcc86dd71d70211e965102fb69414c90381880 (diff)
[ARM] Add ability to dump exception stacks to kernel backtraces
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/irq.c2
-rw-r--r--arch/arm/kernel/traps.c18
-rw-r--r--arch/arm/kernel/vmlinux.lds.S3
3 files changed, 20 insertions, 3 deletions
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index e101846ab7dd..a72b82e727f1 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -109,7 +109,7 @@ static struct irq_desc bad_irq_desc = {
109 * come via this function. Instead, they should provide their 109 * come via this function. Instead, they should provide their
110 * own 'handler' 110 * own 'handler'
111 */ 111 */
112asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) 112asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
113{ 113{
114 struct pt_regs *old_regs = set_irq_regs(regs); 114 struct pt_regs *old_regs = set_irq_regs(regs);
115 struct irq_desc *desc = irq_desc + irq; 115 struct irq_desc *desc = irq_desc + irq;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 24095601359b..ba1c1884e68e 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -45,7 +45,18 @@ static int __init user_debug_setup(char *str)
45__setup("user_debug=", user_debug_setup); 45__setup("user_debug=", user_debug_setup);
46#endif 46#endif
47 47
48void dump_backtrace_entry(unsigned long where, unsigned long from) 48static void dump_mem(const char *str, unsigned long bottom, unsigned long top);
49
50static inline int in_exception_text(unsigned long ptr)
51{
52 extern char __exception_text_start[];
53 extern char __exception_text_end[];
54
55 return ptr >= (unsigned long)&__exception_text_start &&
56 ptr < (unsigned long)&__exception_text_end;
57}
58
59void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
49{ 60{
50#ifdef CONFIG_KALLSYMS 61#ifdef CONFIG_KALLSYMS
51 printk("[<%08lx>] ", where); 62 printk("[<%08lx>] ", where);
@@ -55,6 +66,9 @@ void dump_backtrace_entry(unsigned long where, unsigned long from)
55#else 66#else
56 printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); 67 printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
57#endif 68#endif
69
70 if (in_exception_text(where))
71 dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
58} 72}
59 73
60/* 74/*
@@ -266,7 +280,7 @@ void unregister_undef_hook(struct undef_hook *hook)
266 spin_unlock_irqrestore(&undef_lock, flags); 280 spin_unlock_irqrestore(&undef_lock, flags);
267} 281}
268 282
269asmlinkage void do_undefinstr(struct pt_regs *regs) 283asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
270{ 284{
271 unsigned int correction = thumb_mode(regs) ? 2 : 4; 285 unsigned int correction = thumb_mode(regs) ? 2 : 4;
272 unsigned int instr; 286 unsigned int instr;
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index ddbdad48f5b2..b295f6a85cf1 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -83,6 +83,9 @@ SECTIONS
83 83
84 .text : { /* Real text segment */ 84 .text : { /* Real text segment */
85 _text = .; /* Text and read-only data */ 85 _text = .; /* Text and read-only data */
86 __exception_text_start = .;
87 *(.exception.text)
88 __exception_text_end = .;
86 *(.text) 89 *(.text)
87 SCHED_TEXT 90 SCHED_TEXT
88 LOCK_TEXT 91 LOCK_TEXT