diff options
Diffstat (limited to 'arch/x86/kernel/kgdb.c')
-rw-r--r-- | arch/x86/kernel/kgdb.c | 18 |
1 files changed, 15 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; |