X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=arch%2Farm%2Fkernel%2Ftraps.c;h=f05e66b0f868df49fcd4e6ca4faeaf7b26c32fe2;hb=c6799ade4ae04b53a5f677e5289116155ff01574;hp=24095601359b94e04b9d8b83b2b9ab70cb9a2135;hpb=2874b391bd78a5b8cb84be67297a345fbdec4ac8;p=linux-2.6 diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 2409560135..f05e66b0f8 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -45,7 +44,18 @@ static int __init user_debug_setup(char *str) __setup("user_debug=", user_debug_setup); #endif -void dump_backtrace_entry(unsigned long where, unsigned long from) +static void dump_mem(const char *str, unsigned long bottom, unsigned long top); + +static inline int in_exception_text(unsigned long ptr) +{ + extern char __exception_text_start[]; + extern char __exception_text_end[]; + + return ptr >= (unsigned long)&__exception_text_start && + ptr < (unsigned long)&__exception_text_end; +} + +void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { #ifdef CONFIG_KALLSYMS printk("[<%08lx>] ", where); @@ -55,6 +65,9 @@ void dump_backtrace_entry(unsigned long where, unsigned long from) #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif + + if (in_exception_text(where)) + dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); } /* @@ -266,13 +279,14 @@ void unregister_undef_hook(struct undef_hook *hook) spin_unlock_irqrestore(&undef_lock, flags); } -asmlinkage void do_undefinstr(struct pt_regs *regs) +asmlinkage void __exception do_undefinstr(struct pt_regs *regs) { unsigned int correction = thumb_mode(regs) ? 2 : 4; unsigned int instr; struct undef_hook *hook; siginfo_t info; void __user *pc; + unsigned long flags; /* * According to the ARM ARM, PC is 2 or 4 bytes ahead, @@ -291,7 +305,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) get_user(instr, (u32 __user *)pc); } - spin_lock_irq(&undef_lock); + spin_lock_irqsave(&undef_lock, flags); list_for_each_entry(hook, &undef_hook, node) { if ((instr & hook->instr_mask) == hook->instr_val && (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) { @@ -301,7 +315,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) } } } - spin_unlock_irq(&undef_lock); + spin_unlock_irqrestore(&undef_lock, flags); #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_UNDEFINED) {