Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/arch/x86/nmi.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  linux/arch/i386/nmi.c
3
 *
4
 *  NMI watchdog support on APIC systems
5
 *
6
 *  Started by Ingo Molnar <mingo@redhat.com>
7
 *
8
 *  Fixes:
9
 *  Mikael Pettersson : AMD K7 support for local APIC NMI watchdog.
10
 *  Mikael Pettersson : Power Management for local APIC NMI watchdog.
11
 *  Mikael Pettersson : Pentium 4 support for local APIC NMI watchdog.
12
 *  Pavel Machek and
13
 *  Mikael Pettersson : PM converted to driver model. Disable/enable API.
14
 */
15
16
#include <xen/init.h>
17
#include <xen/lib.h>
18
#include <xen/mm.h>
19
#include <xen/irq.h>
20
#include <xen/delay.h>
21
#include <xen/time.h>
22
#include <xen/sched.h>
23
#include <xen/console.h>
24
#include <xen/smp.h>
25
#include <xen/keyhandler.h>
26
#include <xen/cpu.h>
27
#include <asm/current.h>
28
#include <asm/mc146818rtc.h>
29
#include <asm/msr.h>
30
#include <asm/mpspec.h>
31
#include <asm/nmi.h>
32
#include <asm/debugger.h>
33
#include <asm/div64.h>
34
#include <asm/apic.h>
35
36
unsigned int nmi_watchdog = NMI_NONE;
37
static unsigned int nmi_hz = HZ;
38
static unsigned int nmi_perfctr_msr;  /* the MSR to reset in NMI handler */
39
static unsigned int nmi_p4_cccr_val;
40
static DEFINE_PER_CPU(struct timer, nmi_timer);
41
static DEFINE_PER_CPU(unsigned int, nmi_timer_ticks);
42
43
/* opt_watchdog: If true, run a watchdog NMI on each processor. */
44
bool __initdata opt_watchdog;
45
46
/* watchdog_force: If true, process unknown NMIs when running the watchdog. */
47
bool watchdog_force;
48
49
static int __init parse_watchdog(const char *s)
50
0
{
51
0
    if ( !*s )
52
0
    {
53
0
        opt_watchdog = true;
54
0
        return 0;
55
0
    }
56
0
57
0
    switch ( parse_bool(s, NULL) )
58
0
    {
59
0
    case 0:
60
0
        opt_watchdog = false;
61
0
        return 0;
62
0
    case 1:
63
0
        opt_watchdog = true;
64
0
        return 0;
65
0
    }
66
0
67
0
    if ( !strcmp(s, "force") )
68
0
        watchdog_force = opt_watchdog = true;
69
0
    else
70
0
        return -EINVAL;
71
0
72
0
    return 0;
73
0
}
74
custom_param("watchdog", parse_watchdog);
75
76
/* opt_watchdog_timeout: Number of seconds to wait before panic. */
77
static unsigned int opt_watchdog_timeout = 5;
78
79
static int parse_watchdog_timeout(const char *s)
80
0
{
81
0
    const char *q;
82
0
83
0
    opt_watchdog_timeout = simple_strtoull(s, &q, 0);
84
0
    opt_watchdog = !!opt_watchdog_timeout;
85
0
86
0
    return *q ? -EINVAL : 0;
87
0
}
88
custom_param("watchdog_timeout", parse_watchdog_timeout);
89
90
/*
91
 * lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
92
 * - it may be reserved by some other driver, or not
93
 * - when not reserved by some other driver, it may be used for
94
 *   the NMI watchdog, or not
95
 *
96
 * This is maintained separately from nmi_active because the NMI
97
 * watchdog may also be driven from the I/O APIC timer.
98
 */
99
static DEFINE_SPINLOCK(lapic_nmi_owner_lock);
100
static unsigned int lapic_nmi_owner;
101
0
#define LAPIC_NMI_WATCHDOG  (1<<0)
102
0
#define LAPIC_NMI_RESERVED  (1<<1)
103
104
/* nmi_active:
105
 * +1: the lapic NMI watchdog is active, but can be disabled
106
 *  0: the lapic NMI watchdog has not been set up, and cannot
107
 *     be enabled
108
 * -1: the lapic NMI watchdog is disabled, but can be enabled
109
 */
