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 <linux/vmalloc.h> 39 #include <acpi/apei.h> 40 41 #include "apei-internal.h" 42 43 #undef pr_fmt 44 #define pr_fmt(fmt) "ERST: " fmt 45 46 /* ERST command status */ 47 #define ERST_STATUS_SUCCESS 0x0 48 #define ERST_STATUS_NOT_ENOUGH_SPACE 0x1 49 #define ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x2 50 #define ERST_STATUS_FAILED 0x3 51 #define ERST_STATUS_RECORD_STORE_EMPTY 0x4 52 #define ERST_STATUS_RECORD_NOT_FOUND 0x5 53 54 #define ERST_TAB_ENTRY(tab) \ 55 ((struct acpi_whea_header *)((char *)(tab) + \ 56 sizeof(struct acpi_table_erst))) 57 58 #define SPIN_UNIT 100 /* 100ns */ 59 /* Firmware should respond within 1 milliseconds */ 60 #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) 61 #define FIRMWARE_MAX_STALL 50 /* 50us */ 62 63 int erst_disable; 64 EXPORT_SYMBOL_GPL(erst_disable); 65 66 static struct acpi_table_erst *erst_tab; 67 68 /* ERST Error Log Address Range atrributes */ 69 #define ERST_RANGE_RESERVED 0x0001 70 #define ERST_RANGE_NVRAM 0x0002 71 #define ERST_RANGE_SLOW 0x0004 72 73 /* 74 * ERST Error Log Address Range, used as buffer for reading/writing 75 * error records. 76 */ 77 static struct erst_erange { 78 u64 base; 79 u64 size; 80 void __iomem *vaddr; 81 u32 attr; 82 } erst_erange; 83 84 /* 85 * Prevent ERST interpreter to run simultaneously, because the 86 * corresponding firmware implementation may not work properly when 87 * invoked simultaneously. 88 * 89 * It is used to provide exclusive accessing for ERST Error Log 90 * Address Range too. 91 */ 92 static DEFINE_RAW_SPINLOCK(erst_lock); 93 94 static inline int erst_errno(int command_status) 95 { 96 switch (command_status) { 97 case ERST_STATUS_SUCCESS: 98 return 0; 99 case ERST_STATUS_HARDWARE_NOT_AVAILABLE: 100 return -ENODEV; 101 case ERST_STATUS_NOT_ENOUGH_SPACE: 102 return -ENOSPC; 103 case ERST_STATUS_RECORD_STORE_EMPTY: 104 case ERST_STATUS_RECORD_NOT_FOUND: 105 return -ENOENT; 106 default: 107 return -EINVAL; 108 } 109 } 110 111 static int erst_timedout(u64 *t, u64 spin_unit) 112 { 113 if ((s64)*t < spin_unit) { 114 pr_warn(FW_WARN "Firmware does not respond in time.\n"); 115 return 1; 116 } 117 *t -= spin_unit; 118 ndelay(spin_unit); 119 touch_nmi_watchdog(); 120 return 0; 121 } 122 123 static int erst_exec_load_var1(struct apei_exec_context *ctx, 124 struct acpi_whea_header *entry) 125 { 126 return __apei_exec_read_register(entry, &ctx->var1); 127 } 128 129 static int erst_exec_load_var2(struct apei_exec_context *ctx, 130 struct acpi_whea_header *entry) 131 { 132 return __apei_exec_read_register(entry, &ctx->var2); 133 } 134 135 static int erst_exec_store_var1(struct apei_exec_context *ctx, 136 struct acpi_whea_header *entry) 137 { 138 return __apei_exec_write_register(entry, ctx->var1); 139 } 140 141 static int erst_exec_add(struct apei_exec_context *ctx, 142 struct acpi_whea_header *entry) 143 { 144 ctx->var1 += ctx->var2; 145 return 0; 146 } 147 148 static int erst_exec_subtract(struct apei_exec_context *ctx, 149 struct acpi_whea_header *entry) 150 { 151 ctx->var1 -= ctx->var2; 152 return 0; 153 } 154 155 static int erst_exec_add_value(struct apei_exec_context *ctx, 156 struct acpi_whea_header *entry) 157 { 158 int rc; 159 u64 val; 160 161 rc = __apei_exec_read_register(entry, &val); 162 if (rc) 163 return rc; 164 val += ctx->value; 165 rc = __apei_exec_write_register(entry, val); 166 return rc; 167 } 168 169 static int erst_exec_subtract_value(struct apei_exec_context *ctx, 170 struct acpi_whea_header *entry) 171 { 172 int rc; 173 u64 val; 174 175 rc = __apei_exec_read_register(entry, &val); 176 if (rc) 177 return rc; 178 val -= ctx->value; 179 rc = __apei_exec_write_register(entry, val); 180 return rc; 181 } 182 183 static int erst_exec_stall(struct apei_exec_context *ctx, 184 struct acpi_whea_header *entry) 185 { 186 u64 stall_time; 187 188 if (ctx->value > FIRMWARE_MAX_STALL) { 189 if (!in_nmi()) 190 pr_warn(FW_WARN 191 "Too long stall time for stall instruction: 0x%llx.\n", 192 ctx->value); 193 stall_time = FIRMWARE_MAX_STALL; 194 } else 195 stall_time = ctx->value; 196 udelay(stall_time); 197 return 0; 198 } 199 200 static int erst_exec_stall_while_true(struct apei_exec_context *ctx, 201 struct acpi_whea_header *entry) 202 { 203 int rc; 204 u64 val; 205 u64 timeout = FIRMWARE_TIMEOUT; 206 u64 stall_time; 207 208 if (ctx->var1 > FIRMWARE_MAX_STALL) { 209 if (!in_nmi()) 210 pr_warn(FW_WARN 211 "Too long stall time for stall while true instruction: 0x%llx.\n", 212 ctx->var1); 213 stall_time = FIRMWARE_MAX_STALL; 214 } else 215 stall_time = ctx->var1; 216 217 for (;;) { 218 rc = __apei_exec_read_register(entry, &val); 219 if (rc) 220 return rc; 221 if (val != ctx->value) 222 break; 223 if (erst_timedout(&timeout, stall_time * NSEC_PER_USEC)) 224 return -EIO; 225 } 226 return 0; 227 } 228 229 static int erst_exec_skip_next_instruction_if_true( 230 struct apei_exec_context *ctx, 231 struct acpi_whea_header *entry) 232 { 233 int rc; 234 u64 val; 235 236 rc = __apei_exec_read_register(entry, &val); 237 if (rc) 238 return rc; 239 if (val == ctx->value) { 240 ctx->ip += 2; 241 return APEI_EXEC_SET_IP; 242 } 243 244 return 0; 245 } 246 247 static int erst_exec_goto(struct apei_exec_context *ctx, 248 struct acpi_whea_header *entry) 249 { 250 ctx->ip = ctx->value; 251 return APEI_EXEC_SET_IP; 252 } 253 254 static int erst_exec_set_src_address_base(struct apei_exec_context *ctx, 255 struct acpi_whea_header *entry) 256 { 257 return __apei_exec_read_register(entry, &ctx->src_base); 258 } 259 260 static int erst_exec_set_dst_address_base(struct apei_exec_context *ctx, 261 struct acpi_whea_header *entry) 262 { 263 return __apei_exec_read_register(entry, &ctx->dst_base); 264 } 265 266 static int erst_exec_move_data(struct apei_exec_context *ctx, 267 struct acpi_whea_header *entry) 268 { 269 int rc; 270 u64 offset; 271 void *src, *dst; 272 273 /* ioremap does not work in interrupt context */ 274 if (in_interrupt()) { 275 pr_warn("MOVE_DATA can not be used in interrupt context.\n"); 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 iounmap(src); 289 return -ENOMEM; 290 } 291 292 memmove(dst, src, ctx->var2); 293 294 iounmap(src); 295 iounmap(dst); 296 297 return 0; 298 } 299 300 static struct apei_exec_ins_type erst_ins_type[] = { 301 [ACPI_ERST_READ_REGISTER] = { 302 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 303 .run = apei_exec_read_register, 304 }, 305 [ACPI_ERST_READ_REGISTER_VALUE] = { 306 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 307 .run = apei_exec_read_register_value, 308 }, 309 [ACPI_ERST_WRITE_REGISTER] = { 310 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 311 .run = apei_exec_write_register, 312 }, 313 [ACPI_ERST_WRITE_REGISTER_VALUE] = { 314 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 315 .run = apei_exec_write_register_value, 316 }, 317 [ACPI_ERST_NOOP] = { 318 .flags = 0, 319 .run = apei_exec_noop, 320 }, 321 [ACPI_ERST_LOAD_VAR1] = { 322 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 323 .run = erst_exec_load_var1, 324 }, 325 [ACPI_ERST_LOAD_VAR2] = { 326 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 327 .run = erst_exec_load_var2, 328 }, 329 [ACPI_ERST_STORE_VAR1] = { 330 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 331 .run = erst_exec_store_var1, 332 }, 333 [ACPI_ERST_ADD] = { 334 .flags = 0, 335 .run = erst_exec_add, 336 }, 337 [ACPI_ERST_SUBTRACT] = { 338 .flags = 0, 339 .run = erst_exec_subtract, 340 }, 341 [ACPI_ERST_ADD_VALUE] = { 342 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 343 .run = erst_exec_add_value, 344 }, 345 [ACPI_ERST_SUBTRACT_VALUE] = { 346 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 347 .run = erst_exec_subtract_value, 348 }, 349 [ACPI_ERST_STALL] = { 350 .flags = 0, 351 .run = erst_exec_stall, 352 }, 353 [ACPI_ERST_STALL_WHILE_TRUE] = { 354 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 355 .run = erst_exec_stall_while_true, 356 }, 357 [ACPI_ERST_SKIP_NEXT_IF_TRUE] = { 358 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 359 .run = erst_exec_skip_next_instruction_if_true, 360 }, 361 [ACPI_ERST_GOTO] = { 362 .flags = 0, 363 .run = erst_exec_goto, 364 }, 365 [ACPI_ERST_SET_SRC_ADDRESS_BASE] = { 366 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 367 .run = erst_exec_set_src_address_base, 368 }, 369 [ACPI_ERST_SET_DST_ADDRESS_BASE] = { 370 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 371 .run = erst_exec_set_dst_address_base, 372 }, 373 [ACPI_ERST_MOVE_DATA] = { 374 .flags = APEI_EXEC_INS_ACCESS_REGISTER, 375 .run = erst_exec_move_data, 376 }, 377 }; 378 379 static inline void erst_exec_ctx_init(struct apei_exec_context *ctx) 380 { 381 apei_exec_ctx_init(ctx, erst_ins_type, ARRAY_SIZE(erst_ins_type), 382 ERST_TAB_ENTRY(erst_tab), erst_tab->entries); 383 } 384 385 static int erst_get_erange(struct erst_erange *range) 386 { 387 struct apei_exec_context ctx; 388 int rc; 389 390 erst_exec_ctx_init(&ctx); 391 rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_RANGE); 392 if (rc) 393 return rc; 394 range->base = apei_exec_ctx_get_output(&ctx); 395 rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_LENGTH); 396 if (rc) 397 return rc; 398 range->size = apei_exec_ctx_get_output(&ctx); 399 rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_ATTRIBUTES); 400 if (rc) 401 return rc; 402 range->attr = apei_exec_ctx_get_output(&ctx); 403 404 return 0; 405 } 406 407 static ssize_t __erst_get_record_count(void) 408 { 409 struct apei_exec_context ctx; 410 int rc; 411 412 erst_exec_ctx_init(&ctx); 413 rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_COUNT); 414 if (rc) 415 return rc; 416 return apei_exec_ctx_get_output(&ctx); 417 } 418 419 ssize_t erst_get_record_count(void) 420 { 421 ssize_t count; 422 unsigned long flags; 423 424 if (erst_disable) 425 return -ENODEV; 426 427 raw_spin_lock_irqsave(&erst_lock, flags); 428 count = __erst_get_record_count(); 429 raw_spin_unlock_irqrestore(&erst_lock, flags); 430 431 return count; 432 } 433 EXPORT_SYMBOL_GPL(erst_get_record_count); 434 435 #define ERST_RECORD_ID_CACHE_SIZE_MIN 16 436 #define ERST_RECORD_ID_CACHE_SIZE_MAX 1024 437 438 struct erst_record_id_cache { 439 struct mutex lock; 440 u64 *entries; 441 int len; 442 int size; 443 int refcount; 444 }; 445 446 static struct erst_record_id_cache erst_record_id_cache = { 447 .lock = __MUTEX_INITIALIZER(erst_record_id_cache.lock), 448 .refcount = 0, 449 }; 450 451 static int __erst_get_next_record_id(u64 *record_id) 452 { 453 struct apei_exec_context ctx; 454 int rc; 455 456 erst_exec_ctx_init(&ctx); 457 rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_ID); 458 if (rc) 459 return rc; 460 *record_id = apei_exec_ctx_get_output(&ctx); 461 462 return 0; 463 } 464 465 int erst_get_record_id_begin(int *pos) 466 { 467 int rc; 468 469 if (erst_disable) 470 return -ENODEV; 471 472 rc = mutex_lock_interruptible(&erst_record_id_cache.lock); 473 if (rc) 474 return rc; 475 erst_record_id_cache.refcount++; 476 mutex_unlock(&erst_record_id_cache.lock); 477 478 *pos = 0; 479 480 return 0; 481 } 482 EXPORT_SYMBOL_GPL(erst_get_record_id_begin); 483 484 /* erst_record_id_cache.lock must be held by caller */ 485 static int __erst_record_id_cache_add_one(void) 486 { 487 u64 id, prev_id, first_id; 488 int i, rc; 489 u64 *entries; 490 unsigned long flags; 491 492 id = prev_id = first_id = APEI_ERST_INVALID_RECORD_ID; 493 retry: 494 raw_spin_lock_irqsave(&erst_lock, flags); 495 rc = __erst_get_next_record_id(&id); 496 raw_spin_unlock_irqrestore(&erst_lock, flags); 497 if (rc == -ENOENT) 498 return 0; 499 if (rc) 500 return rc; 501 if (id == APEI_ERST_INVALID_RECORD_ID) 502 return 0; 503 /* can not skip current ID, or loop back to first ID */ 504 if (id == prev_id || id == first_id) 505 return 0; 506 if (first_id == APEI_ERST_INVALID_RECORD_ID) 507 first_id = id; 508 prev_id = id; 509 510 entries = erst_record_id_cache.entries; 511 for (i = 0; i < erst_record_id_cache.len; i++) { 512 if (entries[i] == id) 513 break; 514 } 515 /* record id already in cache, try next */ 516 if (i < erst_record_id_cache.len) 517 goto retry; 518 if (erst_record_id_cache.len >= erst_record_id_cache.size) { 519 int new_size, alloc_size; 520 u64 *new_entries; 521 522 new_size = erst_record_id_cache.size * 2; 523 new_size = clamp_val(new_size, ERST_RECORD_ID_CACHE_SIZE_MIN, 524 ERST_RECORD_ID_CACHE_SIZE_MAX); 525 if (new_size <= erst_record_id_cache.size) { 526 if (printk_ratelimit()) 527 pr_warn(FW_WARN "too many record IDs!\n"); 528 return 0; 529 } 530 alloc_size = new_size * sizeof(entries[0]); 531 if (alloc_size < PAGE_SIZE) 532 new_entries = kmalloc(alloc_size, GFP_KERNEL); 533 else 534 new_entries = vmalloc(alloc_size); 535 if (!new_entries) 536 return -ENOMEM; 537 memcpy(new_entries, entries, 538 erst_record_id_cache.len * sizeof(entries[0])); 539 if (erst_record_id_cache.size < PAGE_SIZE) 540 kfree(entries); 541 else 542 vfree(entries); 543 erst_record_id_cache.entries = entries = new_entries; 544 erst_record_id_cache.size = new_size; 545 } 546 entries[i] = id; 547 erst_record_id_cache.len++; 548 549 return 1; 550 } 551 552 /* 553 * Get the record ID of an existing error record on the persistent 554 * storage. If there is no error record on the persistent storage, the 555 * returned record_id is APEI_ERST_INVALID_RECORD_ID. 556 */ 557 int erst_get_record_id_next(int *pos, u64 *record_id) 558 { 559 int rc = 0; 560 u64 *entries; 561 562 if (erst_disable) 563 return -ENODEV; 564 565 /* must be enclosed by erst_get_record_id_begin/end */ 566 BUG_ON(!erst_record_id_cache.refcount); 567 BUG_ON(*pos < 0 || *pos > erst_record_id_cache.len); 568 569 mutex_lock(&erst_record_id_cache.lock); 570 entries = erst_record_id_cache.entries; 571 for (; *pos < erst_record_id_cache.len; (*pos)++) 572 if (entries[*pos] != APEI_ERST_INVALID_RECORD_ID) 573 break; 574 /* found next record id in cache */ 575 if (*pos < erst_record_id_cache.len) { 576 *record_id = entries[*pos]; 577 (*pos)++; 578 goto out_unlock; 579 } 580 581 /* Try to add one more record ID to cache */ 582 rc = __erst_record_id_cache_add_one(); 583 if (rc < 0) 584 goto out_unlock; 585 /* successfully add one new ID */ 586 if (rc == 1) { 587 *record_id = erst_record_id_cache.entries[*pos]; 588 (*pos)++; 589 rc = 0; 590 } else { 591 *pos = -1; 592 *record_id = APEI_ERST_INVALID_RECORD_ID; 593 } 594 out_unlock: 595 mutex_unlock(&erst_record_id_cache.lock); 596 597 return rc; 598 } 599 EXPORT_SYMBOL_GPL(erst_get_record_id_next); 600 601 /* erst_record_id_cache.lock must be held by caller */ 602 static void __erst_record_id_cache_compact(void) 603 { 604 int i, wpos = 0; 605 u64 *entries; 606 607 if (erst_record_id_cache.refcount) 608 return; 609 610 entries = erst_record_id_cache.entries; 611 for (i = 0; i < erst_record_id_cache.len; i++) { 612 if (entries[i] == APEI_ERST_INVALID_RECORD_ID) 613 continue; 614 if (wpos != i) 615 entries[wpos] = entries[i]; 616 wpos++; 617 } 618 erst_record_id_cache.len = wpos; 619 } 620 621 void erst_get_record_id_end(void) 622 { 623 /* 624 * erst_disable != 0 should be detected by invoker via the 625 * return value of erst_get_record_id_begin/next, so this 626 * function should not be called for erst_disable != 0. 627 */ 628 BUG_ON(erst_disable); 629 630 mutex_lock(&erst_record_id_cache.lock); 631 erst_record_id_cache.refcount--; 632 BUG_ON(erst_record_id_cache.refcount < 0); 633 __erst_record_id_cache_compact(); 634 mutex_unlock(&erst_record_id_cache.lock); 635 } 636 EXPORT_SYMBOL_GPL(erst_get_record_id_end); 637 638 static int __erst_write_to_storage(u64 offset) 639 { 640 struct apei_exec_context ctx; 641 u64 timeout = FIRMWARE_TIMEOUT; 642 u64 val; 643 int rc; 644 645 erst_exec_ctx_init(&ctx); 646 rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_WRITE); 647 if (rc) 648 return rc; 649 apei_exec_ctx_set_input(&ctx, offset); 650 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); 651 if (rc) 652 return rc; 653 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); 654 if (rc) 655 return rc; 656 for (;;) { 657 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); 658 if (rc) 659 return rc; 660 val = apei_exec_ctx_get_output(&ctx); 661 if (!val) 662 break; 663 if (erst_timedout(&timeout, SPIN_UNIT)) 664 return -EIO; 665 } 666 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); 667 if (rc) 668 return rc; 669 val = apei_exec_ctx_get_output(&ctx); 670 rc = apei_exec_run_optional(&ctx, ACPI_ERST_END); 671 if (rc) 672 return rc; 673 674 return erst_errno(val); 675 } 676 677 static int __erst_read_from_storage(u64 record_id, u64 offset) 678 { 679 struct apei_exec_context ctx; 680 u64 timeout = FIRMWARE_TIMEOUT; 681 u64 val; 682 int rc; 683 684 erst_exec_ctx_init(&ctx); 685 rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_READ); 686 if (rc) 687 return rc; 688 apei_exec_ctx_set_input(&ctx, offset); 689 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); 690 if (rc) 691 return rc; 692 apei_exec_ctx_set_input(&ctx, record_id); 693 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); 694 if (rc) 695 return rc; 696 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); 697 if (rc) 698 return rc; 699 for (;;) { 700 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); 701 if (rc) 702 return rc; 703 val = apei_exec_ctx_get_output(&ctx); 704 if (!val) 705 break; 706 if (erst_timedout(&timeout, SPIN_UNIT)) 707 return -EIO; 708 }; 709 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); 710 if (rc) 711 return rc; 712 val = apei_exec_ctx_get_output(&ctx); 713 rc = apei_exec_run_optional(&ctx, ACPI_ERST_END); 714 if (rc) 715 return rc; 716 717 return erst_errno(val); 718 } 719 720 static int __erst_clear_from_storage(u64 record_id) 721 { 722 struct apei_exec_context ctx; 723 u64 timeout = FIRMWARE_TIMEOUT; 724 u64 val; 725 int rc; 726 727 erst_exec_ctx_init(&ctx); 728 rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_CLEAR); 729 if (rc) 730 return rc; 731 apei_exec_ctx_set_input(&ctx, record_id); 732 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); 733 if (rc) 734 return rc; 735 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); 736 if (rc) 737 return rc; 738 for (;;) { 739 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); 740 if (rc) 741 return rc; 742 val = apei_exec_ctx_get_output(&ctx); 743 if (!val) 744 break; 745 if (erst_timedout(&timeout, SPIN_UNIT)) 746 return -EIO; 747 } 748 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); 749 if (rc) 750 return rc; 751 val = apei_exec_ctx_get_output(&ctx); 752 rc = apei_exec_run_optional(&ctx, ACPI_ERST_END); 753 if (rc) 754 return rc; 755 756 return erst_errno(val); 757 } 758 759 /* NVRAM ERST Error Log Address Range is not supported yet */ 760 static void pr_unimpl_nvram(void) 761 { 762 if (printk_ratelimit()) 763 pr_warn("NVRAM ERST Log Address Range 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_erst))) 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, int *count, 935 struct timespec *time, char **buf, 936 bool *compressed, struct pstore_info *psi); 937 static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason, 938 u64 *id, unsigned int part, int count, bool compressed, 939 size_t size, struct pstore_info *psi); 940 static int erst_clearer(enum pstore_type_id type, u64 id, int count, 941 struct timespec time, struct pstore_info *psi); 942 943 static struct pstore_info erst_info = { 944 .owner = THIS_MODULE, 945 .name = "erst", 946 .flags = PSTORE_FLAGS_FRAGILE, 947 .open = erst_open_pstore, 948 .close = erst_close_pstore, 949 .read = erst_reader, 950 .write = erst_writer, 951 .erase = erst_clearer 952 }; 953 954 #define CPER_CREATOR_PSTORE \ 955 UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \ 956 0x64, 0x90, 0xb8, 0x9d) 957 #define CPER_SECTION_TYPE_DMESG \ 958 UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54, \ 959 0x94, 0x19, 0xeb, 0x12) 960 #define CPER_SECTION_TYPE_DMESG_Z \ 961 UUID_LE(0x4f118707, 0x04dd, 0x4055, 0xb5, 0xdd, 0x95, 0x6d, \ 962 0x34, 0xdd, 0xfa, 0xc6) 963 #define CPER_SECTION_TYPE_MCE \ 964 UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \ 965 0x04, 0x4a, 0x38, 0xfc) 966 967 struct cper_pstore_record { 968 struct cper_record_header hdr; 969 struct cper_section_descriptor sec_hdr; 970 char data[]; 971 } __packed; 972 973 static int reader_pos; 974 975 static int erst_open_pstore(struct pstore_info *psi) 976 { 977 int rc; 978 979 if (erst_disable) 980 return -ENODEV; 981 982 rc = erst_get_record_id_begin(&reader_pos); 983 984 return rc; 985 } 986 987 static int erst_close_pstore(struct pstore_info *psi) 988 { 989 erst_get_record_id_end(); 990 991 return 0; 992 } 993 994 static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count, 995 struct timespec *time, char **buf, 996 bool *compressed, struct pstore_info *psi) 997 { 998 int rc; 999 ssize_t len = 0; 1000 u64 record_id; 1001 struct cper_pstore_record *rcd; 1002 size_t rcd_len = sizeof(*rcd) + erst_info.bufsize; 1003 1004 if (erst_disable) 1005 return -ENODEV; 1006 1007 rcd = kmalloc(rcd_len, GFP_KERNEL); 1008 if (!rcd) { 1009 rc = -ENOMEM; 1010 goto out; 1011 } 1012 skip: 1013 rc = erst_get_record_id_next(&reader_pos, &record_id); 1014 if (rc) 1015 goto out; 1016 1017 /* no more record */ 1018 if (record_id == APEI_ERST_INVALID_RECORD_ID) { 1019 rc = -EINVAL; 1020 goto out; 1021 } 1022 1023 len = erst_read(record_id, &rcd->hdr, rcd_len); 1024 /* The record may be cleared by others, try read next record */ 1025 if (len == -ENOENT) 1026 goto skip; 1027 else if (len < sizeof(*rcd)) { 1028 rc = -EIO; 1029 goto out; 1030 } 1031 if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) 1032 goto skip; 1033 1034 *buf = kmalloc(len, GFP_KERNEL); 1035 if (*buf == NULL) { 1036 rc = -ENOMEM; 1037 goto out; 1038 } 1039 memcpy(*buf, rcd->data, len - sizeof(*rcd)); 1040 *id = record_id; 1041 *compressed = false; 1042 if (uuid_le_cmp(rcd->sec_hdr.section_type, 1043 CPER_SECTION_TYPE_DMESG_Z) == 0) { 1044 *type = PSTORE_TYPE_DMESG; 1045 *compressed = true; 1046 } else if (uuid_le_cmp(rcd->sec_hdr.section_type, 1047 CPER_SECTION_TYPE_DMESG) == 0) 1048 *type = PSTORE_TYPE_DMESG; 1049 else if (uuid_le_cmp(rcd->sec_hdr.section_type, 1050 CPER_SECTION_TYPE_MCE) == 0) 1051 *type = PSTORE_TYPE_MCE; 1052 else 1053 *type = PSTORE_TYPE_UNKNOWN; 1054 1055 if (rcd->hdr.validation_bits & CPER_VALID_TIMESTAMP) 1056 time->tv_sec = rcd->hdr.timestamp; 1057 else 1058 time->tv_sec = 0; 1059 time->tv_nsec = 0; 1060 1061 out: 1062 kfree(rcd); 1063 return (rc < 0) ? rc : (len - sizeof(*rcd)); 1064 } 1065 1066 static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason, 1067 u64 *id, unsigned int part, int count, bool compressed, 1068 size_t size, struct pstore_info *psi) 1069 { 1070 struct cper_pstore_record *rcd = (struct cper_pstore_record *) 1071 (erst_info.buf - sizeof(*rcd)); 1072 int ret; 1073 1074 memset(rcd, 0, sizeof(*rcd)); 1075 memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE); 1076 rcd->hdr.revision = CPER_RECORD_REV; 1077 rcd->hdr.signature_end = CPER_SIG_END; 1078 rcd->hdr.section_count = 1; 1079 rcd->hdr.error_severity = CPER_SEV_FATAL; 1080 /* timestamp valid. platform_id, partition_id are invalid */ 1081 rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP; 1082 rcd->hdr.timestamp = get_seconds(); 1083 rcd->hdr.record_length = sizeof(*rcd) + size; 1084 rcd->hdr.creator_id = CPER_CREATOR_PSTORE; 1085 rcd->hdr.notification_type = CPER_NOTIFY_MCE; 1086 rcd->hdr.record_id = cper_next_record_id(); 1087 rcd->hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR; 1088 1089 rcd->sec_hdr.section_offset = sizeof(*rcd); 1090 rcd->sec_hdr.section_length = size; 1091 rcd->sec_hdr.revision = CPER_SEC_REV; 1092 /* fru_id and fru_text is invalid */ 1093 rcd->sec_hdr.validation_bits = 0; 1094 rcd->sec_hdr.flags = CPER_SEC_PRIMARY; 1095 switch (type) { 1096 case PSTORE_TYPE_DMESG: 1097 if (compressed) 1098 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG_Z; 1099 else 1100 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG; 1101 break; 1102 case PSTORE_TYPE_MCE: 1103 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE; 1104 break; 1105 default: 1106 return -EINVAL; 1107 } 1108 rcd->sec_hdr.section_severity = CPER_SEV_FATAL; 1109 1110 ret = erst_write(&rcd->hdr); 1111 *id = rcd->hdr.record_id; 1112 1113 return ret; 1114 } 1115 1116 static int erst_clearer(enum pstore_type_id type, u64 id, int count, 1117 struct timespec time, struct pstore_info *psi) 1118 { 1119 return erst_clear(id); 1120 } 1121 1122 static int __init erst_init(void) 1123 { 1124 int rc = 0; 1125 acpi_status status; 1126 struct apei_exec_context ctx; 1127 struct apei_resources erst_resources; 1128 struct resource *r; 1129 char *buf; 1130 1131 if (acpi_disabled) 1132 goto err; 1133 1134 if (erst_disable) { 1135 pr_info( 1136 "Error Record Serialization Table (ERST) support is disabled.\n"); 1137 goto err; 1138 } 1139 1140 status = acpi_get_table(ACPI_SIG_ERST, 0, 1141 (struct acpi_table_header **)&erst_tab); 1142 if (status == AE_NOT_FOUND) 1143 goto err; 1144 else if (ACPI_FAILURE(status)) { 1145 const char *msg = acpi_format_exception(status); 1146 pr_err("Failed to get table, %s\n", msg); 1147 rc = -EINVAL; 1148 goto err; 1149 } 1150 1151 rc = erst_check_table(erst_tab); 1152 if (rc) { 1153 pr_err(FW_BUG "ERST table is invalid.\n"); 1154 goto err; 1155 } 1156 1157 apei_resources_init(&erst_resources); 1158 erst_exec_ctx_init(&ctx); 1159 rc = apei_exec_collect_resources(&ctx, &erst_resources); 1160 if (rc) 1161 goto err_fini; 1162 rc = apei_resources_request(&erst_resources, "APEI ERST"); 1163 if (rc) 1164 goto err_fini; 1165 rc = apei_exec_pre_map_gars(&ctx); 1166 if (rc) 1167 goto err_release; 1168 rc = erst_get_erange(&erst_erange); 1169 if (rc) { 1170 if (rc == -ENODEV) 1171 pr_info( 1172 "The corresponding hardware device or firmware implementation " 1173 "is not available.\n"); 1174 else 1175 pr_err("Failed to get Error Log Address Range.\n"); 1176 goto err_unmap_reg; 1177 } 1178 1179 r = request_mem_region(erst_erange.base, erst_erange.size, "APEI ERST"); 1180 if (!r) { 1181 pr_err("Can not request [mem %#010llx-%#010llx] for ERST.\n", 1182 (unsigned long long)erst_erange.base, 1183 (unsigned long long)erst_erange.base + erst_erange.size - 1); 1184 rc = -EIO; 1185 goto err_unmap_reg; 1186 } 1187 rc = -ENOMEM; 1188 erst_erange.vaddr = ioremap_cache(erst_erange.base, 1189 erst_erange.size); 1190 if (!erst_erange.vaddr) 1191 goto err_release_erange; 1192 1193 pr_info( 1194 "Error Record Serialization Table (ERST) support is initialized.\n"); 1195 1196 buf = kmalloc(erst_erange.size, GFP_KERNEL); 1197 spin_lock_init(&erst_info.buf_lock); 1198 if (buf) { 1199 erst_info.buf = buf + sizeof(struct cper_pstore_record); 1200 erst_info.bufsize = erst_erange.size - 1201 sizeof(struct cper_pstore_record); 1202 rc = pstore_register(&erst_info); 1203 if (rc) { 1204 if (rc != -EPERM) 1205 pr_info( 1206 "Could not register with persistent store.\n"); 1207 erst_info.buf = NULL; 1208 erst_info.bufsize = 0; 1209 kfree(buf); 1210 } 1211 } else 1212 pr_err( 1213 "Failed to allocate %lld bytes for persistent store error log.\n", 1214 erst_erange.size); 1215 1216 return 0; 1217 1218 err_release_erange: 1219 release_mem_region(erst_erange.base, erst_erange.size); 1220 err_unmap_reg: 1221 apei_exec_post_unmap_gars(&ctx); 1222 err_release: 1223 apei_resources_release(&erst_resources); 1224 err_fini: 1225 apei_resources_fini(&erst_resources); 1226 err: 1227 erst_disable = 1; 1228 return rc; 1229 } 1230 1231 device_initcall(erst_init); 1232