The only way the debugger can handle a trap in inside rcu_lock,
notify_die, or atomic_notifier_call_chain without a recursive fault is
to have a low level "first opportunity handler" low level
program_check_exception() handler.

The other change here is to make sure that kgdb_handle_exception() is
called with correct parameters when catching an oops, because kdb
needs to know if the entry was an oops, single step, or breakpoint
exception.

CC: Benjamin Herrenschmidt <[email protected]>
CC: Paul Mackerras <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
 arch/powerpc/kernel/kgdb.c  |    7 +++++--
 arch/powerpc/kernel/traps.c |    7 +++++++
 lib/Kconfig.kgdb            |    2 +-
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index 7aafcc5..c06fe55 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -20,6 +20,7 @@
 #include <linux/smp.h>
 #include <linux/signal.h>
 #include <linux/ptrace.h>
+#include <linux/kdebug.h>
 #include <asm/current.h>
 #include <asm/processor.h>
 #include <asm/machdep.h>
@@ -115,7 +116,9 @@ void kgdb_roundup_cpus(unsigned long flags)
 /* KGDB functions to use existing PowerPC64 hooks. */
 static int kgdb_debugger(struct pt_regs *regs)
 {
-       return kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs);
+       if (kgdb_handle_exception(1, computeSignal(TRAP(regs)), DIE_OOPS, regs))
+               return 0;
+       return 1;
 }
 
 static int kgdb_handle_breakpoint(struct pt_regs *regs)
@@ -123,7 +126,7 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs)
        if (user_mode(regs))
                return 0;
 
-       if (kgdb_handle_exception(0, SIGTRAP, 0, regs) != 0)
+       if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
                return 0;
 
        if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr))
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index d069ff8..379104a 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -809,12 +809,19 @@ void __kprobes program_check_exception(struct pt_regs 
*regs)
                return;
        }
        if (reason & REASON_TRAP) {
+
+#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
+               if (debugger_bpt(regs))
+                       return;
+#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
                /* trap exception */
                if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP)
                                == NOTIFY_STOP)
                        return;
+#ifndef CONFIG_KGDB_LOW_LEVEL_TRAP
                if (debugger_bpt(regs))
                        return;
+#endif /* ! CONFIG_KGDB_LOW_LEVEL_TRAP */
 
                if (!(regs->msr & MSR_PR) &&  /* not user-mode */
                    report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) {
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb
index 0a0e049..2b1601b 100644
--- a/lib/Kconfig.kgdb
+++ b/lib/Kconfig.kgdb
@@ -59,7 +59,7 @@ config KGDB_TESTS_BOOT_STRING
 
 config KGDB_LOW_LEVEL_TRAP
        bool "KGDB: Allow debugging with traps in notifiers"
-       depends on X86
+       depends on X86 || PPC
        default n
        help
          This will add an extra call back to kgdb for the breakpoint
-- 
1.6.3.1.9.g95405b


------------------------------------------------------------------------------
Throughout its 18-year history, RSA Conference consistently attracts the
world's best and brightest in the field, creating opportunities for Conference
attendees to learn about information security's most important issues through
interactions with peers, luminaries and emerging and established companies.
http://p.sf.net/sfu/rsaconf-dev2dev
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to