Commit bfc7e179 authored by Russell King's avatar Russell King

[ARM] Allow run-time selection of user debugging messages.

parent 576b2e14
......@@ -657,6 +657,15 @@ config DEBUG_USER
sometimes helpful for debugging but serves no purpose on a
production system. Most people should say N here.
In addition, you need to pass user_debug=N on the kernel command
line to enable this feature. N consists of the sum of:
1 - undefined instruction events
2 - system calls
4 - invalid data aborts
8 - SIGSEGV faults
16 - SIGBUS faults
config DEBUG_INFO
bool "Include GDB debugging information in kernel binary"
help
......
......@@ -50,6 +50,17 @@ const char *processor_modes[]=
static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
#ifdef CONFIG_DEBUG_USER
unsigned int user_debug;
static int __init user_debug_setup(char *str)
{
get_option(&str, &user_debug);
return 1;
}
__setup("user_debug=", user_debug_setup);
#endif
void dump_backtrace_entry(unsigned long where, unsigned long from)
{
#ifdef CONFIG_KALLSYMS
......@@ -287,9 +298,11 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
spin_unlock_irq(&undef_lock);
#ifdef CONFIG_DEBUG_USER
printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
current->comm, current->pid, pc);
dump_instr(regs);
if (user_debug & UDBG_UNDEFINED) {
printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
current->comm, current->pid, pc);
dump_instr(regs);
}
#endif
current->thread.error_code = 0;
......@@ -351,9 +364,11 @@ static int bad_syscall(int n, struct pt_regs *regs)
}
#ifdef CONFIG_DEBUG_USER
printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
current->pid, current->comm, n);
dump_instr(regs);
if (user_debug & UDBG_SYSCALL) {
printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
current->pid, current->comm, n);
dump_instr(regs);
}
#endif
info.si_signo = SIGILL;
......@@ -459,11 +474,14 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
* experience shows that these seem to indicate that
* something catastrophic has happened
*/
printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
dump_instr(regs);
if (user_mode(regs)) {
show_regs(regs);
c_backtrace(regs->ARM_fp, processor_mode(regs));
if (user_debug & UDBG_SYSCALL) {
printk("[%d] %s: arm syscall %d\n",
current->pid, current->comm, no);
dump_instr(regs);
if (user_mode(regs)) {
show_regs(regs);
c_backtrace(regs->ARM_fp, processor_mode(regs));
}
}
#endif
info.si_signo = SIGILL;
......@@ -495,10 +513,12 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
siginfo_t info;
#ifdef CONFIG_DEBUG_USER
printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
current->pid, current->comm, code, instr);
dump_instr(regs);
show_pte(current->mm, addr);
if (user_debug & UDBG_BADABORT) {
printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
current->pid, current->comm, code, instr);
dump_instr(regs);
show_pte(current->mm, addr);
}
#endif
info.si_signo = SIGILL;
......
......@@ -132,10 +132,12 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
struct siginfo si;
#ifdef CONFIG_DEBUG_USER
printk(KERN_DEBUG "%s: unhandled page fault at 0x%08lx, code 0x%03x\n",
tsk->comm, addr, fsr);
show_pte(tsk->mm, addr);
show_regs(regs);
if (user_debug & UDBG_SEGV) {
printk(KERN_DEBUG "%s: unhandled page fault at 0x%08lx, code 0x%03x\n",
tsk->comm, addr, fsr);
show_pte(tsk->mm, addr);
show_regs(regs);
}
#endif
tsk->thread.address = addr;
......@@ -296,8 +298,10 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
tsk->thread.trap_no = 14;
force_sig(SIGBUS, tsk);
#ifdef CONFIG_DEBUG_USER
printk(KERN_DEBUG "%s: sigbus at 0x%08lx, pc=0x%08lx\n",
current->comm, addr, instruction_pointer(regs));
if (user_debug & UDBG_BUS) {
printk(KERN_DEBUG "%s: sigbus at 0x%08lx, pc=0x%08lx\n",
current->comm, addr, instruction_pointer(regs));
}
#endif
/* Kernel mode? Handle exceptions or die */
......
......@@ -93,6 +93,14 @@ extern int cpu_architecture(void);
extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
extern unsigned long cr_alignment; /* defined in entry-armv.S */
#define UDBG_UNDEFINED (1 << 0)
#define UDBG_SYSCALL (1 << 1)
#define UDBG_BADABORT (1 << 2)
#define UDBG_SEGV (1 << 3)
#define UDBG_BUS (1 << 4)
extern unsigned int user_debug;
#if __LINUX_ARM_ARCH__ >= 4
#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0)
#else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment