Hi Jiri, > What I am however wondering whether can't be case here is that the jump > label was used before int3_notifier has been registered. > I am thinking about ways around this, but we'll probably have to do the > same ftrace is doing, i.e. hook into do_int3() directly instead of relying > on the notifier to be registered in time. > > Fengguang, as I am not able to reproduce this bug locally, could you do me > a favor and test whether the patch below works the problem around, just > for the sake of testing the hypothesis?
I tested 1000 boots with the patch and find no more boot problem. Thanks, Fengguang > From: Jiri Kosina <jkos...@suse.cz> > Subject: [PATCH] x86: call out into int3 handler directly instead of using > notifier > > --- > arch/x86/include/asm/alternative.h | 2 ++ > arch/x86/kernel/alternative.c | 22 +++++++++++++++++++++- > arch/x86/kernel/traps.c | 4 ++++ > 3 files changed, 27 insertions(+), 1 deletions(-) > > diff --git a/arch/x86/include/asm/alternative.h > b/arch/x86/include/asm/alternative.h > index 3abf8dd..c22a41d 100644 > --- a/arch/x86/include/asm/alternative.h > +++ b/arch/x86/include/asm/alternative.h > @@ -5,6 +5,7 @@ > #include <linux/stddef.h> > #include <linux/stringify.h> > #include <asm/asm.h> > +#include <asm/ptrace.h> > > /* > * Alternative inline assembly for SMP. > @@ -232,6 +233,7 @@ struct text_poke_param { > size_t len; > }; > > +extern int poke_bp_int3_handler(struct pt_regs *regs); > extern void *text_poke(void *addr, const void *opcode, size_t len); > extern void *text_poke_bp(void *addr, const void *opcode, size_t len, void > *handler); > extern void *text_poke_smp(void *addr, const void *opcode, size_t len); > diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c > index 0ab4936..e1088f2 100644 > --- a/arch/x86/kernel/alternative.c > +++ b/arch/x86/kernel/alternative.c > @@ -605,6 +605,24 @@ static void do_sync_core(void *info) > static bool bp_patching_in_progress; > static void *bp_int3_handler, *bp_int3_addr; > > +int poke_bp_int3_handler(struct pt_regs *regs) > +{ > + /* bp_patching_in_progress */ > + smp_rmb(); > + > + if (likely(!bp_patching_in_progress)) > + return 0; > + > + if (user_mode_vm(regs) || regs->ip != (unsigned long)bp_int3_addr) > + return 0; > + > + /* set up the specified breakpoint handler */ > + regs->ip = (unsigned long) bp_int3_handler; > + > + return 1; > + > +} > + > static int int3_notify(struct notifier_block *self, unsigned long val, void > *data) > { > struct die_args *args = data; > @@ -689,6 +707,7 @@ void *text_poke_bp(void *addr, const void *opcode, size_t > len, void *handler) > return addr; > } > > +#if 0 > /* this one needs to run before anything else handles it as a > * regular exception */ > static struct notifier_block int3_nb = { > @@ -700,8 +719,9 @@ static int __init int3_init(void) > { > return register_die_notifier(&int3_nb); > } > - > arch_initcall(int3_init); > +#endif > + > /* > * Cross-modifying kernel text with stop_machine(). > * This code originally comes from immediate value. > diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c > index 772e2a8..e464764 100644 > --- a/arch/x86/kernel/traps.c > +++ b/arch/x86/kernel/traps.c > @@ -58,6 +58,7 @@ > #include <asm/mce.h> > #include <asm/fixmap.h> > #include <asm/mach_traps.h> > +#include <asm/alternative.h> > > #ifdef CONFIG_X86_64 > #include <asm/x86_init.h> > @@ -324,6 +325,9 @@ dotraplinkage void __kprobes notrace do_int3(struct > pt_regs *regs, long error_co > ftrace_int3_handler(regs)) > return; > #endif > + if (poke_bp_int3_handler(regs)) > + return; > + > prev_state = exception_enter(); > #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP > if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, > > -- > Jiri Kosina > SUSE Labs -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/