daeeafecf0
Calling a notifier three times in the debug handler does not make much sense, because a debugger can figure out the various conditions by itself. Remove the additional calls to DIE_DEBUG and DIE_DEBUGSTEP completely. This matches what i386 does now. This also makes sure interrupts are always still disabled when calling a debugger, which prevents: BUG: using smp_processor_id() in preemptible [00000001] code: tpopf/1470 caller is post_kprobe_handler+0x9/0x70 Call Trace:<ffffffff8024f10f>{smp_processor_id+191} <ffffffff80120e69>{post_kpro be_handler+9} <ffffffff80120f7a>{kprobe_exceptions_notify+58} <ffffffff80144fc0>{notifier_call_chain+32} <ffffffff80110daf>{do_debug+335} <ffffffff8010f513>{debug+127} <EOE> on preemptible debug kernels with kprobes when single stepping in user space. This was probably a bug even on non preempt kernels, this function was supposed to be running with interrupts off according to a comment there. Note to third part debugger maintainers: please double check your debugger can still single step. Cc: <prasanna@in.ibm.com> Cc: <jbeulich@novell.com> Cc: <kaos@sgi.com> Cc: <jim.houston@ccur.com> Cc: <jfv@bluesong.net> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
53 lines
1.2 KiB
C
53 lines
1.2 KiB
C
#ifndef _X86_64_KDEBUG_H
|
|
#define _X86_64_KDEBUG_H 1
|
|
|
|
#include <linux/notifier.h>
|
|
|
|
struct pt_regs;
|
|
|
|
struct die_args {
|
|
struct pt_regs *regs;
|
|
const char *str;
|
|
long err;
|
|
int trapnr;
|
|
int signr;
|
|
};
|
|
|
|
/* Note - you should never unregister because that can race with NMIs.
|
|
If you really want to do it first unregister - then synchronize_kernel - then free.
|
|
*/
|
|
int register_die_notifier(struct notifier_block *nb);
|
|
extern struct notifier_block *die_chain;
|
|
/* Grossly misnamed. */
|
|
enum die_val {
|
|
DIE_OOPS = 1,
|
|
DIE_INT3,
|
|
DIE_DEBUG,
|
|
DIE_PANIC,
|
|
DIE_NMI,
|
|
DIE_DIE,
|
|
DIE_NMIWATCHDOG,
|
|
DIE_KERNELDEBUG,
|
|
DIE_TRAP,
|
|
DIE_GPF,
|
|
DIE_CALL,
|
|
DIE_NMI_IPI,
|
|
DIE_PAGE_FAULT,
|
|
};
|
|
|
|
static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
|
|
{
|
|
struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig };
|
|
return notifier_call_chain(&die_chain, val, &args);
|
|
}
|
|
|
|
extern int printk_address(unsigned long address);
|
|
extern void die(const char *,struct pt_regs *,long);
|
|
extern void __die(const char *,struct pt_regs *,long);
|
|
extern void show_registers(struct pt_regs *regs);
|
|
extern void dump_pagetable(unsigned long);
|
|
extern void oops_begin(void);
|
|
extern void oops_end(void);
|
|
|
|
#endif
|