ghes.c revision ba61ca4aab47441f1c6cec28a9a6aa0489fd1df3
1/* 2 * APEI Generic Hardware Error Source support 3 * 4 * Generic Hardware Error Source provides a way to report platform 5 * hardware errors (such as that from chipset). It works in so called 6 * "Firmware First" mode, that is, hardware errors are reported to 7 * firmware firstly, then reported to Linux by firmware. This way, 8 * some non-standard hardware error registers or non-standard hardware 9 * link can be checked by firmware to produce more hardware error 10 * information for Linux. 11 * 12 * For more information about Generic Hardware Error Source, please 13 * refer to ACPI Specification version 4.0, section 17.3.2.6 14 * 15 * Copyright 2010,2011 Intel Corp. 16 * Author: Huang Ying <ying.huang@intel.com> 17 * 18 * This program is free software; you can redistribute it and/or 19 * modify it under the terms of the GNU General Public License version 20 * 2 as published by the Free Software Foundation; 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with this program; if not, write to the Free Software 29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30 */ 31 32#include <linux/kernel.h> 33#include <linux/module.h> 34#include <linux/init.h> 35#include <linux/acpi.h> 36#include <linux/io.h> 37#include <linux/interrupt.h> 38#include <linux/timer.h> 39#include <linux/cper.h> 40#include <linux/kdebug.h> 41#include <linux/platform_device.h> 42#include <linux/mutex.h> 43#include <linux/ratelimit.h> 44#include <linux/vmalloc.h> 45#include <linux/irq_work.h> 46#include <linux/llist.h> 47#include <linux/genalloc.h> 48#include <acpi/apei.h> 49#include <acpi/atomicio.h> 50#include <acpi/hed.h> 51#include <asm/mce.h> 52#include <asm/tlbflush.h> 53 54#include "apei-internal.h" 55 56#define GHES_PFX "GHES: " 57 58#define GHES_ESTATUS_MAX_SIZE 65536 59#define GHES_ESOURCE_PREALLOC_MAX_SIZE 65536 60 61#define GHES_ESTATUS_POOL_MIN_ALLOC_ORDER 3 62 63/* This is just an estimation for memory pool allocation */ 64#define GHES_ESTATUS_CACHE_AVG_SIZE 512 65 66#define GHES_ESTATUS_CACHES_SIZE 4 67 68#define GHES_ESTATUS_IN_CACHE_MAX_NSEC (10 * NSEC_PER_SEC) 69/* Prevent too many caches are allocated because of RCU */ 70#define GHES_ESTATUS_CACHE_ALLOCED_MAX (GHES_ESTATUS_CACHES_SIZE * 3 / 2) 71 72#define GHES_ESTATUS_CACHE_LEN(estatus_len) \ 73 (sizeof(struct ghes_estatus_cache) + (estatus_len)) 74#define GHES_ESTATUS_FROM_CACHE(estatus_cache) \ 75 ((struct acpi_hest_generic_status *) \ 76 ((struct ghes_estatus_cache *)(estatus_cache) + 1)) 77 78#define GHES_ESTATUS_NODE_LEN(estatus_len) \ 79 (sizeof(struct ghes_estatus_node) + (estatus_len)) 80#define GHES_ESTATUS_FROM_NODE(estatus_node) \ 81 ((struct acpi_hest_generic_status *) \ 82 ((struct ghes_estatus_node *)(estatus_node) + 1)) 83 84/* 85 * One struct ghes is created for each generic hardware error source. 86 * It provides the context for APEI hardware error timer/IRQ/SCI/NMI 87 * handler. 88 * 89 * estatus: memory buffer for error status block, allocated during 90 * HEST parsing. 91 */ 92#define GHES_TO_CLEAR 0x0001 93#define GHES_EXITING 0x0002 94 95struct ghes { 96 struct acpi_hest_generic *generic; 97 struct acpi_hest_generic_status *estatus; 98 u64 buffer_paddr; 99 unsigned long flags; 100 union { 101 struct list_head list; 102 struct timer_list timer; 103 unsigned int irq; 104 }; 105}; 106 107struct ghes_estatus_node { 108 struct llist_node llnode; 109 struct acpi_hest_generic *generic; 110}; 111 112struct ghes_estatus_cache { 113 u32 estatus_len; 114 atomic_t count; 115 struct acpi_hest_generic *generic; 116 unsigned long long time_in; 117 struct rcu_head rcu; 118}; 119 120int ghes_disable; 121module_param_named(disable, ghes_disable, bool, 0); 122 123static int ghes_panic_timeout __read_mostly = 30; 124 125/* 126 * All error sources notified with SCI shares one notifier function, 127 * so they need to be linked and checked one by one. This is applied 128 * to NMI too. 129 * 130 * RCU is used for these lists, so ghes_list_mutex is only used for 131 * list changing, not for traversing. 132 */ 133static LIST_HEAD(ghes_sci); 134static LIST_HEAD(ghes_nmi); 135static DEFINE_MUTEX(ghes_list_mutex); 136 137/* 138 * NMI may be triggered on any CPU, so ghes_nmi_lock is used for 139 * mutual exclusion. 140 */ 141static DEFINE_RAW_SPINLOCK(ghes_nmi_lock); 142 143/* 144 * Because the memory area used to transfer hardware error information 145 * from BIOS to Linux can be determined only in NMI, IRQ or timer 146 * handler, but general ioremap can not be used in atomic context, so 147 * a special version of atomic ioremap is implemented for that. 148 */ 149 150/* 151 * Two virtual pages are used, one for NMI context, the other for 152 * IRQ/PROCESS context 153 */ 154#define GHES_IOREMAP_PAGES 2 155#define GHES_IOREMAP_NMI_PAGE(base) (base) 156#define GHES_IOREMAP_IRQ_PAGE(base) ((base) + PAGE_SIZE) 157 158/* virtual memory area for atomic ioremap */ 159static struct vm_struct *ghes_ioremap_area; 160/* 161 * These 2 spinlock is used to prevent atomic ioremap virtual memory 162 * area from being mapped simultaneously. 163 */ 164static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi); 165static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); 166 167/* 168 * printk is not safe in NMI context. So in NMI handler, we allocate 169 * required memory from lock-less memory allocator 170 * (ghes_estatus_pool), save estatus into it, put them into lock-less 171 * list (ghes_estatus_llist), then delay printk into IRQ context via 172 * irq_work (ghes_proc_irq_work). ghes_estatus_size_request record 173 * required pool size by all NMI error source. 174 */ 175static struct gen_pool *ghes_estatus_pool; 176static unsigned long ghes_estatus_pool_size_request; 177static struct llist_head ghes_estatus_llist; 178static struct irq_work ghes_proc_irq_work; 179 180struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; 181static atomic_t ghes_estatus_cache_alloced; 182 183static int ghes_ioremap_init(void) 184{ 185 ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES, 186 VM_IOREMAP, VMALLOC_START, VMALLOC_END); 187 if (!ghes_ioremap_area) { 188 pr_err(GHES_PFX "Failed to allocate virtual memory area for atomic ioremap.\n"); 189 return -ENOMEM; 190 } 191 192 return 0; 193} 194 195static void ghes_ioremap_exit(void) 196{ 197 free_vm_area(ghes_ioremap_area); 198} 199 200static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn) 201{ 202 unsigned long vaddr; 203 204 vaddr = (unsigned long)GHES_IOREMAP_NMI_PAGE(ghes_ioremap_area->addr); 205 ioremap_page_range(vaddr, vaddr + PAGE_SIZE, 206 pfn << PAGE_SHIFT, PAGE_KERNEL); 207 208 return (void __iomem *)vaddr; 209} 210 211static void __iomem *ghes_ioremap_pfn_irq(u64 pfn) 212{ 213 unsigned long vaddr; 214 215 vaddr = (unsigned long)GHES_IOREMAP_IRQ_PAGE(ghes_ioremap_area->addr); 216 ioremap_page_range(vaddr, vaddr + PAGE_SIZE, 217 pfn << PAGE_SHIFT, PAGE_KERNEL); 218 219 return (void __iomem *)vaddr; 220} 221 222static void ghes_iounmap_nmi(void __iomem *vaddr_ptr) 223{ 224 unsigned long vaddr = (unsigned long __force)vaddr_ptr; 225 void *base = ghes_ioremap_area->addr; 226 227 BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base)); 228 unmap_kernel_range_noflush(vaddr, PAGE_SIZE); 229 __flush_tlb_one(vaddr); 230} 231 232static void ghes_iounmap_irq(void __iomem *vaddr_ptr) 233{ 234 unsigned long vaddr = (unsigned long __force)vaddr_ptr; 235 void *base = ghes_ioremap_area->addr; 236 237 BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base)); 238 unmap_kernel_range_noflush(vaddr, PAGE_SIZE); 239 __flush_tlb_one(vaddr); 240} 241 242static int ghes_estatus_pool_init(void) 243{ 244 ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1); 245 if (!ghes_estatus_pool) 246 return -ENOMEM; 247 return 0; 248} 249 250static void ghes_estatus_pool_free_chunk_page(struct gen_pool *pool, 251 struct gen_pool_chunk *chunk, 252 void *data) 253{ 254 free_page(chunk->start_addr); 255} 256 257static void ghes_estatus_pool_exit(void) 258{ 259 gen_pool_for_each_chunk(ghes_estatus_pool, 260 ghes_estatus_pool_free_chunk_page, NULL); 261 gen_pool_destroy(ghes_estatus_pool); 262} 263 264static int ghes_estatus_pool_expand(unsigned long len) 265{ 266 unsigned long i, pages, size, addr; 267 int ret; 268 269 ghes_estatus_pool_size_request += PAGE_ALIGN(len); 270 size = gen_pool_size(ghes_estatus_pool); 271 if (size >= ghes_estatus_pool_size_request) 272 return 0; 273 pages = (ghes_estatus_pool_size_request - size) / PAGE_SIZE; 274 for (i = 0; i < pages; i++) { 275 addr = __get_free_page(GFP_KERNEL); 276 if (!addr) 277 return -ENOMEM; 278 ret = gen_pool_add(ghes_estatus_pool, addr, PAGE_SIZE, -1); 279 if (ret) 280 return ret; 281 } 282 283 return 0; 284} 285 286static void ghes_estatus_pool_shrink(unsigned long len) 287{ 288 ghes_estatus_pool_size_request -= PAGE_ALIGN(len); 289} 290 291static struct ghes *ghes_new(struct acpi_hest_generic *generic) 292{ 293 struct ghes *ghes; 294 unsigned int error_block_length; 295 int rc; 296 297 ghes = kzalloc(sizeof(*ghes), GFP_KERNEL); 298 if (!ghes) 299 return ERR_PTR(-ENOMEM); 300 ghes->generic = generic; 301 rc = acpi_pre_map_gar(&generic->error_status_address); 302 if (rc) 303 goto err_free; 304 error_block_length = generic->error_block_length; 305 if (error_block_length > GHES_ESTATUS_MAX_SIZE) { 306 pr_warning(FW_WARN GHES_PFX 307 "Error status block length is too long: %u for " 308 "generic hardware error source: %d.\n", 309 error_block_length, generic->header.source_id); 310 error_block_length = GHES_ESTATUS_MAX_SIZE; 311 } 312 ghes->estatus = kmalloc(error_block_length, GFP_KERNEL); 313 if (!ghes->estatus) { 314 rc = -ENOMEM; 315 goto err_unmap; 316 } 317 318 return ghes; 319 320err_unmap: 321 acpi_post_unmap_gar(&generic->error_status_address); 322err_free: 323 kfree(ghes); 324 return ERR_PTR(rc); 325} 326 327static void ghes_fini(struct ghes *ghes) 328{ 329 kfree(ghes->estatus); 330 acpi_post_unmap_gar(&ghes->generic->error_status_address); 331} 332 333enum { 334 GHES_SEV_NO = 0x0, 335 GHES_SEV_CORRECTED = 0x1, 336 GHES_SEV_RECOVERABLE = 0x2, 337 GHES_SEV_PANIC = 0x3, 338}; 339 340static inline int ghes_severity(int severity) 341{ 342 switch (severity) { 343 case CPER_SEV_INFORMATIONAL: 344 return GHES_SEV_NO; 345 case CPER_SEV_CORRECTED: 346 return GHES_SEV_CORRECTED; 347 case CPER_SEV_RECOVERABLE: 348 return GHES_SEV_RECOVERABLE; 349 case CPER_SEV_FATAL: 350 return GHES_SEV_PANIC; 351 default: 352 /* Unknown, go panic */ 353 return GHES_SEV_PANIC; 354 } 355} 356 357static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, 358 int from_phys) 359{ 360 void __iomem *vaddr; 361 unsigned long flags = 0; 362 int in_nmi = in_nmi(); 363 u64 offset; 364 u32 trunk; 365 366 while (len > 0) { 367 offset = paddr - (paddr & PAGE_MASK); 368 if (in_nmi) { 369 raw_spin_lock(&ghes_ioremap_lock_nmi); 370 vaddr = ghes_ioremap_pfn_nmi(paddr >> PAGE_SHIFT); 371 } else { 372 spin_lock_irqsave(&ghes_ioremap_lock_irq, flags); 373 vaddr = ghes_ioremap_pfn_irq(paddr >> PAGE_SHIFT); 374 } 375 trunk = PAGE_SIZE - offset; 376 trunk = min(trunk, len); 377 if (from_phys) 378 memcpy_fromio(buffer, vaddr + offset, trunk); 379 else 380 memcpy_toio(vaddr + offset, buffer, trunk); 381 len -= trunk; 382 paddr += trunk; 383 buffer += trunk; 384 if (in_nmi) { 385 ghes_iounmap_nmi(vaddr); 386 raw_spin_unlock(&ghes_ioremap_lock_nmi); 387 } else { 388 ghes_iounmap_irq(vaddr); 389 spin_unlock_irqrestore(&ghes_ioremap_lock_irq, flags); 390 } 391 } 392} 393 394static int ghes_read_estatus(struct ghes *ghes, int silent) 395{ 396 struct acpi_hest_generic *g = ghes->generic; 397 u64 buf_paddr; 398 u32 len; 399 int rc; 400 401 rc = acpi_atomic_read(&buf_paddr, &g->error_status_address); 402 if (rc) { 403 if (!silent && printk_ratelimit()) 404 pr_warning(FW_WARN GHES_PFX 405"Failed to read error status block address for hardware error source: %d.\n", 406 g->header.source_id); 407 return -EIO; 408 } 409 if (!buf_paddr) 410 return -ENOENT; 411 412 ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, 413 sizeof(*ghes->estatus), 1); 414 if (!ghes->estatus->block_status) 415 return -ENOENT; 416 417 ghes->buffer_paddr = buf_paddr; 418 ghes->flags |= GHES_TO_CLEAR; 419 420 rc = -EIO; 421 len = apei_estatus_len(ghes->estatus); 422 if (len < sizeof(*ghes->estatus)) 423 goto err_read_block; 424 if (len > ghes->generic->error_block_length) 425 goto err_read_block; 426 if (apei_estatus_check_header(ghes->estatus)) 427 goto err_read_block; 428 ghes_copy_tofrom_phys(ghes->estatus + 1, 429 buf_paddr + sizeof(*ghes->estatus), 430 len - sizeof(*ghes->estatus), 1); 431 if (apei_estatus_check(ghes->estatus)) 432 goto err_read_block; 433 rc = 0; 434 435err_read_block: 436 if (rc && !silent && printk_ratelimit()) 437 pr_warning(FW_WARN GHES_PFX 438 "Failed to read error status block!\n"); 439 return rc; 440} 441 442static void ghes_clear_estatus(struct ghes *ghes) 443{ 444 ghes->estatus->block_status = 0; 445 if (!(ghes->flags & GHES_TO_CLEAR)) 446 return; 447 ghes_copy_tofrom_phys(ghes->estatus, ghes->buffer_paddr, 448 sizeof(ghes->estatus->block_status), 0); 449 ghes->flags &= ~GHES_TO_CLEAR; 450} 451 452static void ghes_do_proc(const struct acpi_hest_generic_status *estatus) 453{ 454 int sev, sec_sev; 455 struct acpi_hest_generic_data *gdata; 456 457 sev = ghes_severity(estatus->error_severity); 458 apei_estatus_for_each_section(estatus, gdata) { 459 sec_sev = ghes_severity(gdata->error_severity); 460 if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, 461 CPER_SEC_PLATFORM_MEM)) { 462 struct cper_sec_mem_err *mem_err; 463 mem_err = (struct cper_sec_mem_err *)(gdata+1); 464#ifdef CONFIG_X86_MCE 465 apei_mce_report_mem_error(sev == GHES_SEV_CORRECTED, 466 mem_err); 467#endif 468#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE 469 if (sev == GHES_SEV_RECOVERABLE && 470 sec_sev == GHES_SEV_RECOVERABLE && 471 mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) { 472 unsigned long pfn; 473 pfn = mem_err->physical_addr >> PAGE_SHIFT; 474 memory_failure_queue(pfn, 0, 0); 475 } 476#endif 477 } 478 } 479} 480 481static void __ghes_print_estatus(const char *pfx, 482 const struct acpi_hest_generic *generic, 483 const struct acpi_hest_generic_status *estatus) 484{ 485 if (pfx == NULL) { 486 if (ghes_severity(estatus->error_severity) <= 487 GHES_SEV_CORRECTED) 488 pfx = KERN_WARNING HW_ERR; 489 else 490 pfx = KERN_ERR HW_ERR; 491 } 492 printk("%s""Hardware error from APEI Generic Hardware Error Source: %d\n", 493 pfx, generic->header.source_id); 494 apei_estatus_print(pfx, estatus); 495} 496 497static int ghes_print_estatus(const char *pfx, 498 const struct acpi_hest_generic *generic, 499 const struct acpi_hest_generic_status *estatus) 500{ 501 /* Not more than 2 messages every 5 seconds */ 502 static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); 503 static DEFINE_RATELIMIT_STATE(ratelimit_uncorrected, 5*HZ, 2); 504 struct ratelimit_state *ratelimit; 505 506 if (ghes_severity(estatus->error_severity) <= GHES_SEV_CORRECTED) 507 ratelimit = &ratelimit_corrected; 508 else 509 ratelimit = &ratelimit_uncorrected; 510 if (__ratelimit(ratelimit)) { 511 __ghes_print_estatus(pfx, generic, estatus); 512 return 1; 513 } 514 return 0; 515} 516 517/* 518 * GHES error status reporting throttle, to report more kinds of 519 * errors, instead of just most frequently occurred errors. 520 */ 521static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus) 522{ 523 u32 len; 524 int i, cached = 0; 525 unsigned long long now; 526 struct ghes_estatus_cache *cache; 527 struct acpi_hest_generic_status *cache_estatus; 528 529 len = apei_estatus_len(estatus); 530 rcu_read_lock(); 531 for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) { 532 cache = rcu_dereference(ghes_estatus_caches[i]); 533 if (cache == NULL) 534 continue; 535 if (len != cache->estatus_len) 536 continue; 537 cache_estatus = GHES_ESTATUS_FROM_CACHE(cache); 538 if (memcmp(estatus, cache_estatus, len)) 539 continue; 540 atomic_inc(&cache->count); 541 now = sched_clock(); 542 if (now - cache->time_in < GHES_ESTATUS_IN_CACHE_MAX_NSEC) 543 cached = 1; 544 break; 545 } 546 rcu_read_unlock(); 547 return cached; 548} 549 550static struct ghes_estatus_cache *ghes_estatus_cache_alloc( 551 struct acpi_hest_generic *generic, 552 struct acpi_hest_generic_status *estatus) 553{ 554 int alloced; 555 u32 len, cache_len; 556 struct ghes_estatus_cache *cache; 557 struct acpi_hest_generic_status *cache_estatus; 558 559 alloced = atomic_add_return(1, &ghes_estatus_cache_alloced); 560 if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) { 561 atomic_dec(&ghes_estatus_cache_alloced); 562 return NULL; 563 } 564 len = apei_estatus_len(estatus); 565 cache_len = GHES_ESTATUS_CACHE_LEN(len); 566 cache = (void *)gen_pool_alloc(ghes_estatus_pool, cache_len); 567 if (!cache) { 568 atomic_dec(&ghes_estatus_cache_alloced); 569 return NULL; 570 } 571 cache_estatus = GHES_ESTATUS_FROM_CACHE(cache); 572 memcpy(cache_estatus, estatus, len); 573 cache->estatus_len = len; 574 atomic_set(&cache->count, 0); 575 cache->generic = generic; 576 cache->time_in = sched_clock(); 577 return cache; 578} 579 580static void ghes_estatus_cache_free(struct ghes_estatus_cache *cache) 581{ 582 u32 len; 583 584 len = apei_estatus_len(GHES_ESTATUS_FROM_CACHE(cache)); 585 len = GHES_ESTATUS_CACHE_LEN(len); 586 gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len); 587 atomic_dec(&ghes_estatus_cache_alloced); 588} 589 590static void ghes_estatus_cache_rcu_free(struct rcu_head *head) 591{ 592 struct ghes_estatus_cache *cache; 593 594 cache = container_of(head, struct ghes_estatus_cache, rcu); 595 ghes_estatus_cache_free(cache); 596} 597 598static void ghes_estatus_cache_add( 599 struct acpi_hest_generic *generic, 600 struct acpi_hest_generic_status *estatus) 601{ 602 int i, slot = -1, count; 603 unsigned long long now, duration, period, max_period = 0; 604 struct ghes_estatus_cache *cache, *slot_cache = NULL, *new_cache; 605 606 new_cache = ghes_estatus_cache_alloc(generic, estatus); 607 if (new_cache == NULL) 608 return; 609 rcu_read_lock(); 610 now = sched_clock(); 611 for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) { 612 cache = rcu_dereference(ghes_estatus_caches[i]); 613 if (cache == NULL) { 614 slot = i; 615 slot_cache = NULL; 616 break; 617 } 618 duration = now - cache->time_in; 619 if (duration >= GHES_ESTATUS_IN_CACHE_MAX_NSEC) { 620 slot = i; 621 slot_cache = cache; 622 break; 623 } 624 count = atomic_read(&cache->count); 625 period = duration / (count + 1); 626 if (period > max_period) { 627 max_period = period; 628 slot = i; 629 slot_cache = cache; 630 } 631 } 632 /* new_cache must be put into array after its contents are written */ 633 smp_wmb(); 634 if (slot != -1 && cmpxchg(ghes_estatus_caches + slot, 635 slot_cache, new_cache) == slot_cache) { 636 if (slot_cache) 637 call_rcu(&slot_cache->rcu, ghes_estatus_cache_rcu_free); 638 } else 639 ghes_estatus_cache_free(new_cache); 640 rcu_read_unlock(); 641} 642 643static int ghes_proc(struct ghes *ghes) 644{ 645 int rc; 646 647 rc = ghes_read_estatus(ghes, 0); 648 if (rc) 649 goto out; 650 if (!ghes_estatus_cached(ghes->estatus)) { 651 if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus)) 652 ghes_estatus_cache_add(ghes->generic, ghes->estatus); 653 } 654 ghes_do_proc(ghes->estatus); 655out: 656 ghes_clear_estatus(ghes); 657 return 0; 658} 659 660static void ghes_add_timer(struct ghes *ghes) 661{ 662 struct acpi_hest_generic *g = ghes->generic; 663 unsigned long expire; 664 665 if (!g->notify.poll_interval) { 666 pr_warning(FW_WARN GHES_PFX "Poll interval is 0 for generic hardware error source: %d, disabled.\n", 667 g->header.source_id); 668 return; 669 } 670 expire = jiffies + msecs_to_jiffies(g->notify.poll_interval); 671 ghes->timer.expires = round_jiffies_relative(expire); 672 add_timer(&ghes->timer); 673} 674 675static void ghes_poll_func(unsigned long data) 676{ 677 struct ghes *ghes = (void *)data; 678 679 ghes_proc(ghes); 680 if (!(ghes->flags & GHES_EXITING)) 681 ghes_add_timer(ghes); 682} 683 684static irqreturn_t ghes_irq_func(int irq, void *data) 685{ 686 struct ghes *ghes = data; 687 int rc; 688 689 rc = ghes_proc(ghes); 690 if (rc) 691 return IRQ_NONE; 692 693 return IRQ_HANDLED; 694} 695 696static int ghes_notify_sci(struct notifier_block *this, 697 unsigned long event, void *data) 698{ 699 struct ghes *ghes; 700 int ret = NOTIFY_DONE; 701 702 rcu_read_lock(); 703 list_for_each_entry_rcu(ghes, &ghes_sci, list) { 704 if (!ghes_proc(ghes)) 705 ret = NOTIFY_OK; 706 } 707 rcu_read_unlock(); 708 709 return ret; 710} 711 712static void ghes_proc_in_irq(struct irq_work *irq_work) 713{ 714 struct llist_node *llnode, *next, *tail = NULL; 715 struct ghes_estatus_node *estatus_node; 716 struct acpi_hest_generic *generic; 717 struct acpi_hest_generic_status *estatus; 718 u32 len, node_len; 719 720 /* 721 * Because the time order of estatus in list is reversed, 722 * revert it back to proper order. 723 */ 724 llnode = llist_del_all(&ghes_estatus_llist); 725 while (llnode) { 726 next = llnode->next; 727 llnode->next = tail; 728 tail = llnode; 729 llnode = next; 730 } 731 llnode = tail; 732 while (llnode) { 733 next = llnode->next; 734 estatus_node = llist_entry(llnode, struct ghes_estatus_node, 735 llnode); 736 estatus = GHES_ESTATUS_FROM_NODE(estatus_node); 737 len = apei_estatus_len(estatus); 738 node_len = GHES_ESTATUS_NODE_LEN(len); 739 ghes_do_proc(estatus); 740 if (!ghes_estatus_cached(estatus)) { 741 generic = estatus_node->generic; 742 if (ghes_print_estatus(NULL, generic, estatus)) 743 ghes_estatus_cache_add(generic, estatus); 744 } 745 gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, 746 node_len); 747 llnode = next; 748 } 749} 750 751static int ghes_notify_nmi(struct notifier_block *this, 752 unsigned long cmd, void *data) 753{ 754 struct ghes *ghes, *ghes_global = NULL; 755 int sev, sev_global = -1; 756 int ret = NOTIFY_DONE; 757 758 if (cmd != DIE_NMI) 759 return ret; 760 761 raw_spin_lock(&ghes_nmi_lock); 762 list_for_each_entry_rcu(ghes, &ghes_nmi, list) { 763 if (ghes_read_estatus(ghes, 1)) { 764 ghes_clear_estatus(ghes); 765 continue; 766 } 767 sev = ghes_severity(ghes->estatus->error_severity); 768 if (sev > sev_global) { 769 sev_global = sev; 770 ghes_global = ghes; 771 } 772 ret = NOTIFY_STOP; 773 } 774 775 if (ret == NOTIFY_DONE) 776 goto out; 777 778 if (sev_global >= GHES_SEV_PANIC) { 779 oops_begin(); 780 __ghes_print_estatus(KERN_EMERG HW_ERR, ghes_global->generic, 781 ghes_global->estatus); 782 /* reboot to log the error! */ 783 if (panic_timeout == 0) 784 panic_timeout = ghes_panic_timeout; 785 panic("Fatal hardware error!"); 786 } 787 788 list_for_each_entry_rcu(ghes, &ghes_nmi, list) { 789#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG 790 u32 len, node_len; 791 struct ghes_estatus_node *estatus_node; 792 struct acpi_hest_generic_status *estatus; 793#endif 794 if (!(ghes->flags & GHES_TO_CLEAR)) 795 continue; 796#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG 797 if (ghes_estatus_cached(ghes->estatus)) 798 goto next; 799 /* Save estatus for further processing in IRQ context */ 800 len = apei_estatus_len(ghes->estatus); 801 node_len = GHES_ESTATUS_NODE_LEN(len); 802 estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, 803 node_len); 804 if (estatus_node) { 805 estatus_node->generic = ghes->generic; 806 estatus = GHES_ESTATUS_FROM_NODE(estatus_node); 807 memcpy(estatus, ghes->estatus, len); 808 llist_add(&estatus_node->llnode, &ghes_estatus_llist); 809 } 810next: 811#endif 812 ghes_clear_estatus(ghes); 813 } 814#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG 815 irq_work_queue(&ghes_proc_irq_work); 816#endif 817 818out: 819 raw_spin_unlock(&ghes_nmi_lock); 820 return ret; 821} 822 823static struct notifier_block ghes_notifier_sci = { 824 .notifier_call = ghes_notify_sci, 825}; 826 827static struct notifier_block ghes_notifier_nmi = { 828 .notifier_call = ghes_notify_nmi, 829}; 830 831static unsigned long ghes_esource_prealloc_size( 832 const struct acpi_hest_generic *generic) 833{ 834 unsigned long block_length, prealloc_records, prealloc_size; 835 836 block_length = min_t(unsigned long, generic->error_block_length, 837 GHES_ESTATUS_MAX_SIZE); 838 prealloc_records = max_t(unsigned long, 839 generic->records_to_preallocate, 1); 840 prealloc_size = min_t(unsigned long, block_length * prealloc_records, 841 GHES_ESOURCE_PREALLOC_MAX_SIZE); 842 843 return prealloc_size; 844} 845 846static int __devinit ghes_probe(struct platform_device *ghes_dev) 847{ 848 struct acpi_hest_generic *generic; 849 struct ghes *ghes = NULL; 850 unsigned long len; 851 int rc = -EINVAL; 852 853 generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data; 854 if (!generic->enabled) 855 return -ENODEV; 856 857 switch (generic->notify.type) { 858 case ACPI_HEST_NOTIFY_POLLED: 859 case ACPI_HEST_NOTIFY_EXTERNAL: 860 case ACPI_HEST_NOTIFY_SCI: 861 case ACPI_HEST_NOTIFY_NMI: 862 break; 863 case ACPI_HEST_NOTIFY_LOCAL: 864 pr_warning(GHES_PFX "Generic hardware error source: %d notified via local interrupt is not supported!\n", 865 generic->header.source_id); 866 goto err; 867 default: 868 pr_warning(FW_WARN GHES_PFX "Unknown notification type: %u for generic hardware error source: %d\n", 869 generic->notify.type, generic->header.source_id); 870 goto err; 871 } 872 873 rc = -EIO; 874 if (generic->error_block_length < 875 sizeof(struct acpi_hest_generic_status)) { 876 pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n", 877 generic->error_block_length, 878 generic->header.source_id); 879 goto err; 880 } 881 ghes = ghes_new(generic); 882 if (IS_ERR(ghes)) { 883 rc = PTR_ERR(ghes); 884 ghes = NULL; 885 goto err; 886 } 887 switch (generic->notify.type) { 888 case ACPI_HEST_NOTIFY_POLLED: 889 ghes->timer.function = ghes_poll_func; 890 ghes->timer.data = (unsigned long)ghes; 891 init_timer_deferrable(&ghes->timer); 892 ghes_add_timer(ghes); 893 break; 894 case ACPI_HEST_NOTIFY_EXTERNAL: 895 /* External interrupt vector is GSI */ 896 if (acpi_gsi_to_irq(generic->notify.vector, &ghes->irq)) { 897 pr_err(GHES_PFX "Failed to map GSI to IRQ for generic hardware error source: %d\n", 898 generic->header.source_id); 899 goto err; 900 } 901 if (request_irq(ghes->irq, ghes_irq_func, 902 0, "GHES IRQ", ghes)) { 903 pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n", 904 generic->header.source_id); 905 goto err; 906 } 907 break; 908 case ACPI_HEST_NOTIFY_SCI: 909 mutex_lock(&ghes_list_mutex); 910 if (list_empty(&ghes_sci)) 911 register_acpi_hed_notifier(&ghes_notifier_sci); 912 list_add_rcu(&ghes->list, &ghes_sci); 913 mutex_unlock(&ghes_list_mutex); 914 break; 915 case ACPI_HEST_NOTIFY_NMI: 916 len = ghes_esource_prealloc_size(generic); 917 ghes_estatus_pool_expand(len); 918 mutex_lock(&ghes_list_mutex); 919 if (list_empty(&ghes_nmi)) 920 register_die_notifier(&ghes_notifier_nmi); 921 list_add_rcu(&ghes->list, &ghes_nmi); 922 mutex_unlock(&ghes_list_mutex); 923 break; 924 default: 925 BUG(); 926 } 927 platform_set_drvdata(ghes_dev, ghes); 928 929 return 0; 930err: 931 if (ghes) { 932 ghes_fini(ghes); 933 kfree(ghes); 934 } 935 return rc; 936} 937 938static int __devexit ghes_remove(struct platform_device *ghes_dev) 939{ 940 struct ghes *ghes; 941 struct acpi_hest_generic *generic; 942 unsigned long len; 943 944 ghes = platform_get_drvdata(ghes_dev); 945 generic = ghes->generic; 946 947 ghes->flags |= GHES_EXITING; 948 switch (generic->notify.type) { 949 case ACPI_HEST_NOTIFY_POLLED: 950 del_timer_sync(&ghes->timer); 951 break; 952 case ACPI_HEST_NOTIFY_EXTERNAL: 953 free_irq(ghes->irq, ghes); 954 break; 955 case ACPI_HEST_NOTIFY_SCI: 956 mutex_lock(&ghes_list_mutex); 957 list_del_rcu(&ghes->list); 958 if (list_empty(&ghes_sci)) 959 unregister_acpi_hed_notifier(&ghes_notifier_sci); 960 mutex_unlock(&ghes_list_mutex); 961 break; 962 case ACPI_HEST_NOTIFY_NMI: 963 mutex_lock(&ghes_list_mutex); 964 list_del_rcu(&ghes->list); 965 if (list_empty(&ghes_nmi)) 966 unregister_die_notifier(&ghes_notifier_nmi); 967 mutex_unlock(&ghes_list_mutex); 968 /* 969 * To synchronize with NMI handler, ghes can only be 970 * freed after NMI handler finishes. 971 */ 972 synchronize_rcu(); 973 len = ghes_esource_prealloc_size(generic); 974 ghes_estatus_pool_shrink(len); 975 break; 976 default: 977 BUG(); 978 break; 979 } 980 981 ghes_fini(ghes); 982 kfree(ghes); 983 984 platform_set_drvdata(ghes_dev, NULL); 985 986 return 0; 987} 988 989static struct platform_driver ghes_platform_driver = { 990 .driver = { 991 .name = "GHES", 992 .owner = THIS_MODULE, 993 }, 994 .probe = ghes_probe, 995 .remove = ghes_remove, 996}; 997 998static int __init ghes_init(void) 999{ 1000 int rc; 1001 1002 if (acpi_disabled) 1003 return -ENODEV; 1004 1005 if (hest_disable) { 1006 pr_info(GHES_PFX "HEST is not enabled!\n"); 1007 return -EINVAL; 1008 } 1009 1010 if (ghes_disable) { 1011 pr_info(GHES_PFX "GHES is not enabled!\n"); 1012 return -EINVAL; 1013 } 1014 1015 init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq); 1016 1017 rc = ghes_ioremap_init(); 1018 if (rc) 1019 goto err; 1020 1021 rc = ghes_estatus_pool_init(); 1022 if (rc) 1023 goto err_ioremap_exit; 1024 1025 rc = ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE * 1026 GHES_ESTATUS_CACHE_ALLOCED_MAX); 1027 if (rc) 1028 goto err_pool_exit; 1029 1030 rc = platform_driver_register(&ghes_platform_driver); 1031 if (rc) 1032 goto err_pool_exit; 1033 1034 rc = apei_osc_setup(); 1035 if (rc == 0 && osc_sb_apei_support_acked) 1036 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n"); 1037 else if (rc == 0 && !osc_sb_apei_support_acked) 1038 pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n"); 1039 else if (rc && osc_sb_apei_support_acked) 1040 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n"); 1041 else 1042 pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n"); 1043 1044 return 0; 1045err_pool_exit: 1046 ghes_estatus_pool_exit(); 1047err_ioremap_exit: 1048 ghes_ioremap_exit(); 1049err: 1050 return rc; 1051} 1052 1053static void __exit ghes_exit(void) 1054{ 1055 platform_driver_unregister(&ghes_platform_driver); 1056 ghes_estatus_pool_exit(); 1057 ghes_ioremap_exit(); 1058} 1059 1060module_init(ghes_init); 1061module_exit(ghes_exit); 1062 1063MODULE_AUTHOR("Huang Ying"); 1064MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); 1065MODULE_LICENSE("GPL"); 1066MODULE_ALIAS("platform:GHES"); 1067