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 #define ERST_RECORD_ID_CACHE_SIZE_MIN 16 434 #define ERST_RECORD_ID_CACHE_SIZE_MAX 1024 435 436 struct erst_record_id_cache { 437 struct mutex lock; 438 u64 *entries; 439 int len; 440 int size; 441 int refcount; 442 }; 443 444 static struct erst_record_id_cache erst_record_id_cache = { 445 .lock = __MUTEX_INITIALIZER(erst_record_id_cache.lock), 446 .refcount = 0, 447 }; 448 449 static int __erst_get_next_record_id(u64 *record_id) 450 { 451 struct apei_exec_context ctx; 452 int rc; 453 454 erst_exec_ctx_init(&ctx); 455 rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_ID); 456 if (rc) 457 return rc; 458 *record_id = apei_exec_ctx_get_output(&ctx); 459 460 return 0; 461 } 462 463 int erst_get_record_id_begin(int *pos) 464 { 465 int rc; 466 467 if (erst_disable) 468 return -ENODEV; 469 470 rc = mutex_lock_interruptible(&erst_record_id_cache.lock); 471 if (rc) 472 return rc; 473 erst_record_id_cache.refcount++; 474 mutex_unlock(&erst_record_id_cache.lock); 475 476 *pos = 0; 477 478 return 0; 479 } 480 EXPORT_SYMBOL_GPL(erst_get_record_id_begin); 481 482 /* erst_record_id_cache.lock must be held by caller */ 483 static int __erst_record_id_cache_add_one(void) 484 { 485 u64 id, prev_id, first_id; 486 int i, rc; 487 u64 *entries; 488 unsigned long flags; 489 490 id = prev_id = first_id = APEI_ERST_INVALID_RECORD_ID; 491 retry: 492 raw_spin_lock_irqsave(&erst_lock, flags); 493 rc = __erst_get_next_record_id(&id); 494 raw_spin_unlock_irqrestore(&erst_lock, flags); 495 if (rc == -ENOENT) 496 return 0; 497 if (rc) 498 return rc; 499 if (id == APEI_ERST_INVALID_RECORD_ID) 500 return 0; 501 /* can not skip current ID, or loop back to first ID */ 502 if (id == prev_id || id == first_id) 503 return 0; 504 if (first_id == APEI_ERST_INVALID_RECORD_ID) 505 first_id = id; 506 prev_id = id; 507 508 entries = erst_record_id_cache.entries; 509 for (i = 0; i < erst_record_id_cache.len; i++) { 510 if (entries[i] == id) 511 break; 512 } 513 /* record id already in cache, try next */ 514 if (i < erst_record_id_cache.len) 515 goto retry; 516 if (erst_record_id_cache.len >= erst_record_id_cache.size) { 517 int new_size, alloc_size; 518 u64 *new_entries; 519 520 new_size = erst_record_id_cache.size * 2; 521 new_size = clamp_val(new_size, ERST_RECORD_ID_CACHE_SIZE_MIN, 522 ERST_RECORD_ID_CACHE_SIZE_MAX); 523 if (new_size <= erst_record_id_cache.size) { 524 if (printk_ratelimit()) 525 pr_warning(FW_WARN ERST_PFX 526 "too many record ID!\n"); 527 return 0; 528 } 529 alloc_size = new_size * sizeof(entries[0]); 530 if (alloc_size < PAGE_SIZE) 531 new_entries = kmalloc(alloc_size, GFP_KERNEL); 532 else 533 new_entries = vmalloc(alloc_size); 534 if (!new_entries) 535 return -ENOMEM; 536 memcpy(new_entries, entries, 537 erst_record_id_cache.len * sizeof(entries[0])); 538 if (erst_record_id_cache.size < PAGE_SIZE) 539 kfree(entries); 540 else 541 vfree(entries); 542 erst_record_id_cache.entries = entries = new_entries; 543 erst_record_id_cache.size = new_size; 544 } 545 entries[i] = id; 546 erst_record_id_cache.len++; 547 548 return 1; 549 } 550 551 /* 552 * Get the record ID of an existing error record on the persistent 553 * storage. If there is no error record on the persistent storage, the 554 * returned record_id is APEI_ERST_INVALID_RECORD_ID. 555 */ 556 int erst_get_record_id_next(int *pos, u64 *record_id) 557 { 558 int rc = 0; 559 u64 *entries; 560 561 if (erst_disable) 562 return -ENODEV; 563 564 /* must be enclosed by erst_get_record_id_begin/end */ 565 BUG_ON(!erst_record_id_cache.refcount); 566 BUG_ON(*pos < 0 || *pos > erst_record_id_cache.len); 567 568 mutex_lock(&erst_record_id_cache.lock); 569 entries = erst_record_id_cache.entries; 570 for (; *pos < erst_record_id_cache.len; (*pos)++) 571 if (entries[*pos] != APEI_ERST_INVALID_RECORD_ID) 572 break; 573 /* found next record id in cache */ 574 if (*pos < erst_record_id_cache.len) { 575 *record_id = entries[*pos]; 576 (*pos)++; 577 goto out_unlock; 578 } 579 580 /* Try to add one more record ID to cache */ 581 rc = __erst_record_id_cache_add_one(); 582 if (rc < 0) 583 goto out_unlock; 584 /* successfully add one new ID */ 585 if (rc == 1) { 586 *record_id = erst_record_id_cache.entries[*pos]; 587 (*pos)++; 588 rc = 0; 589 } else { 590 *pos = -1; 591 *record_id = APEI_ERST_INVALID_RECORD_ID; 592 } 593 out_unlock: 594 mutex_unlock(&erst_record_id_cache.lock); 595 596 return rc; 597 } 598 EXPORT_SYMBOL_GPL(erst_get_record_id_next); 599 600 /* erst_record_id_cache.lock must be held by caller */ 601 static void __erst_record_id_cache_compact(void) 602 { 603 int i, wpos = 0; 604 u64 *entries; 605 606 if (erst_record_id_cache.refcount) 607 return; 608 609 entries = erst_record_id_cache.entries; 610 for (i = 0; i < erst_record_id_cache.len; i++) { 611 if (entries[i] == APEI_ERST_INVALID_RECORD_ID) 612 continue; 613 if (wpos != i) 614 memcpy(&entries[wpos], &entries[i], sizeof(entries[i])); 615 wpos++; 616 } 617 erst_record_id_cache.len = wpos; 618 } 619 620 void erst_get_record_id_end(void) 621 { 622 /* 623 * erst_disable != 0 should be detected by invoker via the 624 * return value of erst_get_record_id_begin/next, so this 625 * function should not be called for erst_disable != 0. 626 */ 627 BUG_ON(erst_disable); 628 629 mutex_lock(&erst_record_id_cache.lock); 630 erst_record_id_cache.refcount--; 631 BUG_ON(erst_record_id_cache.refcount < 0); 632 __erst_record_id_cache_compact(); 633 mutex_unlock(&erst_record_id_cache.lock); 634 } 635 EXPORT_SYMBOL_GPL(erst_get_record_id_end); 636 637 static int __erst_write_to_storage(u64 offset) 638 { 639 struct apei_exec_context ctx; 640 u64 timeout = FIRMWARE_TIMEOUT; 641 u64 val; 642 int rc; 643 644 erst_exec_ctx_init(&ctx); 645 rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_WRITE); 646 if (rc) 647 return rc; 648 apei_exec_ctx_set_input(&ctx, offset); 649 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); 650 if (rc) 651 return rc; 652 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); 653 if (rc) 654 return rc; 655 for (;;) { 656 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); 657 if (rc) 658 return rc; 659 val = apei_exec_ctx_get_output(&ctx); 660 if (!val) 661 break; 662 if (erst_timedout(&timeout, SPIN_UNIT)) 663 return -EIO; 664 } 665 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); 666 if (rc) 667 return rc; 668 val = apei_exec_ctx_get_output(&ctx); 669 rc = apei_exec_run_optional(&ctx, ACPI_ERST_END); 670 if (rc) 671 return rc; 672 673 return erst_errno(val); 674 } 675 676 static int __erst_read_from_storage(u64 record_id, u64 offset) 677 { 678 struct apei_exec_context ctx; 679 u64 timeout = FIRMWARE_TIMEOUT; 680 u64 val; 681 int rc; 682 683 erst_exec_ctx_init(&ctx); 684 rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_READ); 685 if (rc) 686 return rc; 687 apei_exec_ctx_set_input(&ctx, offset); 688 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); 689 if (rc) 690 return rc; 691 apei_exec_ctx_set_input(&ctx, record_id); 692 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); 693 if (rc) 694 return rc; 695 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); 696 if (rc) 697 return rc; 698 for (;;) { 699 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); 700 if (rc) 701 return rc; 702 val = apei_exec_ctx_get_output(&ctx); 703 if (!val) 704 break; 705 if (erst_timedout(&timeout, SPIN_UNIT)) 706 return -EIO; 707 }; 708 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); 709 if (rc) 710 return rc; 711 val = apei_exec_ctx_get_output(&ctx); 712 rc = apei_exec_run_optional(&ctx, ACPI_ERST_END); 713 if (rc) 714 return rc; 715 716 return erst_errno(val); 717 } 718 719 static int __erst_clear_from_storage(u64 record_id) 720 { 721 struct apei_exec_context ctx; 722 u64 timeout = FIRMWARE_TIMEOUT; 723 u64 val; 724 int rc; 725 726 erst_exec_ctx_init(&ctx); 727 rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_CLEAR); 728 if (rc) 729 return rc; 730 apei_exec_ctx_set_input(&ctx, record_id); 731 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); 732 if (rc) 733 return rc; 734 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); 735 if (rc) 736 return rc; 737 for (;;) { 738 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); 739 if (rc) 740 return rc; 741 val = apei_exec_ctx_get_output(&ctx); 742 if (!val) 743 break; 744 if (erst_timedout(&timeout, SPIN_UNIT)) 745 return -EIO; 746 } 747 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); 748 if (rc) 749 return rc; 750 val = apei_exec_ctx_get_output(&ctx); 751 rc = apei_exec_run_optional(&ctx, ACPI_ERST_END); 752 if (rc) 753 return rc; 754 755 return erst_errno(val); 756 } 757 758 /* NVRAM ERST Error Log Address Range is not supported yet */ 759 static void pr_unimpl_nvram(void) 760 { 761 if (printk_ratelimit()) 762 pr_warning(ERST_PFX 763 "NVRAM ERST Log Address Range is not implemented yet\n"); 764 } 765 766 static int __erst_write_to_nvram(const struct cper_record_header *record) 767 { 768 /* do not print message, because printk is not safe for NMI */ 769 return -ENOSYS; 770 } 771 772 static int __erst_read_to_erange_from_nvram(u64 record_id, u64 *offset) 773 { 774 pr_unimpl_nvram(); 775 return -ENOSYS; 776 } 777 778 static int __erst_clear_from_nvram(u64 record_id) 779 { 780 pr_unimpl_nvram(); 781 return -ENOSYS; 782 } 783 784 int erst_write(const struct cper_record_header *record) 785 { 786 int rc; 787 unsigned long flags; 788 struct cper_record_header *rcd_erange; 789 790 if (erst_disable) 791 return -ENODEV; 792 793 if (memcmp(record->signature, CPER_SIG_RECORD, CPER_SIG_SIZE)) 794 return -EINVAL; 795 796 if (erst_erange.attr & ERST_RANGE_NVRAM) { 797 if (!raw_spin_trylock_irqsave(&erst_lock, flags)) 798 return -EBUSY; 799 rc = __erst_write_to_nvram(record); 800 raw_spin_unlock_irqrestore(&erst_lock, flags); 801 return rc; 802 } 803 804 if (record->record_length > erst_erange.size) 805 return -EINVAL; 806 807 if (!raw_spin_trylock_irqsave(&erst_lock, flags)) 808 return -EBUSY; 809 memcpy(erst_erange.vaddr, record, record->record_length); 810 rcd_erange = erst_erange.vaddr; 811 /* signature for serialization system */ 812 memcpy(&rcd_erange->persistence_information, "ER", 2); 813 814 rc = __erst_write_to_storage(0); 815 raw_spin_unlock_irqrestore(&erst_lock, flags); 816 817 return rc; 818 } 819 EXPORT_SYMBOL_GPL(erst_write); 820 821 static int __erst_read_to_erange(u64 record_id, u64 *offset) 822 { 823 int rc; 824 825 if (erst_erange.attr & ERST_RANGE_NVRAM) 826 return __erst_read_to_erange_from_nvram( 827 record_id, offset); 828 829 rc = __erst_read_from_storage(record_id, 0); 830 if (rc) 831 return rc; 832 *offset = 0; 833 834 return 0; 835 } 836 837 static ssize_t __erst_read(u64 record_id, struct cper_record_header *record, 838 size_t buflen) 839 { 840 int rc; 841 u64 offset, len = 0; 842 struct cper_record_header *rcd_tmp; 843 844 rc = __erst_read_to_erange(record_id, &offset); 845 if (rc) 846 return rc; 847 rcd_tmp = erst_erange.vaddr + offset; 848 len = rcd_tmp->record_length; 849 if (len <= buflen) 850 memcpy(record, rcd_tmp, len); 851 852 return len; 853 } 854 855 /* 856 * If return value > buflen, the buffer size is not big enough, 857 * else if return value < 0, something goes wrong, 858 * else everything is OK, and return value is record length 859 */ 860 ssize_t erst_read(u64 record_id, struct cper_record_header *record, 861 size_t buflen) 862 { 863 ssize_t len; 864 unsigned long flags; 865 866 if (erst_disable) 867 return -ENODEV; 868 869 raw_spin_lock_irqsave(&erst_lock, flags); 870 len = __erst_read(record_id, record, buflen); 871 raw_spin_unlock_irqrestore(&erst_lock, flags); 872 return len; 873 } 874 EXPORT_SYMBOL_GPL(erst_read); 875 876 int erst_clear(u64 record_id) 877 { 878 int rc, i; 879 unsigned long flags; 880 u64 *entries; 881 882 if (erst_disable) 883 return -ENODEV; 884 885 rc = mutex_lock_interruptible(&erst_record_id_cache.lock); 886 if (rc) 887 return rc; 888 raw_spin_lock_irqsave(&erst_lock, flags); 889 if (erst_erange.attr & ERST_RANGE_NVRAM) 890 rc = __erst_clear_from_nvram(record_id); 891 else 892 rc = __erst_clear_from_storage(record_id); 893 raw_spin_unlock_irqrestore(&erst_lock, flags); 894 if (rc) 895 goto out; 896 entries = erst_record_id_cache.entries; 897 for (i = 0; i < erst_record_id_cache.len; i++) { 898 if (entries[i] == record_id) 899 entries[i] = APEI_ERST_INVALID_RECORD_ID; 900 } 901 __erst_record_id_cache_compact(); 902 out: 903 mutex_unlock(&erst_record_id_cache.lock); 904 return rc; 905 } 906 EXPORT_SYMBOL_GPL(erst_clear); 907 908 static int __init setup_erst_disable(char *str) 909 { 910 erst_disable = 1; 911 return 0; 912 } 913 914 __setup("erst_disable", setup_erst_disable); 915 916 static int erst_check_table(struct acpi_table_erst *erst_tab) 917 { 918 if ((erst_tab->header_length != 919 (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) 920 && (erst_tab->header_length != sizeof(struct acpi_table_einj))) 921 return -EINVAL; 922 if (erst_tab->header.length < sizeof(struct acpi_table_erst)) 923 return -EINVAL; 924 if (erst_tab->entries != 925 (erst_tab->header.length - sizeof(struct acpi_table_erst)) / 926 sizeof(struct acpi_erst_entry)) 927 return -EINVAL; 928 929 return 0; 930 } 931 932 static int erst_open_pstore(struct pstore_info *psi); 933 static int erst_close_pstore(struct pstore_info *psi); 934 static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, 935 struct timespec *time, struct pstore_info *psi); 936 static u64 erst_writer(enum pstore_type_id type, unsigned int part, 937 size_t size, struct pstore_info *psi); 938 static int erst_clearer(enum pstore_type_id type, u64 id, 939 struct pstore_info *psi); 940 941 static struct pstore_info erst_info = { 942 .owner = THIS_MODULE, 943 .name = "erst", 944 .open = erst_open_pstore, 945 .close = erst_close_pstore, 946 .read = erst_reader, 947 .write = erst_writer, 948 .erase = erst_clearer 949 }; 950 951 #define CPER_CREATOR_PSTORE \ 952 UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \ 953 0x64, 0x90, 0xb8, 0x9d) 954 #define CPER_SECTION_TYPE_DMESG \ 955 UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54, \ 956 0x94, 0x19, 0xeb, 0x12) 957 #define CPER_SECTION_TYPE_MCE \ 958 UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \ 959 0x04, 0x4a, 0x38, 0xfc) 960 961 struct cper_pstore_record { 962 struct cper_record_header hdr; 963 struct cper_section_descriptor sec_hdr; 964 char data[]; 965 } __packed; 966 967 static int reader_pos; 968 969 static int erst_open_pstore(struct pstore_info *psi) 970 { 971 int rc; 972 973 if (erst_disable) 974 return -ENODEV; 975 976 rc = erst_get_record_id_begin(&reader_pos); 977 978 return rc; 979 } 980 981 static int erst_close_pstore(struct pstore_info *psi) 982 { 983 erst_get_record_id_end(); 984 985 return 0; 986 } 987 988 static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, 989 struct timespec *time, struct pstore_info *psi) 990 { 991 int rc; 992 ssize_t len = 0; 993 u64 record_id; 994 struct cper_pstore_record *rcd = (struct cper_pstore_record *) 995 (erst_info.buf - sizeof(*rcd)); 996 997 if (erst_disable) 998 return -ENODEV; 999 1000 skip: 1001 rc = erst_get_record_id_next(&reader_pos, &record_id); 1002 if (rc) 1003 goto out; 1004 1005 /* no more record */ 1006 if (record_id == APEI_ERST_INVALID_RECORD_ID) { 1007 rc = -1; 1008 goto out; 1009 } 1010 1011 len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) + 1012 erst_info.bufsize); 1013 /* The record may be cleared by others, try read next record */ 1014 if (len == -ENOENT) 1015 goto skip; 1016 else if (len < 0) { 1017 rc = -1; 1018 goto out; 1019 } 1020 if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) 1021 goto skip; 1022 1023 *id = record_id; 1024 if (uuid_le_cmp(rcd->sec_hdr.section_type, 1025 CPER_SECTION_TYPE_DMESG) == 0) 1026 *type = PSTORE_TYPE_DMESG; 1027 else if (uuid_le_cmp(rcd->sec_hdr.section_type, 1028 CPER_SECTION_TYPE_MCE) == 0) 1029 *type = PSTORE_TYPE_MCE; 1030 else 1031 *type = PSTORE_TYPE_UNKNOWN; 1032 1033 if (rcd->hdr.validation_bits & CPER_VALID_TIMESTAMP) 1034 time->tv_sec = rcd->hdr.timestamp; 1035 else 1036 time->tv_sec = 0; 1037 time->tv_nsec = 0; 1038 1039 out: 1040 return (rc < 0) ? rc : (len - sizeof(*rcd)); 1041 } 1042 1043 static u64 erst_writer(enum pstore_type_id type, unsigned int part, 1044 size_t size, struct pstore_info *psi) 1045 { 1046 struct cper_pstore_record *rcd = (struct cper_pstore_record *) 1047 (erst_info.buf - sizeof(*rcd)); 1048 1049 memset(rcd, 0, sizeof(*rcd)); 1050 memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE); 1051 rcd->hdr.revision = CPER_RECORD_REV; 1052 rcd->hdr.signature_end = CPER_SIG_END; 1053 rcd->hdr.section_count = 1; 1054 rcd->hdr.error_severity = CPER_SEV_FATAL; 1055 /* timestamp valid. platform_id, partition_id are invalid */ 1056 rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP; 1057 rcd->hdr.timestamp = get_seconds(); 1058 rcd->hdr.record_length = sizeof(*rcd) + size; 1059 rcd->hdr.creator_id = CPER_CREATOR_PSTORE; 1060 rcd->hdr.notification_type = CPER_NOTIFY_MCE; 1061 rcd->hdr.record_id = cper_next_record_id(); 1062 rcd->hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR; 1063 1064 rcd->sec_hdr.section_offset = sizeof(*rcd); 1065 rcd->sec_hdr.section_length = size; 1066 rcd->sec_hdr.revision = CPER_SEC_REV; 1067 /* fru_id and fru_text is invalid */ 1068 rcd->sec_hdr.validation_bits = 0; 1069 rcd->sec_hdr.flags = CPER_SEC_PRIMARY; 1070 switch (type) { 1071 case PSTORE_TYPE_DMESG: 1072 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG; 1073 break; 1074 case PSTORE_TYPE_MCE: 1075 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE; 1076 break; 1077 default: 1078 return -EINVAL; 1079 } 1080 rcd->sec_hdr.section_severity = CPER_SEV_FATAL; 1081 1082 erst_write(&rcd->hdr); 1083 1084 return rcd->hdr.record_id; 1085 } 1086 1087 static int erst_clearer(enum pstore_type_id type, u64 id, 1088 struct pstore_info *psi) 1089 { 1090 return erst_clear(id); 1091 } 1092 1093 static int __init erst_init(void) 1094 { 1095 int rc = 0; 1096 acpi_status status; 1097 struct apei_exec_context ctx; 1098 struct apei_resources erst_resources; 1099 struct resource *r; 1100 char *buf; 1101 1102 if (acpi_disabled) 1103 goto err; 1104 1105 if (erst_disable) { 1106 pr_info(ERST_PFX 1107 "Error Record Serialization Table (ERST) support is disabled.\n"); 1108 goto err; 1109 } 1110 1111 status = acpi_get_table(ACPI_SIG_ERST, 0, 1112 (struct acpi_table_header **)&erst_tab); 1113 if (status == AE_NOT_FOUND) { 1114 pr_info(ERST_PFX "Table is not found!\n"); 1115 goto err; 1116 } else if (ACPI_FAILURE(status)) { 1117 const char *msg = acpi_format_exception(status); 1118 pr_err(ERST_PFX "Failed to get table, %s\n", msg); 1119 rc = -EINVAL; 1120 goto err; 1121 } 1122 1123 rc = erst_check_table(erst_tab); 1124 if (rc) { 1125 pr_err(FW_BUG ERST_PFX "ERST table is invalid\n"); 1126 goto err; 1127 } 1128 1129 apei_resources_init(&erst_resources); 1130 erst_exec_ctx_init(&ctx); 1131 rc = apei_exec_collect_resources(&ctx, &erst_resources); 1132 if (rc) 1133 goto err_fini; 1134 rc = apei_resources_request(&erst_resources, "APEI ERST"); 1135 if (rc) 1136 goto err_fini; 1137 rc = apei_exec_pre_map_gars(&ctx); 1138 if (rc) 1139 goto err_release; 1140 rc = erst_get_erange(&erst_erange); 1141 if (rc) { 1142 if (rc == -ENODEV) 1143 pr_info(ERST_PFX 1144 "The corresponding hardware device or firmware implementation " 1145 "is not available.\n"); 1146 else 1147 pr_err(ERST_PFX 1148 "Failed to get Error Log Address Range.\n"); 1149 goto err_unmap_reg; 1150 } 1151 1152 r = request_mem_region(erst_erange.base, erst_erange.size, "APEI ERST"); 1153 if (!r) { 1154 pr_err(ERST_PFX 1155 "Can not request iomem region <0x%16llx-0x%16llx> for ERST.\n", 1156 (unsigned long long)erst_erange.base, 1157 (unsigned long long)erst_erange.base + erst_erange.size); 1158 rc = -EIO; 1159 goto err_unmap_reg; 1160 } 1161 rc = -ENOMEM; 1162 erst_erange.vaddr = ioremap_cache(erst_erange.base, 1163 erst_erange.size); 1164 if (!erst_erange.vaddr) 1165 goto err_release_erange; 1166 1167 buf = kmalloc(erst_erange.size, GFP_KERNEL); 1168 mutex_init(&erst_info.buf_mutex); 1169 if (buf) { 1170 erst_info.buf = buf + sizeof(struct cper_pstore_record); 1171 erst_info.bufsize = erst_erange.size - 1172 sizeof(struct cper_pstore_record); 1173 if (pstore_register(&erst_info)) { 1174 pr_info(ERST_PFX "Could not register with persistent store\n"); 1175 kfree(buf); 1176 } 1177 } 1178 1179 pr_info(ERST_PFX 1180 "Error Record Serialization Table (ERST) support is initialized.\n"); 1181 1182 return 0; 1183 1184 err_release_erange: 1185 release_mem_region(erst_erange.base, erst_erange.size); 1186 err_unmap_reg: 1187 apei_exec_post_unmap_gars(&ctx); 1188 err_release: 1189 apei_resources_release(&erst_resources); 1190 err_fini: 1191 apei_resources_fini(&erst_resources); 1192 err: 1193 erst_disable = 1; 1194 return rc; 1195 } 1196 1197 device_initcall(erst_init); 1198