]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/kernel/traps.c
kgdb: support for ARCH=arm
[linux-2.6-omap-h63xx.git] / arch / arm / kernel / traps.c
index 8ad47619c07906b31dcd60c97490426f6330e34c..7277aef8309836fb74b6e2368beabf050757af9d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kallsyms.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/kprobes.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
@@ -46,15 +47,6 @@ __setup("user_debug=", user_debug_setup);
 
 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
@@ -223,7 +215,7 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
        print_modules();
        __show_regs(regs);
        printk("Process %s (pid: %d, stack limit = 0x%p)\n",
-               tsk->comm, tsk->pid, thread + 1);
+               tsk->comm, task_pid_nr(tsk), thread + 1);
 
        if (!user_mode(regs) || in_interrupt()) {
                dump_mem("Stack: ", regs->ARM_sp,
@@ -322,12 +314,23 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
                get_user(instr, (u32 __user *)pc);
        }
 
+#ifdef CONFIG_KPROBES
+       /*
+        * It is possible to have recursive kprobes, so we can't call
+        * the kprobe trap handler with the undef_lock held.
+        */
+       if (instr == KPROBE_BREAKPOINT_INSTRUCTION && !user_mode(regs)) {
+               kprobe_trap_handler(regs, instr);
+               return;
+       }
+#endif
+
        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) {
                        if (hook->fn(regs, instr) == 0) {
-                               spin_unlock_irq(&undef_lock);
+                               spin_unlock_irqrestore(&undef_lock, flags);
                                return;
                        }
                }
@@ -337,7 +340,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 #ifdef CONFIG_DEBUG_USER
        if (user_debug & UDBG_UNDEFINED) {
                printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
-                       current->comm, current->pid, pc);
+                       current->comm, task_pid_nr(current), pc);
                dump_instr(regs);
        }
 #endif
@@ -388,7 +391,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
 #ifdef CONFIG_DEBUG_USER
        if (user_debug & UDBG_SYSCALL) {
                printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
-                       current->pid, current->comm, n);
+                       task_pid_nr(current), current->comm, n);
                dump_instr(regs);
        }
 #endif
@@ -509,7 +512,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
         * existence.  Don't ever use this from user code.
         */
        case 0xfff0:
-       {
+       for (;;) {
                extern void do_DataAbort(unsigned long addr, unsigned int fsr,
                                         struct pt_regs *regs);
                unsigned long val;
@@ -545,7 +548,6 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
                up_read(&mm->mmap_sem);
                /* simulate a write access fault */
                do_DataAbort(addr, 15 + (1 << 11), regs);
-               return -1;
        }
 #endif
 
@@ -565,7 +567,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
         */
        if (user_debug & UDBG_SYSCALL) {
                printk("[%d] %s: arm syscall %d\n",
-                      current->pid, current->comm, no);
+                      task_pid_nr(current), current->comm, no);
                dump_instr(regs);
                if (user_mode(regs)) {
                        __show_regs(regs);
@@ -642,7 +644,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
 #ifdef CONFIG_DEBUG_USER
        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);
+                       task_pid_nr(current), current->comm, code, instr);
                dump_instr(regs);
                show_pte(current->mm, addr);
        }
@@ -705,6 +707,11 @@ void abort(void)
 EXPORT_SYMBOL(abort);
 
 void __init trap_init(void)
+{
+       return;
+}
+
+void __init early_trap_init(void)
 {
        unsigned long vectors = CONFIG_VECTORS_BASE;
        extern char __stubs_start[], __stubs_end[];