Skip to content

Commit b8347c2

Browse files
virtuosoIngo Molnar
authored andcommitted
x86/debug: Handle warnings before the notifier chain, to fix KGDB crash
Commit: 9a93848 ("x86/debug: Implement __WARN() using UD0") turned warnings into UD0, but the fixup code only runs after the notify_die() chain. This is a problem, in particular, with kgdb, which kicks in as if it was a BUG(). Fix this by running the fixup code before the notifier chain in the invalid op handler path. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Tested-by: Ilya Dryomov <idryomov@gmail.com> Acked-by: Daniel Thompson <daniel.thompson@linaro.org> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: Jason Wessel <jason.wessel@windriver.com> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Richard Weinberger <richard.weinberger@gmail.com> Cc: <stable@vger.kernel.org> # v4.12+ Link: http://lkml.kernel.org/r/20170724100428.19173-1-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent be739f4 commit b8347c2

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

arch/x86/kernel/traps.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,6 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str,
209209
if (fixup_exception(regs, trapnr))
210210
return 0;
211211

212-
if (fixup_bug(regs, trapnr))
213-
return 0;
214-
215212
tsk->thread.error_code = error_code;
216213
tsk->thread.trap_nr = trapnr;
217214
die(str, regs, error_code);
@@ -292,6 +289,13 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
292289

293290
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
294291

292+
/*
293+
* WARN*()s end up here; fix them up before we call the
294+
* notifier chain.
295+
*/
296+
if (!user_mode(regs) && fixup_bug(regs, trapnr))
297+
return;
298+
295299
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
296300
NOTIFY_STOP) {
297301
cond_local_irq_enable(regs);

0 commit comments

Comments
 (0)