diff options
-rw-r--r-- | arch/x86/kernel/nmi.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 35b39592732b..d0eaa31b9f37 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c | |||
@@ -53,6 +53,15 @@ static struct nmi_desc nmi_desc[NMI_MAX] = | |||
53 | 53 | ||
54 | }; | 54 | }; |
55 | 55 | ||
56 | struct nmi_stats { | ||
57 | unsigned int normal; | ||
58 | unsigned int unknown; | ||
59 | unsigned int external; | ||
60 | unsigned int swallow; | ||
61 | }; | ||
62 | |||
63 | static DEFINE_PER_CPU(struct nmi_stats, nmi_stats); | ||
64 | |||
56 | static int ignore_nmis; | 65 | static int ignore_nmis; |
57 | 66 | ||
58 | int unknown_nmi_panic; | 67 | int unknown_nmi_panic; |
@@ -262,8 +271,13 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs) | |||
262 | * if it caused the NMI) | 271 | * if it caused the NMI) |
263 | */ | 272 | */ |
264 | handled = nmi_handle(NMI_UNKNOWN, regs, false); | 273 | handled = nmi_handle(NMI_UNKNOWN, regs, false); |
265 | if (handled) | 274 | if (handled) { |
275 | __this_cpu_add(nmi_stats.unknown, handled); | ||
266 | return; | 276 | return; |
277 | } | ||
278 | |||
279 | __this_cpu_add(nmi_stats.unknown, 1); | ||
280 | |||
267 | #ifdef CONFIG_MCA | 281 | #ifdef CONFIG_MCA |
268 | /* | 282 | /* |
269 | * Might actually be able to figure out what the guilty party | 283 | * Might actually be able to figure out what the guilty party |
@@ -314,6 +328,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) | |||
314 | __this_cpu_write(last_nmi_rip, regs->ip); | 328 | __this_cpu_write(last_nmi_rip, regs->ip); |
315 | 329 | ||
316 | handled = nmi_handle(NMI_LOCAL, regs, b2b); | 330 | handled = nmi_handle(NMI_LOCAL, regs, b2b); |
331 | __this_cpu_add(nmi_stats.normal, handled); | ||
317 | if (handled) { | 332 | if (handled) { |
318 | /* | 333 | /* |
319 | * There are cases when a NMI handler handles multiple | 334 | * There are cases when a NMI handler handles multiple |
@@ -344,6 +359,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) | |||
344 | */ | 359 | */ |
345 | reassert_nmi(); | 360 | reassert_nmi(); |
346 | #endif | 361 | #endif |
362 | __this_cpu_add(nmi_stats.external, 1); | ||
347 | raw_spin_unlock(&nmi_reason_lock); | 363 | raw_spin_unlock(&nmi_reason_lock); |
348 | return; | 364 | return; |
349 | } | 365 | } |
@@ -380,7 +396,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) | |||
380 | * for now. | 396 | * for now. |
381 | */ | 397 | */ |
382 | if (b2b && __this_cpu_read(swallow_nmi)) | 398 | if (b2b && __this_cpu_read(swallow_nmi)) |
383 | ; | 399 | __this_cpu_add(nmi_stats.swallow, 1); |
384 | else | 400 | else |
385 | unknown_nmi_error(reason, regs); | 401 | unknown_nmi_error(reason, regs); |
386 | } | 402 | } |