diff options
-rw-r--r-- | arch/x86/kernel/kgdb.c | 18 | ||||
-rw-r--r-- | arch/x86/kernel/traps_32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/traps_64.c | 2 | ||||
-rw-r--r-- | include/asm-x86/kdebug.h | 1 |
4 files changed, 20 insertions, 3 deletions
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 37194d6374d8..5d7a21119bf8 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/kgdb.h> | 41 | #include <linux/kgdb.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/smp.h> | 43 | #include <linux/smp.h> |
44 | #include <linux/nmi.h> | ||
44 | 45 | ||
45 | #include <asm/apicdef.h> | 46 | #include <asm/apicdef.h> |
46 | #include <asm/system.h> | 47 | #include <asm/system.h> |
@@ -290,6 +291,8 @@ single_step_cont(struct pt_regs *regs, struct die_args *args) | |||
290 | return NOTIFY_STOP; | 291 | return NOTIFY_STOP; |
291 | } | 292 | } |
292 | 293 | ||
294 | static int was_in_debug_nmi[NR_CPUS]; | ||
295 | |||
293 | static int __kgdb_notify(struct die_args *args, unsigned long cmd) | 296 | static int __kgdb_notify(struct die_args *args, unsigned long cmd) |
294 | { | 297 | { |
295 | struct pt_regs *regs = args->regs; | 298 | struct pt_regs *regs = args->regs; |
@@ -299,15 +302,24 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) | |||
299 | if (atomic_read(&kgdb_active) != -1) { | 302 | if (atomic_read(&kgdb_active) != -1) { |
300 | /* KGDB CPU roundup */ | 303 | /* KGDB CPU roundup */ |
301 | kgdb_nmicallback(raw_smp_processor_id(), regs); | 304 | kgdb_nmicallback(raw_smp_processor_id(), regs); |
305 | was_in_debug_nmi[raw_smp_processor_id()] = 1; | ||
306 | touch_nmi_watchdog(); | ||
302 | return NOTIFY_STOP; | 307 | return NOTIFY_STOP; |
303 | } | 308 | } |
304 | return NOTIFY_DONE; | 309 | return NOTIFY_DONE; |
305 | 310 | ||
306 | case DIE_NMI_IPI: | 311 | case DIE_NMI_IPI: |
307 | if (atomic_read(&kgdb_active) != -1) { | 312 | if (atomic_read(&kgdb_active) != -1) { |
308 | /* KGDB CPU roundup: */ | 313 | /* KGDB CPU roundup */ |
309 | if (kgdb_nmicallback(raw_smp_processor_id(), regs)) | 314 | kgdb_nmicallback(raw_smp_processor_id(), regs); |
310 | return NOTIFY_DONE; | 315 | was_in_debug_nmi[raw_smp_processor_id()] = 1; |
316 | touch_nmi_watchdog(); | ||
317 | } | ||
318 | return NOTIFY_DONE; | ||
319 | |||
320 | case DIE_NMIUNKNOWN: | ||
321 | if (was_in_debug_nmi[raw_smp_processor_id()]) { | ||
322 | was_in_debug_nmi[raw_smp_processor_id()] = 0; | ||
311 | return NOTIFY_STOP; | 323 | return NOTIFY_STOP; |
312 | } | 324 | } |
313 | return NOTIFY_DONE; | 325 | return NOTIFY_DONE; |
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index b22c01e05a18..c5421f30d678 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c | |||
@@ -708,6 +708,8 @@ io_check_error(unsigned char reason, struct pt_regs * regs) | |||
708 | static __kprobes void | 708 | static __kprobes void |
709 | unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | 709 | unknown_nmi_error(unsigned char reason, struct pt_regs * regs) |
710 | { | 710 | { |
711 | if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) | ||
712 | return; | ||
711 | #ifdef CONFIG_MCA | 713 | #ifdef CONFIG_MCA |
712 | /* Might actually be able to figure out what the guilty party | 714 | /* Might actually be able to figure out what the guilty party |
713 | * is. */ | 715 | * is. */ |
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 045466681911..055b1650c69d 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c | |||
@@ -806,6 +806,8 @@ io_check_error(unsigned char reason, struct pt_regs * regs) | |||
806 | static __kprobes void | 806 | static __kprobes void |
807 | unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | 807 | unknown_nmi_error(unsigned char reason, struct pt_regs * regs) |
808 | { | 808 | { |
809 | if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) | ||
810 | return; | ||
809 | printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", | 811 | printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", |
810 | reason); | 812 | reason); |
811 | printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); | 813 | printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); |
diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index 99dcbafa1511..35231240ebdc 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h | |||
@@ -20,6 +20,7 @@ enum die_val { | |||
20 | DIE_CALL, | 20 | DIE_CALL, |
21 | DIE_NMI_IPI, | 21 | DIE_NMI_IPI, |
22 | DIE_PAGE_FAULT, | 22 | DIE_PAGE_FAULT, |
23 | DIE_NMIUNKNOWN, | ||
23 | }; | 24 | }; |
24 | 25 | ||
25 | extern void printk_address(unsigned long address, int reliable); | 26 | extern void printk_address(unsigned long address, int reliable); |