cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ghes.h (3687B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef GHES_H
      3#define GHES_H
      4
      5#include <acpi/apei.h>
      6#include <acpi/hed.h>
      7
      8/*
      9 * One struct ghes is created for each generic hardware error source.
     10 * It provides the context for APEI hardware error timer/IRQ/SCI/NMI
     11 * handler.
     12 *
     13 * estatus: memory buffer for error status block, allocated during
     14 * HEST parsing.
     15 */
     16#define GHES_EXITING		0x0002
     17
     18struct ghes {
     19	union {
     20		struct acpi_hest_generic *generic;
     21		struct acpi_hest_generic_v2 *generic_v2;
     22	};
     23	struct acpi_hest_generic_status *estatus;
     24	unsigned long flags;
     25	union {
     26		struct list_head list;
     27		struct timer_list timer;
     28		unsigned int irq;
     29	};
     30};
     31
     32struct ghes_estatus_node {
     33	struct llist_node llnode;
     34	struct acpi_hest_generic *generic;
     35	struct ghes *ghes;
     36
     37	int task_work_cpu;
     38	struct callback_head task_work;
     39};
     40
     41struct ghes_estatus_cache {
     42	u32 estatus_len;
     43	atomic_t count;
     44	struct acpi_hest_generic *generic;
     45	unsigned long long time_in;
     46	struct rcu_head rcu;
     47};
     48
     49enum {
     50	GHES_SEV_NO = 0x0,
     51	GHES_SEV_CORRECTED = 0x1,
     52	GHES_SEV_RECOVERABLE = 0x2,
     53	GHES_SEV_PANIC = 0x3,
     54};
     55
     56#ifdef CONFIG_ACPI_APEI_GHES
     57/**
     58 * ghes_register_vendor_record_notifier - register a notifier for vendor
     59 * records that the kernel would otherwise ignore.
     60 * @nb: pointer to the notifier_block structure of the event handler.
     61 *
     62 * return 0 : SUCCESS, non-zero : FAIL
     63 */
     64int ghes_register_vendor_record_notifier(struct notifier_block *nb);
     65
     66/**
     67 * ghes_unregister_vendor_record_notifier - unregister the previously
     68 * registered vendor record notifier.
     69 * @nb: pointer to the notifier_block structure of the vendor record handler.
     70 */
     71void ghes_unregister_vendor_record_notifier(struct notifier_block *nb);
     72#endif
     73
     74int ghes_estatus_pool_init(unsigned int num_ghes);
     75
     76/* From drivers/edac/ghes_edac.c */
     77
     78#ifdef CONFIG_EDAC_GHES
     79void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
     80
     81int ghes_edac_register(struct ghes *ghes, struct device *dev);
     82
     83void ghes_edac_unregister(struct ghes *ghes);
     84
     85#else
     86static inline void ghes_edac_report_mem_error(int sev,
     87				       struct cper_sec_mem_err *mem_err)
     88{
     89}
     90
     91static inline int ghes_edac_register(struct ghes *ghes, struct device *dev)
     92{
     93	return -ENODEV;
     94}
     95
     96static inline void ghes_edac_unregister(struct ghes *ghes)
     97{
     98}
     99#endif
    100
    101static inline int acpi_hest_get_version(struct acpi_hest_generic_data *gdata)
    102{
    103	return gdata->revision >> 8;
    104}
    105
    106static inline void *acpi_hest_get_payload(struct acpi_hest_generic_data *gdata)
    107{
    108	if (acpi_hest_get_version(gdata) >= 3)
    109		return (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1);
    110
    111	return gdata + 1;
    112}
    113
    114static inline int acpi_hest_get_error_length(struct acpi_hest_generic_data *gdata)
    115{
    116	return ((struct acpi_hest_generic_data *)(gdata))->error_data_length;
    117}
    118
    119static inline int acpi_hest_get_size(struct acpi_hest_generic_data *gdata)
    120{
    121	if (acpi_hest_get_version(gdata) >= 3)
    122		return sizeof(struct acpi_hest_generic_data_v300);
    123
    124	return sizeof(struct acpi_hest_generic_data);
    125}
    126
    127static inline int acpi_hest_get_record_size(struct acpi_hest_generic_data *gdata)
    128{
    129	return (acpi_hest_get_size(gdata) + acpi_hest_get_error_length(gdata));
    130}
    131
    132static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata)
    133{
    134	return (void *)(gdata) + acpi_hest_get_record_size(gdata);
    135}
    136
    137#define apei_estatus_for_each_section(estatus, section)			\
    138	for (section = (struct acpi_hest_generic_data *)(estatus + 1);	\
    139	     (void *)section - (void *)(estatus + 1) < estatus->data_length; \
    140	     section = acpi_hest_get_next(section))
    141
    142#ifdef CONFIG_ACPI_APEI_SEA
    143int ghes_notify_sea(void);
    144#else
    145static inline int ghes_notify_sea(void) { return -ENOENT; }
    146#endif
    147
    148#endif /* GHES_H */