diff options
author | Andi Kleen <ak@suse.de> | 2005-04-16 18:25:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:25:13 -0400 |
commit | daeeafecf029a05a304fa299706b3ecc90e16175 (patch) | |
tree | 7b17fd7408b47892e391604c6791674f03109e1c /arch/x86_64/kernel/traps.c | |
parent | ece90303ec7e2e8d8610eb03ee7648755dd8efe7 (diff) |
[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>
Diffstat (limited to 'arch/x86_64/kernel/traps.c')
-rw-r--r-- | arch/x86_64/kernel/traps.c | 14 |
1 files changed, 3 insertions, 11 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 2f42fd5c075f..f6ccf155e3e5 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -659,9 +659,9 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code) | |||
659 | asm("movq %%db6,%0" : "=r" (condition)); | 659 | asm("movq %%db6,%0" : "=r" (condition)); |
660 | 660 | ||
661 | if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, | 661 | if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, |
662 | SIGTRAP) == NOTIFY_STOP) { | 662 | SIGTRAP) == NOTIFY_STOP) |
663 | return; | 663 | return; |
664 | } | 664 | |
665 | conditional_sti(regs); | 665 | conditional_sti(regs); |
666 | 666 | ||
667 | /* Mask out spurious debug traps due to lazy DR7 setting */ | 667 | /* 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) | |||
674 | tsk->thread.debugreg6 = condition; | 674 | tsk->thread.debugreg6 = condition; |
675 | 675 | ||
676 | /* Mask out spurious TF errors due to lazy TF clearing */ | 676 | /* Mask out spurious TF errors due to lazy TF clearing */ |
677 | if ((condition & DR_STEP) && | 677 | if (condition & DR_STEP) { |
678 | (notify_die(DIE_DEBUGSTEP, "debugstep", regs, condition, | ||
679 | 1, SIGTRAP) != NOTIFY_STOP)) { | ||
680 | /* | 678 | /* |
681 | * The TF error should be masked out only if the current | 679 | * The TF error should be masked out only if the current |
682 | * process is not traced and if the TRAP flag has been set | 680 | * 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) | |||
711 | force_sig_info(SIGTRAP, &info, tsk); | 709 | force_sig_info(SIGTRAP, &info, tsk); |
712 | clear_dr7: | 710 | clear_dr7: |
713 | asm volatile("movq %0,%%db7"::"r"(0UL)); | 711 | asm volatile("movq %0,%%db7"::"r"(0UL)); |
714 | notify_die(DIE_DEBUG, "debug", regs, condition, 1, SIGTRAP); | ||
715 | return; | 712 | return; |
716 | 713 | ||
717 | clear_TF_reenable: | 714 | clear_TF_reenable: |
718 | set_tsk_thread_flag(tsk, TIF_SINGLESTEP); | 715 | set_tsk_thread_flag(tsk, TIF_SINGLESTEP); |
719 | |||
720 | clear_TF: | ||
721 | /* RED-PEN could cause spurious errors */ | ||
722 | if (notify_die(DIE_DEBUG, "debug2", regs, condition, 1, SIGTRAP) | ||
723 | != NOTIFY_STOP) | ||
724 | regs->eflags &= ~TF_MASK; | 716 | regs->eflags &= ~TF_MASK; |
725 | } | 717 | } |
726 | 718 | ||