[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:
Родитель
ece90303ec
Коммит
daeeafecf0
|
@ -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,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче