1 /* 2 * APEI Error INJection support 3 * 4 * EINJ provides a hardware error injection mechanism, this is useful 5 * for debugging and testing of other APEI and RAS features. 6 * 7 * For more information about EINJ, please refer to ACPI Specification 8 * version 4.0, section 17.5. 9 * 10 * Copyright 2009-2010 Intel Corp. 11 * Author: Huang Ying <ying.huang@intel.com> 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License version 15 * 2 as published by the Free Software Foundation. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 */ 26 27 #include <linux/kernel.h> 28 #include <linux/module.h> 29 #include <linux/init.h> 30 #include <linux/io.h> 31 #include <linux/debugfs.h> 32 #include <linux/seq_file.h> 33 #include <linux/nmi.h> 34 #include <linux/delay.h> 35 #include <acpi/acpi.h> 36 37 #include "apei-internal.h" 38 39 #define EINJ_PFX "EINJ: " 40 41 #define SPIN_UNIT 100 /* 100ns */ 42 /* Firmware should respond within 1 milliseconds */ 43 #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) 44 45 /* 46 * ACPI version 5 provides a SET_ERROR_TYPE_WITH_ADDRESS action. 47 */ 48 static int acpi5; 49 50 struct set_error_type_with_address { 51 u32 type; 52 u32 vendor_extension; 53 u32 flags; 54 u32 apicid; 55 u64 memory_address; 56 u64 memory_address_range; 57 u32 pcie_sbdf; 58 }; 59 enum { 60 SETWA_FLAGS_APICID = 1, 61 SETWA_FLAGS_MEM = 2, 62 SETWA_FLAGS_PCIE_SBDF = 4, 63 }; 64 65 /* 66 * Vendor extensions for platform specific operations 67 */ 68 struct vendor_error_type_extension { 69 u32 length; 70 u32 pcie_sbdf; 71 u16 vendor_id; 72 u16 device_id; 73 u8 rev_id; 74 u8 reserved[3]; 75 }; 76 77 static u32 vendor_flags; 78 static struct debugfs_blob_wrapper vendor_blob; 79 static char vendor_dev[64]; 80 81 /* 82 * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the 83 * EINJ table through an unpublished extension. Use with caution as 84 * most will ignore the parameter and make their own choice of address 85 * for error injection. This extension is used only if 86 * param_extension module parameter is specified. 87 */ 88 struct einj_parameter { 89 u64 type; 90 u64 reserved1; 91 u64 reserved2; 92 u64 param1; 93 u64 param2; 94 }; 95 96 #define EINJ_OP_BUSY 0x1 97 #define EINJ_STATUS_SUCCESS 0x0 98 #define EINJ_STATUS_FAIL 0x1 99 #define EINJ_STATUS_INVAL 0x2 100 101 #define EINJ_TAB_ENTRY(tab) \ 102 ((struct acpi_whea_header *)((char *)(tab) + \ 103 sizeof(struct acpi_table_einj))) 104 105 static bool param_extension; 106 module_param(param_extension, bool, 0); 107 108 static struct acpi_table_einj *einj_tab; 109 110 static struct apei_resources einj_resources; 111 112 static struct apei_exec_ins_type einj_ins_type[] = { 113 [ACPI_EINJ_READ_REGISTER] = { 114 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 115 .run = apei_exec_read_register, 116 }, 117 [ACPI_EINJ_READ_REGISTER_VALUE] = { 118 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 119 .run = apei_exec_read_register_value, 120 }, 121 [ACPI_EINJ_WRITE_REGISTER] = { 122 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 123 .run = apei_exec_write_register, 124 }, 125 [ACPI_EINJ_WRITE_REGISTER_VALUE] = { 126 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 127 .run = apei_exec_write_register_value, 128 }, 129 [ACPI_EINJ_NOOP] = { 130 .flags = 0, 131 .run = apei_exec_noop, 132 }, 133 }; 134 135 /* 136 * Prevent EINJ interpreter to run simultaneously, because the 137 * corresponding firmware implementation may not work properly when 138 * invoked simultaneously. 139 */ 140 static DEFINE_MUTEX(einj_mutex); 141 142 static void *einj_param; 143 144 static void einj_exec_ctx_init(struct apei_exec_context *ctx) 145 { 146 apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), 147 EINJ_TAB_ENTRY(einj_tab), einj_tab->entries); 148 } 149 150 static int __einj_get_available_error_type(u32 *type) 151 { 152 struct apei_exec_context ctx; 153 int rc; 154 155 einj_exec_ctx_init(&ctx); 156 rc = apei_exec_run(&ctx, ACPI_EINJ_GET_ERROR_TYPE); 157 if (rc) 158 return rc; 159 *type = apei_exec_ctx_get_output(&ctx); 160 161 return 0; 162 } 163 164 /* Get error injection capabilities of the platform */ 165 static int einj_get_available_error_type(u32 *type) 166 { 167 int rc; 168 169 mutex_lock(&einj_mutex); 170 rc = __einj_get_available_error_type(type); 171 mutex_unlock(&einj_mutex); 172 173 return rc; 174 } 175 176 static int einj_timedout(u64 *t) 177 { 178 if ((s64)*t < SPIN_UNIT) { 179 pr_warning(FW_WARN EINJ_PFX 180 "Firmware does not respond in time\n"); 181 return 1; 182 } 183 *t -= SPIN_UNIT; 184 ndelay(SPIN_UNIT); 185 touch_nmi_watchdog(); 186 return 0; 187 } 188 189 static void check_vendor_extension(u64 paddr, 190 struct set_error_type_with_address *v5param) 191 { 192 int offset = v5param->vendor_extension; 193 struct vendor_error_type_extension *v; 194 u32 sbdf; 195 196 if (!offset) 197 return; 198 v = acpi_os_map_memory(paddr + offset, sizeof(*v)); 199 if (!v) 200 return; 201 sbdf = v->pcie_sbdf; 202 sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n", 203 sbdf >> 24, (sbdf >> 16) & 0xff, 204 (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, 205 v->vendor_id, v->device_id, v->rev_id); 206 acpi_os_unmap_memory(v, sizeof(*v)); 207 } 208 209 static void *einj_get_parameter_address(void) 210 { 211 int i; 212 u64 paddrv4 = 0, paddrv5 = 0; 213 struct acpi_whea_header *entry; 214 215 entry = EINJ_TAB_ENTRY(einj_tab); 216 for (i = 0; i < einj_tab->entries; i++) { 217 if (entry->action == ACPI_EINJ_SET_ERROR_TYPE && 218 entry->instruction == ACPI_EINJ_WRITE_REGISTER && 219 entry->register_region.space_id == 220 ACPI_ADR_SPACE_SYSTEM_MEMORY) 221 memcpy(&paddrv4, &entry->register_region.address, 222 sizeof(paddrv4)); 223 if (entry->action == ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS && 224 entry->instruction == ACPI_EINJ_WRITE_REGISTER && 225 entry->register_region.space_id == 226 ACPI_ADR_SPACE_SYSTEM_MEMORY) 227 memcpy(&paddrv5, &entry->register_region.address, 228 sizeof(paddrv5)); 229 entry++; 230 } 231 if (paddrv5) { 232 struct set_error_type_with_address *v5param; 233 234 v5param = acpi_os_map_memory(paddrv5, sizeof(*v5param)); 235 if (v5param) { 236 acpi5 = 1; 237 check_vendor_extension(paddrv5, v5param); 238 return v5param; 239 } 240 } 241 if (paddrv4) { 242 struct einj_parameter *v4param; 243 244 v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param)); 245 if (!v4param) 246 return NULL; 247 if (v4param->reserved1 || v4param->reserved2) { 248 acpi_os_unmap_memory(v4param, sizeof(*v4param)); 249 return NULL; 250 } 251 return v4param; 252 } 253 254 return NULL; 255 } 256 257 /* do sanity check to trigger table */ 258 static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab) 259 { 260 if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger)) 261 return -EINVAL; 262 if (trigger_tab->table_size > PAGE_SIZE || 263 trigger_tab->table_size < trigger_tab->header_size) 264 return -EINVAL; 265 if (trigger_tab->entry_count != 266 (trigger_tab->table_size - trigger_tab->header_size) / 267 sizeof(struct acpi_einj_entry)) 268 return -EINVAL; 269 270 return 0; 271 } 272 273 static struct acpi_generic_address *einj_get_trigger_parameter_region( 274 struct acpi_einj_trigger *trigger_tab, u64 param1, u64 param2) 275 { 276 int i; 277 struct acpi_whea_header *entry; 278 279 entry = (struct acpi_whea_header *) 280 ((char *)trigger_tab + sizeof(struct acpi_einj_trigger)); 281 for (i = 0; i < trigger_tab->entry_count; i++) { 282 if (entry->action == ACPI_EINJ_TRIGGER_ERROR && 283 entry->instruction == ACPI_EINJ_WRITE_REGISTER_VALUE && 284 entry->register_region.space_id == 285 ACPI_ADR_SPACE_SYSTEM_MEMORY && 286 (entry->register_region.address & param2) == (param1 & param2)) 287 return &entry->register_region; 288 entry++; 289 } 290 291 return NULL; 292 } 293 /* Execute instructions in trigger error action table */ 294 static int __einj_error_trigger(u64 trigger_paddr, u32 type, 295 u64 param1, u64 param2) 296 { 297 struct acpi_einj_trigger *trigger_tab = NULL; 298 struct apei_exec_context trigger_ctx; 299 struct apei_resources trigger_resources; 300 struct acpi_whea_header *trigger_entry; 301 struct resource *r; 302 u32 table_size; 303 int rc = -EIO; 304 struct acpi_generic_address *trigger_param_region = NULL; 305 306 r = request_mem_region(trigger_paddr, sizeof(*trigger_tab), 307 "APEI EINJ Trigger Table"); 308 if (!r) { 309 pr_err(EINJ_PFX 310 "Can not request [mem %#010llx-%#010llx] for Trigger table\n", 311 (unsigned long long)trigger_paddr, 312 (unsigned long long)trigger_paddr + 313 sizeof(*trigger_tab) - 1); 314 goto out; 315 } 316 trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab)); 317 if (!trigger_tab) { 318 pr_err(EINJ_PFX "Failed to map trigger table!\n"); 319 goto out_rel_header; 320 } 321 rc = einj_check_trigger_header(trigger_tab); 322 if (rc) { 323 pr_warning(FW_BUG EINJ_PFX 324 "The trigger error action table is invalid\n"); 325 goto out_rel_header; 326 } 327 328 /* No action structures in the TRIGGER_ERROR table, nothing to do */ 329 if (!trigger_tab->entry_count) 330 goto out_rel_header; 331 332 rc = -EIO; 333 table_size = trigger_tab->table_size; 334 r = request_mem_region(trigger_paddr + sizeof(*trigger_tab), 335 table_size - sizeof(*trigger_tab), 336 "APEI EINJ Trigger Table"); 337 if (!r) { 338 pr_err(EINJ_PFX 339 "Can not request [mem %#010llx-%#010llx] for Trigger Table Entry\n", 340 (unsigned long long)trigger_paddr + sizeof(*trigger_tab), 341 (unsigned long long)trigger_paddr + table_size - 1); 342 goto out_rel_header; 343 } 344 iounmap(trigger_tab); 345 trigger_tab = ioremap_cache(trigger_paddr, table_size); 346 if (!trigger_tab) { 347 pr_err(EINJ_PFX "Failed to map trigger table!\n"); 348 goto out_rel_entry; 349 } 350 trigger_entry = (struct acpi_whea_header *) 351 ((char *)trigger_tab + sizeof(struct acpi_einj_trigger)); 352 apei_resources_init(&trigger_resources); 353 apei_exec_ctx_init(&trigger_ctx, einj_ins_type, 354 ARRAY_SIZE(einj_ins_type), 355 trigger_entry, trigger_tab->entry_count); 356 rc = apei_exec_collect_resources(&trigger_ctx, &trigger_resources); 357 if (rc) 358 goto out_fini; 359 rc = apei_resources_sub(&trigger_resources, &einj_resources); 360 if (rc) 361 goto out_fini; 362 /* 363 * Some firmware will access target address specified in 364 * param1 to trigger the error when injecting memory error. 365 * This will cause resource conflict with regular memory. So 366 * remove it from trigger table resources. 367 */ 368 if (param_extension && (type & 0x0038) && param2) { 369 struct apei_resources addr_resources; 370 apei_resources_init(&addr_resources); 371 trigger_param_region = einj_get_trigger_parameter_region( 372 trigger_tab, param1, param2); 373 if (trigger_param_region) { 374 rc = apei_resources_add(&addr_resources, 375 trigger_param_region->address, 376 trigger_param_region->bit_width/8, true); 377 if (rc) 378 goto out_fini; 379 rc = apei_resources_sub(&trigger_resources, 380 &addr_resources); 381 } 382 apei_resources_fini(&addr_resources); 383 if (rc) 384 goto out_fini; 385 } 386 rc = apei_resources_request(&trigger_resources, "APEI EINJ Trigger"); 387 if (rc) 388 goto out_fini; 389 rc = apei_exec_pre_map_gars(&trigger_ctx); 390 if (rc) 391 goto out_release; 392 393 rc = apei_exec_run(&trigger_ctx, ACPI_EINJ_TRIGGER_ERROR); 394 395 apei_exec_post_unmap_gars(&trigger_ctx); 396 out_release: 397 apei_resources_release(&trigger_resources); 398 out_fini: 399 apei_resources_fini(&trigger_resources); 400 out_rel_entry: 401 release_mem_region(trigger_paddr + sizeof(*trigger_tab), 402 table_size - sizeof(*trigger_tab)); 403 out_rel_header: 404 release_mem_region(trigger_paddr, sizeof(*trigger_tab)); 405 out: 406 if (trigger_tab) 407 iounmap(trigger_tab); 408 409 return rc; 410 } 411 412 static int __einj_error_inject(u32 type, u64 param1, u64 param2) 413 { 414 struct apei_exec_context ctx; 415 u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT; 416 int rc; 417 418 einj_exec_ctx_init(&ctx); 419 420 rc = apei_exec_run_optional(&ctx, ACPI_EINJ_BEGIN_OPERATION); 421 if (rc) 422 return rc; 423 apei_exec_ctx_set_input(&ctx, type); 424 if (acpi5) { 425 struct set_error_type_with_address *v5param = einj_param; 426 427 v5param->type = type; 428 if (type & 0x80000000) { 429 switch (vendor_flags) { 430 case SETWA_FLAGS_APICID: 431 v5param->apicid = param1; 432 break; 433 case SETWA_FLAGS_MEM: 434 v5param->memory_address = param1; 435 v5param->memory_address_range = param2; 436 break; 437 case SETWA_FLAGS_PCIE_SBDF: 438 v5param->pcie_sbdf = param1; 439 break; 440 } 441 v5param->flags = vendor_flags; 442 } else { 443 switch (type) { 444 case ACPI_EINJ_PROCESSOR_CORRECTABLE: 445 case ACPI_EINJ_PROCESSOR_UNCORRECTABLE: 446 case ACPI_EINJ_PROCESSOR_FATAL: 447 v5param->apicid = param1; 448 v5param->flags = SETWA_FLAGS_APICID; 449 break; 450 case ACPI_EINJ_MEMORY_CORRECTABLE: 451 case ACPI_EINJ_MEMORY_UNCORRECTABLE: 452 case ACPI_EINJ_MEMORY_FATAL: 453 v5param->memory_address = param1; 454 v5param->memory_address_range = param2; 455 v5param->flags = SETWA_FLAGS_MEM; 456 break; 457 case ACPI_EINJ_PCIX_CORRECTABLE: 458 case ACPI_EINJ_PCIX_UNCORRECTABLE: 459 case ACPI_EINJ_PCIX_FATAL: 460 v5param->pcie_sbdf = param1; 461 v5param->flags = SETWA_FLAGS_PCIE_SBDF; 462 break; 463 } 464 } 465 } else { 466 rc = apei_exec_run(&ctx, ACPI_EINJ_SET_ERROR_TYPE); 467 if (rc) 468 return rc; 469 if (einj_param) { 470 struct einj_parameter *v4param = einj_param; 471 v4param->param1 = param1; 472 v4param->param2 = param2; 473 } 474 } 475 rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION); 476 if (rc) 477 return rc; 478 for (;;) { 479 rc = apei_exec_run(&ctx, ACPI_EINJ_CHECK_BUSY_STATUS); 480 if (rc) 481 return rc; 482 val = apei_exec_ctx_get_output(&ctx); 483 if (!(val & EINJ_OP_BUSY)) 484 break; 485 if (einj_timedout(&timeout)) 486 return -EIO; 487 } 488 rc = apei_exec_run(&ctx, ACPI_EINJ_GET_COMMAND_STATUS); 489 if (rc) 490 return rc; 491 val = apei_exec_ctx_get_output(&ctx); 492 if (val != EINJ_STATUS_SUCCESS) 493 return -EBUSY; 494 495 rc = apei_exec_run(&ctx, ACPI_EINJ_GET_TRIGGER_TABLE); 496 if (rc) 497 return rc; 498 trigger_paddr = apei_exec_ctx_get_output(&ctx); 499 rc = __einj_error_trigger(trigger_paddr, type, param1, param2); 500 if (rc) 501 return rc; 502 rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION); 503 504 return rc; 505 } 506 507 /* Inject the specified hardware error */ 508 static int einj_error_inject(u32 type, u64 param1, u64 param2) 509 { 510 int rc; 511 512 mutex_lock(&einj_mutex); 513 rc = __einj_error_inject(type, param1, param2); 514 mutex_unlock(&einj_mutex); 515 516 return rc; 517 } 518 519 static u32 error_type; 520 static u64 error_param1; 521 static u64 error_param2; 522 static struct dentry *einj_debug_dir; 523 524 static int available_error_type_show(struct seq_file *m, void *v) 525 { 526 int rc; 527 u32 available_error_type = 0; 528 529 rc = einj_get_available_error_type(&available_error_type); 530 if (rc) 531 return rc; 532 if (available_error_type & 0x0001) 533 seq_printf(m, "0x00000001\tProcessor Correctable\n"); 534 if (available_error_type & 0x0002) 535 seq_printf(m, "0x00000002\tProcessor Uncorrectable non-fatal\n"); 536 if (available_error_type & 0x0004) 537 seq_printf(m, "0x00000004\tProcessor Uncorrectable fatal\n"); 538 if (available_error_type & 0x0008) 539 seq_printf(m, "0x00000008\tMemory Correctable\n"); 540 if (available_error_type & 0x0010) 541 seq_printf(m, "0x00000010\tMemory Uncorrectable non-fatal\n"); 542 if (available_error_type & 0x0020) 543 seq_printf(m, "0x00000020\tMemory Uncorrectable fatal\n"); 544 if (available_error_type & 0x0040) 545 seq_printf(m, "0x00000040\tPCI Express Correctable\n"); 546 if (available_error_type & 0x0080) 547 seq_printf(m, "0x00000080\tPCI Express Uncorrectable non-fatal\n"); 548 if (available_error_type & 0x0100) 549 seq_printf(m, "0x00000100\tPCI Express Uncorrectable fatal\n"); 550 if (available_error_type & 0x0200) 551 seq_printf(m, "0x00000200\tPlatform Correctable\n"); 552 if (available_error_type & 0x0400) 553 seq_printf(m, "0x00000400\tPlatform Uncorrectable non-fatal\n"); 554 if (available_error_type & 0x0800) 555 seq_printf(m, "0x00000800\tPlatform Uncorrectable fatal\n"); 556 557 return 0; 558 } 559 560 static int available_error_type_open(struct inode *inode, struct file *file) 561 { 562 return single_open(file, available_error_type_show, NULL); 563 } 564 565 static const struct file_operations available_error_type_fops = { 566 .open = available_error_type_open, 567 .read = seq_read, 568 .llseek = seq_lseek, 569 .release = single_release, 570 }; 571 572 static int error_type_get(void *data, u64 *val) 573 { 574 *val = error_type; 575 576 return 0; 577 } 578 579 static int error_type_set(void *data, u64 val) 580 { 581 int rc; 582 u32 available_error_type = 0; 583 u32 tval, vendor; 584 585 /* 586 * Vendor defined types have 0x80000000 bit set, and 587 * are not enumerated by ACPI_EINJ_GET_ERROR_TYPE 588 */ 589 vendor = val & 0x80000000; 590 tval = val & 0x7fffffff; 591 592 /* Only one error type can be specified */ 593 if (tval & (tval - 1)) 594 return -EINVAL; 595 if (!vendor) { 596 rc = einj_get_available_error_type(&available_error_type); 597 if (rc) 598 return rc; 599 if (!(val & available_error_type)) 600 return -EINVAL; 601 } 602 error_type = val; 603 604 return 0; 605 } 606 607 DEFINE_SIMPLE_ATTRIBUTE(error_type_fops, error_type_get, 608 error_type_set, "0x%llx\n"); 609 610 static int error_inject_set(void *data, u64 val) 611 { 612 if (!error_type) 613 return -EINVAL; 614 615 return einj_error_inject(error_type, error_param1, error_param2); 616 } 617 618 DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL, 619 error_inject_set, "%llu\n"); 620 621 static int einj_check_table(struct acpi_table_einj *einj_tab) 622 { 623 if ((einj_tab->header_length != 624 (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header))) 625 && (einj_tab->header_length != sizeof(struct acpi_table_einj))) 626 return -EINVAL; 627 if (einj_tab->header.length < sizeof(struct acpi_table_einj)) 628 return -EINVAL; 629 if (einj_tab->entries != 630 (einj_tab->header.length - sizeof(struct acpi_table_einj)) / 631 sizeof(struct acpi_einj_entry)) 632 return -EINVAL; 633 634 return 0; 635 } 636 637 static int __init einj_init(void) 638 { 639 int rc; 640 acpi_status status; 641 struct dentry *fentry; 642 struct apei_exec_context ctx; 643 644 if (acpi_disabled) 645 return -ENODEV; 646 647 status = acpi_get_table(ACPI_SIG_EINJ, 0, 648 (struct acpi_table_header **)&einj_tab); 649 if (status == AE_NOT_FOUND) 650 return -ENODEV; 651 else if (ACPI_FAILURE(status)) { 652 const char *msg = acpi_format_exception(status); 653 pr_err(EINJ_PFX "Failed to get table, %s\n", msg); 654 return -EINVAL; 655 } 656 657 rc = einj_check_table(einj_tab); 658 if (rc) { 659 pr_warning(FW_BUG EINJ_PFX "EINJ table is invalid\n"); 660 return -EINVAL; 661 } 662 663 rc = -ENOMEM; 664 einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir()); 665 if (!einj_debug_dir) 666 goto err_cleanup; 667 fentry = debugfs_create_file("available_error_type", S_IRUSR, 668 einj_debug_dir, NULL, 669 &available_error_type_fops); 670 if (!fentry) 671 goto err_cleanup; 672 fentry = debugfs_create_file("error_type", S_IRUSR | S_IWUSR, 673 einj_debug_dir, NULL, &error_type_fops); 674 if (!fentry) 675 goto err_cleanup; 676 fentry = debugfs_create_file("error_inject", S_IWUSR, 677 einj_debug_dir, NULL, &error_inject_fops); 678 if (!fentry) 679 goto err_cleanup; 680 681 apei_resources_init(&einj_resources); 682 einj_exec_ctx_init(&ctx); 683 rc = apei_exec_collect_resources(&ctx, &einj_resources); 684 if (rc) 685 goto err_fini; 686 rc = apei_resources_request(&einj_resources, "APEI EINJ"); 687 if (rc) 688 goto err_fini; 689 rc = apei_exec_pre_map_gars(&ctx); 690 if (rc) 691 goto err_release; 692 693 einj_param = einj_get_parameter_address(); 694 if ((param_extension || acpi5) && einj_param) { 695 fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR, 696 einj_debug_dir, &error_param1); 697 if (!fentry) 698 goto err_unmap; 699 fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR, 700 einj_debug_dir, &error_param2); 701 if (!fentry) 702 goto err_unmap; 703 } 704 705 if (vendor_dev[0]) { 706 vendor_blob.data = vendor_dev; 707 vendor_blob.size = strlen(vendor_dev); 708 fentry = debugfs_create_blob("vendor", S_IRUSR, 709 einj_debug_dir, &vendor_blob); 710 if (!fentry) 711 goto err_unmap; 712 fentry = debugfs_create_x32("vendor_flags", S_IRUSR | S_IWUSR, 713 einj_debug_dir, &vendor_flags); 714 if (!fentry) 715 goto err_unmap; 716 } 717 718 pr_info(EINJ_PFX "Error INJection is initialized.\n"); 719 720 return 0; 721 722 err_unmap: 723 if (einj_param) { 724 acpi_size size = (acpi5) ? 725 sizeof(struct set_error_type_with_address) : 726 sizeof(struct einj_parameter); 727 728 acpi_os_unmap_memory(einj_param, size); 729 } 730 apei_exec_post_unmap_gars(&ctx); 731 err_release: 732 apei_resources_release(&einj_resources); 733 err_fini: 734 apei_resources_fini(&einj_resources); 735 err_cleanup: 736 debugfs_remove_recursive(einj_debug_dir); 737 738 return rc; 739 } 740 741 static void __exit einj_exit(void) 742 { 743 struct apei_exec_context ctx; 744 745 if (einj_param) { 746 acpi_size size = (acpi5) ? 747 sizeof(struct set_error_type_with_address) : 748 sizeof(struct einj_parameter); 749 750 acpi_os_unmap_memory(einj_param, size); 751 } 752 einj_exec_ctx_init(&ctx); 753 apei_exec_post_unmap_gars(&ctx); 754 apei_resources_release(&einj_resources); 755 apei_resources_fini(&einj_resources); 756 debugfs_remove_recursive(einj_debug_dir); 757 } 758 759 module_init(einj_init); 760 module_exit(einj_exit); 761 762 MODULE_AUTHOR("Huang Ying"); 763 MODULE_DESCRIPTION("APEI Error INJection support"); 764 MODULE_LICENSE("GPL"); 765