diff options
author | Peter Zijlstra <peterz@infradead.org> | 2017-06-12 07:52:46 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-06-12 15:17:48 -0400 |
commit | 8a524f803a3e0290cdba6d373361b2cef9752934 (patch) | |
tree | 6de661f3898c330e2f7c418dae74e7363951d544 | |
parent | 32c1431eea4881a6b17bd7c639315010aeefa452 (diff) |
x86/debug: Handle early WARN_ONs proper
Hans managed to trigger a WARN very early in the boot which killed his
(Virtual) box.
The reason is that the recent rework of WARN() to use UD0 forgot to add the
fixup_bug() call to early_fixup_exception(). As a result the kernel does
not handle the WARN_ON injected UD0 exception and panics.
Add the missing fixup call, so early UD's injected by WARN() get handled.
Fixes: 9a93848fe787 ("x86/debug: Implement __WARN() using UD0")
Reported-and-tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Frank Mehnert <frank.mehnert@oracle.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Michael Thayer <michael.thayer@oracle.com>
Link: http://lkml.kernel.org/r/20170612180108.w4vgu2ckucmllf3a@hirez.programming.kicks-ass.net
-rw-r--r-- | arch/x86/include/asm/extable.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/x86/mm/extable.c | 3 |
3 files changed, 5 insertions, 1 deletions
diff --git a/arch/x86/include/asm/extable.h b/arch/x86/include/asm/extable.h index b8ad261d11dc..c66d19e3c23e 100644 --- a/arch/x86/include/asm/extable.h +++ b/arch/x86/include/asm/extable.h | |||
@@ -29,6 +29,7 @@ struct pt_regs; | |||
29 | } while (0) | 29 | } while (0) |
30 | 30 | ||
31 | extern int fixup_exception(struct pt_regs *regs, int trapnr); | 31 | extern int fixup_exception(struct pt_regs *regs, int trapnr); |
32 | extern int fixup_bug(struct pt_regs *regs, int trapnr); | ||
32 | extern bool ex_has_fault_handler(unsigned long ip); | 33 | extern bool ex_has_fault_handler(unsigned long ip); |
33 | extern void early_fixup_exception(struct pt_regs *regs, int trapnr); | 34 | extern void early_fixup_exception(struct pt_regs *regs, int trapnr); |
34 | 35 | ||
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 3995d3a777d4..bf54309b85da 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -182,7 +182,7 @@ int is_valid_bugaddr(unsigned long addr) | |||
182 | return ud == INSN_UD0 || ud == INSN_UD2; | 182 | return ud == INSN_UD0 || ud == INSN_UD2; |
183 | } | 183 | } |
184 | 184 | ||
185 | static int fixup_bug(struct pt_regs *regs, int trapnr) | 185 | int fixup_bug(struct pt_regs *regs, int trapnr) |
186 | { | 186 | { |
187 | if (trapnr != X86_TRAP_UD) | 187 | if (trapnr != X86_TRAP_UD) |
188 | return 0; | 188 | return 0; |
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index 35ea061010a1..0ea8afcb929c 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c | |||
@@ -162,6 +162,9 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr) | |||
162 | if (fixup_exception(regs, trapnr)) | 162 | if (fixup_exception(regs, trapnr)) |
163 | return; | 163 | return; |
164 | 164 | ||
165 | if (fixup_bug(regs, trapnr)) | ||
166 | return; | ||
167 | |||
165 | fail: | 168 | fail: |
166 | early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n", | 169 | early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n", |
167 | (unsigned)trapnr, (unsigned long)regs->cs, regs->ip, | 170 | (unsigned)trapnr, (unsigned long)regs->cs, regs->ip, |