xref: /openbmc/linux/arch/x86/kernel/cpu/mce/inject.c (revision cb3908c133f1285069673f11ad651d14ae0406cf)
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 "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 > 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 |= (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 (boot_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");
740