ghes.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef GHES_H
  3. #define GHES_H
  4. #include <acpi/apei.h>
  5. #include <acpi/hed.h>
  6. /*
  7. * One struct ghes is created for each generic hardware error source.
  8. * It provides the context for APEI hardware error timer/IRQ/SCI/NMI
  9. * handler.
  10. *
  11. * estatus: memory buffer for error status block, allocated during
  12. * HEST parsing.
  13. */
  14. #define GHES_TO_CLEAR 0x0001
  15. #define GHES_EXITING 0x0002
  16. struct ghes {
  17. union {
  18. struct acpi_hest_generic *generic;
  19. struct acpi_hest_generic_v2 *generic_v2;
  20. };
  21. struct acpi_hest_generic_status *estatus;
  22. u64 buffer_paddr;
  23. unsigned long flags;
  24. union {
  25. struct list_head list;
  26. struct timer_list timer;
  27. unsigned int irq;
  28. };
  29. };
  30. struct ghes_estatus_node {
  31. struct llist_node llnode;
  32. struct acpi_hest_generic *generic;
  33. struct ghes *ghes;
  34. };
  35. struct ghes_estatus_cache {
  36. u32 estatus_len;
  37. atomic_t count;
  38. struct acpi_hest_generic *generic;
  39. unsigned long long time_in;
  40. struct rcu_head rcu;
  41. };
  42. enum {
  43. GHES_SEV_NO = 0x0,
  44. GHES_SEV_CORRECTED = 0x1,
  45. GHES_SEV_RECOVERABLE = 0x2,
  46. GHES_SEV_PANIC = 0x3,
  47. };
  48. /* From drivers/edac/ghes_edac.c */
  49. #ifdef CONFIG_EDAC_GHES
  50. void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
  51. int ghes_edac_register(struct ghes *ghes, struct device *dev);
  52. void ghes_edac_unregister(struct ghes *ghes);
  53. #else
  54. static inline void ghes_edac_report_mem_error(int sev,
  55. struct cper_sec_mem_err *mem_err)
  56. {
  57. }
  58. static inline int ghes_edac_register(struct ghes *ghes, struct device *dev)
  59. {
  60. return -ENODEV;
  61. }
  62. static inline void ghes_edac_unregister(struct ghes *ghes)
  63. {
  64. }
  65. #endif
  66. static inline int acpi_hest_get_version(struct acpi_hest_generic_data *gdata)
  67. {
  68. return gdata->revision >> 8;
  69. }
  70. static inline void *acpi_hest_get_payload(struct acpi_hest_generic_data *gdata)
  71. {
  72. if (acpi_hest_get_version(gdata) >= 3)
  73. return (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1);
  74. return gdata + 1;
  75. }
  76. static inline int acpi_hest_get_error_length(struct acpi_hest_generic_data *gdata)
  77. {
  78. return ((struct acpi_hest_generic_data *)(gdata))->error_data_length;
  79. }
  80. static inline int acpi_hest_get_size(struct acpi_hest_generic_data *gdata)
  81. {
  82. if (acpi_hest_get_version(gdata) >= 3)
  83. return sizeof(struct acpi_hest_generic_data_v300);
  84. return sizeof(struct acpi_hest_generic_data);
  85. }
  86. static inline int acpi_hest_get_record_size(struct acpi_hest_generic_data *gdata)
  87. {
  88. return (acpi_hest_get_size(gdata) + acpi_hest_get_error_length(gdata));
  89. }
  90. static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata)
  91. {
  92. return (void *)(gdata) + acpi_hest_get_record_size(gdata);
  93. }
  94. #define apei_estatus_for_each_section(estatus, section) \
  95. for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
  96. (void *)section - (void *)(estatus + 1) < estatus->data_length; \
  97. section = acpi_hest_get_next(section))
  98. #ifdef CONFIG_ACPI_APEI_SEA
  99. int ghes_notify_sea(void);
  100. #else
  101. static inline int ghes_notify_sea(void) { return -ENOENT; }
  102. #endif
  103. #endif /* GHES_H */