root/drivers/acpi/apei/ghes.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_hest_type_generic_v2
  2. ghes_map
  3. ghes_unmap
  4. ghes_estatus_pool_init
  5. map_gen_v2
  6. unmap_gen_v2
  7. ghes_ack_error
  8. ghes_new
  9. ghes_fini
  10. ghes_severity
  11. ghes_copy_tofrom_phys
  12. __ghes_check_estatus
  13. __ghes_peek_estatus
  14. __ghes_read_estatus
  15. ghes_read_estatus
  16. ghes_clear_estatus
  17. ghes_handle_memory_failure
  18. ghes_handle_aer
  19. ghes_do_proc
  20. __ghes_print_estatus
  21. ghes_print_estatus
  22. ghes_estatus_cached
  23. ghes_estatus_cache_alloc
  24. ghes_estatus_cache_free
  25. ghes_estatus_cache_rcu_free
  26. ghes_estatus_cache_add
  27. __ghes_panic
  28. ghes_proc
  29. ghes_add_timer
  30. ghes_poll_func
  31. ghes_irq_func
  32. ghes_notify_hed
  33. ghes_proc_in_irq
  34. ghes_print_queued_estatus
  35. ghes_in_nmi_queue_one_entry
  36. ghes_in_nmi_spool_from_list
  37. ghes_notify_sea
  38. ghes_sea_add
  39. ghes_sea_remove
  40. ghes_sea_add
  41. ghes_sea_remove
  42. ghes_notify_nmi
  43. ghes_nmi_add
  44. ghes_nmi_remove
  45. ghes_nmi_add
  46. ghes_nmi_remove
  47. ghes_nmi_init_cxt
  48. __ghes_sdei_callback
  49. ghes_sdei_normal_callback
  50. ghes_sdei_critical_callback
  51. apei_sdei_register_ghes
  52. apei_sdei_unregister_ghes
  53. ghes_probe
  54. ghes_remove
  55. ghes_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * APEI Generic Hardware Error Source support
   4  *
   5  * Generic Hardware Error Source provides a way to report platform
   6  * hardware errors (such as that from chipset). It works in so called
   7  * "Firmware First" mode, that is, hardware errors are reported to
   8  * firmware firstly, then reported to Linux by firmware. This way,
   9  * some non-standard hardware error registers or non-standard hardware
  10  * link can be checked by firmware to produce more hardware error
  11  * information for Linux.
  12  *
  13  * For more information about Generic Hardware Error Source, please
  14  * refer to ACPI Specification version 4.0, section 17.3.2.6
  15  *
  16  * Copyright 2010,2011 Intel Corp.
  17  *   Author: Huang Ying <ying.huang@intel.com>
  18  */
  19 
  20 #include <linux/arm_sdei.h>
  21 #include <linux/kernel.h>
  22 #include <linux/moduleparam.h>
  23 #include <linux/init.h>
  24 #include <linux/acpi.h>
  25 #include <linux/io.h>
  26 #include <linux/interrupt.h>
  27 #include <linux/timer.h>
  28 #include <linux/cper.h>
  29 #include <linux/platform_device.h>
  30 #include <linux/mutex.h>
  31 #include <linux/ratelimit.h>
  32 #include <linux/vmalloc.h>
  33 #include <linux/irq_work.h>
  34 #include <linux/llist.h>
  35 #include <linux/genalloc.h>
  36 #include <linux/pci.h>
  37 #include <linux/pfn.h>
  38 #include <linux/aer.h>
  39 #include <linux/nmi.h>
  40 #include <linux/sched/clock.h>
  41 #include <linux/uuid.h>
  42 #include <linux/ras.h>
  43 
  44 #include <acpi/actbl1.h>
  45 #include <acpi/ghes.h>
  46 #include <acpi/apei.h>
  47 #include <asm/fixmap.h>
  48 #include <asm/tlbflush.h>
  49 #include <ras/ras_event.h>
  50 
  51 #include "apei-internal.h"
  52 
  53 #define GHES_PFX        "GHES: "
  54 
  55 #define GHES_ESTATUS_MAX_SIZE           65536
  56 #define GHES_ESOURCE_PREALLOC_MAX_SIZE  65536
  57 
  58 #define GHES_ESTATUS_POOL_MIN_ALLOC_ORDER 3
  59 
  60 /* This is just an estimation for memory pool allocation */
  61 #define GHES_ESTATUS_CACHE_AVG_SIZE     512
  62 
  63 #define GHES_ESTATUS_CACHES_SIZE        4
  64 
  65 #define GHES_ESTATUS_IN_CACHE_MAX_NSEC  10000000000ULL
  66 /* Prevent too many caches are allocated because of RCU */
  67 #define GHES_ESTATUS_CACHE_ALLOCED_MAX  (GHES_ESTATUS_CACHES_SIZE * 3 / 2)
  68 
  69 #define GHES_ESTATUS_CACHE_LEN(estatus_len)                     \
  70         (sizeof(struct ghes_estatus_cache) + (estatus_len))
  71 #define GHES_ESTATUS_FROM_CACHE(estatus_cache)                  \
  72         ((struct acpi_hest_generic_status *)                            \
  73          ((struct ghes_estatus_cache *)(estatus_cache) + 1))
  74 
  75 #define GHES_ESTATUS_NODE_LEN(estatus_len)                      \
  76         (sizeof(struct ghes_estatus_node) + (estatus_len))
  77 #define GHES_ESTATUS_FROM_NODE(estatus_node)                    \
  78         ((struct acpi_hest_generic_status *)                            \
  79          ((struct ghes_estatus_node *)(estatus_node) + 1))
  80 
  81 /*
  82  *  NMI-like notifications vary by architecture, before the compiler can prune
  83  *  unused static functions it needs a value for these enums.
  84  */
  85 #ifndef CONFIG_ARM_SDE_INTERFACE
  86 #define FIX_APEI_GHES_SDEI_NORMAL       __end_of_fixed_addresses
  87 #define FIX_APEI_GHES_SDEI_CRITICAL     __end_of_fixed_addresses
  88 #endif
  89 
  90 static inline bool is_hest_type_generic_v2(struct ghes *ghes)
  91 {
  92         return ghes->generic->header.type == ACPI_HEST_TYPE_GENERIC_ERROR_V2;
  93 }
  94 
  95 /*
  96  * This driver isn't really modular, however for the time being,
  97  * continuing to use module_param is the easiest way to remain
  98  * compatible with existing boot arg use cases.
  99  */
 100 bool ghes_disable;
 101 module_param_named(disable, ghes_disable, bool, 0);
 102 
 103 /*
 104  * All error sources notified with HED (Hardware Error Device) share a
 105  * single notifier callback, so they need to be linked and checked one
 106  * by one. This holds true for NMI too.
 107  *
 108  * RCU is used for these lists, so ghes_list_mutex is only used for
 109  * list changing, not for traversing.
 110  */
 111 static LIST_HEAD(ghes_hed);
 112 static DEFINE_MUTEX(ghes_list_mutex);
 113 
 114 /*
 115  * Because the memory area used to transfer hardware error information
 116  * from BIOS to Linux can be determined only in NMI, IRQ or timer
 117  * handler, but general ioremap can not be used in atomic context, so
 118  * the fixmap is used instead.
 119  *
 120  * This spinlock is used to prevent the fixmap entry from being used
 121  * simultaneously.
 122  */
 123 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 124 
 125 static struct gen_pool *ghes_estatus_pool;
 126 static unsigned long ghes_estatus_pool_size_request;
 127 
 128 static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
 129 static atomic_t ghes_estatus_cache_alloced;
 130 
 131 static int ghes_panic_timeout __read_mostly = 30;
 132 
 133 static void __iomem *ghes_map(u64 pfn, enum fixed_addresses fixmap_idx)
 134 {
 135         phys_addr_t paddr;
 136         pgprot_t prot;
 137 
 138         paddr = PFN_PHYS(pfn);
 139         prot = arch_apei_get_mem_attribute(paddr);
 140         __set_fixmap(fixmap_idx, paddr, prot);
 141 
 142         return (void __iomem *) __fix_to_virt(fixmap_idx);
 143 }
 144 
 145 static void ghes_unmap(void __iomem *vaddr, enum fixed_addresses fixmap_idx)
 146 {
 147         int _idx = virt_to_fix((unsigned long)vaddr);
 148 
 149         WARN_ON_ONCE(fixmap_idx != _idx);
 150         clear_fixmap(fixmap_idx);
 151 }
 152 
 153 int ghes_estatus_pool_init(int num_ghes)
 154 {
 155         unsigned long addr, len;
 156         int rc;
 157 
 158         ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1);
 159         if (!ghes_estatus_pool)
 160                 return -ENOMEM;
 161 
 162         len = GHES_ESTATUS_CACHE_AVG_SIZE * GHES_ESTATUS_CACHE_ALLOCED_MAX;
 163         len += (num_ghes * GHES_ESOURCE_PREALLOC_MAX_SIZE);
 164 
 165         ghes_estatus_pool_size_request = PAGE_ALIGN(len);
 166         addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
 167         if (!addr)
 168                 goto err_pool_alloc;
 169 
 170         /*
 171          * New allocation must be visible in all pgd before it can be found by
 172          * an NMI allocating from the pool.
 173          */
 174         vmalloc_sync_mappings();
 175 
 176         rc = gen_pool_add(ghes_estatus_pool, addr, PAGE_ALIGN(len), -1);
 177         if (rc)
 178                 goto err_pool_add;
 179 
 180         return 0;
 181 
 182 err_pool_add:
 183         vfree((void *)addr);
 184 
 185 err_pool_alloc:
 186         gen_pool_destroy(ghes_estatus_pool);
 187 
 188         return -ENOMEM;
 189 }
 190 
 191 static int map_gen_v2(struct ghes *ghes)
 192 {
 193         return apei_map_generic_address(&ghes->generic_v2->read_ack_register);
 194 }
 195 
 196 static void unmap_gen_v2(struct ghes *ghes)
 197 {
 198         apei_unmap_generic_address(&ghes->generic_v2->read_ack_register);
 199 }
 200 
 201 static void ghes_ack_error(struct acpi_hest_generic_v2 *gv2)
 202 {
 203         int rc;
 204         u64 val = 0;
 205 
 206         rc = apei_read(&val, &gv2->read_ack_register);
 207         if (rc)
 208                 return;
 209 
 210         val &= gv2->read_ack_preserve << gv2->read_ack_register.bit_offset;
 211         val |= gv2->read_ack_write    << gv2->read_ack_register.bit_offset;
 212 
 213         apei_write(val, &gv2->read_ack_register);
 214 }
 215 
 216 static struct ghes *ghes_new(struct acpi_hest_generic *generic)
 217 {
 218         struct ghes *ghes;
 219         unsigned int error_block_length;
 220         int rc;
 221 
 222         ghes = kzalloc(sizeof(*ghes), GFP_KERNEL);
 223         if (!ghes)
 224                 return ERR_PTR(-ENOMEM);
 225 
 226         ghes->generic = generic;
 227         if (is_hest_type_generic_v2(ghes)) {
 228                 rc = map_gen_v2(ghes);
 229                 if (rc)
 230                         goto err_free;
 231         }
 232 
 233         rc = apei_map_generic_address(&generic->error_status_address);
 234         if (rc)
 235                 goto err_unmap_read_ack_addr;
 236         error_block_length = generic->error_block_length;
 237         if (error_block_length > GHES_ESTATUS_MAX_SIZE) {
 238                 pr_warning(FW_WARN GHES_PFX
 239                            "Error status block length is too long: %u for "
 240                            "generic hardware error source: %d.\n",
 241                            error_block_length, generic->header.source_id);
 242                 error_block_length = GHES_ESTATUS_MAX_SIZE;
 243         }
 244         ghes->estatus = kmalloc(error_block_length, GFP_KERNEL);
 245         if (!ghes->estatus) {
 246                 rc = -ENOMEM;
 247                 goto err_unmap_status_addr;
 248         }
 249 
 250         return ghes;
 251 
 252 err_unmap_status_addr:
 253         apei_unmap_generic_address(&generic->error_status_address);
 254 err_unmap_read_ack_addr:
 255         if (is_hest_type_generic_v2(ghes))
 256                 unmap_gen_v2(ghes);
 257 err_free:
 258         kfree(ghes);
 259         return ERR_PTR(rc);
 260 }
 261 
 262 static void ghes_fini(struct ghes *ghes)
 263 {
 264         kfree(ghes->estatus);
 265         apei_unmap_generic_address(&ghes->generic->error_status_address);
 266         if (is_hest_type_generic_v2(ghes))
 267                 unmap_gen_v2(ghes);
 268 }
 269 
 270 static inline int ghes_severity(int severity)
 271 {
 272         switch (severity) {
 273         case CPER_SEV_INFORMATIONAL:
 274                 return GHES_SEV_NO;
 275         case CPER_SEV_CORRECTED:
 276                 return GHES_SEV_CORRECTED;
 277         case CPER_SEV_RECOVERABLE:
 278                 return GHES_SEV_RECOVERABLE;
 279         case CPER_SEV_FATAL:
 280                 return GHES_SEV_PANIC;
 281         default:
 282                 /* Unknown, go panic */
 283                 return GHES_SEV_PANIC;
 284         }
 285 }
 286 
 287 static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len,
 288                                   int from_phys,
 289                                   enum fixed_addresses fixmap_idx)
 290 {
 291         void __iomem *vaddr;
 292         u64 offset;
 293         u32 trunk;
 294 
 295         while (len > 0) {
 296                 offset = paddr - (paddr & PAGE_MASK);
 297                 vaddr = ghes_map(PHYS_PFN(paddr), fixmap_idx);
 298                 trunk = PAGE_SIZE - offset;
 299                 trunk = min(trunk, len);
 300                 if (from_phys)
 301                         memcpy_fromio(buffer, vaddr + offset, trunk);
 302                 else
 303                         memcpy_toio(vaddr + offset, buffer, trunk);
 304                 len -= trunk;
 305                 paddr += trunk;
 306                 buffer += trunk;
 307                 ghes_unmap(vaddr, fixmap_idx);
 308         }
 309 }
 310 
 311 /* Check the top-level record header has an appropriate size. */
 312 static int __ghes_check_estatus(struct ghes *ghes,
 313                                 struct acpi_hest_generic_status *estatus)
 314 {
 315         u32 len = cper_estatus_len(estatus);
 316 
 317         if (len < sizeof(*estatus)) {
 318                 pr_warn_ratelimited(FW_WARN GHES_PFX "Truncated error status block!\n");
 319                 return -EIO;
 320         }
 321 
 322         if (len > ghes->generic->error_block_length) {
 323                 pr_warn_ratelimited(FW_WARN GHES_PFX "Invalid error status block length!\n");
 324                 return -EIO;
 325         }
 326 
 327         if (cper_estatus_check_header(estatus)) {
 328                 pr_warn_ratelimited(FW_WARN GHES_PFX "Invalid CPER header!\n");
 329                 return -EIO;
 330         }
 331 
 332         return 0;
 333 }
 334 
 335 /* Read the CPER block, returning its address, and header in estatus. */
 336 static int __ghes_peek_estatus(struct ghes *ghes,
 337                                struct acpi_hest_generic_status *estatus,
 338                                u64 *buf_paddr, enum fixed_addresses fixmap_idx)
 339 {
 340         struct acpi_hest_generic *g = ghes->generic;
 341         int rc;
 342 
 343         rc = apei_read(buf_paddr, &g->error_status_address);
 344         if (rc) {
 345                 *buf_paddr = 0;
 346                 pr_warn_ratelimited(FW_WARN GHES_PFX
 347 "Failed to read error status block address for hardware error source: %d.\n",
 348                                    g->header.source_id);
 349                 return -EIO;
 350         }
 351         if (!*buf_paddr)
 352                 return -ENOENT;
 353 
 354         ghes_copy_tofrom_phys(estatus, *buf_paddr, sizeof(*estatus), 1,
 355                               fixmap_idx);
 356         if (!estatus->block_status) {
 357                 *buf_paddr = 0;
 358                 return -ENOENT;
 359         }
 360 
 361         return 0;
 362 }
 363 
 364 static int __ghes_read_estatus(struct acpi_hest_generic_status *estatus,
 365                                u64 buf_paddr, enum fixed_addresses fixmap_idx,
 366                                size_t buf_len)
 367 {
 368         ghes_copy_tofrom_phys(estatus, buf_paddr, buf_len, 1, fixmap_idx);
 369         if (cper_estatus_check(estatus)) {
 370                 pr_warn_ratelimited(FW_WARN GHES_PFX
 371                                     "Failed to read error status block!\n");
 372                 return -EIO;
 373         }
 374 
 375         return 0;
 376 }
 377 
 378 static int ghes_read_estatus(struct ghes *ghes,
 379                              struct acpi_hest_generic_status *estatus,
 380                              u64 *buf_paddr, enum fixed_addresses fixmap_idx)
 381 {
 382         int rc;
 383 
 384         rc = __ghes_peek_estatus(ghes, estatus, buf_paddr, fixmap_idx);
 385         if (rc)
 386                 return rc;
 387 
 388         rc = __ghes_check_estatus(ghes, estatus);
 389         if (rc)
 390                 return rc;
 391 
 392         return __ghes_read_estatus(estatus, *buf_paddr, fixmap_idx,
 393                                    cper_estatus_len(estatus));
 394 }
 395 
 396 static void ghes_clear_estatus(struct ghes *ghes,
 397                                struct acpi_hest_generic_status *estatus,
 398                                u64 buf_paddr, enum fixed_addresses fixmap_idx)
 399 {
 400         estatus->block_status = 0;
 401 
 402         if (!buf_paddr)
 403                 return;
 404 
 405         ghes_copy_tofrom_phys(estatus, buf_paddr,
 406                               sizeof(estatus->block_status), 0,
 407                               fixmap_idx);
 408 
 409         /*
 410          * GHESv2 type HEST entries introduce support for error acknowledgment,
 411          * so only acknowledge the error if this support is present.
 412          */
 413         if (is_hest_type_generic_v2(ghes))
 414                 ghes_ack_error(ghes->generic_v2);
 415 }
 416 
 417 static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev)
 418 {
 419 #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
 420         unsigned long pfn;
 421         int flags = -1;
 422         int sec_sev = ghes_severity(gdata->error_severity);
 423         struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
 424 
 425         if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
 426                 return;
 427 
 428         pfn = mem_err->physical_addr >> PAGE_SHIFT;
 429         if (!pfn_valid(pfn)) {
 430                 pr_warn_ratelimited(FW_WARN GHES_PFX
 431                 "Invalid address in generic error data: %#llx\n",
 432                 mem_err->physical_addr);
 433                 return;
 434         }
 435 
 436         /* iff following two events can be handled properly by now */
 437         if (sec_sev == GHES_SEV_CORRECTED &&
 438             (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED))
 439                 flags = MF_SOFT_OFFLINE;
 440         if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE)
 441                 flags = 0;
 442 
 443         if (flags != -1)
 444                 memory_failure_queue(pfn, flags);
 445 #endif
 446 }
 447 
 448 /*
 449  * PCIe AER errors need to be sent to the AER driver for reporting and
 450  * recovery. The GHES severities map to the following AER severities and
 451  * require the following handling:
 452  *
 453  * GHES_SEV_CORRECTABLE -> AER_CORRECTABLE
 454  *     These need to be reported by the AER driver but no recovery is
 455  *     necessary.
 456  * GHES_SEV_RECOVERABLE -> AER_NONFATAL
 457  * GHES_SEV_RECOVERABLE && CPER_SEC_RESET -> AER_FATAL
 458  *     These both need to be reported and recovered from by the AER driver.
 459  * GHES_SEV_PANIC does not make it to this handling since the kernel must
 460  *     panic.
 461  */
 462 static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
 463 {
 464 #ifdef CONFIG_ACPI_APEI_PCIEAER
 465         struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
 466 
 467         if (pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID &&
 468             pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
 469                 unsigned int devfn;
 470                 int aer_severity;
 471 
 472                 devfn = PCI_DEVFN(pcie_err->device_id.device,
 473                                   pcie_err->device_id.function);
 474                 aer_severity = cper_severity_to_aer(gdata->error_severity);
 475 
 476                 /*
 477                  * If firmware reset the component to contain
 478                  * the error, we must reinitialize it before
 479                  * use, so treat it as a fatal AER error.
 480                  */
 481                 if (gdata->flags & CPER_SEC_RESET)
 482                         aer_severity = AER_FATAL;
 483 
 484                 aer_recover_queue(pcie_err->device_id.segment,
 485                                   pcie_err->device_id.bus,
 486                                   devfn, aer_severity,
 487                                   (struct aer_capability_regs *)
 488                                   pcie_err->aer_info);
 489         }
 490 #endif
 491 }
 492 
 493 static void ghes_do_proc(struct ghes *ghes,
 494                          const struct acpi_hest_generic_status *estatus)
 495 {
 496         int sev, sec_sev;
 497         struct acpi_hest_generic_data *gdata;
 498         guid_t *sec_type;
 499         const guid_t *fru_id = &guid_null;
 500         char *fru_text = "";
 501 
 502         sev = ghes_severity(estatus->error_severity);
 503         apei_estatus_for_each_section(estatus, gdata) {
 504                 sec_type = (guid_t *)gdata->section_type;
 505                 sec_sev = ghes_severity(gdata->error_severity);
 506                 if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
 507                         fru_id = (guid_t *)gdata->fru_id;
 508 
 509                 if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
 510                         fru_text = gdata->fru_text;
 511 
 512                 if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
 513                         struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
 514 
 515                         ghes_edac_report_mem_error(sev, mem_err);
 516 
 517                         arch_apei_report_mem_error(sev, mem_err);
 518                         ghes_handle_memory_failure(gdata, sev);
 519                 }
 520                 else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
 521                         ghes_handle_aer(gdata);
 522                 }
 523                 else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
 524                         struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
 525 
 526                         log_arm_hw_error(err);
 527                 } else {
 528                         void *err = acpi_hest_get_payload(gdata);
 529 
 530                         log_non_standard_event(sec_type, fru_id, fru_text,
 531                                                sec_sev, err,
 532                                                gdata->error_data_length);
 533                 }
 534         }
 535 }
 536 
 537 static void __ghes_print_estatus(const char *pfx,
 538                                  const struct acpi_hest_generic *generic,
 539                                  const struct acpi_hest_generic_status *estatus)
 540 {
 541         static atomic_t seqno;
 542         unsigned int curr_seqno;
 543         char pfx_seq[64];
 544 
 545         if (pfx == NULL) {
 546                 if (ghes_severity(estatus->error_severity) <=
 547                     GHES_SEV_CORRECTED)
 548                         pfx = KERN_WARNING;
 549                 else
 550                         pfx = KERN_ERR;
 551         }
 552         curr_seqno = atomic_inc_return(&seqno);
 553         snprintf(pfx_seq, sizeof(pfx_seq), "%s{%u}" HW_ERR, pfx, curr_seqno);
 554         printk("%s""Hardware error from APEI Generic Hardware Error Source: %d\n",
 555                pfx_seq, generic->header.source_id);
 556         cper_estatus_print(pfx_seq, estatus);
 557 }
 558 
 559 static int ghes_print_estatus(const char *pfx,
 560                               const struct acpi_hest_generic *generic,
 561                               const struct acpi_hest_generic_status *estatus)
 562 {
 563         /* Not more than 2 messages every 5 seconds */
 564         static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
 565         static DEFINE_RATELIMIT_STATE(ratelimit_uncorrected, 5*HZ, 2);
 566         struct ratelimit_state *ratelimit;
 567 
 568         if (ghes_severity(estatus->error_severity) <= GHES_SEV_CORRECTED)
 569                 ratelimit = &ratelimit_corrected;
 570         else
 571                 ratelimit = &ratelimit_uncorrected;
 572         if (__ratelimit(ratelimit)) {
 573                 __ghes_print_estatus(pfx, generic, estatus);
 574                 return 1;
 575         }
 576         return 0;
 577 }
 578 
 579 /*
 580  * GHES error status reporting throttle, to report more kinds of
 581  * errors, instead of just most frequently occurred errors.
 582  */
 583 static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus)
 584 {
 585         u32 len;
 586         int i, cached = 0;
 587         unsigned long long now;
 588         struct ghes_estatus_cache *cache;
 589         struct acpi_hest_generic_status *cache_estatus;
 590 
 591         len = cper_estatus_len(estatus);
 592         rcu_read_lock();
 593         for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) {
 594                 cache = rcu_dereference(ghes_estatus_caches[i]);
 595                 if (cache == NULL)
 596                         continue;
 597                 if (len != cache->estatus_len)
 598                         continue;
 599                 cache_estatus = GHES_ESTATUS_FROM_CACHE(cache);
 600                 if (memcmp(estatus, cache_estatus, len))
 601                         continue;
 602                 atomic_inc(&cache->count);
 603                 now = sched_clock();
 604                 if (now - cache->time_in < GHES_ESTATUS_IN_CACHE_MAX_NSEC)
 605                         cached = 1;
 606                 break;
 607         }
 608         rcu_read_unlock();
 609         return cached;
 610 }
 611 
 612 static struct ghes_estatus_cache *ghes_estatus_cache_alloc(
 613         struct acpi_hest_generic *generic,
 614         struct acpi_hest_generic_status *estatus)
 615 {
 616         int alloced;
 617         u32 len, cache_len;
 618         struct ghes_estatus_cache *cache;
 619         struct acpi_hest_generic_status *cache_estatus;
 620 
 621         alloced = atomic_add_return(1, &ghes_estatus_cache_alloced);
 622         if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) {
 623                 atomic_dec(&ghes_estatus_cache_alloced);
 624                 return NULL;
 625         }
 626         len = cper_estatus_len(estatus);
 627         cache_len = GHES_ESTATUS_CACHE_LEN(len);
 628         cache = (void *)gen_pool_alloc(ghes_estatus_pool, cache_len);
 629         if (!cache) {
 630                 atomic_dec(&ghes_estatus_cache_alloced);
 631                 return NULL;
 632         }
 633         cache_estatus = GHES_ESTATUS_FROM_CACHE(cache);
 634         memcpy(cache_estatus, estatus, len);
 635         cache->estatus_len = len;
 636         atomic_set(&cache->count, 0);
 637         cache->generic = generic;
 638         cache->time_in = sched_clock();
 639         return cache;
 640 }
 641 
 642 static void ghes_estatus_cache_free(struct ghes_estatus_cache *cache)
 643 {
 644         u32 len;
 645 
 646         len = cper_estatus_len(GHES_ESTATUS_FROM_CACHE(cache));
 647         len = GHES_ESTATUS_CACHE_LEN(len);
 648         gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len);
 649         atomic_dec(&ghes_estatus_cache_alloced);
 650 }
 651 
 652 static void ghes_estatus_cache_rcu_free(struct rcu_head *head)
 653 {
 654         struct ghes_estatus_cache *cache;
 655 
 656         cache = container_of(head, struct ghes_estatus_cache, rcu);
 657         ghes_estatus_cache_free(cache);
 658 }
 659 
 660 static void ghes_estatus_cache_add(
 661         struct acpi_hest_generic *generic,
 662         struct acpi_hest_generic_status *estatus)
 663 {
 664         int i, slot = -1, count;
 665         unsigned long long now, duration, period, max_period = 0;
 666         struct ghes_estatus_cache *cache, *slot_cache = NULL, *new_cache;
 667 
 668         new_cache = ghes_estatus_cache_alloc(generic, estatus);
 669         if (new_cache == NULL)
 670                 return;
 671         rcu_read_lock();
 672         now = sched_clock();
 673         for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) {
 674                 cache = rcu_dereference(ghes_estatus_caches[i]);
 675                 if (cache == NULL) {
 676                         slot = i;
 677                         slot_cache = NULL;
 678                         break;
 679                 }
 680                 duration = now - cache->time_in;
 681                 if (duration >= GHES_ESTATUS_IN_CACHE_MAX_NSEC) {
 682                         slot = i;
 683                         slot_cache = cache;
 684                         break;
 685                 }
 686                 count = atomic_read(&cache->count);
 687                 period = duration;
 688                 do_div(period, (count + 1));
 689                 if (period > max_period) {
 690                         max_period = period;
 691                         slot = i;
 692                         slot_cache = cache;
 693                 }
 694         }
 695         /* new_cache must be put into array after its contents are written */
 696         smp_wmb();
 697         if (slot != -1 && cmpxchg(ghes_estatus_caches + slot,
 698                                   slot_cache, new_cache) == slot_cache) {
 699                 if (slot_cache)
 700                         call_rcu(&slot_cache->rcu, ghes_estatus_cache_rcu_free);
 701         } else
 702                 ghes_estatus_cache_free(new_cache);
 703         rcu_read_unlock();
 704 }
 705 
 706 static void __ghes_panic(struct ghes *ghes,
 707                          struct acpi_hest_generic_status *estatus,
 708                          u64 buf_paddr, enum fixed_addresses fixmap_idx)
 709 {
 710         __ghes_print_estatus(KERN_EMERG, ghes->generic, estatus);
 711 
 712         ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx);
 713 
 714         /* reboot to log the error! */
 715         if (!panic_timeout)
 716                 panic_timeout = ghes_panic_timeout;
 717         panic("Fatal hardware error!");
 718 }
 719 
 720 static int ghes_proc(struct ghes *ghes)
 721 {
 722         struct acpi_hest_generic_status *estatus = ghes->estatus;
 723         u64 buf_paddr;
 724         int rc;
 725 
 726         rc = ghes_read_estatus(ghes, estatus, &buf_paddr, FIX_APEI_GHES_IRQ);
 727         if (rc)
 728                 goto out;
 729 
 730         if (ghes_severity(estatus->error_severity) >= GHES_SEV_PANIC)
 731                 __ghes_panic(ghes, estatus, buf_paddr, FIX_APEI_GHES_IRQ);
 732 
 733         if (!ghes_estatus_cached(estatus)) {
 734                 if (ghes_print_estatus(NULL, ghes->generic, estatus))
 735                         ghes_estatus_cache_add(ghes->generic, estatus);
 736         }
 737         ghes_do_proc(ghes, estatus);
 738 
 739 out:
 740         ghes_clear_estatus(ghes, estatus, buf_paddr, FIX_APEI_GHES_IRQ);
 741 
 742         return rc;
 743 }
 744 
 745 static void ghes_add_timer(struct ghes *ghes)
 746 {
 747         struct acpi_hest_generic *g = ghes->generic;
 748         unsigned long expire;
 749 
 750         if (!g->notify.poll_interval) {
 751                 pr_warning(FW_WARN GHES_PFX "Poll interval is 0 for generic hardware error source: %d, disabled.\n",
 752                            g->header.source_id);
 753                 return;
 754         }
 755         expire = jiffies + msecs_to_jiffies(g->notify.poll_interval);
 756         ghes->timer.expires = round_jiffies_relative(expire);
 757         add_timer(&ghes->timer);
 758 }
 759 
 760 static void ghes_poll_func(struct timer_list *t)
 761 {
 762         struct ghes *ghes = from_timer(ghes, t, timer);
 763         unsigned long flags;
 764 
 765         spin_lock_irqsave(&ghes_notify_lock_irq, flags);
 766         ghes_proc(ghes);
 767         spin_unlock_irqrestore(&ghes_notify_lock_irq, flags);
 768         if (!(ghes->flags & GHES_EXITING))
 769                 ghes_add_timer(ghes);
 770 }
 771 
 772 static irqreturn_t ghes_irq_func(int irq, void *data)
 773 {
 774         struct ghes *ghes = data;
 775         unsigned long flags;
 776         int rc;
 777 
 778         spin_lock_irqsave(&ghes_notify_lock_irq, flags);
 779         rc = ghes_proc(ghes);
 780         spin_unlock_irqrestore(&ghes_notify_lock_irq, flags);
 781         if (rc)
 782                 return IRQ_NONE;
 783 
 784         return IRQ_HANDLED;
 785 }
 786 
 787 static int ghes_notify_hed(struct notifier_block *this, unsigned long event,
 788                            void *data)
 789 {
 790         struct ghes *ghes;
 791         unsigned long flags;
 792         int ret = NOTIFY_DONE;
 793 
 794         spin_lock_irqsave(&ghes_notify_lock_irq, flags);
 795         rcu_read_lock();
 796         list_for_each_entry_rcu(ghes, &ghes_hed, list) {
 797                 if (!ghes_proc(ghes))
 798                         ret = NOTIFY_OK;
 799         }
 800         rcu_read_unlock();
 801         spin_unlock_irqrestore(&ghes_notify_lock_irq, flags);
 802 
 803         return ret;
 804 }
 805 
 806 static struct notifier_block ghes_notifier_hed = {
 807         .notifier_call = ghes_notify_hed,
 808 };
 809 
 810 /*
 811  * Handlers for CPER records may not be NMI safe. For example,
 812  * memory_failure_queue() takes spinlocks and calls schedule_work_on().
 813  * In any NMI-like handler, memory from ghes_estatus_pool is used to save
 814  * estatus, and added to the ghes_estatus_llist. irq_work_queue() causes
 815  * ghes_proc_in_irq() to run in IRQ context where each estatus in
 816  * ghes_estatus_llist is processed.
 817  *
 818  * Memory from the ghes_estatus_pool is also used with the ghes_estatus_cache
 819  * to suppress frequent messages.
 820  */
 821 static struct llist_head ghes_estatus_llist;
 822 static struct irq_work ghes_proc_irq_work;
 823 
 824 static void ghes_proc_in_irq(struct irq_work *irq_work)
 825 {
 826         struct llist_node *llnode, *next;
 827         struct ghes_estatus_node *estatus_node;
 828         struct acpi_hest_generic *generic;
 829         struct acpi_hest_generic_status *estatus;
 830         u32 len, node_len;
 831 
 832         llnode = llist_del_all(&ghes_estatus_llist);
 833         /*
 834          * Because the time order of estatus in list is reversed,
 835          * revert it back to proper order.
 836          */
 837         llnode = llist_reverse_order(llnode);
 838         while (llnode) {
 839                 next = llnode->next;
 840                 estatus_node = llist_entry(llnode, struct ghes_estatus_node,
 841                                            llnode);
 842                 estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
 843                 len = cper_estatus_len(estatus);
 844                 node_len = GHES_ESTATUS_NODE_LEN(len);
 845                 ghes_do_proc(estatus_node->ghes, estatus);
 846                 if (!ghes_estatus_cached(estatus)) {
 847                         generic = estatus_node->generic;
 848                         if (ghes_print_estatus(NULL, generic, estatus))
 849                                 ghes_estatus_cache_add(generic, estatus);
 850                 }
 851                 gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node,
 852                               node_len);
 853                 llnode = next;
 854         }
 855 }
 856 
 857 static void ghes_print_queued_estatus(void)
 858 {
 859         struct llist_node *llnode;
 860         struct ghes_estatus_node *estatus_node;
 861         struct acpi_hest_generic *generic;
 862         struct acpi_hest_generic_status *estatus;
 863 
 864         llnode = llist_del_all(&ghes_estatus_llist);
 865         /*
 866          * Because the time order of estatus in list is reversed,
 867          * revert it back to proper order.
 868          */
 869         llnode = llist_reverse_order(llnode);
 870         while (llnode) {
 871                 estatus_node = llist_entry(llnode, struct ghes_estatus_node,
 872                                            llnode);
 873                 estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
 874                 generic = estatus_node->generic;
 875                 ghes_print_estatus(NULL, generic, estatus);
 876                 llnode = llnode->next;
 877         }
 878 }
 879 
 880 static int ghes_in_nmi_queue_one_entry(struct ghes *ghes,
 881                                        enum fixed_addresses fixmap_idx)
 882 {
 883         struct acpi_hest_generic_status *estatus, tmp_header;
 884         struct ghes_estatus_node *estatus_node;
 885         u32 len, node_len;
 886         u64 buf_paddr;
 887         int sev, rc;
 888 
 889         if (!IS_ENABLED(CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG))
 890                 return -EOPNOTSUPP;
 891 
 892         rc = __ghes_peek_estatus(ghes, &tmp_header, &buf_paddr, fixmap_idx);
 893         if (rc) {
 894                 ghes_clear_estatus(ghes, &tmp_header, buf_paddr, fixmap_idx);
 895                 return rc;
 896         }
 897 
 898         rc = __ghes_check_estatus(ghes, &tmp_header);
 899         if (rc) {
 900                 ghes_clear_estatus(ghes, &tmp_header, buf_paddr, fixmap_idx);
 901                 return rc;
 902         }
 903 
 904         len = cper_estatus_len(&tmp_header);
 905         node_len = GHES_ESTATUS_NODE_LEN(len);
 906         estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, node_len);
 907         if (!estatus_node)
 908                 return -ENOMEM;
 909 
 910         estatus_node->ghes = ghes;
 911         estatus_node->generic = ghes->generic;
 912         estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
 913 
 914         if (__ghes_read_estatus(estatus, buf_paddr, fixmap_idx, len)) {
 915                 ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx);
 916                 rc = -ENOENT;
 917                 goto no_work;
 918         }
 919 
 920         sev = ghes_severity(estatus->error_severity);
 921         if (sev >= GHES_SEV_PANIC) {
 922                 ghes_print_queued_estatus();
 923                 __ghes_panic(ghes, estatus, buf_paddr, fixmap_idx);
 924         }
 925 
 926         ghes_clear_estatus(ghes, &tmp_header, buf_paddr, fixmap_idx);
 927 
 928         /* This error has been reported before, don't process it again. */
 929         if (ghes_estatus_cached(estatus))
 930                 goto no_work;
 931 
 932         llist_add(&estatus_node->llnode, &ghes_estatus_llist);
 933 
 934         return rc;
 935 
 936 no_work:
 937         gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node,
 938                       node_len);
 939 
 940         return rc;
 941 }
 942 
 943 static int ghes_in_nmi_spool_from_list(struct list_head *rcu_list,
 944                                        enum fixed_addresses fixmap_idx)
 945 {
 946         int ret = -ENOENT;
 947         struct ghes *ghes;
 948 
 949         rcu_read_lock();
 950         list_for_each_entry_rcu(ghes, rcu_list, list) {
 951                 if (!ghes_in_nmi_queue_one_entry(ghes, fixmap_idx))
 952                         ret = 0;
 953         }
 954         rcu_read_unlock();
 955 
 956         if (IS_ENABLED(CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG) && !ret)
 957                 irq_work_queue(&ghes_proc_irq_work);
 958 
 959         return ret;
 960 }
 961 
 962 #ifdef CONFIG_ACPI_APEI_SEA
 963 static LIST_HEAD(ghes_sea);
 964 
 965 /*
 966  * Return 0 only if one of the SEA error sources successfully reported an error
 967  * record sent from the firmware.
 968  */
 969 int ghes_notify_sea(void)
 970 {
 971         static DEFINE_RAW_SPINLOCK(ghes_notify_lock_sea);
 972         int rv;
 973 
 974         raw_spin_lock(&ghes_notify_lock_sea);
 975         rv = ghes_in_nmi_spool_from_list(&ghes_sea, FIX_APEI_GHES_SEA);
 976         raw_spin_unlock(&ghes_notify_lock_sea);
 977 
 978         return rv;
 979 }
 980 
 981 static void ghes_sea_add(struct ghes *ghes)
 982 {
 983         mutex_lock(&ghes_list_mutex);
 984         list_add_rcu(&ghes->list, &ghes_sea);
 985         mutex_unlock(&ghes_list_mutex);
 986 }
 987 
 988 static void ghes_sea_remove(struct ghes *ghes)
 989 {
 990         mutex_lock(&ghes_list_mutex);
 991         list_del_rcu(&ghes->list);
 992         mutex_unlock(&ghes_list_mutex);
 993         synchronize_rcu();
 994 }
 995 #else /* CONFIG_ACPI_APEI_SEA */
 996 static inline void ghes_sea_add(struct ghes *ghes) { }
 997 static inline void ghes_sea_remove(struct ghes *ghes) { }
 998 #endif /* CONFIG_ACPI_APEI_SEA */
 999 
