[PATCH] x86_64: Keep only a single debug notifier chain

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>
This commit is contained in:
Andi Kleen 2005-04-16 15:25:13 -07:00 коммит произвёл Linus Torvalds
Родитель ece90303ec
Коммит daeeafecf0
2 изменённых файлов: 3 добавлений и 12 удалений

Просмотреть файл

@ -659,9 +659,9 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code)
asm("movq %%db6,%0" : "=r" (condition)); asm("movq %%db6,%0" : "=r" (condition));
if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
SIGTRAP) == NOTIFY_STOP) { SIGTRAP) == NOTIFY_STOP)
return; return;
}
conditional_sti(regs); conditional_sti(regs);
/* Mask out spurious debug traps due to lazy DR7 setting */ /* Mask out spurious debug traps due to lazy DR7 setting */
@ -674,9 +674,7 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code)
tsk->thread.debugreg6 = condition; tsk->thread.debugreg6 = condition;
/* Mask out spurious TF errors due to lazy TF clearing */ /* Mask out spurious TF errors due to lazy TF clearing */
if ((condition & DR_STEP) && if (condition & DR_STEP) {
(notify_die(DIE_DEBUGSTEP, "debugstep", regs, condition,
1, SIGTRAP) != NOTIFY_STOP)) {
/* /*
* The TF error should be masked out only if the current * The TF error should be masked out only if the current
* process is not traced and if the TRAP flag has been set * process is not traced and if the TRAP flag has been set
@ -711,16 +709,10 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code)
force_sig_info(SIGTRAP, &info, tsk); force_sig_info(SIGTRAP, &info, tsk);
clear_dr7: clear_dr7:
asm volatile("movq %0,%%db7"::"r"(0UL)); asm volatile("movq %0,%%db7"::"r"(0UL));
notify_die(DIE_DEBUG, "debug", regs, condition, 1, SIGTRAP);
return; return;
clear_TF_reenable: clear_TF_reenable:
set_tsk_thread_flag(tsk, TIF_SINGLESTEP); set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
clear_TF:
/* RED-PEN could cause spurious errors */
if (notify_die(DIE_DEBUG, "debug2", regs, condition, 1, SIGTRAP)
!= NOTIFY_STOP)
regs->eflags &= ~TF_MASK; regs->eflags &= ~TF_MASK;
} }

Просмотреть файл

@ -23,7 +23,6 @@ enum die_val {
DIE_OOPS = 1, DIE_OOPS = 1,
DIE_INT3, DIE_INT3,
DIE_DEBUG, DIE_DEBUG,
DIE_DEBUGSTEP,
DIE_PANIC, DIE_PANIC,
DIE_NMI, DIE_NMI,
DIE_DIE, DIE_DIE,