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