1000 #ifdef CONFIG_HAVE_ACPI_APEI_NMI
1001 /*
1002  * NMI may be triggered on any CPU, so ghes_in_nmi is used for
1003  * having only one concurrent reader.
1004  */
1005 static atomic_t ghes_in_nmi = ATOMIC_INIT(0);
1006 
1007 static LIST_HEAD(ghes_nmi);
1008 
1009 static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
1010 {
1011         static DEFINE_RAW_SPINLOCK(ghes_notify_lock_nmi);
1012         int ret = NMI_DONE;
1013 
1014         if (!atomic_add_unless(&ghes_in_nmi, 1, 1))
1015                 return ret;
1016 
1017         raw_spin_lock(&ghes_notify_lock_nmi);
1018         if (!ghes_in_nmi_spool_from_list(&ghes_nmi, FIX_APEI_GHES_NMI))
1019                 ret = NMI_HANDLED;
1020         raw_spin_unlock(&ghes_notify_lock_nmi);
1021 
1022         atomic_dec(&ghes_in_nmi);
1023         return ret;
1024 }
1025 
1026 static void ghes_nmi_add(struct ghes *ghes)
1027 {
1028         mutex_lock(&ghes_list_mutex);
1029         if (list_empty(&ghes_nmi))
1030                 register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes");
1031         list_add_rcu(&ghes->list, &ghes_nmi);
1032         mutex_unlock(&ghes_list_mutex);
1033 }
1034 
1035 static void ghes_nmi_remove(struct ghes *ghes)
1036 {
1037         mutex_lock(&ghes_list_mutex);
1038         list_del_rcu(&ghes->list);
1039         if (list_empty(&ghes_nmi))
1040                 unregister_nmi_handler(NMI_LOCAL, "ghes");
1041         mutex_unlock(&ghes_list_mutex);
1042         /*
1043          * To synchronize with NMI handler, ghes can only be
1044          * freed after NMI handler finishes.
1045          */
1046         synchronize_rcu();
1047 }
1048 #else /* CONFIG_HAVE_ACPI_APEI_NMI */
1049 static inline void ghes_nmi_add(struct ghes *ghes) { }
1050 static inline void ghes_nmi_remove(struct ghes *ghes) { }
1051 #endif /* CONFIG_HAVE_ACPI_APEI_NMI */
1052 
1053 static void ghes_nmi_init_cxt(void)
1054 {
1055         init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq);
1056 }
1057 
1058 static int __ghes_sdei_callback(struct ghes *ghes,
1059                                 enum fixed_addresses fixmap_idx)
1060 {
1061         if (!ghes_in_nmi_queue_one_entry(ghes, fixmap_idx)) {
1062                 irq_work_queue(&ghes_proc_irq_work);
1063 
1064                 return 0;
1065         }
1066 
1067         return -ENOENT;
1068 }
1069 
1070 static int ghes_sdei_normal_callback(u32 event_num, struct pt_regs *regs,
1071                                       void *arg)
1072 {
1073         static DEFINE_RAW_SPINLOCK(ghes_notify_lock_sdei_normal);
1074         struct ghes *ghes = arg;
1075         int err;
1076 
1077         raw_spin_lock(&ghes_notify_lock_sdei_normal);
1078         err = __ghes_sdei_callback(ghes, FIX_APEI_GHES_SDEI_NORMAL);
1079         raw_spin_unlock(&ghes_notify_lock_sdei_normal);
1080 
1081         return err;
1082 }
1083 
1084 static int ghes_sdei_critical_callback(u32 event_num, struct pt_regs *regs,
1085                                        void *arg)
1086 {
1087         static DEFINE_RAW_SPINLOCK(ghes_notify_lock_sdei_critical);
1088         struct ghes *ghes = arg;
1089         int err;
1090 
1091         raw_spin_lock(&ghes_notify_lock_sdei_critical);
1092         err = __ghes_sdei_callback(ghes, FIX_APEI_GHES_SDEI_CRITICAL);
1093         raw_spin_unlock(&ghes_notify_lock_sdei_critical);
1094 
1095         return err;
1096 }
1097 
1098 static int apei_sdei_register_ghes(struct ghes *ghes)
1099 {
1100         if (!IS_ENABLED(CONFIG_ARM_SDE_INTERFACE))
1101                 return -EOPNOTSUPP;
1102 
1103         return sdei_register_ghes(ghes, ghes_sdei_normal_callback,
1104                                  ghes_sdei_critical_callback);
1105 }
1106 
1107 static int apei_sdei_unregister_ghes(struct ghes *ghes)
1108 {
1109         if (!IS_ENABLED(CONFIG_ARM_SDE_INTERFACE))
1110                 return -EOPNOTSUPP;
1111 
1112         return sdei_unregister_ghes(ghes);
1113 }
1114 
1115 static int ghes_probe(struct platform_device *ghes_dev)
1116 {
1117         struct acpi_hest_generic *generic;
1118         struct ghes *ghes = NULL;
1119         unsigned long flags;
1120 
1121         int rc = -EINVAL;
1122 
1123         generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data;
1124         if (!generic->enabled)
1125                 return -ENODEV;
1126 
1127         switch (generic->notify.type) {
1128         case ACPI_HEST_NOTIFY_POLLED:
1129         case ACPI_HEST_NOTIFY_EXTERNAL:
1130         case ACPI_HEST_NOTIFY_SCI:
1131         case ACPI_HEST_NOTIFY_GSIV:
1132         case ACPI_HEST_NOTIFY_GPIO:
1133                 break;
1134 
1135         case ACPI_HEST_NOTIFY_SEA:
1136                 if (!IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
1137                         pr_warn(GHES_PFX "Generic hardware error source: %d notified via SEA is not supported\n",
1138                                 generic->header.source_id);
1139                         rc = -ENOTSUPP;
1140                         goto err;
1141                 }
1142                 break;
1143         case ACPI_HEST_NOTIFY_NMI:
1144                 if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_NMI)) {
1145                         pr_warn(GHES_PFX "Generic hardware error source: %d notified via NMI interrupt is not supported!\n",
1146                                 generic->header.source_id);
1147                         goto err;
1148                 }
1149                 break;
1150         case ACPI_HEST_NOTIFY_SOFTWARE_DELEGATED:
1151                 if (!IS_ENABLED(CONFIG_ARM_SDE_INTERFACE)) {
1152                         pr_warn(GHES_PFX "Generic hardware error source: %d notified via SDE Interface is not supported!\n",
1153                                 generic->header.source_id);
1154                         goto err;
1155                 }
1156                 break;
1157         case ACPI_HEST_NOTIFY_LOCAL:
1158                 pr_warning(GHES_PFX "Generic hardware error source: %d notified via local interrupt is not supported!\n",
1159                            generic->header.source_id);
1160                 goto err;
1161         default:
1162                 pr_warning(FW_WARN GHES_PFX "Unknown notification type: %u for generic hardware error source: %d\n",
1163                            generic->notify.type, generic->header.source_id);
1164                 goto err;
1165         }
1166 
1167         rc = -EIO;
1168         if (generic->error_block_length <
1169             sizeof(struct acpi_hest_generic_status)) {
1170                 pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n",
1171                            generic->error_block_length,
1172                            generic->header.source_id);
1173                 goto err;
1174         }
1175         ghes = ghes_new(generic);
1176         if (IS_ERR(ghes)) {
1177                 rc = PTR_ERR(ghes);
1178                 ghes = NULL;
1179                 goto err;
1180         }
1181 
1182         switch (generic->notify.type) {
1183         case ACPI_HEST_NOTIFY_POLLED:
1184                 timer_setup(&ghes->timer, ghes_poll_func, TIMER_DEFERRABLE);
1185                 ghes_add_timer(ghes);
1186                 break;
1187         case ACPI_HEST_NOTIFY_EXTERNAL:
1188                 /* External interrupt vector is GSI */
1189                 rc = acpi_gsi_to_irq(generic->notify.vector, &ghes->irq);
1190                 if (rc) {
1191                         pr_err(GHES_PFX "Failed to map GSI to IRQ for generic hardware error source: %d\n",
1192                                generic->header.source_id);
1193                         goto err;
1194                 }
1195                 rc = request_irq(ghes->irq, ghes_irq_func, IRQF_SHARED,
1196                                  "GHES IRQ", ghes);
1197                 if (rc) {
1198                         pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n",
1199                                generic->header.source_id);
1200                         goto err;
1201                 }
1202                 break;
1203 
1204         case ACPI_HEST_NOTIFY_SCI:
1205         case ACPI_HEST_NOTIFY_GSIV:
1206         case ACPI_HEST_NOTIFY_GPIO:
1207                 mutex_lock(&ghes_list_mutex);
1208                 if (list_empty(&ghes_hed))
1209                         register_acpi_hed_notifier(&ghes_notifier_hed);
1210                 list_add_rcu(&ghes->list, &ghes_hed);
1211                 mutex_unlock(&ghes_list_mutex);
1212                 break;
1213 
1214         case ACPI_HEST_NOTIFY_SEA:
1215                 ghes_sea_add(ghes);
1216                 break;
1217         case ACPI_HEST_NOTIFY_NMI:
1218                 ghes_nmi_add(ghes);
1219                 break;
1220         case ACPI_HEST_NOTIFY_SOFTWARE_DELEGATED:
1221                 rc = apei_sdei_register_ghes(ghes);
1222                 if (rc)
1223                         goto err;
1224                 break;
1225         default:
1226                 BUG();
1227         }
1228 
1229         platform_set_drvdata(ghes_dev, ghes);
1230 
1231         ghes_edac_register(ghes, &ghes_dev->dev);
1232 
1233         /* Handle any pending errors right away */
1234         spin_lock_irqsave(&ghes_notify_lock_irq, flags);
1235         ghes_proc(ghes);
1236         spin_unlock_irqrestore(&ghes_notify_lock_irq, flags);
1237 
1238         return 0;
1239 
1240 err:
1241         if (ghes) {
1242                 ghes_fini(ghes);
1243                 kfree(ghes);
1244         }
1245         return rc;
1246 }
1247 
1248 static int ghes_remove(struct platform_device *ghes_dev)
1249 {
1250         int rc;
1251         struct ghes *ghes;
1252         struct acpi_hest_generic *generic;
1253 
1254         ghes = platform_get_drvdata(ghes_dev);
1255         generic = ghes->generic;
1256 
1257         ghes->flags |= GHES_EXITING;
1258         switch (generic->notify.type) {
1259         case ACPI_HEST_NOTIFY_POLLED:
1260                 del_timer_sync(&ghes->timer);
1261                 break;
1262         case ACPI_HEST_NOTIFY_EXTERNAL:
1263                 free_irq(ghes->irq, ghes);
1264                 break;
1265 
1266         case ACPI_HEST_NOTIFY_SCI:
1267         case ACPI_HEST_NOTIFY_GSIV:
1268         case ACPI_HEST_NOTIFY_GPIO:
1269                 mutex_lock(&ghes_list_mutex);
1270                 list_del_rcu(&ghes->list);
1271                 if (list_empty(&ghes_hed))
1272                         unregister_acpi_hed_notifier(&ghes_notifier_hed);
1273                 mutex_unlock(&ghes_list_mutex);
1274                 synchronize_rcu();
1275                 break;
1276 
1277         case ACPI_HEST_NOTIFY_SEA:
1278                 ghes_sea_remove(ghes);
1279                 break;
1280         case ACPI_HEST_NOTIFY_NMI:
1281                 ghes_nmi_remove(ghes);
1282                 break;
1283         case ACPI_HEST_NOTIFY_SOFTWARE_DELEGATED:
1284                 rc = apei_sdei_unregister_ghes(ghes);
1285                 if (rc)
1286                         return rc;
1287                 break;
1288         default:
1289                 BUG();
1290                 break;
1291         }
1292 
1293         ghes_fini(ghes);
1294 
1295         ghes_edac_unregister(ghes);
1296 
1297         kfree(ghes);
1298 
1299         platform_set_drvdata(ghes_dev, NULL);
1300 
1301         return 0;
1302 }
1303 
1304 static struct platform_driver ghes_platform_driver = {
1305         .driver         = {
1306                 .name   = "GHES",
1307         },
1308         .probe          = ghes_probe,
1309         .remove         = ghes_remove,
1310 };
1311 
1312 static int __init ghes_init(void)
1313 {
1314         int rc;
1315 
1316         if (acpi_disabled)
1317                 return -ENODEV;
1318 
1319         switch (hest_disable) {
1320         case HEST_NOT_FOUND:
1321                 return -ENODEV;
1322         case HEST_DISABLED:
1323                 pr_info(GHES_PFX "HEST is not enabled!\n");
1324                 return -EINVAL;
1325         default:
1326                 break;
1327         }
1328 
1329         if (ghes_disable) {
1330                 pr_info(GHES_PFX "GHES is not enabled!\n");
1331                 return -EINVAL;
1332         }
1333 
1334         ghes_nmi_init_cxt();
1335 
1336         rc = platform_driver_register(&ghes_platform_driver);
1337         if (rc)
1338                 goto err;
1339 
1340         rc = apei_osc_setup();
1341         if (rc == 0 && osc_sb_apei_support_acked)
1342                 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n");
1343         else if (rc == 0 && !osc_sb_apei_support_acked)
1344                 pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n");
1345         else if (rc && osc_sb_apei_support_acked)
1346                 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
1347         else
1348                 pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
1349 
1350         return 0;
1351 err:
1352         return rc;
1353 }
1354 device_initcall(ghes_init);

/* [<][>][^][v][top][bottom][index][help] */