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 pr_info("Machine check poll done on CPU %d\n", cpu); 233 } else 234 m->finished = 0; 235 236 return ret; 237 } 238 239 static void __maybe_unused raise_mce(struct mce *m) 240 { 241 int context = MCJ_CTX(m->inject_flags); 242 243 inject_mce(m); 244 245 if (context == MCJ_CTX_RANDOM) 246 return; 247 248 if (m->inject_flags & (MCJ_IRQ_BROADCAST | MCJ_NMI_BROADCAST)) { 249 unsigned long start; 250 int cpu; 251 252 cpus_read_lock(); 253 cpumask_copy(mce_inject_cpumask, cpu_online_mask); 254 cpumask_clear_cpu(get_cpu(), mce_inject_cpumask); 255 for_each_online_cpu(cpu) { 256 struct mce *mcpu = &per_cpu(injectm, cpu); 257 if (!mcpu->finished || 258 MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM) 259 cpumask_clear_cpu(cpu, mce_inject_cpumask); 260 } 261 if (!cpumask_empty(mce_inject_cpumask)) { 262 if (m->inject_flags & MCJ_IRQ_BROADCAST) { 263 /* 264 * don't wait because mce_irq_ipi is necessary 265 * to be sync with following raise_local 266 */ 267 preempt_disable(); 268 smp_call_function_many(mce_inject_cpumask, 269 mce_irq_ipi, NULL, 0); 270 preempt_enable(); 271 } else if (m->inject_flags & MCJ_NMI_BROADCAST) 272 __apic_send_IPI_mask(mce_inject_cpumask, NMI_VECTOR); 273 } 274 start = jiffies; 275 while (!cpumask_empty(mce_inject_cpumask)) { 276 if (!time_before(jiffies, start + 2*HZ)) { 277 pr_err("Timeout waiting for mce inject %lx\n", 278 *cpumask_bits(mce_inject_cpumask)); 279 break; 280 } 281 cpu_relax(); 282 } 283 raise_local(); 284 put_cpu(); 285 cpus_read_unlock(); 286 } else { 287 preempt_disable(); 288 raise_local(); 289 preempt_enable(); 290 } 291 } 292 293 static int mce_inject_raise(struct notifier_block *nb, unsigned long val, 294 void *data) 295 { 296 struct mce *m = (struct mce *)data; 297 298 if (!m) 299 return NOTIFY_DONE; 300 301 mutex_lock(&mce_inject_mutex); 302 raise_mce(m); 303 mutex_unlock(&mce_inject_mutex); 304 305 return NOTIFY_DONE; 306 } 307 308 static struct notifier_block inject_nb = { 309 .notifier_call = mce_inject_raise, 310 }; 311 312 /* 313 * Caller needs to be make sure this cpu doesn't disappear 314 * from under us, i.e.: get_cpu/put_cpu. 315 */ 316 static int toggle_hw_mce_inject(unsigned int cpu, bool enable) 317 { 318 u32 l, h; 319 int err; 320 321 err = rdmsr_on_cpu(cpu, MSR_K7_HWCR, &l, &h); 322 if (err) { 323 pr_err("%s: error reading HWCR\n", __func__); 324 return err; 325 } 326 327 enable ? (l |= BIT(18)) : (l &= ~BIT(18)); 328 329 err = wrmsr_on_cpu(cpu, MSR_K7_HWCR, l, h); 330 if (err) 331 pr_err("%s: error writing HWCR\n", __func__); 332 333 return err; 334 } 335 336 static int __set_inj(const char *buf) 337 { 338 int i; 339 340 for (i = 0; i < N_INJ_TYPES; i++) { 341 if (!strncmp(flags_options[i], buf, strlen(flags_options[i]))) { 342 if (i > SW_INJ && !hw_injection_possible) 343 continue; 344 inj_type = i; 345 return 0; 346 } 347 } 348 return -EINVAL; 349 } 350 351 static ssize_t flags_read(struct file *filp, char __user *ubuf, 352 size_t cnt, loff_t *ppos) 353 { 354 char buf[MAX_FLAG_OPT_SIZE]; 355 int n; 356 357 n = sprintf(buf, "%s\n", flags_options[inj_type]); 358 359 return simple_read_from_buffer(ubuf, cnt, ppos, buf, n); 360 } 361 362 static ssize_t flags_write(struct file *filp, const char __user *ubuf, 363 size_t cnt, loff_t *ppos) 364 { 365 char buf[MAX_FLAG_OPT_SIZE], *__buf; 366 int err; 367 368 if (!cnt || cnt > MAX_FLAG_OPT_SIZE) 369 return -EINVAL; 370 371 if (copy_from_user(&buf, ubuf, cnt)) 372 return -EFAULT; 373 374 buf[cnt - 1] = 0; 375 376 /* strip whitespace */ 377 __buf = strstrip(buf); 378 379 err = __set_inj(__buf); 380 if (err) { 381 pr_err("%s: Invalid flags value: %s\n", __func__, __buf); 382 return err; 383 } 384 385 *ppos += cnt; 386 387 return cnt; 388 } 389 390 static const struct file_operations flags_fops = { 391 .read = flags_read, 392 .write = flags_write, 393 .llseek = generic_file_llseek, 394 }; 395 396 /* 397 * On which CPU to inject? 398 */ 399 MCE_INJECT_GET(extcpu); 400 401 static int inj_extcpu_set(void *data, u64 val) 402 { 403 struct mce *m = (struct mce *)data; 404 405 if (val >= nr_cpu_ids || !cpu_online(val)) { 406 pr_err("%s: Invalid CPU: %llu\n", __func__, val); 407 return -EINVAL; 408 } 409 m->extcpu = val; 410 return 0; 411 } 412 413 DEFINE_SIMPLE_ATTRIBUTE(extcpu_fops, inj_extcpu_get, inj_extcpu_set, "%llu\n"); 414 415 static void trigger_mce(void *info) 416 { 417 asm volatile("int $18"); 418 } 419 420 static void trigger_dfr_int(void *info) 421 { 422 asm volatile("int %0" :: "i" (DEFERRED_ERROR_VECTOR)); 423 } 424 425 static void trigger_thr_int(void *info) 426 { 427 asm volatile("int %0" :: "i" (THRESHOLD_APIC_VECTOR)); 428 } 429 430 static u32 get_nbc_for_node(int node_id) 431 { 432 u32 cores_per_node; 433 434 cores_per_node = topology_num_threads_per_package() / topology_amd_nodes_per_pkg(); 435 return cores_per_node * node_id; 436 } 437 438 static void toggle_nb_mca_mst_cpu(u16 nid) 439 { 440 struct amd_northbridge *nb; 441 struct pci_dev *F3; 442 u32 val; 443 int err; 444 445 nb = node_to_amd_nb(nid); 446 if (!nb) 447 return; 448 449 F3 = nb->misc; 450 if (!F3) 451 return; 452 453 err = pci_read_config_dword(F3, NBCFG, &val); 454 if (err) { 455 pr_err("%s: Error reading F%dx%03x.\n", 456 __func__, PCI_FUNC(F3->devfn), NBCFG); 457 return; 458 } 459 460 if (val & BIT(27)) 461 return; 462 463 pr_err("%s: Set D18F3x44[NbMcaToMstCpuEn] which BIOS hasn't done.\n", 464 __func__); 465 466 val |= BIT(27); 467 err = pci_write_config_dword(F3, NBCFG, val); 468 if (err) 469 pr_err("%s: Error writing F%dx%03x.\n", 470 __func__, PCI_FUNC(F3->devfn), NBCFG); 471 } 472 473 static void prepare_msrs(void *info) 474 { 475 struct mce m = *(struct mce *)info; 476 u8 b = m.bank; 477 478 wrmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); 479 480 if (boot_cpu_has(X86_FEATURE_SMCA)) { 481 if (m.inject_flags == DFR_INT_INJ) { 482 wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(b), m.status); 483 wrmsrl(MSR_AMD64_SMCA_MCx_DEADDR(b), m.addr); 484 } else { 485 wrmsrl(MSR_AMD64_SMCA_MCx_STATUS(b), m.status); 486 wrmsrl(MSR_AMD64_SMCA_MCx_ADDR(b), m.addr); 487 } 488 489 wrmsrl(MSR_AMD64_SMCA_MCx_SYND(b), m.synd); 490 491 if (m.misc) 492 wrmsrl(MSR_AMD64_SMCA_MCx_MISC(b), m.misc); 493 } else { 494 wrmsrl(MSR_IA32_MCx_STATUS(b), m.status); 495 wrmsrl(MSR_IA32_MCx_ADDR(b), m.addr); 496 497 if (m.misc) 498 wrmsrl(MSR_IA32_MCx_MISC(b), m.misc); 499 } 500 } 501 502 static void do_inject(void) 503 { 504 unsigned int cpu = i_mce.extcpu; 505 struct mce_hw_err err; 506 u64 mcg_status = 0; 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 err.m = i_mce; 521 mce_log(&err); 522 return; 523 } 524 525 /* prep MCE global settings for the injection */ 526 mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV; 527 528 if (!(i_mce.status & MCI_STATUS_PCC)) 529 mcg_status |= MCG_STATUS_RIPV; 530 531 /* 532 * Ensure necessary status bits for deferred errors: 533 * - MCx_STATUS[Deferred]: make sure it is a deferred error 534 * - MCx_STATUS[UC] cleared: deferred errors are _not_ UC 535 */ 536 if (inj_type == DFR_INT_INJ) { 537 i_mce.status |= MCI_STATUS_DEFERRED; 538 i_mce.status &= ~MCI_STATUS_UC; 539 } 540 541 /* 542 * For multi node CPUs, logging and reporting of bank 4 errors happens 543 * only on the node base core. Refer to D18F3x44[NbMcaToMstCpuEn] for 544 * Fam10h and later BKDGs. 545 */ 546 if (boot_cpu_has(X86_FEATURE_AMD_DCM) && 547 b == 4 && 548 boot_cpu_data.x86 < 0x17) { 549 toggle_nb_mca_mst_cpu(topology_amd_node_id(cpu)); 550 cpu = get_nbc_for_node(topology_amd_node_id(cpu)); 551 } 552 553 cpus_read_lock(); 554 if (!cpu_online(cpu)) 555 goto err; 556 557 toggle_hw_mce_inject(cpu, true); 558 559 i_mce.mcgstatus = mcg_status; 560 i_mce.inject_flags = inj_type; 561 smp_call_function_single(cpu, prepare_msrs, &i_mce, 0); 562 563 toggle_hw_mce_inject(cpu, false); 564 565 switch (inj_type) { 566 case DFR_INT_INJ: 567 smp_call_function_single(cpu, trigger_dfr_int, NULL, 0); 568 break; 569 case THR_INT_INJ: 570 smp_call_function_single(cpu, trigger_thr_int, NULL, 0); 571 break; 572 default: 573 smp_call_function_single(cpu, trigger_mce, NULL, 0); 574 } 575 576 err: 577 cpus_read_unlock(); 578 579 } 580 581 /* 582 * This denotes into which bank we're injecting and triggers 583 * the injection, at the same time. 584 */ 585 static int inj_bank_set(void *data, u64 val) 586 { 587 struct mce *m = (struct mce *)data; 588 u8 n_banks; 589 u64 cap; 590 591 /* Get bank count on target CPU so we can handle non-uniform values. */ 592 rdmsrl_on_cpu(m->extcpu, MSR_IA32_MCG_CAP, &cap); 593 n_banks = cap & MCG_BANKCNT_MASK; 594 595 if (val >= n_banks) { 596 pr_err("MCA bank %llu non-existent on CPU%d\n", val, m->extcpu); 597 return -EINVAL; 598 } 599 600 m->bank = val; 601 602 /* 603 * sw-only injection allows to write arbitrary values into the MCA 604 * registers because it tests only the decoding paths. 605 */ 606 if (inj_type == SW_INJ) 607 goto inject; 608 609 /* 610 * Read IPID value to determine if a bank is populated on the target 611 * CPU. 612 */ 613 if (cpu_feature_enabled(X86_FEATURE_SMCA)) { 614 u64 ipid; 615 616 if (rdmsrl_on_cpu(m->extcpu, MSR_AMD64_SMCA_MCx_IPID(val), &ipid)) { 617 pr_err("Error reading IPID on CPU%d\n", m->extcpu); 618 return -EINVAL; 619 } 620 621 if (!ipid) { 622 pr_err("Cannot inject into unpopulated bank %llu\n", val); 623 return -ENODEV; 624 } 625 } 626 627 inject: 628 do_inject(); 629 630 /* Reset injection struct */ 631 setup_inj_struct(&i_mce); 632 633 return 0; 634 } 635 636 MCE_INJECT_GET(bank); 637 638 DEFINE_SIMPLE_ATTRIBUTE(bank_fops, inj_bank_get, inj_bank_set, "%llu\n"); 639 640 static const char readme_msg[] = 641 "Description of the files and their usages:\n" 642 "\n" 643 "Note1: i refers to the bank number below.\n" 644 "Note2: See respective BKDGs for the exact bit definitions of the files below\n" 645 "as they mirror the hardware registers.\n" 646 "\n" 647 "status:\t Set MCi_STATUS: the bits in that MSR control the error type and\n" 648 "\t attributes of the error which caused the MCE.\n" 649 "\n" 650 "misc:\t Set MCi_MISC: provide auxiliary info about the error. It is mostly\n" 651 "\t used for error thresholding purposes and its validity is indicated by\n" 652 "\t MCi_STATUS[MiscV].\n" 653 "\n" 654 "synd:\t Set MCi_SYND: provide syndrome info about the error. Only valid on\n" 655 "\t Scalable MCA systems, and its validity is indicated by MCi_STATUS[SyndV].\n" 656 "\n" 657 "addr:\t Error address value to be written to MCi_ADDR. Log address information\n" 658 "\t associated with the error.\n" 659 "\n" 660 "cpu:\t The CPU to inject the error on.\n" 661 "\n" 662 "bank:\t Specify the bank you want to inject the error into: the number of\n" 663 "\t banks in a processor varies and is family/model-specific, therefore, the\n" 664 "\t supplied value is sanity-checked. Setting the bank value also triggers the\n" 665 "\t injection.\n" 666 "\n" 667 "flags:\t Injection type to be performed. Writing to this file will trigger a\n" 668 "\t real machine check, an APIC interrupt or invoke the error decoder routines\n" 669 "\t for AMD processors.\n" 670 "\n" 671 "\t Allowed error injection types:\n" 672 "\t - \"sw\": Software error injection. Decode error to a human-readable \n" 673 "\t format only. Safe to use.\n" 674 "\t - \"hw\": Hardware error injection. Causes the #MC exception handler to \n" 675 "\t handle the error. Be warned: might cause system panic if MCi_STATUS[PCC] \n" 676 "\t is set. Therefore, consider setting (debugfs_mountpoint)/mce/fake_panic \n" 677 "\t before injecting.\n" 678 "\t - \"df\": Trigger APIC interrupt for Deferred error. Causes deferred \n" 679 "\t error APIC interrupt handler to handle the error if the feature is \n" 680 "\t is present in hardware. \n" 681 "\t - \"th\": Trigger APIC interrupt for Threshold errors. Causes threshold \n" 682 "\t APIC interrupt handler to handle the error. \n" 683 "\n" 684 "ipid:\t IPID (AMD-specific)\n" 685 "\n"; 686 687 static ssize_t 688 inj_readme_read(struct file *filp, char __user *ubuf, 689 size_t cnt, loff_t *ppos) 690 { 691 return simple_read_from_buffer(ubuf, cnt, ppos, 692 readme_msg, strlen(readme_msg)); 693 } 694 695 static const struct file_operations readme_fops = { 696 .read = inj_readme_read, 697 }; 698 699 static struct dfs_node { 700 char *name; 701 const struct file_operations *fops; 702 umode_t perm; 703 } dfs_fls[] = { 704 { .name = "status", .fops = &status_fops, .perm = S_IRUSR | S_IWUSR }, 705 { .name = "misc", .fops = &misc_fops, .perm = S_IRUSR | S_IWUSR }, 706 { .name = "addr", .fops = &addr_fops, .perm = S_IRUSR | S_IWUSR }, 707 { .name = "synd", .fops = &synd_fops, .perm = S_IRUSR | S_IWUSR }, 708 { .name = "ipid", .fops = &ipid_fops, .perm = S_IRUSR | S_IWUSR }, 709 { .name = "bank", .fops = &bank_fops, .perm = S_IRUSR | S_IWUSR }, 710 { .name = "flags", .fops = &flags_fops, .perm = S_IRUSR | S_IWUSR }, 711 { .name = "cpu", .fops = &extcpu_fops, .perm = S_IRUSR | S_IWUSR }, 712 { .name = "README", .fops = &readme_fops, .perm = S_IRUSR | S_IRGRP | S_IROTH }, 713 }; 714 715 static void __init debugfs_init(void) 716 { 717 unsigned int i; 718 719 dfs_inj = debugfs_create_dir("mce-inject", NULL); 720 721 for (i = 0; i < ARRAY_SIZE(dfs_fls); i++) 722 debugfs_create_file(dfs_fls[i].name, dfs_fls[i].perm, dfs_inj, 723 &i_mce, dfs_fls[i].fops); 724 } 725 726 static void check_hw_inj_possible(void) 727 { 728 int cpu; 729 u8 bank; 730 731 /* 732 * This behavior exists only on SMCA systems though its not directly 733 * related to SMCA. 734 */ 735 if (!cpu_feature_enabled(X86_FEATURE_SMCA)) 736 return; 737 738 cpu = get_cpu(); 739 740 for (bank = 0; bank < MAX_NR_BANKS; ++bank) { 741 u64 status = MCI_STATUS_VAL, ipid; 742 743 /* Check whether bank is populated */ 744 rdmsrl(MSR_AMD64_SMCA_MCx_IPID(bank), ipid); 745 if (!ipid) 746 continue; 747 748 toggle_hw_mce_inject(cpu, true); 749 750 wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), status); 751 rdmsrl_safe(mca_msr_reg(bank, MCA_STATUS), &status); 752 wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), 0); 753 754 if (!status) { 755 hw_injection_possible = false; 756 pr_warn("Platform does not allow *hardware* error injection." 757 "Try using APEI EINJ instead.\n"); 758 } 759 760 toggle_hw_mce_inject(cpu, false); 761 762 break; 763 } 764 765 put_cpu(); 766 } 767 768 static int __init inject_init(void) 769 { 770 if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) 771 return -ENOMEM; 772 773 check_hw_inj_possible(); 774 775 debugfs_init(); 776 777 register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, "mce_notify"); 778 mce_register_injector_chain(&inject_nb); 779 780 setup_inj_struct(&i_mce); 781 782 pr_info("Machine check injector initialized\n"); 783 784 return 0; 785 } 786 787 static void __exit inject_exit(void) 788 { 789 790 mce_unregister_injector_chain(&inject_nb); 791 unregister_nmi_handler(NMI_LOCAL, "mce_notify"); 792 793 debugfs_remove_recursive(dfs_inj); 794 dfs_inj = NULL; 795 796 memset(&dfs_fls, 0, sizeof(dfs_fls)); 797 798 free_cpumask_var(mce_inject_cpumask); 799 } 800 801 module_init(inject_init); 802 module_exit(inject_exit); 803 MODULE_DESCRIPTION("Machine check injection support"); 804 MODULE_LICENSE("GPL"); 805