1 /* 2 * APEI Error Record Serialization Table support 3 * 4 * ERST is a way provided by APEI to save and retrieve hardware error 5 * information to and from a persistent store. 6 * 7 * For more information about ERST, please refer to ACPI Specification 8 * version 4.0, section 17.4. 9 * 10 * Copyright 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/delay.h> 31 #include <linux/io.h> 32 #include <linux/acpi.h> 33 #include <linux/uaccess.h> 34 #include <linux/cper.h> 35 #include <linux/nmi.h> 36 #include <linux/hardirq.h> 37 #include <linux/pstore.h> 38 #include <acpi/apei.h> 39 40 #include "apei-internal.h" 41 42 #define ERST_PFX "ERST: " 43 44 /* ERST command status */ 45 #define ERST_STATUS_SUCCESS 0x0 46 #define ERST_STATUS_NOT_ENOUGH_SPACE 0x1 47 #define ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x2 48 #define ERST_STATUS_FAILED 0x3 49 #define ERST_STATUS_RECORD_STORE_EMPTY 0x4 50 #define ERST_STATUS_RECORD_NOT_FOUND 0x5 51 52 #define ERST_TAB_ENTRY(tab) \ 53 ((struct acpi_whea_header *)((char *)(tab) + \ 54 sizeof(struct acpi_table_erst))) 55 56 #define SPIN_UNIT 100 /* 100ns */ 57 /* Firmware should respond within 1 milliseconds */ 58 #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) 59 #define FIRMWARE_MAX_STALL 50 /* 50us */ 60 61 int erst_disable; 62 EXPORT_SYMBOL_GPL(erst_disable); 63 64 static struct acpi_table_erst *erst_tab; 65 66 /* ERST Error Log Address Range atrributes */ 67 #define ERST_RANGE_RESERVED 0x0001 68 #define ERST_RANGE_NVRAM 0x0002 69 #define ERST_RANGE_SLOW 0x0004 70 71 /* 72 * ERST Error Log Address Range, used as buffer for reading/writing 73 * error records. 74 */ 75 static struct erst_erange { 76 u64 base; 77 u64 size; 78 void __iomem *vaddr; 79 u32 attr; 80 } erst_erange; 81 82 /* 83 * Prevent ERST interpreter to run simultaneously, because the 84 * corresponding firmware implementation may not work properly when 85 * invoked simultaneously. 86 * 87 * It is used to provide exclusive accessing for ERST Error Log 88 * Address Range too. 89 */ 90 static DEFINE_RAW_SPINLOCK(erst_lock); 91 92 static inline int erst_errno(int command_status) 93 { 94 switch (command_status) { 95 case ERST_STATUS_SUCCESS: 96 return 0; 97 case ERST_STATUS_HARDWARE_NOT_AVAILABLE: 98 return -ENODEV; 99 case ERST_STATUS_NOT_ENOUGH_SPACE: 100 return -ENOSPC; 101 case ERST_STATUS_RECORD_STORE_EMPTY: 102 case ERST_STATUS_RECORD_NOT_FOUND: 103 return -ENOENT; 104 default: 105 return -EINVAL; 106 } 107 } 108 109 static int erst_timedout(u64 *t, u64 spin_unit) 110 { 111 if ((s64)*t < spin_unit) { 112 pr_warning(FW_WARN ERST_PFX 113 "Firmware does not respond in time\n"); 114 return 1; 115 } 116 *t -= spin_unit; 117 ndelay(spin_unit); 118 touch_nmi_watchdog(); 119 return 0; 120 } 121 122 static int erst_exec_load_var1(struct apei_exec_context *ctx, 123 struct acpi_whea_header *entry) 124 { 125 return __apei_exec_read_register(entry, &ctx->var1); 126 } 127 128 static int erst_exec_load_var2(struct apei_exec_context *ctx, 129 struct acpi_whea_header *entry) 130 { 131 return __apei_exec_read_register(entry, &ctx->var2); 132 } 133 134 static int erst_exec_store_var1(struct apei_exec_context *ctx, 135 struct acpi_whea_header *entry) 136 { 137 return __apei_exec_write_register(entry, ctx->var1); 138 } 139 140 static int erst_exec_add(struct apei_exec_context *ctx, 141 struct acpi_whea_header *entry) 142 { 143 ctx->var1 += ctx->var2; 144 return 0; 145 } 146 147 static int erst_exec_subtract(struct apei_exec_context *ctx, 148 struct acpi_whea_header *entry) 149 { 150 ctx->var1 -= ctx->var2; 151 return 0; 152 } 153 154 static int erst_exec_add_value(struct apei_exec_context *ctx, 155 struct acpi_whea_header *entry) 156 { 157 int rc; 158 u64 val; 159 160 rc = __apei_exec_read_register(entry, &val); 161 if (rc) 162 return rc; 163 val += ctx->value; 164 rc = __apei_exec_write_register(entry, val); 165 return rc; 166 } 167 168 static int erst_exec_subtract_value(struct apei_exec_context *ctx, 169 struct acpi_whea_header *entry) 170 { 171 int rc; 172 u64 val; 173 174 rc = __apei_exec_read_register(entry, &val); 175 if (rc) 176 return rc; 177 val -= ctx->value; 178 rc = __apei_exec_write_register(entry, val); 179 return rc; 180 } 181 182 static int erst_exec_stall(struct apei_exec_context *ctx, 183 struct acpi_whea_header *entry) 184 { 185 u64 stall_time; 186 187 if (ctx->value > FIRMWARE_MAX_STALL) { 188 if (!in_nmi()) 189 pr_warning(FW_WARN ERST_PFX 190 "Too long stall time for stall instruction: %llx.\n", 191 ctx->value); 192 stall_time = FIRMWARE_MAX_STALL; 193 } else 194 stall_time = ctx->value; 195 udelay(stall_time); 196 return 0; 197 } 198 199 static int erst_exec_stall_while_true(struct apei_exec_context *ctx, 200 struct acpi_whea_header *entry) 201 { 202 int rc; 203 u64 val; 204 u64 timeout = FIRMWARE_TIMEOUT; 205 u64 stall_time; 206 207 if (ctx->var1 > FIRMWARE_MAX_STALL) { 208 if (!in_nmi()) 209 pr_warning(FW_WARN ERST_PFX 210 "Too long stall time for stall while true instruction: %llx.\n", 211 ctx->var1); 212 stall_time = FIRMWARE_MAX_STALL; 213 } else 214 stall_time = ctx->var1; 215 216 for (;;) { 217 rc = __apei_exec_read_register(entry, &val); 218 if (rc) 219 return rc; 220 if (val != ctx->value) 221 break; 222 if (erst_timedout(&timeout, stall_time * NSEC_PER_USEC)) 223 return -EIO; 224 } 225 return 0; 226 } 227 228 static int erst_exec_skip_next_instruction_if_true( 229 struct apei_exec_context *ctx, 230 struct acpi_whea_header *entry) 231 { 232 int rc; 233 u64 val; 234 235 rc = __apei_exec_read_register(entry, &val); 236 if (rc) 237 return rc; 238 if (val == ctx->value) { 239 ctx->ip += 2; 240 return APEI_EXEC_SET_IP; 241 } 242 243 return 0; 244 } 245 246 static int erst_exec_goto(struct apei_exec_context *ctx, 247 struct acpi_whea_header *entry) 248 { 249 ctx->ip = ctx->value; 250 return APEI_EXEC_SET_IP; 251 } 252 253 static int erst_exec_set_src_address_base(struct apei_exec_context *ctx, 254 struct acpi_whea_header *entry) 255 { 256 return __apei_exec_read_register(entry, &ctx->src_base); 257 } 258 259 static int erst_exec_set_dst_address_base(struct apei_exec_context *ctx, 260 struct acpi_whea_header *entry) 261 { 262 return __apei_exec_read_register(entry, &ctx->dst_base); 263 } 264 265 static int erst_exec_move_data(struct apei_exec_context *ctx, 266 struct acpi_whea_header *entry) 267 { 268 int rc; 269 u64 offset; 270 void *src, *dst; 271 272 /* ioremap does not work in interrupt context */ 273 if (in_interrupt()) { 274 pr_warning(ERST_PFX 275 "MOVE_DATA can not be used in interrupt context"); 276 return -EBUSY; 277 } 278 279 rc = __apei_exec_read_register(entry, &offset); 280 if (rc) 281 return rc; 282 283 src = ioremap(ctx->src_base + offset, ctx->var2); 284 if (!src) 285 return -ENOMEM; 286 dst = ioremap(ctx->dst_base + offset, ctx->var2); 287 if (!dst) 288 return -ENOMEM; 289 290 memmove(dst, src, ctx->var2); 291 292 iounmap(src); 293 iounmap(dst); 294 295 return 0; 296 } 297 298 static struct apei_exec_ins_type erst_ins_type[] = { 299 [ACPI_ERST_READ_REGISTER] = { 300 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 301 .run = apei_exec_read_register, 302 }, 303 [ACPI_ERST_READ_REGISTER_VALUE] = { 304 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 305 .run = apei_exec_read_register_value, 306 }, 307 [ACPI_ERST_WRITE_REGISTER] = { 308 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 309 .run = apei_exec_write_register, 310 }, 311 [ACPI_ERST_WRITE_REGISTER_VALUE] = { 312 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 313 .run = apei_exec_write_register_value, 314 }, 315 [ACPI_ERST_NOOP] = { 316 .flags = 0, 317 .run = apei_exec_noop, 318 }, 319 [ACPI_ERST_LOAD_VAR1] = { 320 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 321 .run = erst_exec_load_var1, 322 }, 323 [ACPI_ERST_LOAD_VAR2] = { 324 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 325 .run = erst_exec_load_var2, 326 }, 327 [ACPI_ERST_STORE_VAR1] = { 328 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 329 .run = erst_exec_store_var1, 330 }, 331 [ACPI_ERST_ADD] = { 332 .flags = 0, 333 .run = erst_exec_add, 334 }, 335 [ACPI_ERST_SUBTRACT] = { 336 .flags = 0, 337 .run = erst_exec_subtract, 338 }, 339 [ACPI_ERST_ADD_VALUE] = { 340 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 341 .run = erst_exec_add_value, 342 }, 343 [ACPI_ERST_SUBTRACT_VALUE] = { 344 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 345 .run = erst_exec_subtract_value, 346 }, 347 [ACPI_ERST_STALL] = { 348 .flags = 0, 349 .run = erst_exec_stall, 350 }, 351 [ACPI_ERST_STALL_WHILE_TRUE] = { 352 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 353 .run = erst_exec_stall_while_true, 354 }, 355 [ACPI_ERST_SKIP_NEXT_IF_TRUE] = { 356 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 357 .run = erst_exec_skip_next_instruction_if_true, 358 }, 359 [ACPI_ERST_GOTO] = { 360 .flags = 0, 361 .run = erst_exec_goto, 362 }, 363 [ACPI_ERST_SET_SRC_ADDRESS_BASE] = { 364 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 365 .run = erst_exec_set_src_address_base, 366 }, 367 [ACPI_ERST_SET_DST_ADDRESS_BASE] = { 368 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 369 .run = erst_exec_set_dst_address_base, 370 }, 371 [ACPI_ERST_MOVE_DATA] = { 372 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 373 .run = erst_exec_move_data, 374 }, 375 }; 376 377 static inline void erst_exec_ctx_init(struct apei_exec_context *ctx) 378 { 379 apei_exec_ctx_init(ctx, erst_ins_type, ARRAY_SIZE(erst_ins_type), 380 ERST_TAB_ENTRY(erst_tab), erst_tab->entries); 381 } 382 383 static int erst_get_erange(struct erst_erange *range) 384 { 385 struct apei_exec_context ctx; 386 int rc; 387 388 erst_exec_ctx_init(&ctx); 389 rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_RANGE); 390 if (rc) 391 return rc; 392 range->base = apei_exec_ctx_get_output(&ctx); 393 rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_LENGTH); 394 if (rc) 395 return rc; 396 range->size = apei_exec_ctx_get_output(&ctx); 397 rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_ATTRIBUTES); 398 if (rc) 399 return rc; 400 range->attr = apei_exec_ctx_get_output(&ctx); 401 402 return 0; 403 } 404 405 static ssize_t __erst_get_record_count(void) 406 { 407 struct apei_exec_context ctx; 408 int rc; 409 410 erst_exec_ctx_init(&ctx); 411 rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_COUNT); 412 if (rc) 413 return rc; 414 return apei_exec_ctx_get_output(&ctx); 415 } 416 417 ssize_t erst_get_record_count(void) 418 { 419 ssize_t count; 420 unsigned long flags; 421 422 if (erst_disable) 423 return -ENODEV; 424 425 raw_spin_lock_irqsave(&erst_lock, flags); 426 count = __erst_get_record_count(); 427 raw_spin_unlock_irqrestore(&erst_lock, flags); 428 429 return count; 430 } 431 EXPORT_SYMBOL_GPL(erst_get_record_count); 432 433 static int __erst_get_next_record_id(u64 *record_id) 434 { 435 struct apei_exec_context ctx; 436 int rc; 437 438 erst_exec_ctx_init(&ctx); 439 rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_ID); 440 if (rc) 441 return rc; 442 *record_id = apei_exec_ctx_get_output(&ctx); 443 444 return 0; 445 } 446 447 /* 448 * Get the record ID of an existing error record on the persistent 449 * storage. If there is no error record on the persistent storage, the 450 * returned record_id is APEI_ERST_INVALID_RECORD_ID. 451 */ 452 int erst_get_next_record_id(u64 *record_id) 453 { 454 int rc; 455 unsigned long flags; 456 457 if (erst_disable) 458 return -ENODEV; 459 460 raw_spin_lock_irqsave(&erst_lock, flags); 461 rc = __erst_get_next_record_id(record_id); 462 raw_spin_unlock_irqrestore(&erst_lock, flags); 463 464 return rc; 465 } 466 EXPORT_SYMBOL_GPL(erst_get_next_record_id); 467 468 static int __erst_write_to_storage(u64 offset) 469 { 470 struct apei_exec_context ctx; 471 u64 timeout = FIRMWARE_TIMEOUT; 472 u64 val; 473 int rc; 474 475 erst_exec_ctx_init(&ctx); 476 rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_WRITE); 477 if (rc) 478 return rc; 479 apei_exec_ctx_set_input(&ctx, offset); 480 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); 481 if (rc) 482 return rc; 483 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); 484 if (rc) 485 return rc; 486 for (;;) { 487 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); 488 if (rc) 489 return rc; 490 val = apei_exec_ctx_get_output(&ctx); 491 if (!val) 492 break; 493 if (erst_timedout(&timeout, SPIN_UNIT)) 494 return -EIO; 495 } 496 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); 497 if (rc) 498 return rc; 499 val = apei_exec_ctx_get_output(&ctx); 500 rc = apei_exec_run(&ctx, ACPI_ERST_END); 501 if (rc) 502 return rc; 503 504 return erst_errno(val); 505 } 506 507 static int __erst_read_from_storage(u64 record_id, u64 offset) 508 { 509 struct apei_exec_context ctx; 510 u64 timeout = FIRMWARE_TIMEOUT; 511 u64 val; 512 int rc; 513 514 erst_exec_ctx_init(&ctx); 515 rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_READ); 516 if (rc) 517 return rc; 518 apei_exec_ctx_set_input(&ctx, offset); 519 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); 520 if (rc) 521 return rc; 522 apei_exec_ctx_set_input(&ctx, record_id); 523 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); 524 if (rc) 525 return rc; 526 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); 527 if (rc) 528 return rc; 529 for (;;) { 530 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); 531 if (rc) 532 return rc; 533 val = apei_exec_ctx_get_output(&ctx); 534 if (!val) 535 break; 536 if (erst_timedout(&timeout, SPIN_UNIT)) 537 return -EIO; 538 }; 539 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); 540 if (rc) 541 return rc; 542 val = apei_exec_ctx_get_output(&ctx); 543 rc = apei_exec_run(&ctx, ACPI_ERST_END); 544 if (rc) 545 return rc; 546 547 return erst_errno(val); 548 } 549 550 static int __erst_clear_from_storage(u64 record_id) 551 { 552 struct apei_exec_context ctx; 553 u64 timeout = FIRMWARE_TIMEOUT; 554 u64 val; 555 int rc; 556 557 erst_exec_ctx_init(&ctx); 558 rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_CLEAR); 559 if (rc) 560 return rc; 561 apei_exec_ctx_set_input(&ctx, record_id); 562 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); 563 if (rc) 564 return rc; 565 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); 566 if (rc) 567 return rc; 568 for (;;) { 569 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); 570 if (rc) 571 return rc; 572 val = apei_exec_ctx_get_output(&ctx); 573 if (!val) 574 break; 575 if (erst_timedout(&timeout, SPIN_UNIT)) 576 return -EIO; 577 } 578 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); 579 if (rc) 580 return rc; 581 val = apei_exec_ctx_get_output(&ctx); 582 rc = apei_exec_run(&ctx, ACPI_ERST_END); 583 if (rc) 584 return rc; 585 586 return erst_errno(val); 587 } 588 589 /* NVRAM ERST Error Log Address Range is not supported yet */ 590 static void pr_unimpl_nvram(void) 591 { 592 if (printk_ratelimit()) 593 pr_warning(ERST_PFX 594 "NVRAM ERST Log Address Range is not implemented yet\n"); 595 } 596 597 static int __erst_write_to_nvram(const struct cper_record_header *record) 598 { 599 /* do not print message, because printk is not safe for NMI */ 600 return -ENOSYS; 601 } 602 603 static int __erst_read_to_erange_from_nvram(u64 record_id, u64 *offset) 604 { 605 pr_unimpl_nvram(); 606 return -ENOSYS; 607 } 608 609 static int __erst_clear_from_nvram(u64 record_id) 610 { 611 pr_unimpl_nvram(); 612 return -ENOSYS; 613 } 614 615 int erst_write(const struct cper_record_header *record) 616 { 617 int rc; 618 unsigned long flags; 619 struct cper_record_header *rcd_erange; 620 621 if (erst_disable) 622 return -ENODEV; 623 624 if (memcmp(record->signature, CPER_SIG_RECORD, CPER_SIG_SIZE)) 625 return -EINVAL; 626 627 if (erst_erange.attr & ERST_RANGE_NVRAM) { 628 if (!raw_spin_trylock_irqsave(&erst_lock, flags)) 629 return -EBUSY; 630 rc = __erst_write_to_nvram(record); 631 raw_spin_unlock_irqrestore(&erst_lock, flags); 632 return rc; 633 } 634 635 if (record->record_length > erst_erange.size) 636 return -EINVAL; 637 638 if (!raw_spin_trylock_irqsave(&erst_lock, flags)) 639 return -EBUSY; 640 memcpy(erst_erange.vaddr, record, record->record_length); 641 rcd_erange = erst_erange.vaddr; 642 /* signature for serialization system */ 643 memcpy(&rcd_erange->persistence_information, "ER", 2); 644 645 rc = __erst_write_to_storage(0); 646 raw_spin_unlock_irqrestore(&erst_lock, flags); 647 648 return rc; 649 } 650 EXPORT_SYMBOL_GPL(erst_write); 651 652 static int __erst_read_to_erange(u64 record_id, u64 *offset) 653 { 654 int rc; 655 656 if (erst_erange.attr & ERST_RANGE_NVRAM) 657 return __erst_read_to_erange_from_nvram( 658 record_id, offset); 659 660 rc = __erst_read_from_storage(record_id, 0); 661 if (rc) 662 return rc; 663 *offset = 0; 664 665 return 0; 666 } 667 668 static ssize_t __erst_read(u64 record_id, struct cper_record_header *record, 669 size_t buflen) 670 { 671 int rc; 672 u64 offset, len = 0; 673 struct cper_record_header *rcd_tmp; 674 675 rc = __erst_read_to_erange(record_id, &offset); 676 if (rc) 677 return rc; 678 rcd_tmp = erst_erange.vaddr + offset; 679 len = rcd_tmp->record_length; 680 if (len <= buflen) 681 memcpy(record, rcd_tmp, len); 682 683 return len; 684 } 685 686 /* 687 * If return value > buflen, the buffer size is not big enough, 688 * else if return value < 0, something goes wrong, 689 * else everything is OK, and return value is record length 690 */ 691 ssize_t erst_read(u64 record_id, struct cper_record_header *record, 692 size_t buflen) 693 { 694 ssize_t len; 695 unsigned long flags; 696 697 if (erst_disable) 698 return -ENODEV; 699 700 raw_spin_lock_irqsave(&erst_lock, flags); 701 len = __erst_read(record_id, record, buflen); 702 raw_spin_unlock_irqrestore(&erst_lock, flags); 703 return len; 704 } 705 EXPORT_SYMBOL_GPL(erst_read); 706 707 /* 708 * If return value > buflen, the buffer size is not big enough, 709 * else if return value = 0, there is no more record to read, 710 * else if return value < 0, something goes wrong, 711 * else everything is OK, and return value is record length 712 */ 713 ssize_t erst_read_next(struct cper_record_header *record, size_t buflen) 714 { 715 int rc; 716 ssize_t len; 717 unsigned long flags; 718 u64 record_id; 719 720 if (erst_disable) 721 return -ENODEV; 722 723 raw_spin_lock_irqsave(&erst_lock, flags); 724 rc = __erst_get_next_record_id(&record_id); 725 if (rc) { 726 raw_spin_unlock_irqrestore(&erst_lock, flags); 727 return rc; 728 } 729 /* no more record */ 730 if (record_id == APEI_ERST_INVALID_RECORD_ID) { 731 raw_spin_unlock_irqrestore(&erst_lock, flags); 732 return 0; 733 } 734 735 len = __erst_read(record_id, record, buflen); 736 raw_spin_unlock_irqrestore(&erst_lock, flags); 737 738 return len; 739 } 740 EXPORT_SYMBOL_GPL(erst_read_next); 741 742 int erst_clear(u64 record_id) 743 { 744 int rc; 745 unsigned long flags; 746 747 if (erst_disable) 748 return -ENODEV; 749 750 raw_spin_lock_irqsave(&erst_lock, flags); 751 if (erst_erange.attr & ERST_RANGE_NVRAM) 752 rc = __erst_clear_from_nvram(record_id); 753 else 754 rc = __erst_clear_from_storage(record_id); 755 raw_spin_unlock_irqrestore(&erst_lock, flags); 756 757 return rc; 758 } 759 EXPORT_SYMBOL_GPL(erst_clear); 760 761 static int __init setup_erst_disable(char *str) 762 { 763 erst_disable = 1; 764 return 0; 765 } 766 767 __setup("erst_disable", setup_erst_disable); 768 769 static int erst_check_table(struct acpi_table_erst *erst_tab) 770 { 771 if ((erst_tab->header_length != 772 (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) 773 && (erst_tab->header_length != sizeof(struct acpi_table_einj))) 774 return -EINVAL; 775 if (erst_tab->header.length < sizeof(struct acpi_table_erst)) 776 return -EINVAL; 777 if (erst_tab->entries != 778 (erst_tab->header.length - sizeof(struct acpi_table_erst)) / 779 sizeof(struct acpi_erst_entry)) 780 return -EINVAL; 781 782 return 0; 783 } 784 785 static size_t erst_reader(u64 *id, enum pstore_type_id *type, 786 struct timespec *time); 787 static u64 erst_writer(enum pstore_type_id type, size_t size); 788 789 static struct pstore_info erst_info = { 790 .owner = THIS_MODULE, 791 .name = "erst", 792 .read = erst_reader, 793 .write = erst_writer, 794 .erase = erst_clear 795 }; 796 797 #define CPER_CREATOR_PSTORE \ 798 UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \ 799 0x64, 0x90, 0xb8, 0x9d) 800 #define CPER_SECTION_TYPE_DMESG \ 801 UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54, \ 802 0x94, 0x19, 0xeb, 0x12) 803 #define CPER_SECTION_TYPE_MCE \ 804 UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \ 805 0x04, 0x4a, 0x38, 0xfc) 806 807 struct cper_pstore_record { 808 struct cper_record_header hdr; 809 struct cper_section_descriptor sec_hdr; 810 char data[]; 811 } __packed; 812 813 static size_t erst_reader(u64 *id, enum pstore_type_id *type, 814 struct timespec *time) 815 { 816 int rc; 817 ssize_t len; 818 unsigned long flags; 819 u64 record_id; 820 struct cper_pstore_record *rcd = (struct cper_pstore_record *) 821 (erst_info.buf - sizeof(*rcd)); 822 823 if (erst_disable) 824 return -ENODEV; 825 826 raw_spin_lock_irqsave(&erst_lock, flags); 827 skip: 828 rc = __erst_get_next_record_id(&record_id); 829 if (rc) { 830 raw_spin_unlock_irqrestore(&erst_lock, flags); 831 return rc; 832 } 833 /* no more record */ 834 if (record_id == APEI_ERST_INVALID_RECORD_ID) { 835 raw_spin_unlock_irqrestore(&erst_lock, flags); 836 return 0; 837 } 838 839 len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) + 840 erst_erange.size); 841 if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) 842 goto skip; 843 raw_spin_unlock_irqrestore(&erst_lock, flags); 844 845 *id = record_id; 846 if (uuid_le_cmp(rcd->sec_hdr.section_type, 847 CPER_SECTION_TYPE_DMESG) == 0) 848 *type = PSTORE_TYPE_DMESG; 849 else if (uuid_le_cmp(rcd->sec_hdr.section_type, 850 CPER_SECTION_TYPE_MCE) == 0) 851 *type = PSTORE_TYPE_MCE; 852 else 853 *type = PSTORE_TYPE_UNKNOWN; 854 855 if (rcd->hdr.validation_bits & CPER_VALID_TIMESTAMP) 856 time->tv_sec = rcd->hdr.timestamp; 857 else 858 time->tv_sec = 0; 859 time->tv_nsec = 0; 860 861 return len - sizeof(*rcd); 862 } 863 864 static u64 erst_writer(enum pstore_type_id type, size_t size) 865 { 866 struct cper_pstore_record *rcd = (struct cper_pstore_record *) 867 (erst_info.buf - sizeof(*rcd)); 868 869 memset(rcd, 0, sizeof(*rcd)); 870 memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE); 871 rcd->hdr.revision = CPER_RECORD_REV; 872 rcd->hdr.signature_end = CPER_SIG_END; 873 rcd->hdr.section_count = 1; 874 rcd->hdr.error_severity = CPER_SEV_FATAL; 875 /* timestamp valid. platform_id, partition_id are invalid */ 876 rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP; 877 rcd->hdr.timestamp = get_seconds(); 878 rcd->hdr.record_length = sizeof(*rcd) + size; 879 rcd->hdr.creator_id = CPER_CREATOR_PSTORE; 880 rcd->hdr.notification_type = CPER_NOTIFY_MCE; 881 rcd->hdr.record_id = cper_next_record_id(); 882 rcd->hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR; 883 884 rcd->sec_hdr.section_offset = sizeof(*rcd); 885 rcd->sec_hdr.section_length = size; 886 rcd->sec_hdr.revision = CPER_SEC_REV; 887 /* fru_id and fru_text is invalid */ 888 rcd->sec_hdr.validation_bits = 0; 889 rcd->sec_hdr.flags = CPER_SEC_PRIMARY; 890 switch (type) { 891 case PSTORE_TYPE_DMESG: 892 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG; 893 break; 894 case PSTORE_TYPE_MCE: 895 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE; 896 break; 897 default: 898 return -EINVAL; 899 } 900 rcd->sec_hdr.section_severity = CPER_SEV_FATAL; 901 902 erst_write(&rcd->hdr); 903 904 return rcd->hdr.record_id; 905 } 906 907 static int __init erst_init(void) 908 { 909 int rc = 0; 910 acpi_status status; 911 struct apei_exec_context ctx; 912 struct apei_resources erst_resources; 913 struct resource *r; 914 char *buf; 915 916 if (acpi_disabled) 917 goto err; 918 919 if (erst_disable) { 920 pr_info(ERST_PFX 921 "Error Record Serialization Table (ERST) support is disabled.\n"); 922 goto err; 923 } 924 925 status = acpi_get_table(ACPI_SIG_ERST, 0, 926 (struct acpi_table_header **)&erst_tab); 927 if (status == AE_NOT_FOUND) { 928 pr_info(ERST_PFX "Table is not found!\n"); 929 goto err; 930 } else if (ACPI_FAILURE(status)) { 931 const char *msg = acpi_format_exception(status); 932 pr_err(ERST_PFX "Failed to get table, %s\n", msg); 933 rc = -EINVAL; 934 goto err; 935 } 936 937 rc = erst_check_table(erst_tab); 938 if (rc) { 939 pr_err(FW_BUG ERST_PFX "ERST table is invalid\n"); 940 goto err; 941 } 942 943 apei_resources_init(&erst_resources); 944 erst_exec_ctx_init(&ctx); 945 rc = apei_exec_collect_resources(&ctx, &erst_resources); 946 if (rc) 947 goto err_fini; 948 rc = apei_resources_request(&erst_resources, "APEI ERST"); 949 if (rc) 950 goto err_fini; 951 rc = apei_exec_pre_map_gars(&ctx); 952 if (rc) 953 goto err_release; 954 rc = erst_get_erange(&erst_erange); 955 if (rc) { 956 if (rc == -ENODEV) 957 pr_info(ERST_PFX 958 "The corresponding hardware device or firmware implementation " 959 "is not available.\n"); 960 else 961 pr_err(ERST_PFX 962 "Failed to get Error Log Address Range.\n"); 963 goto err_unmap_reg; 964 } 965 966 r = request_mem_region(erst_erange.base, erst_erange.size, "APEI ERST"); 967 if (!r) { 968 pr_err(ERST_PFX 969 "Can not request iomem region <0x%16llx-0x%16llx> for ERST.\n", 970 (unsigned long long)erst_erange.base, 971 (unsigned long long)erst_erange.base + erst_erange.size); 972 rc = -EIO; 973 goto err_unmap_reg; 974 } 975 rc = -ENOMEM; 976 erst_erange.vaddr = ioremap_cache(erst_erange.base, 977 erst_erange.size); 978 if (!erst_erange.vaddr) 979 goto err_release_erange; 980 981 buf = kmalloc(erst_erange.size, GFP_KERNEL); 982 mutex_init(&erst_info.buf_mutex); 983 if (buf) { 984 erst_info.buf = buf + sizeof(struct cper_pstore_record); 985 erst_info.bufsize = erst_erange.size - 986 sizeof(struct cper_pstore_record); 987 if (pstore_register(&erst_info)) { 988 pr_info(ERST_PFX "Could not register with persistent store\n"); 989 kfree(buf); 990 } 991 } 992 993 pr_info(ERST_PFX 994 "Error Record Serialization Table (ERST) support is initialized.\n"); 995 996 return 0; 997 998 err_release_erange: 999 release_mem_region(erst_erange.base, erst_erange.size); 1000 err_unmap_reg: 1001 apei_exec_post_unmap_gars(&ctx); 1002 err_release: 1003 apei_resources_release(&erst_resources); 1004 err_fini: 1005 apei_resources_fini(&erst_resources); 1006 err: 1007 erst_disable = 1; 1008 return rc; 1009 } 1010 1011 device_initcall(erst_init); 1012