[PATCH v9 4/7] RAS/AMD, EDAC/amd64: Use unified interface for SPA translation

From: Yazen Ghannam

Date: Thu Jul 30 2026 - 15:51:19 EST


Switch all users of the ATL SPA translation function to the new unified
interface.

No functional change intended.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yazen Ghannam <yazen.ghannam@xxxxxxx>
---
drivers/edac/amd64_edac.c | 15 +++++++--------
drivers/edac/amd64_edac.h | 2 ++
drivers/ras/amd/atl/umc.c | 8 +++++---
drivers/ras/amd/fmpm.c | 10 +++++-----
4 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 475235c402e8..f428d815bff1 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2809,9 +2809,7 @@ static void decode_umc_error(int node_id, struct mce *m)
{
u8 ecc_type = (m->status >> 45) & 0x3;
struct mem_ctl_info *mci;
- unsigned long sys_addr;
struct amd64_pvt *pvt;
- struct atl_err a_err;
struct err_info err;

node_id = fixup_node_id(node_id, m);
@@ -2843,17 +2841,18 @@ static void decode_umc_error(int node_id, struct mce *m)

pvt->ops->get_err_info(m, &err);

- a_err.addr = m->addr;
- a_err.ipid = m->ipid;
- a_err.cpu = m->extcpu;
+ err.a_err.addr = m->addr;
+ err.a_err.ipid = m->ipid;
+ err.a_err.cpu = m->extcpu;
+ err.a_err.requested = ATL_OP_SPA;

- sys_addr = amd_convert_umc_mca_addr_to_sys_addr(&a_err);
- if (IS_ERR_VALUE(sys_addr)) {
+ amd_translate_umc_mca_addr(&err.a_err);
+ if (!(err.a_err.valid & ATL_OP_SPA)) {
err.err_code = ERR_NORM_ADDR;
goto log_error;
}

- error_address_to_page_and_offset(sys_addr, &err);
+ error_address_to_page_and_offset(err.a_err.spa, &err);

log_error:
__log_ecc_error(mci, &err, ecc_type);
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 1757c1b99fc8..b11da6fdf0fc 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -17,6 +17,7 @@
#include <linux/mmzone.h>
#include <linux/edac.h>
#include <linux/bitfield.h>
+#include <linux/ras.h>
#include <asm/cpu_device_id.h>
#include <asm/msr.h>
#include "edac_module.h"
@@ -400,6 +401,7 @@ struct err_info {
u16 syndrome;
u32 page;
u32 offset;
+ struct atl_err a_err;
};

static inline u32 get_umc_base(u8 channel)
diff --git a/drivers/ras/amd/atl/umc.c b/drivers/ras/amd/atl/umc.c
index 2d61f890e4b8..4d75ad4483e8 100644
--- a/drivers/ras/amd/atl/umc.c
+++ b/drivers/ras/amd/atl/umc.c
@@ -314,15 +314,17 @@ static void _retire_row_mi300(struct atl_err *a_err)
struct page *p;
u8 col;

+ a_err->requested = ATL_OP_SPA;
+
for (col = 0; col < MI300_NUM_COL; col++) {
a_err->addr &= ~MI300_UMC_MCA_COL;
a_err->addr |= FIELD_PREP(MI300_UMC_MCA_COL, col);

- addr = amd_convert_umc_mca_addr_to_sys_addr(a_err);
- if (IS_ERR_VALUE(addr))
+ amd_atl_umc_translate_addr(a_err);
+ if (!(a_err->valid & ATL_OP_SPA))
continue;

- addr = PHYS_PFN(addr);
+ addr = PHYS_PFN(a_err->spa);

/*
* Skip invalid or already poisoned pages to avoid unnecessary
diff --git a/drivers/ras/amd/fmpm.c b/drivers/ras/amd/fmpm.c
index 4ccaaf7b70bf..21f645197410 100644
--- a/drivers/ras/amd/fmpm.c
+++ b/drivers/ras/amd/fmpm.c
@@ -302,7 +302,6 @@ static void save_spa(struct fru_rec *rec, unsigned int entry,
{
unsigned int i, fru_idx, spa_entry;
struct atl_err a_err;
- unsigned long spa;

if (entry >= max_nr_entries) {
pr_warn_once("FRU descriptor entry %d out-of-bounds (max: %d)\n",
@@ -328,19 +327,20 @@ static void save_spa(struct fru_rec *rec, unsigned int entry,
return;
}

- memset(&a_err, 0, sizeof(struct atl_err));
+ memset(&a_err, 0, sizeof(a_err));

a_err.addr = addr;
a_err.ipid = id;
a_err.cpu = cpu;
+ a_err.requested = ATL_OP_SPA;

- spa = amd_convert_umc_mca_addr_to_sys_addr(&a_err);
- if (IS_ERR_VALUE(spa)) {
+ amd_translate_umc_mca_addr(&a_err);
+ if (!(a_err.valid & ATL_OP_SPA)) {
pr_debug("Failed to get system address\n");
return;
}

- spa_entries[spa_entry] = spa;
+ spa_entries[spa_entry] = a_err.spa;
pr_debug("fru_idx: %u, entry: %u, spa_entry: %u, spa: 0x%016llx\n",
fru_idx, entry, spa_entry, spa_entries[spa_entry]);
}
--
2.53.0