[PATCH v3 4/7] EDAC/ghes: Extract error report initialization

From: Pierre Gondois

Date: Wed Nov 04 2026 - 06:09:58 EST


Extract a ghes_edac_init_error_desc() function to prepare for
Memory Error Section 2 support (and re-usage).

Also use a guard in the caller ghes_edac_report_mem_error()
function for code simplification.

Signed-off-by: Pierre Gondois <pierre.gondois@xxxxxxx>
---
drivers/edac/ghes_edac.c | 70 +++++++++++++++++++++-------------------
1 file changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
index d80c88818691..f1cf4d640d68 100644
--- a/drivers/edac/ghes_edac.c
+++ b/drivers/edac/ghes_edac.c
@@ -267,6 +267,39 @@ static int print_mem_error_other_detail(const struct cper_sec_mem_err *mem, char
return n;
}

+static void ghes_edac_init_error_desc(struct edac_raw_error_desc *e,
+ unsigned long sev, char *msg, char *other_detail)
+{
+ lockdep_assert_held(&ghes_lock);
+
+ /* Cleans the error report buffer */
+ memset(e, 0, sizeof(*e));
+ e->error_count = 1;
+ e->grain = 1;
+ e->msg = msg;
+ e->other_detail = other_detail;
+ e->top_layer = -1;
+ e->mid_layer = -1;
+ e->low_layer = -1;
+ *msg = '\0';
+ *other_detail = '\0';
+
+ switch (sev) {
+ case GHES_SEV_CORRECTED:
+ e->type = HW_EVENT_ERR_CORRECTED;
+ break;
+ case GHES_SEV_RECOVERABLE:
+ e->type = HW_EVENT_ERR_UNCORRECTED;
+ break;
+ case GHES_SEV_PANIC:
+ e->type = HW_EVENT_ERR_FATAL;
+ break;
+ default:
+ case GHES_SEV_NO:
+ e->type = HW_EVENT_ERR_INFO;
+ }
+}
+
static int ghes_edac_report_mem_error(struct notifier_block *nb,
unsigned long val, void *data)
{
@@ -274,9 +307,7 @@ static int ghes_edac_report_mem_error(struct notifier_block *nb,
struct cper_mem_err_compact cmem;
struct edac_raw_error_desc *e;
struct mem_ctl_info *mci;
- unsigned long sev = val;
struct ghes_pvt *pvt;
- unsigned long flags;
char *p;

/*
@@ -287,41 +318,15 @@ static int ghes_edac_report_mem_error(struct notifier_block *nb,
if (WARN_ON_ONCE(in_nmi()))
return NOTIFY_OK;

- spin_lock_irqsave(&ghes_lock, flags);
+ guard(spinlock_irqsave)(&ghes_lock);

pvt = ghes_pvt;
if (!pvt)
- goto unlock;
+ return NOTIFY_OK;

mci = pvt->mci;
e = &mci->error_desc;
-
- /* Cleans the error report buffer */
- memset(e, 0, sizeof (*e));
- e->error_count = 1;
- e->grain = 1;
- e->msg = pvt->msg;
- e->other_detail = pvt->other_detail;
- e->top_layer = -1;
- e->mid_layer = -1;
- e->low_layer = -1;
- *pvt->other_detail = '\0';
- *pvt->msg = '\0';
-
- switch (sev) {
- case GHES_SEV_CORRECTED:
- e->type = HW_EVENT_ERR_CORRECTED;
- break;
- case GHES_SEV_RECOVERABLE:
- e->type = HW_EVENT_ERR_UNCORRECTED;
- break;
- case GHES_SEV_PANIC:
- e->type = HW_EVENT_ERR_FATAL;
- break;
- default:
- case GHES_SEV_NO:
- e->type = HW_EVENT_ERR_INFO;
- }
+ ghes_edac_init_error_desc(e, val, pvt->msg, pvt->other_detail);

edac_dbg(1, "error validation_bits: 0x%08llx\n",
(long long)mem_err->validation_bits);
@@ -375,9 +380,6 @@ static int ghes_edac_report_mem_error(struct notifier_block *nb,

edac_raw_mc_handle_error(e);

-unlock:
- spin_unlock_irqrestore(&ghes_lock, flags);
-
return NOTIFY_OK;
}

--
2.43.0