Commit ba8af8e1 authored by Fabio M. De Francesco's avatar Fabio M. De Francesco Committed by Rafael J. Wysocki
Browse files

ACPI: APEI: GHES: Add helper to copy CPER CXL protocol error info to work struct



Make a helper out of cxl_cper_post_prot_err() that checks the CXL agent
type and copy the CPER CXL protocol errors information to a work data
structure.

Export the new symbol for reuse by ELOG.

Reviewed-by: default avatarDave Jiang <dave.jiang@intel.com>
Reviewed-by: default avatarJonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: default avatarHanjun Guo <guohanjun@huawei.com>
Signed-off-by: default avatarFabio M. De Francesco <fabio.m.de.francesco@linux.intel.com>
[ rjw: Subject tweak ]
Link: https://patch.msgid.link/20260114101543.85926-5-fabio.m.de.francesco@linux.intel.com


Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 70205869
Loading
Loading
Loading
Loading
+1 −21
Original line number Diff line number Diff line
@@ -739,7 +739,6 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
{
#ifdef CONFIG_ACPI_APEI_PCIEAER
	struct cxl_cper_prot_err_work_data wd;
	u8 *dvsec_start, *cap_start;

	if (cxl_cper_sec_prot_err_valid(prot_err))
		return;
@@ -749,27 +748,8 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
	if (!cxl_cper_prot_err_work)
		return;

	switch (prot_err->agent_type) {
	case RCD:
	case DEVICE:
	case LD:
	case FMLD:
	case RP:
	case DSP:
	case USP:
		memcpy(&wd.prot_err, prot_err, sizeof(wd.prot_err));

		dvsec_start = (u8 *)(prot_err + 1);
		cap_start = dvsec_start + prot_err->dvsec_len;

		memcpy(&wd.ras_cap, cap_start, sizeof(wd.ras_cap));
		wd.severity = cper_severity_to_aer(severity);
		break;
	default:
		pr_err_ratelimited("CXL CPER invalid agent type: %d\n",
				   prot_err->agent_type);
	if (cxl_cper_setup_prot_err_work_data(&wd, prot_err, severity))
		return;
	}

	if (!kfifo_put(&cxl_cper_prot_err_fifo, wd)) {
		pr_err_ratelimited("CXL CPER kfifo overflow\n");
+33 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
// Copyright(c) 2025 Intel Corporation. All rights reserved

#include <linux/printk.h>
#include <linux/aer.h>
#include <cxl/event.h>

int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
@@ -31,3 +32,35 @@ int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
	return 0;
}
EXPORT_SYMBOL_GPL(cxl_cper_sec_prot_err_valid);

int cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd,
				      struct cxl_cper_sec_prot_err *prot_err,
				      int severity)
{
	u8 *dvsec_start, *cap_start;

	switch (prot_err->agent_type) {
	case RCD:
	case DEVICE:
	case LD:
	case FMLD:
	case RP:
	case DSP:
	case USP:
		memcpy(&wd->prot_err, prot_err, sizeof(wd->prot_err));

		dvsec_start = (u8 *)(prot_err + 1);
		cap_start = dvsec_start + prot_err->dvsec_len;

		memcpy(&wd->ras_cap, cap_start, sizeof(wd->ras_cap));
		wd->severity = cper_severity_to_aer(severity);
		break;
	default:
		pr_err_ratelimited("CXL CPER invalid agent type: %d\n",
				   prot_err->agent_type);
		return -EINVAL;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(cxl_cper_setup_prot_err_work_data);
+10 −0
Original line number Diff line number Diff line
@@ -322,12 +322,22 @@ static inline int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data

#ifdef CONFIG_ACPI_APEI_PCIEAER
int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err);
int cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd,
				      struct cxl_cper_sec_prot_err *prot_err,
				      int severity);
#else
static inline int
cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
{
	return -EOPNOTSUPP;
}
static inline int
cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd,
				  struct cxl_cper_sec_prot_err *prot_err,
				  int severity)
{
	return -EOPNOTSUPP;
}
#endif

#endif /* _LINUX_CXL_EVENT_H */