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. */ 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 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. */ 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 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 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(®s, 0, sizeof(struct pt_regs)); 163 regs.ip = m->ip; 164 regs.cs = m->cs; 165 pregs = ®s; 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 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 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 */ 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 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 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 */ 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 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 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 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 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 416 static void trigger_mce(void *info) 417 { 418 asm volatile("int $18"); 419 } 420 421 static void trigger_dfr_int(void *info) 422 { 423 asm volatile("int %0" :: "i" (DEFERRED_ERROR_VECTOR)); 424 } 425 426 static void trigger_thr_int(void *info) 427 { 428 asm volatile("int %0" :: "i" (THRESHOLD_APIC_VECTOR)); 429 } 430 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 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 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_MISC(b), m.misc); 491 wrmsrl(MSR_AMD64_SMCA_MCx_SYND(b), m.synd); 492 } else { 493 wrmsrl(MSR_IA32_MCx_STATUS(b), m.status); 494 wrmsrl(MSR_IA32_MCx_ADDR(b), m.addr); 495 wrmsrl(MSR_IA32_MCx_MISC(b), m.misc); 496 } 497 } 498 499 static void do_inject(void) 500 { 501 u64 mcg_status = 0; 502 unsigned int cpu = i_mce.extcpu; 503 u8 b = i_mce.bank; 504 505 i_mce.tsc = rdtsc_ordered(); 506 507 i_mce.status |= MCI_STATUS_VAL; 508 509 if (i_mce.misc) 510 i_mce.status |= MCI_STATUS_MISCV; 511 512 if (i_mce.synd) 513 i_mce.status |= MCI_STATUS_SYNDV; 514 515 if (inj_type == SW_INJ) { 516 mce_log(&i_mce); 517 return; 518 } 519 520 /* prep MCE global settings for the injection */ 521 mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV; 522 523 if (!(i_mce.status & MCI_STATUS_PCC)) 524 mcg_status |= MCG_STATUS_RIPV; 525 526 /* 527 * Ensure necessary status bits for deferred errors: 528 * - MCx_STATUS[Deferred]: make sure it is a deferred error 529 * - MCx_STATUS[UC] cleared: deferred errors are _not_ UC 530 */ 531 if (inj_type == DFR_INT_INJ) { 532 i_mce.status |= MCI_STATUS_DEFERRED; 533 i_mce.status &= ~MCI_STATUS_UC; 534 } 535 536 /* 537 * For multi node CPUs, logging and reporting of bank 4 errors happens 538 * only on the node base core. Refer to D18F3x44[NbMcaToMstCpuEn] for 539 * Fam10h and later BKDGs. 540 */ 541 if (boot_cpu_has(X86_FEATURE_AMD_DCM) && 542 b == 4 && 543 boot_cpu_data.x86 < 0x17) { 544 toggle_nb_mca_mst_cpu(topology_amd_node_id(cpu)); 545 cpu = get_nbc_for_node(topology_amd_node_id(cpu)); 546 } 547 548 cpus_read_lock(); 549 if (!cpu_online(cpu)) 550 goto err; 551 552 toggle_hw_mce_inject(cpu, true); 553 554 i_mce.mcgstatus = mcg_status; 555 i_mce.inject_flags = inj_type; 556 smp_call_function_single(cpu, prepare_msrs, &i_mce, 0); 557 558 toggle_hw_mce_inject(cpu, false); 559 560 switch (inj_type) { 561 case DFR_INT_INJ: 562 smp_call_function_single(cpu, trigger_dfr_int, NULL, 0); 563 break; 564 case THR_INT_INJ: 565 smp_call_function_single(cpu, trigger_thr_int, NULL, 0); 566 break; 567 default: 568 smp_call_function_single(cpu, trigger_mce, NULL, 0); 569 } 570 571 err: 572 cpus_read_unlock(); 573 574 } 575 576 /* 577 * This denotes into which bank we're injecting and triggers 578 * the injection, at the same time. 579 */ 580 static int inj_bank_set(void *data, u64 val) 581 { 582 struct mce *m = (struct mce *)data; 583 u8 n_banks; 584 u64 cap; 585 586 /* Get bank count on target CPU so we can handle non-uniform values. */ 587 rdmsrl_on_cpu(m->extcpu, MSR_IA32_MCG_CAP, &cap); 588 n_banks = cap & MCG_BANKCNT_MASK; 589 590 if (val >= n_banks) { 591 pr_err("MCA bank %llu non-existent on CPU%d\n", val, m->extcpu); 592 return -EINVAL; 593 } 594 595 m->bank = val; 596 597 /* 598 * sw-only injection allows to write arbitrary values into the MCA 599 * registers because it tests only the decoding paths. 600 */ 601 if (inj_type == SW_INJ) 602 goto inject; 603 604 /* 605 * Read IPID value to determine if a bank is populated on the target 606 * CPU. 607 */ 608 if (cpu_feature_enabled(X86_FEATURE_SMCA)) { 609 u64 ipid; 610 611 if (rdmsrl_on_cpu(m->extcpu, MSR_AMD64_SMCA_MCx_IPID(val), &ipid)) { 612 pr_err("Error reading IPID on CPU%d\n", m->extcpu); 613 return -EINVAL; 614 } 615 616 if (!ipid) { 617 pr_err("Cannot inject into unpopulated bank %llu\n", val); 618 return -ENODEV; 619 } 620 } 621 622 inject: 623 do_inject(); 624 625 /* Reset injection struct */ 626 setup_inj_struct(&i_mce); 627 628 return 0; 629 } 630 631 MCE_INJECT_GET(bank); 632 633 DEFINE_SIMPLE_ATTRIBUTE(bank_fops, inj_bank_get, inj_bank_set, "%llu\n"); 634 635 static const char readme_msg[] = 636 "Description of the files and their usages:\n" 637 "\n" 638 "Note1: i refers to the bank number below.\n" 639 "Note2: See respective BKDGs for the exact bit definitions of the files below\n" 640 "as they mirror the hardware registers.\n" 641 "\n" 642 "status:\t Set MCi_STATUS: the bits in that MSR control the error type and\n" 643 "\t attributes of the error which caused the MCE.\n" 644 "\n" 645 "misc:\t Set MCi_MISC: provide auxiliary info about the error. It is mostly\n" 646 "\t used for error thresholding purposes and its validity is indicated by\n" 647 "\t MCi_STATUS[MiscV].\n" 648 "\n" 649 "synd:\t Set MCi_SYND: provide syndrome info about the error. Only valid on\n" 650 "\t Scalable MCA systems, and its validity is indicated by MCi_STATUS[SyndV].\n" 651 "\n" 652 "addr:\t Error address value to be written to MCi_ADDR. Log address information\n" 653 "\t associated with the error.\n" 654 "\n" 655 "cpu:\t The CPU to inject the error on.\n" 656 "\n" 657 "bank:\t Specify the bank you want to inject the error into: the number of\n" 658 "\t banks in a processor varies and is family/model-specific, therefore, the\n" 659 "\t supplied value is sanity-checked. Setting the bank value also triggers the\n" 660 "\t injection.\n" 661 "\n" 662 "flags:\t Injection type to be performed. Writing to this file will trigger a\n" 663 "\t real machine check, an APIC interrupt or invoke the error decoder routines\n" 664 "\t for AMD processors.\n" 665 "\n" 666 "\t Allowed error injection types:\n" 667 "\t - \"sw\": Software error injection. Decode error to a human-readable \n" 668 "\t format only. Safe to use.\n" 669 "\t - \"hw\": Hardware error injection. Causes the #MC exception handler to \n" 670 "\t handle the error. Be warned: might cause system panic if MCi_STATUS[PCC] \n" 671 "\t is set. Therefore, consider setting (debugfs_mountpoint)/mce/fake_panic \n" 672 "\t before injecting.\n" 673 "\t - \"df\": Trigger APIC interrupt for Deferred error. Causes deferred \n" 674 "\t error APIC interrupt handler to handle the error if the feature is \n" 675 "\t is present in hardware. \n" 676 "\t - \"th\": Trigger APIC interrupt for Threshold errors. Causes threshold \n" 677 "\t APIC interrupt handler to handle the error. \n" 678 "\n" 679 "ipid:\t IPID (AMD-specific)\n" 680 "\n"; 681 682 static ssize_t 683 inj_readme_read(struct file *filp, char __user *ubuf, 684 size_t cnt, loff_t *ppos) 685 { 686 return simple_read_from_buffer(ubuf, cnt, ppos, 687 readme_msg, strlen(readme_msg)); 688 } 689 690 static const struct file_operations readme_fops = { 691 .read = inj_readme_read, 692 }; 693 694 static struct dfs_node { 695 char *name; 696 const struct file_operations *fops; 697 umode_t perm; 698 } dfs_fls[] = { 699 { .name = "status", .fops = &status_fops, .perm = S_IRUSR | S_IWUSR }, 700 { .name = "misc", .fops = &misc_fops, .perm = S_IRUSR | S_IWUSR }, 701 { .name = "addr", .fops = &addr_fops, .perm = S_IRUSR | S_IWUSR }, 702 { .name = "synd", .fops = &synd_fops, .perm = S_IRUSR | S_IWUSR }, 703 { .name = "ipid", .fops = &ipid_fops, .perm = S_IRUSR | S_IWUSR }, 704 { .name = "bank", .fops = &bank_fops, .perm = S_IRUSR | S_IWUSR }, 705 { .name = "flags", .fops = &flags_fops, .perm = S_IRUSR | S_IWUSR }, 706 { .name = "cpu", .fops = &extcpu_fops, .perm = S_IRUSR | S_IWUSR }, 707 { .name = "README", .fops = &readme_fops, .perm = S_IRUSR | S_IRGRP | S_IROTH }, 708 }; 709 710 static void __init debugfs_init(void) 711 { 712 unsigned int i; 713 714 dfs_inj = debugfs_create_dir("mce-inject", NULL); 715 716 for (i = 0; i < ARRAY_SIZE(dfs_fls); i++) 717 debugfs_create_file(dfs_fls[i].name, dfs_fls[i].perm, dfs_inj, 718 &i_mce, dfs_fls[i].fops); 719 } 720 721 static void check_hw_inj_possible(void) 722 { 723 int cpu; 724 u8 bank; 725 726 /* 727 * This behavior exists only on SMCA systems though its not directly 728 * related to SMCA. 729 */ 730 if (!cpu_feature_enabled(X86_FEATURE_SMCA)) 731 return; 732 733 cpu = get_cpu(); 734 735 for (bank = 0; bank < MAX_NR_BANKS; ++bank) { 736 u64 status = MCI_STATUS_VAL, ipid; 737 738 /* Check whether bank is populated */ 739 rdmsrl(MSR_AMD64_SMCA_MCx_IPID(bank), ipid); 740 if (!ipid) 741 continue; 742 743 toggle_hw_mce_inject(cpu, true); 744 745 wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), status); 746 rdmsrl_safe(mca_msr_reg(bank, MCA_STATUS), &status); 747 wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), 0); 748 749 if (!status) { 750 hw_injection_possible = false; 751 pr_warn("Platform does not allow *hardware* error injection." 752 "Try using APEI EINJ instead.\n"); 753 } 754 755 toggle_hw_mce_inject(cpu, false); 756 757 break; 758 } 759 760 put_cpu(); 761 } 762 763 static int __init inject_init(void) 764 { 765 if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) 766 return -ENOMEM; 767 768 check_hw_inj_possible(); 769 770 debugfs_init(); 771 772 register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, "mce_notify"); 773 mce_register_injector_chain(&inject_nb); 774 775 setup_inj_struct(&i_mce); 776 777 pr_info("Machine check injector initialized\n"); 778 779 return 0; 780 } 781 782 static void __exit inject_exit(void) 783 { 784 785 mce_unregister_injector_chain(&inject_nb); 786 unregister_nmi_handler(NMI_LOCAL, "mce_notify"); 787 788 debugfs_remove_recursive(dfs_inj); 789 dfs_inj = NULL; 790 791 memset(&dfs_fls, 0, sizeof(dfs_fls)); 792 793 free_cpumask_var(mce_inject_cpumask); 794 } 795 796 module_init(inject_init); 797 module_exit(inject_exit); 798 MODULE_LICENSE("GPL"); 799