110
int nmi_active;
111
112
0
#define K7_EVNTSEL_ENABLE (1 << 22)
113
0
#define K7_EVNTSEL_INT    (1 << 20)
114
0
#define K7_EVNTSEL_OS   (1 << 17)
115
0
#define K7_EVNTSEL_USR    (1 << 16)
116
0
#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING  0x76
117
0
#define K7_NMI_EVENT    K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
118
0
#define K7_EVENT_WIDTH          32
119
120
0
#define P6_EVNTSEL0_ENABLE  (1 << 22)
121
0
#define P6_EVNTSEL_INT    (1 << 20)
122
0
#define P6_EVNTSEL_OS   (1 << 17)
123
0
#define P6_EVNTSEL_USR    (1 << 16)
124
0
#define P6_EVENT_CPU_CLOCKS_NOT_HALTED   0x79
125
0
#define CORE_EVENT_CPU_CLOCKS_NOT_HALTED 0x3c
126
0
#define P6_EVENT_WIDTH          32
127
128
0
#define P4_ESCR_EVENT_SELECT(N) ((N)<<25)
129
0
#define P4_CCCR_OVF_PMI0  (1<<26)
130
0
#define P4_CCCR_OVF_PMI1  (1<<27)
131
0
#define P4_CCCR_OVF   (1<<31)
132
0
#define P4_CCCR_THRESHOLD(N)  ((N)<<20)
133
0
#define P4_CCCR_COMPLEMENT  (1<<19)
134
0
#define P4_CCCR_COMPARE   (1<<18)
135
0
#define P4_CCCR_REQUIRED  (3<<16)
136
0
#define P4_CCCR_ESCR_SELECT(N)  ((N)<<13)
137
0
#define P4_CCCR_ENABLE    (1<<12)
138
/* 
139
 * Set up IQ_PERFCTR0 to behave like a clock, by having IQ_CCCR0 filter
140
 * CRU_ESCR0 (with any non-null event selector) through a complemented
141
 * max threshold. [IA32-Vol3, Section 14.9.9] 
142
 */
