aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/nmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/nmi.c')
-rw-r--r--arch/x86/kernel/nmi.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index e88f37b58dd..de8d4b333f4 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -408,6 +408,18 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
408dotraplinkage notrace __kprobes void 408dotraplinkage notrace __kprobes void
409do_nmi(struct pt_regs *regs, long error_code) 409do_nmi(struct pt_regs *regs, long error_code)
410{ 410{
411 int update_debug_stack = 0;
412
413 /*
414 * If we interrupted a breakpoint, it is possible that
415 * the nmi handler will have breakpoints too. We need to
416 * change the IDT such that breakpoints that happen here
417 * continue to use the NMI stack.
418 */
419 if (unlikely(is_debug_stack(regs->sp))) {
420 debug_stack_set_zero();
421 update_debug_stack = 1;
422 }
411 nmi_enter(); 423 nmi_enter();
412 424
413 inc_irq_stat(__nmi_count); 425 inc_irq_stat(__nmi_count);
@@ -416,6 +428,9 @@ do_nmi(struct pt_regs *regs, long error_code)
416 default_do_nmi(regs); 428 default_do_nmi(regs);
417 429
418 nmi_exit(); 430 nmi_exit();
431
432 if (unlikely(update_debug_stack))
433 debug_stack_reset();
419} 434}
420 435
421void stop_nmi(void) 436void stop_nmi(void)