lkml.org 
[lkml]   [2010]   [Feb]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 18/28] powerpc,kgdb: Introduce low level trap catching
    Date
    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 allow the kernel debugger to handle the exception first in
    program_check_exception().

    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.

    [benh@kernel.crashing.org: move debugger_bpt instead of #ifdef]

    CC: Paul Mackerras <paulus@samba.org>
    Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
    Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    ---
    arch/powerpc/kernel/kgdb.c | 6 ++++--
    arch/powerpc/kernel/traps.c | 7 +++++--
    2 files changed, 9 insertions(+), 4 deletions(-)

    diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
    index 7aafcc5..8ee7b6e 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,8 @@ 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);
    + return !kgdb_handle_exception(1, computeSignal(TRAP(regs)),
    + DIE_OOPS, regs);
    }

    static int kgdb_handle_breakpoint(struct pt_regs *regs)
    @@ -123,7 +125,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..9b72f08 100644
    --- a/arch/powerpc/kernel/traps.c
    +++ b/arch/powerpc/kernel/traps.c
    @@ -809,12 +809,15 @@ void __kprobes program_check_exception(struct pt_regs *regs)
    return;
    }
    if (reason & REASON_TRAP) {
    + /* Debugger is first in line to stop recursive faults in
    + * rcu_lock, notify_die, or atomic_notifier_call_chain */
    + if (debugger_bpt(regs))
    + return;
    +
    /* trap exception */
    if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP)
    == NOTIFY_STOP)
    return;
    - if (debugger_bpt(regs))
    - return;

    if (!(regs->msr & MSR_PR) && /* not user-mode */
    report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) {
    --
    1.6.4.rc1


    \
     
     \ /
      Last update: 2010-02-25 22:29    [W:0.024 / U:213.372 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site