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