[PATCH 6.18 109/314] ACPI: APEI: GHES: Add helper for CPER CXL protocol errors checks

Sasha Levin
2026-03-10T11:26:24Z

From: "Fabio M. De Francesco" <fabio.m.de.francesco@linux.intel.com>

[ Upstream commit 70205869686212eb8e4cddf02bf87fd5fd597bc2 ]

Move the CPER CXL protocol errors validity check out of
cxl_cper_post_prot_err() to new cxl_cper_sec_prot_err_valid() and limit
the serial number check only to CXL agents that are CXL devices (UEFI
v2.10, Appendix N.2.13).

Export the new symbol for reuse by ELOG.

Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: Fabio M. De Francesco <fabio.m.de.francesco@linux.intel.com>
[ rjw: Subject tweak ]
Link: https://patch.msgid.link/20260114101543.85926-4-fabio.m.de.francesco@linux.intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Stable-dep-of: b584bfbd7ec4 ("ACPI: APEI: GHES: Disable KASAN instrumentation when compile testing with clang < 18")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/acpi/apei/Makefile | 1 +
drivers/acpi/apei/ghes.c | 18 +----------------
drivers/acpi/apei/ghes_helpers.c | 33 ++++++++++++++++++++++++++++++++
include/cxl/event.h | 10 ++++++++++
4 files changed, 45 insertions(+), 17 deletions(-)
create mode 100644 drivers/acpi/apei/ghes_helpers.c

diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile
index 2c474e6477e12..5db61dfb46915 100644
--- a/drivers/acpi/apei/Makefile
+++ b/drivers/acpi/apei/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_ACPI_APEI) += apei.o
obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o
+obj-$(CONFIG_ACPI_APEI_PCIEAER) += ghes_helpers.o
obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o
einj-y := einj-core.o
einj-$(CONFIG_ACPI_APEI_EINJ_CXL) += einj-cxl.o
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 42872fdc36bfc..fc96a5e234f06 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -746,24 +746,8 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
struct cxl_cper_prot_err_work_data wd;
u8 *dvsec_start, *cap_start;

- if (!(prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS)) {
- pr_err_ratelimited("CXL CPER invalid agent type\n");
+ if (cxl_cper_sec_prot_err_valid(prot_err))
return;
- }
-
- if (!(prot_err->valid_bits & PROT_ERR_VALID_ERROR_LOG)) {
- pr_err_ratelimited("CXL CPER invalid protocol error log\n");
- return;
- }
-
- if (prot_err->err_len != sizeof(struct cxl_ras_capability_regs)) {
- pr_err_ratelimited("CXL CPER invalid RAS Cap size (%u)\n",
- prot_err->err_len);
- return;
- }
-
- if (!(prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER))
- pr_warn(FW_WARN "CXL CPER no device serial number\n");

guard(spinlock_irqsave)(&cxl_cper_prot_err_work_lock);

diff --git a/drivers/acpi/apei/ghes_helpers.c b/drivers/acpi/apei/ghes_helpers.c
new file mode 100644
index 0000000000000..f3d162139a974
--- /dev/null
+++ b/drivers/acpi/apei/ghes_helpers.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2025 Intel Corporation. All rights reserved
+
+#include <linux/printk.h>
+#include <cxl/event.h>
+
+int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
+{
+ if (!(prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS)) {
+ pr_err_ratelimited("CXL CPER invalid agent type\n");
+ return -EINVAL;
+ }
+
+ if (!(prot_err->valid_bits & PROT_ERR_VALID_ERROR_LOG)) {
+ pr_err_ratelimited("CXL CPER invalid protocol error log\n");
+ return -EINVAL;
+ }
+
+ if (prot_err->err_len != sizeof(struct cxl_ras_capability_regs)) {
+ pr_err_ratelimited("CXL CPER invalid RAS Cap size (%u)\n",
+ prot_err->err_len);
+ return -EINVAL;
+ }
+
+ if ((prot_err->agent_type == RCD || prot_err->agent_type == DEVICE ||
+ prot_err->agent_type == LD || prot_err->agent_type == FMLD) &&
+ !(prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER))
+ pr_warn_ratelimited(FW_WARN
+ "CXL CPER no device serial number\n");
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxl_cper_sec_prot_err_valid);
diff --git a/include/cxl/event.h b/include/cxl/event.h
index 6fd90f9cc2034..4d7d1036ea9cb 100644
--- a/include/cxl/event.h
+++ b/include/cxl/event.h
@@ -320,4 +320,14 @@ static inline int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data
}
#endif

+#ifdef CONFIG_ACPI_APEI_PCIEAER
+int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err);
+#else
+static inline int
+cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
#endif /* _LINUX_CXL_EVENT_H */
--
2.51.0