dt-bindings: soc: bcm: use absolute path to other schema
[linux-2.6-microblaze.git] / arch / x86 / kernel / cpu / mce / inject.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Machine check injection support.
4  * Copyright 2008 Intel Corporation.
5  *
6  * Authors:
7  * Andi Kleen
8  * Ying Huang
9  *
10  * The AMD part (from mce_amd_inj.c): a simple MCE injection facility
11  * for testing different aspects of the RAS code. This driver should be
12  * built as module so that it can be loaded on production kernels for
13  * testing purposes.
14  *
15  * Copyright (c) 2010-17:  Borislav Petkov <bp@alien8.de>
16  *                         Advanced Micro Devices Inc.
17  */
18
19 #include <linux/cpu.h>
20 #include <linux/debugfs.h>
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/notifier.h>
24 #include <linux/pci.h>
25 #include <linux/uaccess.h>
26
27 #include <asm/amd_nb.h>
28 #include <asm/apic.h>
29 #include <asm/irq_vectors.h>
30 #include <asm/mce.h>
31 #include <asm/nmi.h>
32 #include <asm/smp.h>
33
34 #include "internal.h"
35
36 /*
37  * Collect all the MCi_XXX settings
38  */
39 static struct mce i_mce;
40 static struct dentry *dfs_inj;
41
42 #define MAX_FLAG_OPT_SIZE       4
43 #define NBCFG                   0x44
44
45 enum injection_type {
46         SW_INJ = 0,     /* SW injection, simply decode the error */
47         HW_INJ,         /* Trigger a #MC */
48         DFR_INT_INJ,    /* Trigger Deferred error interrupt */
49         THR_INT_INJ,    /* Trigger threshold interrupt */
50         N_INJ_TYPES,
51 };
52
53 static const char * const flags_options[] = {
54         [SW_INJ] = "sw",
55         [HW_INJ] = "hw",
56         [DFR_INT_INJ] = "df",
57         [THR_INT_INJ] = "th",
58         NULL
59 };
60
61 /* Set default injection to SW_INJ */
62 static enum injection_type inj_type = SW_INJ;
63
64 #define MCE_INJECT_SET(reg)                                             \
65 static int inj_##reg##_set(void *data, u64 val)                         \
66 {                                                                       \
67         struct mce *m = (struct mce *)data;                             \
68                                                                         \
69         m->reg = val;                                                   \
70         return 0;                                                       \
71 }
72
73 MCE_INJECT_SET(status);
74 MCE_INJECT_SET(misc);
75 MCE_INJECT_SET(addr);
76 MCE_INJECT_SET(synd);
77
78 #define MCE_INJECT_GET(reg)                                             \
79 static int inj_##reg##_get(void *data, u64 *val)                        \
80 {                                                                       \
81         struct mce *m = (struct mce *)data;                             \
82                                                                         \
83         *val = m->reg;                                                  \
84         return 0;                                                       \
85 }
86
87 MCE_INJECT_GET(status);
88 MCE_INJECT_GET(misc);
89 MCE_INJECT_GET(addr);
90 MCE_INJECT_GET(synd);
91 MCE_INJECT_GET(ipid);
92
93 DEFINE_SIMPLE_ATTRIBUTE(status_fops, inj_status_get, inj_status_set, "%llx\n");
94 DEFINE_SIMPLE_ATTRIBUTE(misc_fops, inj_misc_get, inj_misc_set, "%llx\n");
95 DEFINE_SIMPLE_ATTRIBUTE(addr_fops, inj_addr_get, inj_addr_set, "%llx\n");
96 DEFINE_SIMPLE_ATTRIBUTE(synd_fops, inj_synd_get, inj_synd_set, "%llx\n");
97
98 /* Use the user provided IPID value on a sw injection. */
99 static int inj_ipid_set(void *data, u64 val)
100 {
101         struct mce *m = (struct mce *)data;
102
103         if (cpu_feature_enabled(X86_FEATURE_SMCA)) {
104                 if (inj_type == SW_INJ)
105                         m->ipid = val;
106         }
107
108         return 0;
109 }
110
111 DEFINE_SIMPLE_ATTRIBUTE(ipid_fops, inj_ipid_get, inj_ipid_set, "%llx\n");
112
113 static void setup_inj_struct(struct mce *m)
114 {
115         memset(m, 0, sizeof(struct mce));
116
117         m->cpuvendor = boot_cpu_data.x86_vendor;
118         m->time      = ktime_get_real_seconds();
119         m->cpuid     = cpuid_eax(1);
120         m->microcode = boot_cpu_data.microcode;
121 }
122
123 /* Update fake mce registers on current CPU. */
124 static void inject_mce(struct mce *m)
125 {
126         struct mce *i = &per_cpu(injectm, m->extcpu);
127
128         /* Make sure no one reads partially written injectm */
129         i->finished = 0;
130         mb();
131         m->finished = 0;
132         /* First set the fields after finished */
133         i->extcpu = m->extcpu;
134         mb();
135         /* Now write record in order, finished last (except above) */
136         memcpy(i, m, sizeof(struct mce));
137         /* Finally activate it */
138         mb();
139         i->finished = 1;
140 }
141
142 static void raise_poll(struct mce *m)
143 {
144         unsigned long flags;
145         mce_banks_t b;
146
147         memset(&b, 0xff, sizeof(mce_banks_t));
148         local_irq_save(flags);
149         machine_check_poll(0, &b);
150         local_irq_restore(flags);
151         m->finished = 0;
152 }
153
154 static void raise_exception(struct mce *m, struct pt_regs *pregs)
155 {
156         struct pt_regs regs;
157         unsigned long flags;
158
159         if (!pregs) {
160                 memset(&regs, 0, sizeof(struct pt_regs));
161                 regs.ip = m->ip;
162                 regs.cs = m->cs;
163                 pregs = &regs;
164         }
165         /* do_machine_check() expects interrupts disabled -- at least */
166         local_irq_save(flags);
167         do_machine_check(pregs);
168         local_irq_restore(flags);
169         m->finished = 0;
170 }
171
172 static cpumask_var_t mce_inject_cpumask;
173 static DEFINE_MUTEX(mce_inject_mutex);
174
175 static int mce_raise_notify(unsigned int cmd, struct pt_regs *regs)
176 {
177         int cpu = smp_processor_id();
178         struct mce *m = this_cpu_ptr(&injectm);
179         if (!cpumask_test_cpu(cpu, mce_inject_cpumask))
180                 return NMI_DONE;
181         cpumask_clear_cpu(cpu, mce_inject_cpumask);
182         if (m->inject_flags & MCJ_EXCEPTION)
183                 raise_exception(m, regs);
184         else if (m->status)
185                 raise_poll(m);
186         return NMI_HANDLED;
187 }
188
189 static void mce_irq_ipi(void *info)
190 {
191         int cpu = smp_processor_id();
192         struct mce *m = this_cpu_ptr(&injectm);
193
194         if (cpumask_test_cpu(cpu, mce_inject_cpumask) &&
195                         m->inject_flags & MCJ_EXCEPTION) {
196                 cpumask_clear_cpu(cpu, mce_inject_cpumask);
197                 raise_exception(m, NULL);
198         }
199 }
200
201 /* Inject mce on current CPU */
202 static int raise_local(void)
203 {
204         struct mce *m = this_cpu_ptr(&injectm);
205         int context = MCJ_CTX(m->inject_flags);
206         int ret = 0;
207         int cpu = m->extcpu;
208
209         if (m->inject_flags & MCJ_EXCEPTION) {
210                 pr_info("Triggering MCE exception on CPU %d\n", cpu);
211                 switch (context) {
212                 case MCJ_CTX_IRQ:
213                         /*
214                          * Could do more to fake interrupts like
215                          * calling irq_enter, but the necessary
216                          * machinery isn't exported currently.
217                          */
218                         fallthrough;
219                 case MCJ_CTX_PROCESS:
220                         raise_exception(m, NULL);
221                         break;
222                 default:
223                         pr_info("Invalid MCE context\n");
224                         ret = -EINVAL;
225                 }
226                 pr_info("MCE exception done on CPU %d\n", cpu);
227         } else if (m->status) {
228                 pr_info("Starting machine check poll CPU %d\n", cpu);
229                 raise_poll(m);
230                 mce_notify_irq();
231                 pr_info("Machine check poll done on CPU %d\n", cpu);
232         } else
233                 m->finished = 0;
234
235         return ret;
236 }
237
238 static void __maybe_unused raise_mce(struct mce *m)
239 {
240         int context = MCJ_CTX(m->inject_flags);
241
242         inject_mce(m);
243
244         if (context == MCJ_CTX_RANDOM)
245                 return;
246
247         if (m->inject_flags & (MCJ_IRQ_BROADCAST | MCJ_NMI_BROADCAST)) {
248                 unsigned long start;
249                 int cpu;
250
251                 cpus_read_lock();
252                 cpumask_copy(mce_inject_cpumask, cpu_online_mask);
253                 cpumask_clear_cpu(get_cpu(), mce_inject_cpumask);
254                 for_each_online_cpu(cpu) {
255                         struct mce *mcpu = &per_cpu(injectm, cpu);
256                         if (!mcpu->finished ||
257                             MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM)
258                                 cpumask_clear_cpu(cpu, mce_inject_cpumask);
259                 }
260                 if (!cpumask_empty(mce_inject_cpumask)) {
261                         if (m->inject_flags & MCJ_IRQ_BROADCAST) {
262                                 /*
263                                  * don't wait because mce_irq_ipi is necessary
264                                  * to be sync with following raise_local
265                                  */
266                                 preempt_disable();
267                                 smp_call_function_many(mce_inject_cpumask,
268                                         mce_irq_ipi, NULL, 0);
269                                 preempt_enable();
270                         } else if (m->inject_flags & MCJ_NMI_BROADCAST)
271                                 apic->send_IPI_mask(mce_inject_cpumask,
272                                                 NMI_VECTOR);
273                 }
274                 start = jiffies;
275                 while (!cpumask_empty(mce_inject_cpumask)) {
276                         if (!time_before(jiffies, start + 2*HZ)) {
277                                 pr_err("Timeout waiting for mce inject %lx\n",
278                                         *cpumask_bits(mce_inject_cpumask));
279                                 break;
280                         }
281                         cpu_relax();
282                 }
283                 raise_local();
284                 put_cpu();
285                 cpus_read_unlock();
286         } else {
287                 preempt_disable();
288                 raise_local();
289                 preempt_enable();
290         }
291 }
292
293 static int mce_inject_raise(struct notifier_block *nb, unsigned long val,
294                             void *data)
295 {
296         struct mce *m = (struct mce *)data;
297
298         if (!m)
299                 return NOTIFY_DONE;
300
301         mutex_lock(&mce_inject_mutex);
302         raise_mce(m);
303         mutex_unlock(&mce_inject_mutex);
304
305         return NOTIFY_DONE;
306 }
307
308 static struct notifier_block inject_nb = {
309         .notifier_call  = mce_inject_raise,
310 };
311
312 /*
313  * Caller needs to be make sure this cpu doesn't disappear
314  * from under us, i.e.: get_cpu/put_cpu.
315  */
316 static int toggle_hw_mce_inject(unsigned int cpu, bool enable)
317 {
318         u32 l, h;
319         int err;
320
321         err = rdmsr_on_cpu(cpu, MSR_K7_HWCR, &l, &h);
322         if (err) {
323                 pr_err("%s: error reading HWCR\n", __func__);
324                 return err;
325         }
326
327         enable ? (l |= BIT(18)) : (l &= ~BIT(18));
328
329         err = wrmsr_on_cpu(cpu, MSR_K7_HWCR, l, h);
330         if (err)
331                 pr_err("%s: error writing HWCR\n", __func__);
332
333         return err;
334 }
335
336 static int __set_inj(const char *buf)
337 {
338         int i;
339
340         for (i = 0; i < N_INJ_TYPES; i++) {
341                 if (!strncmp(flags_options[i], buf, strlen(flags_options[i]))) {
342                         inj_type = i;
343                         return 0;
344                 }
345         }
346         return -EINVAL;
347 }
348
349 static ssize_t flags_read(struct file *filp, char __user *ubuf,
350                           size_t cnt, loff_t *ppos)
351 {
352         char buf[MAX_FLAG_OPT_SIZE];
353         int n;
354
355         n = sprintf(buf, "%s\n", flags_options[inj_type]);
356
357         return simple_read_from_buffer(ubuf, cnt, ppos, buf, n);
358 }
359
360 static ssize_t flags_write(struct file *filp, const char __user *ubuf,
361                            size_t cnt, loff_t *ppos)
362 {
363         char buf[MAX_FLAG_OPT_SIZE], *__buf;
364         int err;
365
366         if (!cnt || cnt > MAX_FLAG_OPT_SIZE)
367                 return -EINVAL;
368
369         if (copy_from_user(&buf, ubuf, cnt))
370                 return -EFAULT;
371
372         buf[cnt - 1] = 0;
373
374         /* strip whitespace */
375         __buf = strstrip(buf);
376
377         err = __set_inj(__buf);
378         if (err) {
379                 pr_err("%s: Invalid flags value: %s\n", __func__, __buf);
380                 return err;
381         }
382
383         *ppos += cnt;
384
385         return cnt;
386 }
387
388 static const struct file_operations flags_fops = {
389         .read           = flags_read,
390         .write          = flags_write,
391         .llseek         = generic_file_llseek,
392 };
393
394 /*
395  * On which CPU to inject?
396  */
397 MCE_INJECT_GET(extcpu);
398
399 static int inj_extcpu_set(void *data, u64 val)
400 {
401         struct mce *m = (struct mce *)data;
402
403         if (val >= nr_cpu_ids || !cpu_online(val)) {
404                 pr_err("%s: Invalid CPU: %llu\n", __func__, val);
405                 return -EINVAL;
406         }
407         m->extcpu = val;
408         return 0;
409 }
410
411 DEFINE_SIMPLE_ATTRIBUTE(extcpu_fops, inj_extcpu_get, inj_extcpu_set, "%llu\n");
412
413 static void trigger_mce(void *info)
414 {
415         asm volatile("int $18");
416 }
417
418 static void trigger_dfr_int(void *info)
419 {
420         asm volatile("int %0" :: "i" (DEFERRED_ERROR_VECTOR));
421 }
422
423 static void trigger_thr_int(void *info)
424 {
425         asm volatile("int %0" :: "i" (THRESHOLD_APIC_VECTOR));
426 }
427
428 static u32 get_nbc_for_node(int node_id)
429 {
430         struct cpuinfo_x86 *c = &boot_cpu_data;
431         u32 cores_per_node;
432
433         cores_per_node = (c->x86_max_cores * smp_num_siblings) / amd_get_nodes_per_socket();
434
435         return cores_per_node * node_id;
436 }
437
438 static void toggle_nb_mca_mst_cpu(u16 nid)
439 {
440         struct amd_northbridge *nb;
441         struct pci_dev *F3;
442         u32 val;
443         int err;
444
445         nb = node_to_amd_nb(nid);
446         if (!nb)
447                 return;
448
449         F3 = nb->misc;
450         if (!F3)
451                 return;
452
453         err = pci_read_config_dword(F3, NBCFG, &val);
454         if (err) {
455                 pr_err("%s: Error reading F%dx%03x.\n",
456                        __func__, PCI_FUNC(F3->devfn), NBCFG);
457                 return;
458         }
459
460         if (val & BIT(27))
461                 return;
462
463         pr_err("%s: Set D18F3x44[NbMcaToMstCpuEn] which BIOS hasn't done.\n",
464                __func__);
465
466         val |= BIT(27);
467         err = pci_write_config_dword(F3, NBCFG, val);
468         if (err)
469                 pr_err("%s: Error writing F%dx%03x.\n",
470                        __func__, PCI_FUNC(F3->devfn), NBCFG);
471 }
472
473 static void prepare_msrs(void *info)
474 {
475         struct mce m = *(struct mce *)info;
476         u8 b = m.bank;
477
478         wrmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus);
479
480         if (boot_cpu_has(X86_FEATURE_SMCA)) {
481                 if (m.inject_flags == DFR_INT_INJ) {
482                         wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(b), m.status);
483                         wrmsrl(MSR_AMD64_SMCA_MCx_DEADDR(b), m.addr);
484                 } else {
485                         wrmsrl(MSR_AMD64_SMCA_MCx_STATUS(b), m.status);
486                         wrmsrl(MSR_AMD64_SMCA_MCx_ADDR(b), m.addr);
487                 }
488
489                 wrmsrl(MSR_AMD64_SMCA_MCx_MISC(b), m.misc);
490                 wrmsrl(MSR_AMD64_SMCA_MCx_SYND(b), m.synd);
491         } else {
492                 wrmsrl(MSR_IA32_MCx_STATUS(b), m.status);
493                 wrmsrl(MSR_IA32_MCx_ADDR(b), m.addr);
494                 wrmsrl(MSR_IA32_MCx_MISC(b), m.misc);
495         }
496 }
497
498 static void do_inject(void)
499 {
500         u64 mcg_status = 0;
501         unsigned int cpu = i_mce.extcpu;
502         u8 b = i_mce.bank;
503
504         i_mce.tsc = rdtsc_ordered();
505
506         i_mce.status |= MCI_STATUS_VAL;
507
508         if (i_mce.misc)
509                 i_mce.status |= MCI_STATUS_MISCV;
510
511         if (i_mce.synd)
512                 i_mce.status |= MCI_STATUS_SYNDV;
513
514         if (inj_type == SW_INJ) {
515                 mce_log(&i_mce);
516                 return;
517         }
518
519         /* prep MCE global settings for the injection */
520         mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV;
521
522         if (!(i_mce.status & MCI_STATUS_PCC))
523                 mcg_status |= MCG_STATUS_RIPV;
524
525         /*
526          * Ensure necessary status bits for deferred errors:
527          * - MCx_STATUS[Deferred]: make sure it is a deferred error
528          * - MCx_STATUS[UC] cleared: deferred errors are _not_ UC
529          */
530         if (inj_type == DFR_INT_INJ) {
531                 i_mce.status |= MCI_STATUS_DEFERRED;
532                 i_mce.status &= ~MCI_STATUS_UC;
533         }
534
535         /*
536          * For multi node CPUs, logging and reporting of bank 4 errors happens
537          * only on the node base core. Refer to D18F3x44[NbMcaToMstCpuEn] for
538          * Fam10h and later BKDGs.
539          */
540         if (boot_cpu_has(X86_FEATURE_AMD_DCM) &&
541             b == 4 &&
542             boot_cpu_data.x86 < 0x17) {
543                 toggle_nb_mca_mst_cpu(topology_die_id(cpu));
544                 cpu = get_nbc_for_node(topology_die_id(cpu));
545         }
546
547         cpus_read_lock();
548         if (!cpu_online(cpu))
549                 goto err;
550
551         toggle_hw_mce_inject(cpu, true);
552
553         i_mce.mcgstatus = mcg_status;
554         i_mce.inject_flags = inj_type;
555         smp_call_function_single(cpu, prepare_msrs, &i_mce, 0);
556
557         toggle_hw_mce_inject(cpu, false);
558
559         switch (inj_type) {
560         case DFR_INT_INJ:
561                 smp_call_function_single(cpu, trigger_dfr_int, NULL, 0);
562                 break;
563         case THR_INT_INJ:
564                 smp_call_function_single(cpu, trigger_thr_int, NULL, 0);
565                 break;
566         default:
567                 smp_call_function_single(cpu, trigger_mce, NULL, 0);
568         }
569
570 err:
571         cpus_read_unlock();
572
573 }
574
575 /*
576  * This denotes into which bank we're injecting and triggers
577  * the injection, at the same time.
578  */
579 static int inj_bank_set(void *data, u64 val)
580 {
581         struct mce *m = (struct mce *)data;
582         u8 n_banks;
583         u64 cap;
584
585         /* Get bank count on target CPU so we can handle non-uniform values. */
586         rdmsrl_on_cpu(m->extcpu, MSR_IA32_MCG_CAP, &cap);
587         n_banks = cap & MCG_BANKCNT_MASK;
588
589         if (val >= n_banks) {
590                 pr_err("MCA bank %llu non-existent on CPU%d\n", val, m->extcpu);
591                 return -EINVAL;
592         }
593
594         m->bank = val;
595
596         /*
597          * sw-only injection allows to write arbitrary values into the MCA
598          * registers because it tests only the decoding paths.
599          */
600         if (inj_type == SW_INJ)
601                 goto inject;
602
603         /*
604          * Read IPID value to determine if a bank is populated on the target
605          * CPU.
606          */
607         if (cpu_feature_enabled(X86_FEATURE_SMCA)) {
608                 u64 ipid;
609
610                 if (rdmsrl_on_cpu(m->extcpu, MSR_AMD64_SMCA_MCx_IPID(val), &ipid)) {
611                         pr_err("Error reading IPID on CPU%d\n", m->extcpu);
612                         return -EINVAL;
613                 }
614
615                 if (!ipid) {
616                         pr_err("Cannot inject into unpopulated bank %llu\n", val);
617                         return -ENODEV;
618                 }
619         }
620
621 inject:
622         do_inject();
623
624         /* Reset injection struct */
625         setup_inj_struct(&i_mce);
626
627         return 0;
628 }
629
630 MCE_INJECT_GET(bank);
631
632 DEFINE_SIMPLE_ATTRIBUTE(bank_fops, inj_bank_get, inj_bank_set, "%llu\n");
633
634 static const char readme_msg[] =
635 "Description of the files and their usages:\n"
636 "\n"
637 "Note1: i refers to the bank number below.\n"
638 "Note2: See respective BKDGs for the exact bit definitions of the files below\n"
639 "as they mirror the hardware registers.\n"
640 "\n"
641 "status:\t Set MCi_STATUS: the bits in that MSR control the error type and\n"
642 "\t attributes of the error which caused the MCE.\n"
643 "\n"
644 "misc:\t Set MCi_MISC: provide auxiliary info about the error. It is mostly\n"
645 "\t used for error thresholding purposes and its validity is indicated by\n"
646 "\t MCi_STATUS[MiscV].\n"
647 "\n"
648 "synd:\t Set MCi_SYND: provide syndrome info about the error. Only valid on\n"
649 "\t Scalable MCA systems, and its validity is indicated by MCi_STATUS[SyndV].\n"
650 "\n"
651 "addr:\t Error address value to be written to MCi_ADDR. Log address information\n"
652 "\t associated with the error.\n"
653 "\n"
654 "cpu:\t The CPU to inject the error on.\n"
655 "\n"
656 "bank:\t Specify the bank you want to inject the error into: the number of\n"
657 "\t banks in a processor varies and is family/model-specific, therefore, the\n"
658 "\t supplied value is sanity-checked. Setting the bank value also triggers the\n"
659 "\t injection.\n"
660 "\n"
661 "flags:\t Injection type to be performed. Writing to this file will trigger a\n"
662 "\t real machine check, an APIC interrupt or invoke the error decoder routines\n"
663 "\t for AMD processors.\n"
664 "\n"
665 "\t Allowed error injection types:\n"
666 "\t  - \"sw\": Software error injection. Decode error to a human-readable \n"
667 "\t    format only. Safe to use.\n"
668 "\t  - \"hw\": Hardware error injection. Causes the #MC exception handler to \n"
669 "\t    handle the error. Be warned: might cause system panic if MCi_STATUS[PCC] \n"
670 "\t    is set. Therefore, consider setting (debugfs_mountpoint)/mce/fake_panic \n"
671 "\t    before injecting.\n"
672 "\t  - \"df\": Trigger APIC interrupt for Deferred error. Causes deferred \n"
673 "\t    error APIC interrupt handler to handle the error if the feature is \n"
674 "\t    is present in hardware. \n"
675 "\t  - \"th\": Trigger APIC interrupt for Threshold errors. Causes threshold \n"
676 "\t    APIC interrupt handler to handle the error. \n"
677 "\n"
678 "ipid:\t IPID (AMD-specific)\n"
679 "\n";
680
681 static ssize_t
682 inj_readme_read(struct file *filp, char __user *ubuf,
683                        size_t cnt, loff_t *ppos)
684 {
685         return simple_read_from_buffer(ubuf, cnt, ppos,
686                                         readme_msg, strlen(readme_msg));
687 }
688
689 static const struct file_operations readme_fops = {
690         .read           = inj_readme_read,
691 };
692
693 static struct dfs_node {
694         char *name;
695         const struct file_operations *fops;
696         umode_t perm;
697 } dfs_fls[] = {
698         { .name = "status",     .fops = &status_fops, .perm = S_IRUSR | S_IWUSR },
699         { .name = "misc",       .fops = &misc_fops,   .perm = S_IRUSR | S_IWUSR },
700         { .name = "addr",       .fops = &addr_fops,   .perm = S_IRUSR | S_IWUSR },
701         { .name = "synd",       .fops = &synd_fops,   .perm = S_IRUSR | S_IWUSR },
702         { .name = "ipid",       .fops = &ipid_fops,   .perm = S_IRUSR | S_IWUSR },
703         { .name = "bank",       .fops = &bank_fops,   .perm = S_IRUSR | S_IWUSR },
704         { .name = "flags",      .fops = &flags_fops,  .perm = S_IRUSR | S_IWUSR },
705         { .name = "cpu",        .fops = &extcpu_fops, .perm = S_IRUSR | S_IWUSR },
706         { .name = "README",     .fops = &readme_fops, .perm = S_IRUSR | S_IRGRP | S_IROTH },
707 };
708
709 static void __init debugfs_init(void)
710 {
711         unsigned int i;
712
713         dfs_inj = debugfs_create_dir("mce-inject", NULL);
714
715         for (i = 0; i < ARRAY_SIZE(dfs_fls); i++)
716                 debugfs_create_file(dfs_fls[i].name, dfs_fls[i].perm, dfs_inj,
717                                     &i_mce, dfs_fls[i].fops);
718 }
719
720 static int __init inject_init(void)
721 {
722         if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL))
723                 return -ENOMEM;
724
725         debugfs_init();
726
727         register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, "mce_notify");
728         mce_register_injector_chain(&inject_nb);
729
730         setup_inj_struct(&i_mce);
731
732         pr_info("Machine check injector initialized\n");
733
734         return 0;
735 }
736
737 static void __exit inject_exit(void)
738 {
739
740         mce_unregister_injector_chain(&inject_nb);
741         unregister_nmi_handler(NMI_LOCAL, "mce_notify");
742
743         debugfs_remove_recursive(dfs_inj);
744         dfs_inj = NULL;
745
746         memset(&dfs_fls, 0, sizeof(dfs_fls));
747
748         free_cpumask_var(mce_inject_cpumask);
749 }
750
751 module_init(inject_init);
752 module_exit(inject_exit);
753 MODULE_LICENSE("GPL");