* [RFC PATCH 1/6] ACPI: extlog: fix extlog_mem_event build issue
2026-09-29 7:45 [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support Pierre Gondois
@ 2026-09-29 7:46 ` Pierre Gondois
2026-09-29 7:46 ` [RFC PATCH 2/6] cper: add Memory Error Section 2 structures Pierre Gondois
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Pierre Gondois @ 2026-09-29 7:46 UTC (permalink / raw)
To: linux-kernel
Cc: James Morse, Mark Brown, Pierre Gondois, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Rafael J. Wysocki, Len Brown, Tony Luck, Hanjun Guo,
Mauro Carvalho Chehab, Shuai Xue, Maciej Wieczor-Retman,
Pawel Chmielewski, Yazen Ghannam, Avadhut Naik, Radu Rendec,
Kees Cook, Jonathan Cameron, Dave Jiang, Fabio M. De Francesco,
Breno Leitao, Terry Bowman, Dan Williams, Ard Biesheuvel,
Morduan Zang, linux-acpi, linux-edac, acpica-devel
With CONFIG_ACPI_EXTLOG=n and with the following command:
make -j4 drivers/acpi/acpi_extlog.o drivers/acpi/
trace_extlog_mem_event() is not defined. Add a extlog_mem_err_event()
wrapper to fix the build issue.
Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
---
drivers/acpi/acpi_extlog.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 7ad3b36013cc6..699534b6a732d 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -180,6 +180,15 @@ extlog_cxl_cper_handle_prot_err(struct cxl_cper_sec_prot_err *prot_err,
#endif
}
+static void
+extlog_mem_err_event(struct cper_sec_mem_err *mem, u32 err_seq,
+ const guid_t *fru_id, const char *fru_text, u8 sev)
+{
+#if defined(CONFIG_ACPI_EXTLOG) || defined(CONFIG_ACPI_EXTLOG_MODULE)
+ trace_extlog_mem_event(mem, err_seq, fru_id, fru_text, sev);
+#endif
+}
+
static int extlog_print(struct notifier_block *nb, unsigned long val,
void *data)
{
@@ -229,8 +238,9 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
struct cper_sec_mem_err *mem = acpi_hest_get_payload(gdata);
if (gdata->error_data_length >= sizeof(*mem))
- trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
- (u8)gdata->error_severity);
+ extlog_mem_err_event(&mem, err_seq, fru_id,
+ fru_text,
+ (u8)gdata->error_severity);
} else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) {
struct cxl_cper_sec_prot_err *prot_err =
acpi_hest_get_payload(gdata);
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [RFC PATCH 2/6] cper: add Memory Error Section 2 structures
2026-09-29 7:45 [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support Pierre Gondois
2026-09-29 7:46 ` [RFC PATCH 1/6] ACPI: extlog: fix extlog_mem_event build issue Pierre Gondois
@ 2026-09-29 7:46 ` Pierre Gondois
2026-09-29 7:46 ` [RFC PATCH 3/6] cper: extend cper_mem_err_compact struct Pierre Gondois
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Pierre Gondois @ 2026-09-29 7:46 UTC (permalink / raw)
To: linux-kernel
Cc: James Morse, Mark Brown, Pierre Gondois, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Rafael J. Wysocki, Len Brown, Tony Luck, Hanjun Guo,
Mauro Carvalho Chehab, Shuai Xue, Maciej Wieczor-Retman,
Pawel Chmielewski, Yazen Ghannam, Avadhut Naik, Kees Cook,
Jonathan Cameron, Dave Jiang, Fabio M. De Francesco,
Breno Leitao, Terry Bowman, Dan Williams, Ard Biesheuvel,
Morduan Zang, linux-acpi, linux-edac, acpica-devel
Add CPER Memory Error Section 2 definitions to the CPER headers.
Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
---
include/linux/cper.h | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/include/linux/cper.h b/include/linux/cper.h
index 440b35e459e53..170bb15f616d0 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -198,6 +198,10 @@ enum {
#define CPER_SEC_PLATFORM_MEM \
GUID_INIT(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83, \
0xED, 0x7C, 0x83, 0xB1)
+/* Platform Memory 2 */
+#define CPER_SEC_PLATFORM_MEM2 \
+ GUID_INIT(0x61EC04FC, 0x48E6, 0xD813, 0x25, 0xC9, 0x8D, 0xAA, \
+ 0x44, 0x75, 0x0B, 0x12)
#define CPER_SEC_PCIE \
GUID_INIT(0xD995E954, 0xBBC1, 0x430F, 0xAD, 0x91, 0xB4, 0x4D, \
0xCB, 0x3C, 0x6F, 0x35)
@@ -506,6 +510,32 @@ struct cper_sec_mem_err {
u16 mem_dev_handle; /* "module handle" in UEFI 2.4 */
};
+/* Memory Error Section 2, UEFI v2.11 sec N.2.6 */
+struct cper_sec_mem_err2 {
+ u64 validation_bits;
+ u64 error_status;
+ u64 physical_addr;
+ u64 physical_addr_mask;
+ u16 node;
+ u16 card;
+ u16 module;
+ u16 bank;
+ u32 device;
+ u32 row;
+ u32 column;
+ u32 rank;
+ u32 bit_pos;
+ u8 chip_id;
+ u8 error_type;
+ u8 status;
+ u8 reserved;
+ u64 requestor_id;
+ u64 responder_id;
+ u64 target_id;
+ u32 mem_array_handle; /* "card handle" */
+ u32 mem_dev_handle; /* "module handle" */
+};
+
struct cper_mem_err_compact {
u64 validation_bits;
u16 node;
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [RFC PATCH 3/6] cper: extend cper_mem_err_compact struct
2026-09-29 7:45 [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support Pierre Gondois
2026-09-29 7:46 ` [RFC PATCH 1/6] ACPI: extlog: fix extlog_mem_event build issue Pierre Gondois
2026-09-29 7:46 ` [RFC PATCH 2/6] cper: add Memory Error Section 2 structures Pierre Gondois
@ 2026-09-29 7:46 ` Pierre Gondois
2026-09-29 7:46 ` [RFC PATCH 4/6] cper: add helpers to handle Memory Error Section 2 Pierre Gondois
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Pierre Gondois @ 2026-09-29 7:46 UTC (permalink / raw)
To: linux-kernel
Cc: James Morse, Mark Brown, Pierre Gondois, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Rafael J. Wysocki, Len Brown, Tony Luck, Hanjun Guo,
Mauro Carvalho Chehab, Shuai Xue, Maciej Wieczor-Retman,
Pawel Chmielewski, Yazen Ghannam, Avadhut Naik, Kees Cook,
Jonathan Cameron, Dave Jiang, Fabio M. De Francesco,
Breno Leitao, Terry Bowman, Dan Williams, Ard Biesheuvel,
Morduan Zang, linux-acpi, linux-edac, acpica-devel
Extend cper_mem_err_compact struct to prepare for:
- additional support of Memory Error Section 2
- widening the usage of cper_mem_err_compact struct for both
Memory Error Section 2 and Memory Error Section (1)
Remove the extended field which contains Memory Error Section (1)
additional bits that can now fit in the larger (u32) fields.
Add fields that were previously not populated (physical_addr, ...)
to prepare for using this cper_mem_err_compact struct for both
Memory Error sections.
Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
---
drivers/firmware/efi/cper.c | 21 ++++++++++++---------
include/linux/cper.h | 22 ++++++++++++++--------
2 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 06b4fdb59917a..6285b67e8fcd9 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -325,12 +325,8 @@ int cper_mem_err_location(struct cper_mem_err_compact *mem, char *msg)
mem->bank & CPER_MEM_BANK_ADDRESS_MASK);
if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
n += scnprintf(msg + n, len - n, "device:%d ", mem->device);
- if (mem->validation_bits & (CPER_MEM_VALID_ROW | CPER_MEM_VALID_ROW_EXT)) {
- u32 row = mem->row;
-
- row |= cper_get_mem_extension(mem->validation_bits, mem->extended);
- n += scnprintf(msg + n, len - n, "row:%d ", row);
- }
+ if (mem->validation_bits & (CPER_MEM_VALID_ROW | CPER_MEM_VALID_ROW_EXT))
+ n += scnprintf(msg + n, len - n, "row:%d ", mem->row);
if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
n += scnprintf(msg + n, len - n, "column:%d ", mem->column);
if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
@@ -347,7 +343,7 @@ int cper_mem_err_location(struct cper_mem_err_compact *mem, char *msg)
mem->target_id);
if (mem->validation_bits & CPER_MEM_VALID_CHIP_ID)
n += scnprintf(msg + n, len - n, "chip_id:%d ",
- mem->extended >> CPER_MEM_CHIP_ID_SHIFT);
+ mem->chip_id);
return n;
}
@@ -362,7 +358,7 @@ int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg)
return 0;
len = CPER_REC_LEN;
- dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
+ dmi_memdev_name((u16)mem->mem_dev_handle, &bank, &device);
if (bank && device)
n = snprintf(msg, len, "DIMM location: %s %s ", bank, device);
else
@@ -377,6 +373,7 @@ EXPORT_SYMBOL_GPL(cper_dimm_err_location);
void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
struct cper_mem_err_compact *cmem)
{
+ memset(cmem, 0, sizeof(*cmem));
cmem->validation_bits = mem->validation_bits;
cmem->node = mem->node;
cmem->card = mem->card;
@@ -384,15 +381,21 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
cmem->bank = mem->bank;
cmem->device = mem->device;
cmem->row = mem->row;
+ cmem->row |= cper_get_mem_extension(mem->validation_bits, mem->extended);
cmem->column = mem->column;
cmem->bit_pos = mem->bit_pos;
cmem->requestor_id = mem->requestor_id;
cmem->responder_id = mem->responder_id;
cmem->target_id = mem->target_id;
- cmem->extended = mem->extended;
cmem->rank = mem->rank;
cmem->mem_array_handle = mem->mem_array_handle;
cmem->mem_dev_handle = mem->mem_dev_handle;
+ cmem->error_status = mem->error_status;
+ cmem->physical_addr = mem->physical_addr;
+ cmem->physical_addr_mask = mem->physical_addr_mask;
+ cmem->error_type = mem->error_type;
+ if (mem->validation_bits & CPER_MEM_VALID_CHIP_ID)
+ cmem->chip_id = mem->extended >> CPER_MEM_CHIP_ID_SHIFT;
}
EXPORT_SYMBOL_GPL(cper_mem_err_pack);
diff --git a/include/linux/cper.h b/include/linux/cper.h
index 170bb15f616d0..b5e2a0d115ca2 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -542,17 +542,23 @@ struct cper_mem_err_compact {
u16 card;
u16 module;
u16 bank;
- u16 device;
- u16 row;
- u16 column;
- u16 bit_pos;
+ u32 device;
+ u32 row;
+ u32 column;
+ u32 bit_pos;
u64 requestor_id;
u64 responder_id;
u64 target_id;
- u16 rank;
- u16 mem_array_handle;
- u16 mem_dev_handle;
- u8 extended;
+ u32 rank;
+ u32 mem_array_handle;
+ u32 mem_dev_handle;
+ u64 error_status;
+ u64 physical_addr;
+ u64 physical_addr_mask;
+ u8 chip_id;
+ u8 status;
+ u8 error_type;
+ u8 is_section2;
};
static inline u32 cper_get_mem_extension(u64 mem_valid, u8 mem_extended)
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [RFC PATCH 4/6] cper: add helpers to handle Memory Error Section 2
2026-09-29 7:45 [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support Pierre Gondois
` (2 preceding siblings ...)
2026-09-29 7:46 ` [RFC PATCH 3/6] cper: extend cper_mem_err_compact struct Pierre Gondois
@ 2026-09-29 7:46 ` Pierre Gondois
2026-09-29 7:46 ` [RFC PATCH 5/6] x86/mce/apei: switch cper_sec_mem_err struct users to compact CPER records Pierre Gondois
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Pierre Gondois @ 2026-09-29 7:46 UTC (permalink / raw)
To: linux-kernel
Cc: James Morse, Mark Brown, Pierre Gondois, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Rafael J. Wysocki, Len Brown, Tony Luck, Hanjun Guo,
Mauro Carvalho Chehab, Shuai Xue, Maciej Wieczor-Retman,
Pawel Chmielewski, Yazen Ghannam, Avadhut Naik, Kees Cook,
Jonathan Cameron, Dave Jiang, Fabio M. De Francesco,
Breno Leitao, Terry Bowman, Dan Williams, Ard Biesheuvel,
Morduan Zang, linux-acpi, linux-edac, acpica-devel
Add helpers to parse Memory Error Section 2 CPER records.
Memory Error Section (1)/2 can be parsed indistinctly into a
cper_mem_err_compact struct.
Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
---
drivers/firmware/efi/cper.c | 141 ++++++++++++++++++++++++++++++++++++
include/linux/cper.h | 4 +
2 files changed, 145 insertions(+)
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 6285b67e8fcd9..cfcd01e3f47bf 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -370,6 +370,28 @@ int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg)
}
EXPORT_SYMBOL_GPL(cper_dimm_err_location);
+static void cper_mem_err_old_pack(const struct cper_sec_mem_err_old *mem,
+ struct cper_mem_err_compact *cmem)
+{
+ memset(cmem, 0, sizeof(*cmem));
+ cmem->validation_bits = mem->validation_bits;
+ cmem->node = mem->node;
+ cmem->card = mem->card;
+ cmem->module = mem->module;
+ cmem->bank = mem->bank;
+ cmem->device = mem->device;
+ cmem->row = mem->row;
+ cmem->column = mem->column;
+ cmem->bit_pos = mem->bit_pos;
+ cmem->requestor_id = mem->requestor_id;
+ cmem->responder_id = mem->responder_id;
+ cmem->target_id = mem->target_id;
+ cmem->error_status = mem->error_status;
+ cmem->physical_addr = mem->physical_addr;
+ cmem->physical_addr_mask = mem->physical_addr_mask;
+ cmem->error_type = mem->error_type;
+}
+
void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
struct cper_mem_err_compact *cmem)
{
@@ -399,6 +421,125 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
}
EXPORT_SYMBOL_GPL(cper_mem_err_pack);
+static void cper_mem_err2_pack(const struct cper_sec_mem_err2 *mem,
+ struct cper_mem_err_compact *cmem)
+{
+ u64 valid = mem->validation_bits;
+
+ memset(cmem, 0, sizeof(*cmem));
+ /*
+ * Memory Error Section 2 uses different validation bit assignments
+ * from the legacy section starting at bit 10. Translate them to the
+ * assignments used by struct cper_mem_err_compact and its consumers.
+ */
+ cmem->validation_bits = valid & GENMASK_ULL(9, 0);
+ if (valid & BIT_ULL(10))
+ cmem->validation_bits |= CPER_MEM_VALID_RANK_NUMBER;
+ if (valid & BIT_ULL(11))
+ cmem->validation_bits |= CPER_MEM_VALID_BIT_POSITION;
+ if (valid & BIT_ULL(12))
+ cmem->validation_bits |= CPER_MEM_VALID_CHIP_ID;
+ if (valid & BIT_ULL(13))
+ cmem->validation_bits |= CPER_MEM_VALID_ERROR_TYPE;
+ if (valid & BIT_ULL(14))
+ cmem->validation_bits |= CPER_MEM_VALID_STATUS;
+ if (valid & BIT_ULL(15))
+ cmem->validation_bits |= CPER_MEM_VALID_REQUESTOR_ID;
+ if (valid & BIT_ULL(16))
+ cmem->validation_bits |= CPER_MEM_VALID_RESPONDER_ID;
+ if (valid & BIT_ULL(17))
+ cmem->validation_bits |= CPER_MEM_VALID_TARGET_ID;
+ if (valid & BIT_ULL(18))
+ cmem->validation_bits |= CPER_MEM_VALID_CARD_HANDLE;
+ if (valid & BIT_ULL(19))
+ cmem->validation_bits |= CPER_MEM_VALID_MODULE_HANDLE;
+ if (valid & BIT_ULL(20))
+ cmem->validation_bits |= CPER_MEM_VALID_BANK_GROUP;
+ if (valid & BIT_ULL(21))
+ cmem->validation_bits |= CPER_MEM_VALID_BANK_ADDRESS;
+ cmem->node = mem->node;
+ cmem->card = mem->card;
+ cmem->module = mem->module;
+ cmem->bank = mem->bank;
+ cmem->device = mem->device;
+ cmem->row = mem->row;
+ cmem->column = mem->column;
+ cmem->bit_pos = mem->bit_pos;
+ cmem->requestor_id = mem->requestor_id;
+ cmem->responder_id = mem->responder_id;
+ cmem->target_id = mem->target_id;
+ cmem->rank = mem->rank;
+ cmem->mem_array_handle = mem->mem_array_handle;
+ cmem->mem_dev_handle = mem->mem_dev_handle;
+ cmem->error_status = mem->error_status;
+ cmem->physical_addr = mem->physical_addr;
+ cmem->physical_addr_mask = mem->physical_addr_mask;
+ cmem->chip_id = mem->chip_id;
+ cmem->status = mem->status;
+ cmem->error_type = mem->error_type;
+ cmem->is_section2 = 1;
+
+ if ((cmem->validation_bits & CPER_MEM_VALID_CARD_HANDLE) &&
+ cmem->mem_array_handle > U16_MAX) {
+ pr_warn(FW_WARN "Memory Error Section 2 card handle 0x%x exceeds SMBIOS range\n",
+ cmem->mem_array_handle);
+ cmem->mem_array_handle = 0;
+ cmem->validation_bits &= ~CPER_MEM_VALID_CARD_HANDLE;
+ }
+
+ if ((cmem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) &&
+ cmem->mem_dev_handle > U16_MAX) {
+ pr_warn(FW_WARN "Memory Error Section 2 module handle 0x%x exceeds SMBIOS range\n",
+ cmem->mem_dev_handle);
+ cmem->mem_dev_handle = 0;
+ cmem->validation_bits &= ~CPER_MEM_VALID_MODULE_HANDLE;
+ }
+}
+
+bool cper_sec_is_platform_mem(const guid_t *sec_type)
+{
+ return guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM) ||
+ guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM2);
+}
+EXPORT_SYMBOL_GPL(cper_sec_is_platform_mem);
+
+int cper_mem_err_parse(const guid_t *sec_type, const void *mem, size_t len,
+ struct cper_mem_err_compact *cmem)
+{
+ memset(cmem, 0, sizeof(*cmem));
+
+ if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM2)) {
+ const struct cper_sec_mem_err2 *mem2 = mem;
+
+ if (len < sizeof(*mem2))
+ return -EINVAL;
+
+ cper_mem_err2_pack(mem2, cmem);
+ return 0;
+ }
+
+ if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
+ const struct cper_sec_mem_err_old *old = mem;
+
+ if (len < sizeof(*old))
+ return -EINVAL;
+
+ if (len < sizeof(struct cper_sec_mem_err)) {
+ u64 old_valid_mask = CPER_MEM_VALID_RANK_NUMBER - 1;
+
+ cper_mem_err_old_pack(old, cmem);
+ cmem->validation_bits &= old_valid_mask;
+ return 0;
+ }
+
+ cper_mem_err_pack(mem, cmem);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(cper_mem_err_parse);
+
const char *cper_mem_err_unpack(struct trace_seq *p,
struct cper_mem_err_compact *cmem)
{
diff --git a/include/linux/cper.h b/include/linux/cper.h
index b5e2a0d115ca2..ac236043ce859 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -265,6 +265,7 @@ enum {
#define CPER_MEM_VALID_BANK_GROUP 0x80000
#define CPER_MEM_VALID_BANK_ADDRESS 0x100000
#define CPER_MEM_VALID_CHIP_ID 0x200000
+#define CPER_MEM_VALID_STATUS 0x400000
#define CPER_MEM_EXT_ROW_MASK 0x3
#define CPER_MEM_EXT_ROW_SHIFT 16
@@ -628,6 +629,9 @@ int cper_bits_to_str(char *buf, int buf_size, unsigned long bits,
const char * const strs[], unsigned int strs_size);
void cper_mem_err_pack(const struct cper_sec_mem_err *,
struct cper_mem_err_compact *);
+bool cper_sec_is_platform_mem(const guid_t *sec_type);
+int cper_mem_err_parse(const guid_t *sec_type, const void *mem, size_t len,
+ struct cper_mem_err_compact *cmem);
const char *cper_mem_err_unpack(struct trace_seq *,
struct cper_mem_err_compact *);
void cper_print_proc_arm(const char *pfx,
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [RFC PATCH 5/6] x86/mce/apei: switch cper_sec_mem_err struct users to compact CPER records
2026-09-29 7:45 [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support Pierre Gondois
` (3 preceding siblings ...)
2026-09-29 7:46 ` [RFC PATCH 4/6] cper: add helpers to handle Memory Error Section 2 Pierre Gondois
@ 2026-09-29 7:46 ` Pierre Gondois
2026-09-29 7:46 ` [RFC PATCH 6/6] cper: make cper_mem_err_pack() static Pierre Gondois
2026-09-29 16:35 ` [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support Jonathan Cameron
6 siblings, 0 replies; 8+ messages in thread
From: Pierre Gondois @ 2026-09-29 7:46 UTC (permalink / raw)
To: linux-kernel
Cc: James Morse, Mark Brown, Pierre Gondois, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Rafael J. Wysocki, Len Brown, Tony Luck, Hanjun Guo,
Mauro Carvalho Chehab, Shuai Xue, Maciej Wieczor-Retman,
Pawel Chmielewski, Yazen Ghannam, Radu Rendec, Avadhut Naik,
Kees Cook, Jonathan Cameron, Dave Jiang, Fabio M. De Francesco,
Breno Leitao, Terry Bowman, Dan Williams, Ard Biesheuvel,
Morduan Zang, linux-acpi, linux-edac, acpica-devel
Convert the GHES, EDAC and x86 APEI memory error paths to consume
struct cper_mem_err_compact instead of raw legacy CPER memory error
sections.
This switches the users over to the common parsed representation,
allowing them to handle both legacy platform memory sections and
Memory Error Section 2 without duplicating format-specific logic.
Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
---
arch/x86/include/asm/mce.h | 4 +--
arch/x86/kernel/acpi/apei.c | 2 +-
arch/x86/kernel/cpu/mce/apei.c | 2 +-
drivers/acpi/acpi_extlog.c | 9 +++---
drivers/acpi/apei/apei-base.c | 2 +-
drivers/acpi/apei/ghes.c | 20 ++++++++-----
drivers/edac/ghes_edac.c | 26 ++++++++---------
drivers/firmware/efi/cper.c | 52 +++++++++++++++++++---------------
include/acpi/apei.h | 2 +-
include/ras/ras_event.h | 4 +--
10 files changed, 68 insertions(+), 55 deletions(-)
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index e575b702063d0..76cff0d9d0308 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -330,9 +330,9 @@ extern void (*deferred_error_int_vector)(void);
* Used by APEI to report memory error via /dev/mcelog
*/
-struct cper_sec_mem_err;
+struct cper_mem_err_compact;
extern void apei_mce_report_mem_error(int corrected,
- struct cper_sec_mem_err *mem_err);
+ struct cper_mem_err_compact *mem_err);
/*
* Enumerate new IP types and HWID values in AMD processors which support
diff --git a/arch/x86/kernel/acpi/apei.c b/arch/x86/kernel/acpi/apei.c
index e21419e686eb3..7b914204b6ab4 100644
--- a/arch/x86/kernel/acpi/apei.c
+++ b/arch/x86/kernel/acpi/apei.c
@@ -39,7 +39,7 @@ int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data)
return 1;
}
-void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
+void arch_apei_report_mem_error(int sev, struct cper_mem_err_compact *mem_err)
{
#ifdef CONFIG_X86_MCE
apei_mce_report_mem_error(sev, mem_err);
diff --git a/arch/x86/kernel/cpu/mce/apei.c b/arch/x86/kernel/cpu/mce/apei.c
index 0a89947e47bc8..a46bc1325c951 100644
--- a/arch/x86/kernel/cpu/mce/apei.c
+++ b/arch/x86/kernel/cpu/mce/apei.c
@@ -26,7 +26,7 @@
#include "internal.h"
-void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err)
+void apei_mce_report_mem_error(int severity, struct cper_mem_err_compact *mem_err)
{
struct mce_hw_err err;
struct mce *m;
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 699534b6a732d..6f1f1b8ecf924 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -181,7 +181,7 @@ extlog_cxl_cper_handle_prot_err(struct cxl_cper_sec_prot_err *prot_err,
}
static void
-extlog_mem_err_event(struct cper_sec_mem_err *mem, u32 err_seq,
+extlog_mem_err_event(struct cper_mem_err_compact *mem, u32 err_seq,
const guid_t *fru_id, const char *fru_text, u8 sev)
{
#if defined(CONFIG_ACPI_EXTLOG) || defined(CONFIG_ACPI_EXTLOG_MODULE)
@@ -234,10 +234,11 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
else
fru_text = "";
sec_type = (guid_t *)gdata->section_type;
- if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
- struct cper_sec_mem_err *mem = acpi_hest_get_payload(gdata);
+ if (cper_sec_is_platform_mem(sec_type)) {
+ struct cper_mem_err_compact mem;
- if (gdata->error_data_length >= sizeof(*mem))
+ if (!cper_mem_err_parse(sec_type, acpi_hest_get_payload(gdata),
+ gdata->error_data_length, &mem))
extlog_mem_err_event(&mem, err_seq, fru_id,
fru_text,
(u8)gdata->error_severity);
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index 7a06d30bd40e9..c2b731054f329 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -768,7 +768,7 @@ int __weak arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr,
EXPORT_SYMBOL_GPL(arch_apei_enable_cmcff);
void __weak arch_apei_report_mem_error(int sev,
- struct cper_sec_mem_err *mem_err)
+ struct cper_mem_err_compact *mem_err)
{
}
EXPORT_SYMBOL_GPL(arch_apei_report_mem_error);
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index fe10ab0e02f68..b0368e55856ef 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -529,11 +529,11 @@ static bool ghes_do_memory_failure(u64 physical_addr, int flags)
}
static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
+ struct cper_mem_err_compact *mem_err,
int sev, bool sync)
{
int flags = -1;
int sec_sev = ghes_severity(gdata->error_severity);
- struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
return false;
@@ -915,7 +915,7 @@ static void ghes_log_hwerr(int sev, guid_t *sec_type)
return;
}
- if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
+ if (cper_sec_is_platform_mem(sec_type)) {
hwerr_log_error_type(HWERR_RECOV_MEMORY);
return;
}
@@ -945,13 +945,19 @@ static void ghes_do_proc(struct ghes *ghes,
fru_text = gdata->fru_text;
ghes_log_hwerr(sev, sec_type);
- if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
- struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
+ if (cper_sec_is_platform_mem(sec_type)) {
+ struct cper_mem_err_compact mem_err;
- atomic_notifier_call_chain(&ghes_report_chain, sev, mem_err);
+ if (cper_mem_err_parse(sec_type, acpi_hest_get_payload(gdata),
+ gdata->error_data_length, &mem_err)) {
+ pr_warn(FW_WARN "memory error section length is too small\n");
+ continue;
+ }
- arch_apei_report_mem_error(sev, mem_err);
- queued = ghes_handle_memory_failure(gdata, sev, sync);
+ atomic_notifier_call_chain(&ghes_report_chain, sev, &mem_err);
+
+ arch_apei_report_mem_error(sev, &mem_err);
+ queued = ghes_handle_memory_failure(gdata, &mem_err, sev, sync);
} else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
ghes_handle_aer(gdata);
} else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
index d80c88818691c..ae4c92463e305 100644
--- a/drivers/edac/ghes_edac.c
+++ b/drivers/edac/ghes_edac.c
@@ -242,7 +242,7 @@ static void ghes_scan_system(void)
system_scanned = true;
}
-static int print_mem_error_other_detail(const struct cper_sec_mem_err *mem, char *msg,
+static int print_mem_error_other_detail(struct cper_mem_err_compact *mem, char *msg,
const char *location, unsigned int len)
{
u32 n;
@@ -255,13 +255,15 @@ static int print_mem_error_other_detail(const struct cper_sec_mem_err *mem, char
n += scnprintf(msg + n, len - n, "APEI location: %s ", location);
- if (!(mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS))
- goto out;
-
- n += scnprintf(msg + n, len - n, "status(0x%016llx): ", mem->error_status);
- n += scnprintf(msg + n, len - n, "%s ", cper_mem_err_status_str(mem->error_status));
+ if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS) {
+ n += scnprintf(msg + n, len - n, "status(0x%016llx): ", mem->error_status);
+ n += scnprintf(msg + n, len - n, "%s ",
+ cper_mem_err_status_str(mem->error_status));
+ }
+ if (mem->validation_bits & CPER_MEM_VALID_STATUS)
+ n += scnprintf(msg + n, len - n, "section_status:0x%02x ",
+ mem->status);
-out:
msg[n] = '\0';
return n;
@@ -270,8 +272,7 @@ static int print_mem_error_other_detail(const struct cper_sec_mem_err *mem, char
static int ghes_edac_report_mem_error(struct notifier_block *nb,
unsigned long val, void *data)
{
- struct cper_sec_mem_err *mem_err = (struct cper_sec_mem_err *)data;
- struct cper_mem_err_compact cmem;
+ struct cper_mem_err_compact *mem_err = data;
struct edac_raw_error_desc *e;
struct mem_ctl_info *mci;
unsigned long sev = val;
@@ -348,14 +349,13 @@ static int ghes_edac_report_mem_error(struct notifier_block *nb,
/* Memory error location, mapped on e->location */
p = e->location;
- cper_mem_err_pack(mem_err, &cmem);
- p += cper_mem_err_location(&cmem, p);
+ p += cper_mem_err_location(mem_err, p);
if (mem_err->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
struct dimm_info *dimm;
- p += cper_dimm_err_location(&cmem, p);
- dimm = find_dimm_by_handle(mci, mem_err->mem_dev_handle);
+ p += cper_dimm_err_location(mem_err, p);
+ dimm = find_dimm_by_handle(mci, (u16)mem_err->mem_dev_handle);
if (dimm) {
e->top_layer = dimm->idx;
strscpy(e->label, dimm->label);
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index cfcd01e3f47bf..e0ba2ca498e75 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -555,36 +555,41 @@ const char *cper_mem_err_unpack(struct trace_seq *p,
return ret;
}
-static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem,
- int len)
+static void cper_print_mem(const char *pfx, const guid_t *sec_type,
+ const void *mem, int len)
{
struct cper_mem_err_compact cmem;
char rcd_decode_str[CPER_REC_LEN];
/* Don't trust UEFI 2.1/2.2 structure with bad validation bits */
- if (len == sizeof(struct cper_sec_mem_err_old) &&
- (mem->validation_bits & ~(CPER_MEM_VALID_RANK_NUMBER - 1))) {
+ if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM) &&
+ len == sizeof(struct cper_sec_mem_err_old) &&
+ (((const struct cper_sec_mem_err_old *)mem)->validation_bits &
+ ~(CPER_MEM_VALID_RANK_NUMBER - 1))) {
pr_err(FW_WARN "valid bits set for fields beyond structure\n");
return;
}
- if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
+
+ if (cper_mem_err_parse(sec_type, mem, len, &cmem))
+ return;
+
+ if (cmem.validation_bits & CPER_MEM_VALID_ERROR_STATUS)
printk("%s error_status: %s (0x%016llx)\n",
- pfx, cper_mem_err_status_str(mem->error_status),
- mem->error_status);
- if (mem->validation_bits & CPER_MEM_VALID_PA)
+ pfx, cper_mem_err_status_str(cmem.error_status),
+ cmem.error_status);
+ if (cmem.validation_bits & CPER_MEM_VALID_PA)
printk("%s""physical_address: 0x%016llx\n",
- pfx, mem->physical_addr);
- if (mem->validation_bits & CPER_MEM_VALID_PA_MASK)
+ pfx, cmem.physical_addr);
+ if (cmem.validation_bits & CPER_MEM_VALID_PA_MASK)
printk("%s""physical_address_mask: 0x%016llx\n",
- pfx, mem->physical_addr_mask);
- cper_mem_err_pack(mem, &cmem);
+ pfx, cmem.physical_addr_mask);
if (cper_mem_err_location(&cmem, rcd_decode_str))
printk("%s%s\n", pfx, rcd_decode_str);
- if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
- u8 etype = mem->error_type;
- printk("%s""error_type: %d, %s\n", pfx, etype,
- cper_mem_err_type_str(etype));
- }
+ if (cmem.validation_bits & CPER_MEM_VALID_ERROR_TYPE)
+ printk("%s""error_type: %d, %s\n", pfx, cmem.error_type,
+ cper_mem_err_type_str(cmem.error_type));
+ if (cmem.validation_bits & CPER_MEM_VALID_STATUS)
+ printk("%s""status: 0x%02x\n", pfx, cmem.status);
if (cper_dimm_err_location(&cmem, rcd_decode_str))
printk("%s%s\n", pfx, rcd_decode_str);
}
@@ -784,13 +789,14 @@ cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata
cper_print_proc_generic(newpfx, proc_err);
else
goto err_section_too_small;
- } else if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
- struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
-
+ } else if (cper_sec_is_platform_mem(sec_type)) {
printk("%s""section_type: memory error\n", newpfx);
- if (gdata->error_data_length >=
- sizeof(struct cper_sec_mem_err_old))
- cper_print_mem(newpfx, mem_err,
+ if ((guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM) &&
+ gdata->error_data_length >= sizeof(struct cper_sec_mem_err_old)) ||
+ (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM2) &&
+ gdata->error_data_length >= sizeof(struct cper_sec_mem_err2)))
+ cper_print_mem(newpfx, sec_type,
+ acpi_hest_get_payload(gdata),
gdata->error_data_length);
else
goto err_section_too_small;
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index dc60f7db5524f..5aabf92bd867d 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -51,7 +51,7 @@ ssize_t erst_read_record(u64 record_id, struct cper_record_header *record,
int erst_clear(u64 record_id);
int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data);
-void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
+void arch_apei_report_mem_error(int sev, struct cper_mem_err_compact *mem_err);
#endif
#endif
diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
index fdb785fa4613a..921089912fbfb 100644
--- a/include/ras/ras_event.h
+++ b/include/ras/ras_event.h
@@ -24,7 +24,7 @@
#if defined(CONFIG_ACPI_EXTLOG) || defined(CONFIG_ACPI_EXTLOG_MODULE)
TRACE_EVENT(extlog_mem_event,
- TP_PROTO(struct cper_sec_mem_err *mem,
+ TP_PROTO(struct cper_mem_err_compact *mem,
u32 err_seq,
const guid_t *fru_id,
const char *fru_text,
@@ -61,7 +61,7 @@ TRACE_EVENT(extlog_mem_event,
__entry->pa_mask_lsb = ~0;
__entry->fru_id = *fru_id;
__assign_str(fru_text);
- cper_mem_err_pack(mem, &__entry->data);
+ __entry->data = *mem;
),
TP_printk("{%d} %s error: %s physical addr: %016llx (mask lsb: %x) %sFRU: %pUl %.20s",
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [RFC PATCH 6/6] cper: make cper_mem_err_pack() static
2026-09-29 7:45 [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support Pierre Gondois
` (4 preceding siblings ...)
2026-09-29 7:46 ` [RFC PATCH 5/6] x86/mce/apei: switch cper_sec_mem_err struct users to compact CPER records Pierre Gondois
@ 2026-09-29 7:46 ` Pierre Gondois
2026-09-29 16:35 ` [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support Jonathan Cameron
6 siblings, 0 replies; 8+ messages in thread
From: Pierre Gondois @ 2026-09-29 7:46 UTC (permalink / raw)
To: linux-kernel
Cc: James Morse, Mark Brown, Pierre Gondois, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Rafael J. Wysocki, Len Brown, Tony Luck, Hanjun Guo,
Mauro Carvalho Chehab, Shuai Xue, Maciej Wieczor-Retman,
Pawel Chmielewski, Yazen Ghannam, Radu Rendec, Avadhut Naik,
Kees Cook, Jonathan Cameron, Dave Jiang, Fabio M. De Francesco,
Breno Leitao, Terry Bowman, Dan Williams, Ard Biesheuvel,
Morduan Zang, linux-acpi, linux-edac, acpica-devel
Make cper_mem_err_pack() local to cper.c and drop its public
declaration as it is only used in the local file.
Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
---
drivers/firmware/efi/cper.c | 5 ++---
include/linux/cper.h | 2 --
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index e0ba2ca498e75..066359c549aff 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -392,8 +392,8 @@ static void cper_mem_err_old_pack(const struct cper_sec_mem_err_old *mem,
cmem->error_type = mem->error_type;
}
-void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
- struct cper_mem_err_compact *cmem)
+static void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
+ struct cper_mem_err_compact *cmem)
{
memset(cmem, 0, sizeof(*cmem));
cmem->validation_bits = mem->validation_bits;
@@ -419,7 +419,6 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
if (mem->validation_bits & CPER_MEM_VALID_CHIP_ID)
cmem->chip_id = mem->extended >> CPER_MEM_CHIP_ID_SHIFT;
}
-EXPORT_SYMBOL_GPL(cper_mem_err_pack);
static void cper_mem_err2_pack(const struct cper_sec_mem_err2 *mem,
struct cper_mem_err_compact *cmem)
diff --git a/include/linux/cper.h b/include/linux/cper.h
index ac236043ce859..dac8e0b83a9fa 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -627,8 +627,6 @@ void cper_print_bits(const char *prefix, unsigned int bits,
const char * const strs[], unsigned int strs_size);
int cper_bits_to_str(char *buf, int buf_size, unsigned long bits,
const char * const strs[], unsigned int strs_size);
-void cper_mem_err_pack(const struct cper_sec_mem_err *,
- struct cper_mem_err_compact *);
bool cper_sec_is_platform_mem(const guid_t *sec_type);
int cper_mem_err_parse(const guid_t *sec_type, const void *mem, size_t len,
struct cper_mem_err_compact *cmem);
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support
2026-09-29 7:45 [RFC PATCH 0/6] CPER: Add Memory Error Section 2 support Pierre Gondois
` (5 preceding siblings ...)
2026-09-29 7:46 ` [RFC PATCH 6/6] cper: make cper_mem_err_pack() static Pierre Gondois
@ 2026-09-29 16:35 ` Jonathan Cameron
6 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2026-09-29 16:35 UTC (permalink / raw)
To: Pierre Gondois
Cc: linux-kernel, James Morse, Mark Brown, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Rafael J. Wysocki, Len Brown, Tony Luck, Hanjun Guo,
Mauro Carvalho Chehab, Shuai Xue, Maciej Wieczor-Retman,
Pawel Chmielewski, Yazen Ghannam, Radu Rendec, Avadhut Naik,
Kees Cook, Dave Jiang, Fabio M. De Francesco, Breno Leitao,
Terry Bowman, Dan Williams, Ard Biesheuvel, Morduan Zang,
linux-acpi, linux-edac, acpica-devel
On Tue, 29 Sep 2026 09:45:59 +0200
Pierre Gondois <pierre.gondois@arm.com> wrote:
> Add support for Memory Error Section 2 records.
>
> Extend cper_mem_err_compact to hold both legacy and section-2 records.
> Add a common parser and convert the CPER, GHES, EDAC, extlog and x86 APEI
> paths to use it.
>
> The extlog_mem_event payload layout changes with this series.
> Compatibility with existing userspace decoders still needs to be
> addressed. More specifically, the rasdaemon relies on the current
> struct cper_mem_err_compact definition.
> Either:
> A-
> this patchset should not modify struct cper_mem_err_compact and
> create a new structure to handle Memory Error Section 2 events,
> but this would ignore the similarities of Memory Error Section (1)/2
> B-
> userspace should not rely on the struct cper_mem_err_compact
> layout. extlog_mem_event trace events should instead emit data
> that relies on the actual layout of the CPER records, as defined
> in the ACPI spec.
>
> I am looking for guidance on how to handle the above question.
> Current implementation lean toward B, but emits data in the trace
> event that maps the new/updated struct cper_mem_err_compact.
My initial thought is a no to modifying the usespace ABI.
It isn't particularly painful to just have separate handling code
for the new record. Unfortunately the ext_log tracepoints don't
split out the fields in a fashion that would let you change
the structure. Other RAS tracepoints do it field by field which
would have been possible to augment - even then it would have
required care to deal with field size changes.
It may be worth considering a much more 'expanded' tracepoint for
memory error section 2 to reduce similar future extension problems.
That is express ever field and don't use a compact structure at all.
Mauro, perhaps you can give input on what works better over the
long term?
Jonathan
>
> Pierre Gondois (6):
> ACPI: extlog: fix extlog_mem_event build issue
> cper: add Memory Error Section 2 structures
> cper: extend cper_mem_err_compact struct
> cper: add helpers to handle Memory Error Section 2
> x86/mce/apei: switch cper_sec_mem_err struct users to compact CPER
> records
> cper: make cper_mem_err_pack() static
>
> arch/x86/include/asm/mce.h | 4 +-
> arch/x86/kernel/acpi/apei.c | 2 +-
> arch/x86/kernel/cpu/mce/apei.c | 2 +-
> drivers/acpi/acpi_extlog.c | 23 +++-
> drivers/acpi/apei/apei-base.c | 2 +-
> drivers/acpi/apei/ghes.c | 20 +--
> drivers/edac/ghes_edac.c | 26 ++--
> drivers/firmware/efi/cper.c | 219 +++++++++++++++++++++++++++------
> include/acpi/apei.h | 2 +-
> include/linux/cper.h | 58 +++++++--
> include/ras/ras_event.h | 4 +-
> 11 files changed, 283 insertions(+), 79 deletions(-)
>
> --
> 2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread