mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	drop this forced built-in only configuration by disentangling it from GHES. Work by Jia He. - The usual small cleanups and improvements all over EDAC land -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmOXPvoACgkQEsHwGGHe VUq98xAAmhz4u9e9pXG0Ixkx25ZtnZ+YxANeQ53Hsa2gWicbcoFgL2E30gi97c1y X9W361B2Q5dYq+J/YRUnEOXlI/KMWLxzNykSvVipUFNfxXZH+PijEAArz2V35/uE 6ZISRLUYVYEtHEoUXbTogeyBmBUnIaJfYheZCluDQlWPggsDESP1qmE+FTg25OBs rDl5y+zUZYPxrWustNodVThPyhdMwGyYAUS6qYKCoNs9SNkAjGnrXoPc9j/U+cV+ qMY2dNS3uKnCujKEssQhcHucyWgCEDvmEKWMH4ItryV2UBBjpNRoM6HDe7XFKwVJ riOKX8VDrpdSdlV1jbCx9KB47BUwFygOYsFdW7gIDJ1hb8usN4nSYQNDIlZKEIQG cHNpv2XGT+pCSvyc4Iv2Fgyvnp25XensSQwQAtk5Y4/lJL1yrgcPjMOkPmRS+mmH BclDWNbL+gwqkyWxgfoivDBOetLgwJYTr2ewBr6QbBtwLB8rL4BxXIdomcoFPuxi jAxixZnTbS+Xq5S7uYK4r6KbaHGcJtwolXMGjx13IHmPfvYtTTQzfRcrBlAtQ/pV BDLoygmDVlkhSVx6bi5V5QZ06rcWYR4cRsBQ54FnBGMr730ZljgFONOHFtUab28T C+YUOaeLEYEYI0cIkkyoSuiz6avB6YvQAiyEPM0EdHZrQFwhBBw= =DFp8 -----END PGP SIGNATURE----- Merge tag 'edac_updates_for_6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras Pull EDAC updates from Borislav Petkov: - Make ghes_edac a simple module like the rest of the EDAC drivers and drop the forced built-in only configuration by disentangling it from GHES (Jia He) - The usual small cleanups and improvements all over EDAC land * tag 'edac_updates_for_6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras: EDAC/i10nm: fix refcount leak in pci_get_dev_wrapper() EDAC/i5400: Fix typo in comment: vaious -> various EDAC/mc_sysfs: Increase legacy channel support to 12 MAINTAINERS: Make Mauro EDAC reviewer MAINTAINERS: Make Manivannan Sadhasivam the maintainer of qcom_edac EDAC/igen6: Return the correct error type when not the MC owner apei/ghes: Use xchg_release() for updating new cache slot instead of cmpxchg() EDAC: Check for GHES preference in the chipset-specific EDAC drivers EDAC/ghes: Make ghes_edac a proper module EDAC/ghes: Prepare to make ghes_edac a proper module EDAC/ghes: Add a notifier for reporting memory errors efi/cper: Export several helpers for ghes_edac to use EDAC/i5000: Mark as BROKEN
		
			
				
	
	
		
			132 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* SPDX-License-Identifier: GPL-2.0 */
 | 
						|
#ifndef GHES_H
 | 
						|
#define GHES_H
 | 
						|
 | 
						|
#include <acpi/apei.h>
 | 
						|
#include <acpi/hed.h>
 | 
						|
 | 
						|
/*
 | 
						|
 * One struct ghes is created for each generic hardware error source.
 | 
						|
 * It provides the context for APEI hardware error timer/IRQ/SCI/NMI
 | 
						|
 * handler.
 | 
						|
 *
 | 
						|
 * estatus: memory buffer for error status block, allocated during
 | 
						|
 * HEST parsing.
 | 
						|
 */
 | 
						|
#define GHES_EXITING		0x0002
 | 
						|
 | 
						|
struct ghes {
 | 
						|
	union {
 | 
						|
		struct acpi_hest_generic *generic;
 | 
						|
		struct acpi_hest_generic_v2 *generic_v2;
 | 
						|
	};
 | 
						|
	struct acpi_hest_generic_status *estatus;
 | 
						|
	unsigned long flags;
 | 
						|
	union {
 | 
						|
		struct list_head list;
 | 
						|
		struct timer_list timer;
 | 
						|
		unsigned int irq;
 | 
						|
	};
 | 
						|
	struct device *dev;
 | 
						|
	struct list_head elist;
 | 
						|
};
 | 
						|
 | 
						|
struct ghes_estatus_node {
 | 
						|
	struct llist_node llnode;
 | 
						|
	struct acpi_hest_generic *generic;
 | 
						|
	struct ghes *ghes;
 | 
						|
 | 
						|
	int task_work_cpu;
 | 
						|
	struct callback_head task_work;
 | 
						|
};
 | 
						|
 | 
						|
struct ghes_estatus_cache {
 | 
						|
	u32 estatus_len;
 | 
						|
	atomic_t count;
 | 
						|
	struct acpi_hest_generic *generic;
 | 
						|
	unsigned long long time_in;
 | 
						|
	struct rcu_head rcu;
 | 
						|
};
 | 
						|
 | 
						|
enum {
 | 
						|
	GHES_SEV_NO = 0x0,
 | 
						|
	GHES_SEV_CORRECTED = 0x1,
 | 
						|
	GHES_SEV_RECOVERABLE = 0x2,
 | 
						|
	GHES_SEV_PANIC = 0x3,
 | 
						|
};
 | 
						|
 | 
						|
#ifdef CONFIG_ACPI_APEI_GHES
 | 
						|
/**
 | 
						|
 * ghes_register_vendor_record_notifier - register a notifier for vendor
 | 
						|
 * records that the kernel would otherwise ignore.
 | 
						|
 * @nb: pointer to the notifier_block structure of the event handler.
 | 
						|
 *
 | 
						|
 * return 0 : SUCCESS, non-zero : FAIL
 | 
						|
 */
 | 
						|
int ghes_register_vendor_record_notifier(struct notifier_block *nb);
 | 
						|
 | 
						|
/**
 | 
						|
 * ghes_unregister_vendor_record_notifier - unregister the previously
 | 
						|
 * registered vendor record notifier.
 | 
						|
 * @nb: pointer to the notifier_block structure of the vendor record handler.
 | 
						|
 */
 | 
						|
void ghes_unregister_vendor_record_notifier(struct notifier_block *nb);
 | 
						|
 | 
						|
struct list_head *ghes_get_devices(void);
 | 
						|
#else
 | 
						|
static inline struct list_head *ghes_get_devices(void) { return NULL; }
 | 
						|
#endif
 | 
						|
 | 
						|
int ghes_estatus_pool_init(unsigned int num_ghes);
 | 
						|
 | 
						|
static inline int acpi_hest_get_version(struct acpi_hest_generic_data *gdata)
 | 
						|
{
 | 
						|
	return gdata->revision >> 8;
 | 
						|
}
 | 
						|
 | 
						|
static inline void *acpi_hest_get_payload(struct acpi_hest_generic_data *gdata)
 | 
						|
{
 | 
						|
	if (acpi_hest_get_version(gdata) >= 3)
 | 
						|
		return (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1);
 | 
						|
 | 
						|
	return gdata + 1;
 | 
						|
}
 | 
						|
 | 
						|
static inline int acpi_hest_get_error_length(struct acpi_hest_generic_data *gdata)
 | 
						|
{
 | 
						|
	return ((struct acpi_hest_generic_data *)(gdata))->error_data_length;
 | 
						|
}
 | 
						|
 | 
						|
static inline int acpi_hest_get_size(struct acpi_hest_generic_data *gdata)
 | 
						|
{
 | 
						|
	if (acpi_hest_get_version(gdata) >= 3)
 | 
						|
		return sizeof(struct acpi_hest_generic_data_v300);
 | 
						|
 | 
						|
	return sizeof(struct acpi_hest_generic_data);
 | 
						|
}
 | 
						|
 | 
						|
static inline int acpi_hest_get_record_size(struct acpi_hest_generic_data *gdata)
 | 
						|
{
 | 
						|
	return (acpi_hest_get_size(gdata) + acpi_hest_get_error_length(gdata));
 | 
						|
}
 | 
						|
 | 
						|
static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata)
 | 
						|
{
 | 
						|
	return (void *)(gdata) + acpi_hest_get_record_size(gdata);
 | 
						|
}
 | 
						|
 | 
						|
#define apei_estatus_for_each_section(estatus, section)			\
 | 
						|
	for (section = (struct acpi_hest_generic_data *)(estatus + 1);	\
 | 
						|
	     (void *)section - (void *)(estatus + 1) < estatus->data_length; \
 | 
						|
	     section = acpi_hest_get_next(section))
 | 
						|
 | 
						|
#ifdef CONFIG_ACPI_APEI_SEA
 | 
						|
int ghes_notify_sea(void);
 | 
						|
#else
 | 
						|
static inline int ghes_notify_sea(void) { return -ENOENT; }
 | 
						|
#endif
 | 
						|
 | 
						|
struct notifier_block;
 | 
						|
extern void ghes_register_report_chain(struct notifier_block *nb);
 | 
						|
extern void ghes_unregister_report_chain(struct notifier_block *nb);
 | 
						|
#endif /* GHES_H */
 |