143
0
#define P4_NMI_CRU_ESCR0  P4_ESCR_EVENT_SELECT(0x3F)
144
#define P4_NMI_IQ_CCCR0 \
145
0
    (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \
146
0
     P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
147
148
static void __init wait_for_nmis(void *p)
149
0
{
150
0
    unsigned int cpu = smp_processor_id();
151
0
    unsigned int start_count = nmi_count(cpu);
152
0
    unsigned long ticks = 10 * 1000 * cpu_khz / nmi_hz;
153
0
    unsigned long s, e;
154
0
155
0
    s = rdtsc();
156
0
    do {
157
0
        cpu_relax();
158
0
        if ( nmi_count(cpu) >= start_count + 2 )
159
0
            break;
160
0
        e = rdtsc();
161
0
    } while( e - s < ticks );
162
0
}
163
164
void __init check_nmi_watchdog(void)
165
0
{
166
0
    static unsigned int __initdata prev_nmi_count[NR_CPUS];
167
0
    int cpu;
168
0
    bool ok = true;
169
0
170
0
    if ( nmi_watchdog == NMI_NONE )
171
0
        return;
172
0
173
0
    printk("Testing NMI watchdog on all CPUs:");
174
0
175
0
    for_each_online_cpu ( cpu )
176
0
        prev_nmi_count[cpu] = nmi_count(cpu);
177
0
178
0
    /*
179
0
     * Wait at most 10 ticks for 2 watchdog NMIs on each CPU.
180
0
     * Busy-wait on all CPUs: the LAPIC counter that the NMI watchdog
181
0
     * uses only runs while the core's not halted
182
0
     */
183
0
    on_selected_cpus(&cpu_online_map, wait_for_nmis, NULL, 1);
184
0
185
0
    for_each_online_cpu ( cpu )
186
0
    {
187
0
        if ( nmi_count(cpu) - prev_nmi_count[cpu] < 2 )
188
0
        {
189
0
            printk(" %d", cpu);
190
0
            ok = false;
191
0
        }
192
0
    }
193
0
194
0
    printk(" %s\n", ok ? "ok" : "stuck");
195
0
196
0
    /*
197
0
     * Now that we know it works we can reduce NMI frequency to
198
0
     * something more reasonable; makes a difference in some configs.
199
0
     * There's a limit to how slow we can go because writing the perfctr
200
0
     * MSRs only sets the low 32 bits, with the top 8 bits sign-extended
201
0
     * from those, so it's not possible to set up a delay larger than
202
0
     * 2^31 cycles and smaller than (2^40 - 2^31) cycles. 
203
0
     * (Intel SDM, section 18.22.2)
204
0
     */
205
0
    if ( nmi_watchdog == NMI_LOCAL_APIC )
206
0
        nmi_hz = max(1ul, cpu_khz >> 20);
207
0
208
0
    return;
209
0
}
210
211
static void nmi_timer_fn(void *unused)
212
0
{
213
0
    this_cpu(nmi_timer_ticks)++;
214
0
    set_timer(&this_cpu(nmi_timer), NOW() + MILLISECS(1000));
215
0
}
216
217
void disable_lapic_nmi_watchdog(void)
218
0
{
219
0
    if (nmi_active <= 0)
220
0
        return;
221
0
    switch (boot_cpu_data.x86_vendor) {
222
0
    case X86_VENDOR_AMD:
223
0
        wrmsr(MSR_K7_EVNTSEL0, 0, 0);
224
0
        break;
225
0
    case X86_VENDOR_INTEL:
226
0
        switch (boot_cpu_data.x86) {
227
0
        case 6:
228
0
            wrmsr(MSR_P6_EVNTSEL(0), 0, 0);
229
0
            break;
230
0
        case 15:
231
0
            wrmsr(MSR_P4_IQ_CCCR0, 0, 0);
232
0
            wrmsr(MSR_P4_CRU_ESCR0, 0, 0);
233
0
            break;
234
0
        }
235
0
        break;
236
0
    }
237
0
    nmi_active = -1;
238
0
    /* tell do_nmi() and others that we're not active any more */
239
0
    nmi_watchdog = NMI_NONE;
240
0
}
241
242
static void enable_lapic_nmi_watchdog(void)
243
0
{
244
0
    if (nmi_active < 0) {
245
0
        nmi_watchdog = NMI_LOCAL_APIC;
246
0
        setup_apic_nmi_watchdog();
247
0
    }
248
0
}
249
250
int reserve_lapic_nmi(void)
251
0
{
252
0
    unsigned int old_owner;
253
0
254
0
    spin_lock(&lapic_nmi_owner_lock);
255
0
    old_owner = lapic_nmi_owner;
256
0
    lapic_nmi_owner |= LAPIC_NMI_RESERVED;
257
0
    spin_unlock(&lapic_nmi_owner_lock);
258
0
    if (old_owner & LAPIC_NMI_RESERVED)
259
0
        return -EBUSY;
260
0
    if (old_owner & LAPIC_NMI_WATCHDOG)
261
0
        disable_lapic_nmi_watchdog();
262
0
    return 0;
263
0
}
264
265
void release_lapic_nmi(void)
266
0
{
267
0
    unsigned int new_owner;
268
0
269
0
    spin_lock(&lapic_nmi_owner_lock);
270
0
    new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED;
271
0
    lapic_nmi_owner = new_owner;
272
0
    spin_unlock(&lapic_nmi_owner_lock);
273
0
    if (new_owner & LAPIC_NMI_WATCHDOG)
274
0
        enable_lapic_nmi_watchdog();
275
0
}
276
277
/*
278
 * Activate the NMI watchdog via the local APIC.
279
 * Original code written by Keith Owens.
280
 */
281
282
static void clear_msr_range(unsigned int base, unsigned int n)
283
0
{
284
0
    unsigned int i;
285
0
286
0
    for (i = 0; i < n; i++)
287
0
        wrmsr(base+i, 0, 0);
288
0
}
289
290
static inline void write_watchdog_counter(const char *descr)
291
0
{
292
0
    u64 count = (u64)cpu_khz * 1000;
293
0
294
0
    do_div(count, nmi_hz);
295
0
    if(descr)
296
0
        Dprintk("setting %s to -%#"PRIx64"\n", descr, count);
297
0
    wrmsrl(nmi_perfctr_msr, 0 - count);
298
0
}
299
300
static void setup_k7_watchdog(void)
301
0
{
302
0
    unsigned int evntsel;
303
0
304
0
    nmi_perfctr_msr = MSR_K7_PERFCTR0;
305
0
306
0
    clear_msr_range(MSR_K7_EVNTSEL0, 4);
307
0
    clear_msr_range(MSR_K7_PERFCTR0, 4);
308
0
309
0
    evntsel = K7_EVNTSEL_INT
310
0
        | K7_EVNTSEL_OS
311
0
        | K7_EVNTSEL_USR
312
0
        | K7_NMI_EVENT;
313
0
314
0
    wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
315
0
    write_watchdog_counter("K7_PERFCTR0");
316
0
    apic_write(APIC_LVTPC, APIC_DM_NMI);
317
0
    evntsel |= K7_EVNTSEL_ENABLE;
318
0
    wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
319
0
}
320
321
static void setup_p6_watchdog(unsigned counter)
322
0
{
323
0
    unsigned int evntsel;
324
0
325
0
    nmi_perfctr_msr = MSR_P6_PERFCTR(0);
326
0
327
0
    clear_msr_range(MSR_P6_EVNTSEL(0), 2);
328
0
    clear_msr_range(MSR_P6_PERFCTR(0), 2);
329
0
330
0
    evntsel = P6_EVNTSEL_INT
331
0
        | P6_EVNTSEL_OS
332
0
        | P6_EVNTSEL_USR
333
0
        | counter;
334
0
335
0
    wrmsr(MSR_P6_EVNTSEL(0), evntsel, 0);
336
0
    write_watchdog_counter("P6_PERFCTR0");
337
0
    apic_write(APIC_LVTPC, APIC_DM_NMI);
338
0
    evntsel |= P6_EVNTSEL0_ENABLE;
339
0
    wrmsr(MSR_P6_EVNTSEL(0), evntsel, 0);
340
0
}
341
342
static int setup_p4_watchdog(void)
343
0
{
344
0
    uint64_t misc_enable;
345
0
346
0
    rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
347
0
    if (!(misc_enable & MSR_IA32_MISC_ENABLE_PERF_AVAIL))
348
0
        return 0;
349
0
350
0
    nmi_perfctr_msr = MSR_P4_IQ_PERFCTR0;
351
0
    nmi_p4_cccr_val = P4_NMI_IQ_CCCR0;
352
0
    if ( boot_cpu_data.x86_num_siblings == 2 )
353
0
        nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1;
354
0
355
0
    if (!(misc_enable & MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL))
356
0
        clear_msr_range(0x3F1, 2);
357
0
    /* MSR 0x3F0 seems to have a default value of 0xFC00, but current
358
0
       docs doesn't fully define it, so leave it alone for now. */
359
0
    if (boot_cpu_data.x86_model >= 0x3) {
360
0
        /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */
361
0
        clear_msr_range(0x3A0, 26);
362
0
        clear_msr_range(0x3BC, 3);
363
0
    } else {
364
0
        clear_msr_range(0x3A0, 31);
365
0
    }
366
0
    clear_msr_range(0x3C0, 6);
367
0
    clear_msr_range(0x3C8, 6);
368
0
    clear_msr_range(0x3E0, 2);
369
0
    clear_msr_range(MSR_P4_BPU_CCCR0, 18);
370
0
    clear_msr_range(MSR_P4_BPU_PERFCTR0, 18);
371
0
        
372
0
    wrmsrl(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0);
373
0
    wrmsrl(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE);
374
0
    write_watchdog_counter("P4_IQ_COUNTER0");
375
0
    apic_write(APIC_LVTPC, APIC_DM_NMI);
376
0
    wrmsrl(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val);
377
0
    return 1;
378
0
}
379
380
void setup_apic_nmi_watchdog(void)
381
0
{
382
0
    if ( nmi_watchdog == NMI_NONE )
383
0
        return;
384
0
385
0
    switch (boot_cpu_data.x86_vendor) {
386
0
    case X86_VENDOR_AMD:
387
0
        switch (boot_cpu_data.x86) {
388
0
        case 6:
389
0
        case 0xf ... 0x17:
390
0
            setup_k7_watchdog();
391
0
            break;
392
0
        default:
393
0
            return;
394
0
        }
395
0
        break;
396
0
    case X86_VENDOR_INTEL:
397
0
        switch (boot_cpu_data.x86) {
398
0
        case 6:
399
0
            setup_p6_watchdog((boot_cpu_data.x86_model < 14) 
400
0
                              ? P6_EVENT_CPU_CLOCKS_NOT_HALTED
401
0
                              : CORE_EVENT_CPU_CLOCKS_NOT_HALTED);
402
0
            break;
403
0
        case 15:
404
0
            if (!setup_p4_watchdog())
405
0
                return;
406
0
            break;
407
0
        default:
408
0
            return;
409
0
        }
410
0
        break;
411
0
    default:
412
0
        return;
413
0
    }
414
0
415
0
    lapic_nmi_owner = LAPIC_NMI_WATCHDOG;
416
0
    nmi_active = 1;
417
0
}
418
419
static int cpu_nmi_callback(
420
    struct notifier_block *nfb, unsigned long action, void *hcpu)
421
0
{
422
0
    unsigned int cpu = (unsigned long)hcpu;
423
0
424
0
    switch ( action )
425
0
    {
426
0
    case CPU_UP_PREPARE:
427
0
        init_timer(&per_cpu(nmi_timer, cpu), nmi_timer_fn, NULL, cpu);
428
0
        set_timer(&per_cpu(nmi_timer, cpu), NOW());
429
0
        break;
430
0
    case CPU_UP_CANCELED:
431
0
    case CPU_DEAD:
432
0
        kill_timer(&per_cpu(nmi_timer, cpu));
433
0
        break;
434
0
    default:
435
0
        break;
436
0
    }
437
0
438
0
    return NOTIFY_DONE;
439
0
}
440
441
static struct notifier_block cpu_nmi_nfb = {
442
    .notifier_call = cpu_nmi_callback
443
};
444
445
static DEFINE_PER_CPU(unsigned int, last_irq_sums);
446
static DEFINE_PER_CPU(unsigned int, alert_counter);
447
448
static atomic_t watchdog_disable_count = ATOMIC_INIT(1);
449
450
void watchdog_disable(void)
451
0
{
452
0
    atomic_inc(&watchdog_disable_count);
453
0
}
454
455
void watchdog_enable(void)
456
0
{
457
0
    atomic_dec(&watchdog_disable_count);
458
0
}
459
460
bool watchdog_enabled(void)
461
0
{
462
0
    return !atomic_read(&watchdog_disable_count);
463
0
}
464
465
int __init watchdog_setup(void)
466
0
{
467
0
    unsigned int cpu;
468
0
469
0
    /*
470
0
     * Activate periodic heartbeats. We cannot do this earlier during 
471
0
     * setup because the timer infrastructure is not available.
472
0
     */
473
0
    for_each_online_cpu ( cpu )
474
0
        cpu_nmi_callback(&cpu_nmi_nfb, CPU_UP_PREPARE, (void *)(long)cpu);
475
0
    register_cpu_notifier(&cpu_nmi_nfb);
476
0
477
0
    watchdog_enable();
478
0
    return 0;
479
0
}
480
481
/* Returns false if this was not a watchdog NMI, true otherwise */
482
bool nmi_watchdog_tick(const struct cpu_user_regs *regs)
483
0
{
484
0
    bool watchdog_tick = true;
485
0
    unsigned int sum = this_cpu(nmi_timer_ticks);
486
0
487
0
    if ( (this_cpu(last_irq_sums) == sum) && watchdog_enabled() )
488
0
    {
489
0
        /*
490
0
         * Ayiee, looks like this CPU is stuck ... wait for the timeout
491
0
         * before doing the oops ...
492
0
         */
493
0
        this_cpu(alert_counter)++;
494
0
        if ( this_cpu(alert_counter) == opt_watchdog_timeout*nmi_hz )
495
0
        {
496
0
            console_force_unlock();
497
0
            printk("Watchdog timer detects that CPU%d is stuck!\n",
498
0
                   smp_processor_id());
499
0
            fatal_trap(regs, 1);
500
0
        }
501
0
    } 
502
0
    else 
503
0
    {
504
0
        this_cpu(last_irq_sums) = sum;
505
0
        this_cpu(alert_counter) = 0;
506
0
    }
507
0
508
0
    if ( nmi_perfctr_msr )
509
0
    {
510
0
        uint64_t msr_content;
511
0
512
0
        /* Work out if this is a watchdog tick by checking for overflow. */
513
0
        if ( nmi_perfctr_msr == MSR_P4_IQ_PERFCTR0 )
514
0
        {
515
0
            rdmsrl(MSR_P4_IQ_CCCR0, msr_content);
516
0
            if ( !(msr_content & P4_CCCR_OVF) )
517
0
                watchdog_tick = false;
518
0
519
0
            /*
520
0
             * P4 quirks:
521
0
             * - An overflown perfctr will assert its interrupt
522
0
             *   until the OVF flag in its CCCR is cleared.
523
0
             * - LVTPC is masked on interrupt and must be
524
0
             *   unmasked by the LVTPC handler.
525
0
             */
526
0
            wrmsrl(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val);
527
0
            apic_write(APIC_LVTPC, APIC_DM_NMI);
528
0
        }
529
0
        else if ( nmi_perfctr_msr == MSR_P6_PERFCTR(0) )
530
0
        {
531
0
            rdmsrl(MSR_P6_PERFCTR(0), msr_content);
532
0
            if ( msr_content & (1ULL << P6_EVENT_WIDTH) )
533
0
                watchdog_tick = false;
534
0
535
0
            /*
536
0
             * Only P6 based Pentium M need to re-unmask the apic vector but
537
0
             * it doesn't hurt other P6 variants.
538
0
             */
539
0
            apic_write(APIC_LVTPC, APIC_DM_NMI);
540
0
        }
541
0
        else if ( nmi_perfctr_msr == MSR_K7_PERFCTR0 )
542
0
        {
543
0
            rdmsrl(MSR_K7_PERFCTR0, msr_content);
544
0
            if ( msr_content & (1ULL << K7_EVENT_WIDTH) )
545
0
                watchdog_tick = false;
546
0
        }
547
0
        write_watchdog_counter(NULL);
548
0
    }
549
0
550
0
    return watchdog_tick;
551
0
}
552
553
/*
554
 * For some reason the destination shorthand for self is not valid
555
 * when used with the NMI delivery mode. This is documented in Tables
556
 * 8-3 and 8-4 in IA32 Reference Manual Volume 3. We send the IPI to
557
 * our own APIC ID explicitly which is valid.
558
 */
559
void self_nmi(void)
560
0
{
561
0
    unsigned long flags;
562
0
    u32 id = get_apic_id();
563
0
    local_irq_save(flags);
564
0
    apic_wait_icr_idle();
565
0
    apic_icr_write(APIC_DM_NMI | APIC_DEST_PHYSICAL, id);
566
0
    local_irq_restore(flags);
567
0
}
568
569
static void do_nmi_trigger(unsigned char key)
570
0
{
571
0
    printk("Triggering NMI on APIC ID %x\n", get_apic_id());
572
0
    self_nmi();
573
0
}
574
575
static void do_nmi_stats(unsigned char key)
576
0
{
577
0
    int i;
578
0
    struct domain *d;
579
0
    struct vcpu *v;
580
0
581
0
    printk("CPU\tNMI\n");
582
0
    for_each_online_cpu ( i )
583
0
        printk("%3d\t%3d\n", i, nmi_count(i));
584
0
585
0
    if ( ((d = hardware_domain) == NULL) || (d->vcpu == NULL) ||
586
0
         ((v = d->vcpu[0]) == NULL) )
587
0
        return;
588
0
589
0
    i = v->async_exception_mask & (1 << VCPU_TRAP_NMI);
590
0
    if ( v->nmi_pending || i )
591
0
        printk("dom0 vpu0: NMI %s%s\n",
592
0
               v->nmi_pending ? "pending " : "",
593
0
               i ? "masked " : "");
594
0
    else
595
0
        printk("dom0 vcpu0: NMI neither pending nor masked\n");
596
0
}
597
598
static __init int register_nmi_trigger(void)
599
1
{
600
1
    register_keyhandler('N', do_nmi_trigger, "trigger an NMI", 0);
601
1
    register_keyhandler('n', do_nmi_stats, "NMI statistics", 1);
602
1
    return 0;
603
1
}
604
__initcall(register_nmi_trigger);