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