* [PATCH v10 0/7] Incorporate DRAM address in EDAC messages
@ 2026-09-22 20:23 Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 1/7] RAS/AMD/ATL: Make PRM address translation support builtin Yazen Ghannam
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-09-22 20:23 UTC (permalink / raw)
To: bp, linux-edac; +Cc: linux-kernel
Hi all,
This revision addresses a couple comments from Boris. Also, the couple
of patches originally by Avadhut have gone through a few revisions. So I
updated the attributions.
Thanks,
Yazen
Link:
https://lore.kernel.org/20260730194834.3203601-1-yazen.ghannam@amd.com
Changes in v10:
- Retitle patch 1 and rewrite its commit message as suggested.
- Pass a struct param_buf to prm_umc_norm_to_addr() in patch 2
instead of the individual fields, and trim the commit message.
- Move struct param_buf to internal.h in patch 3 so that callers
outside prm.c can build it, and build it at each call site.
- Drop Avadhut as author of patches 6 and 7; credit him with
Originally-by instead.
- Update the Assisted-by tags to the format documented in
Documentation/process/coding-assistants.rst.
Changes in v9:
- Treat -EOPNOTSUPP like -ENODEV when PRM support is not built.
(Sashiko)
- Document why the PRM handlers do not need the MI300 address
conversion. (Sashiko)
- Clear the completed-operations bits in the translation entry points
rather than at each call site.
- Narrow the operation bitmaps to u8.
- Note that struct atl_dram_addr mirrors the PRM output buffer.
- Widen the subject prefix of patch 4 to cover the EDAC changes.
- Reorder variable declarations and reword commit messages.
Changes in v8:
- Drop "Directly export address translation helper".
- Merge the two PRM translation helpers into one. (Boris)
- Build the PRM support unconditionally and drop CONFIG_AMD_ATL_PRM.
- Formatting and other small changes.
Changes in v7:
- Drop fake_inject patch that was already accepted.
- Remove function pointers. (Boris).
Changes in v6:
- Remove fake_inject interface. (Boris)
- Add two more values to 'other_detail'.
Changes in v5:
- Address a comment from Sashiko in patch 2.
Changes in v4:
- Drop a "handler available" check in patch 1.
- Reword commit message in patch 2.
- Reformat string in patch 2.
Yazen Ghannam (7):
RAS/AMD/ATL: Make PRM address translation support builtin
RAS/AMD/ATL: Refactor PRM address translation into a common helper
RAS/AMD/ATL: Add unified UMC address translation interface
RAS/AMD, EDAC/amd64: Use unified interface for SPA translation
RAS/AMD/ATL: Remove the standalone SPA translation interface
RAS/AMD/ATL: Add DRAM address translation via PRM
EDAC/amd64: Include DRAM address in output
drivers/edac/amd64_edac.c | 38 ++++++++++++++-----
drivers/edac/amd64_edac.h | 2 +
drivers/ras/amd/atl/Kconfig | 4 --
drivers/ras/amd/atl/Makefile | 3 +-
drivers/ras/amd/atl/core.c | 4 +-
drivers/ras/amd/atl/internal.h | 19 +++++-----
drivers/ras/amd/atl/prm.c | 30 +++------------
drivers/ras/amd/atl/system.c | 4 ++
drivers/ras/amd/atl/umc.c | 69 +++++++++++++++++++++++++++++-----
drivers/ras/amd/fmpm.c | 10 ++---
drivers/ras/ras.c | 31 ++++++++-------
include/linux/ras.h | 46 +++++++++++++++++++----
12 files changed, 171 insertions(+), 89 deletions(-)
base-commit: 2a11decdb2ddf456d743417d5d86b55c52baf101
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v10 1/7] RAS/AMD/ATL: Make PRM address translation support builtin
2026-09-22 20:23 [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Yazen Ghannam
@ 2026-09-22 20:23 ` Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 2/7] RAS/AMD/ATL: Refactor PRM address translation into a common helper Yazen Ghannam
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-09-22 20:23 UTC (permalink / raw)
To: bp, linux-edac; +Cc: linux-kernel, Yazen Ghannam
PRM (Platform Runtime Mechanism) is the only address translation method
for current and future AMD systems. The library should therefore always
include it.
The PRM helpers in <linux/prmt.h> already provide stubs that return an
error when CONFIG_ACPI_PRMT is disabled. Make prm.c builtin. The library
then falls back to native translation at runtime when no PRM handler is
available.
Assisted-by: LLM
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
drivers/ras/amd/atl/Kconfig | 4 ----
drivers/ras/amd/atl/Makefile | 3 +--
drivers/ras/amd/atl/internal.h | 8 --------
drivers/ras/amd/atl/prm.c | 2 +-
4 files changed, 2 insertions(+), 15 deletions(-)
diff --git a/drivers/ras/amd/atl/Kconfig b/drivers/ras/amd/atl/Kconfig
index 44c2fd7febc5..29befaf2a1e2 100644
--- a/drivers/ras/amd/atl/Kconfig
+++ b/drivers/ras/amd/atl/Kconfig
@@ -19,7 +19,3 @@ config AMD_ATL
Enable this option if using DRAM ECC on Zen-based systems
and OS-based error handling.
-
-config AMD_ATL_PRM
- depends on AMD_ATL && ACPI_PRMT
- def_bool y
diff --git a/drivers/ras/amd/atl/Makefile b/drivers/ras/amd/atl/Makefile
index b56892c0c0d9..ff52452b678f 100644
--- a/drivers/ras/amd/atl/Makefile
+++ b/drivers/ras/amd/atl/Makefile
@@ -12,9 +12,8 @@ amd_atl-y += core.o
amd_atl-y += dehash.o
amd_atl-y += denormalize.o
amd_atl-y += map.o
+amd_atl-y += prm.o
amd_atl-y += system.o
amd_atl-y += umc.o
-amd_atl-$(CONFIG_AMD_ATL_PRM) += prm.o
-
obj-$(CONFIG_AMD_ATL) += amd_atl.o
diff --git a/drivers/ras/amd/atl/internal.h b/drivers/ras/amd/atl/internal.h
index 82a56d9c2be1..4fc4bc3c3500 100644
--- a/drivers/ras/amd/atl/internal.h
+++ b/drivers/ras/amd/atl/internal.h
@@ -287,15 +287,7 @@ u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr);
/* GUIDs for PRM handlers */
extern const guid_t norm_to_sys_guid;
-#ifdef CONFIG_AMD_ATL_PRM
unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 umc_bank_inst_id, unsigned long addr);
-#else
-static inline unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 umc_bank_inst_id,
- unsigned long addr)
-{
- return -ENODEV;
-}
-#endif
/*
* Make a gap in @data that is @num_bits long starting at @bit_num.
diff --git a/drivers/ras/amd/atl/prm.c b/drivers/ras/amd/atl/prm.c
index 0f9bfa96e16a..eba9d104d09e 100644
--- a/drivers/ras/amd/atl/prm.c
+++ b/drivers/ras/amd/atl/prm.c
@@ -44,7 +44,7 @@ unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long
if (!ret)
return ret_addr;
- if (ret == -ENODEV)
+ if (ret == -ENODEV || ret == -EOPNOTSUPP)
pr_debug("PRM module/handler not available\n");
else
pr_notice_once("PRM address translation failed\n");
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v10 2/7] RAS/AMD/ATL: Refactor PRM address translation into a common helper
2026-09-22 20:23 [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 1/7] RAS/AMD/ATL: Make PRM address translation support builtin Yazen Ghannam
@ 2026-09-22 20:23 ` Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 3/7] RAS/AMD/ATL: Add unified UMC address translation interface Yazen Ghannam
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-09-22 20:23 UTC (permalink / raw)
To: bp, linux-edac; +Cc: linux-kernel, Yazen Ghannam
Every PRM address translation follows the same pattern. Each fills a
parameter buffer, invokes the handler, and checks the result. Only the
handler GUID and the output buffer differ.
Factor the common sequence into prm_umc_norm_to_addr().
Assisted-by: LLM
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
drivers/ras/amd/atl/prm.c | 42 +++++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/drivers/ras/amd/atl/prm.c b/drivers/ras/amd/atl/prm.c
index eba9d104d09e..b3ff33a668c2 100644
--- a/drivers/ras/amd/atl/prm.c
+++ b/drivers/ras/amd/atl/prm.c
@@ -18,36 +18,44 @@
#include <linux/prmt.h>
-/*
- * PRM parameter buffer - normalized to system physical address, as described
- * in the "PRM Parameter Buffer" section of the AMD ACPI Porting Guide.
- */
-struct norm_to_sys_param_buf {
+/* See "PRM Parameter Buffer" in the AMD ACPI Porting Guide. */
+struct param_buf {
u64 norm_addr;
u8 socket;
u64 bank_id;
void *out_buf;
} __packed;
-unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
+static int prm_umc_norm_to_addr(guid_t guid, struct param_buf *p_buf)
{
- struct norm_to_sys_param_buf p_buf;
- unsigned long ret_addr;
int ret;
- p_buf.norm_addr = addr;
- p_buf.socket = socket_id;
- p_buf.bank_id = bank_id;
- p_buf.out_buf = &ret_addr;
-
- ret = acpi_call_prm_handler(norm_to_sys_guid, &p_buf);
+ ret = acpi_call_prm_handler(guid, p_buf);
if (!ret)
- return ret_addr;
+ return 0;
if (ret == -ENODEV || ret == -EOPNOTSUPP)
- pr_debug("PRM module/handler not available\n");
+ pr_debug("PRM module/handler not available: %d\n", ret);
else
- pr_notice_once("PRM address translation failed\n");
+ pr_notice_once("PRM address translation failed: %d\n", ret);
return ret;
}
+
+unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
+{
+ unsigned long sys_addr;
+ struct param_buf p_buf = {
+ .norm_addr = addr,
+ .socket = socket_id,
+ .bank_id = bank_id,
+ .out_buf = &sys_addr,
+ };
+ int ret;
+
+ ret = prm_umc_norm_to_addr(norm_to_sys_guid, &p_buf);
+ if (ret)
+ return ret;
+
+ return sys_addr;
+}
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v10 3/7] RAS/AMD/ATL: Add unified UMC address translation interface
2026-09-22 20:23 [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 1/7] RAS/AMD/ATL: Make PRM address translation support builtin Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 2/7] RAS/AMD/ATL: Refactor PRM address translation into a common helper Yazen Ghannam
@ 2026-09-22 20:23 ` Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 4/7] RAS/AMD, EDAC/amd64: Use unified interface for SPA translation Yazen Ghannam
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-09-22 20:23 UTC (permalink / raw)
To: bp, linux-edac; +Cc: linux-kernel, Yazen Ghannam
The library exposes a single function for UMC address translation. Adding a
new translation would mean adding and plumbing another export. Callers also
have no way to request more than one representation of an address in a
single call.
Add a single entry point, amd_translate_umc_mca_addr(), that operates
entirely through struct atl_err. Expand the struct with a pair of
operation bitmaps and the per-operation output fields.
The caller provides the error inputs and requests one or more operations.
Each operation is attempted independently. The library sets a validation
bit and fills the matching output for each operation that succeeds. The
caller must check the validation bit before consuming an output value.
Group the error identifiers (normalized address, socket, and UMC bank ID)
into struct atl_umc_addr. Lay it out to match the PRM parameter buffer
inputs that every handler shares, and embed it in the buffer. A caller can
then build the buffer straight from its own struct atl_err. Move the buffer
definition to internal.h so callers outside prm.c can do so.
Route the interface through the always-built RAS core so the library
remains optional. The core provides the entry point and a
register/unregister pair. The library registers its implementation on load.
The entry point does nothing (no validation bits set) when the library is
absent.
Start with a single operation, ATL_OP_SPA, that produces the System
Physical Address. Try the PRM handler first. Fall back to the native Data
Fabric translation if PRM is unavailable and the Data Fabric revision
supports it.
Leave the existing amd_convert_umc_mca_addr_to_sys_addr() interface in
place for now.
Assisted-by: LLM
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
drivers/ras/amd/atl/core.c | 2 ++
drivers/ras/amd/atl/internal.h | 8 +++++++
drivers/ras/amd/atl/prm.c | 18 +++++----------
drivers/ras/amd/atl/umc.c | 42 ++++++++++++++++++++++++++++++++++
drivers/ras/ras.c | 28 +++++++++++++++++++++++
include/linux/ras.h | 28 +++++++++++++++++++++--
6 files changed, 112 insertions(+), 14 deletions(-)
diff --git a/drivers/ras/amd/atl/core.c b/drivers/ras/amd/atl/core.c
index d77dacdd4f56..b754eaef8585 100644
--- a/drivers/ras/amd/atl/core.c
+++ b/drivers/ras/amd/atl/core.c
@@ -210,6 +210,7 @@ static int __init amd_atl_init(void)
/* Increment this module's recount so that it can't be easily unloaded. */
__module_get(THIS_MODULE);
amd_atl_register_decoder(convert_umc_mca_addr_to_sys_addr);
+ amd_atl_register_umc_translator(amd_atl_umc_translate_addr);
pr_info("AMD Address Translation Library initialized\n");
return 0;
@@ -222,6 +223,7 @@ static int __init amd_atl_init(void)
static void __exit amd_atl_exit(void)
{
amd_atl_unregister_decoder();
+ amd_atl_unregister_umc_translator();
}
module_init(amd_atl_init);
diff --git a/drivers/ras/amd/atl/internal.h b/drivers/ras/amd/atl/internal.h
index 4fc4bc3c3500..0c86f40a094b 100644
--- a/drivers/ras/amd/atl/internal.h
+++ b/drivers/ras/amd/atl/internal.h
@@ -280,6 +280,7 @@ int dehash_address(struct addr_ctx *ctx);
unsigned long norm_to_sys_addr(u8 socket_id, u8 die_id, u8 coh_st_inst_id, unsigned long addr);
unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err);
+void amd_atl_umc_translate_addr(struct atl_err *err);
u64 add_base_and_hole(struct addr_ctx *ctx, u64 addr);
u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr);
@@ -287,6 +288,13 @@ u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr);
/* GUIDs for PRM handlers */
extern const guid_t norm_to_sys_guid;
+/* See "PRM Parameter Buffer" in the AMD ACPI Porting Guide. */
+struct param_buf {
+ struct atl_umc_addr addr;
+ void *out_buf;
+} __packed;
+
+int prm_umc_norm_to_addr(guid_t guid, struct param_buf *p_buf);
unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 umc_bank_inst_id, unsigned long addr);
/*
diff --git a/drivers/ras/amd/atl/prm.c b/drivers/ras/amd/atl/prm.c
index b3ff33a668c2..0635215f220a 100644
--- a/drivers/ras/amd/atl/prm.c
+++ b/drivers/ras/amd/atl/prm.c
@@ -18,15 +18,7 @@
#include <linux/prmt.h>
-/* See "PRM Parameter Buffer" in the AMD ACPI Porting Guide. */
-struct param_buf {
- u64 norm_addr;
- u8 socket;
- u64 bank_id;
- void *out_buf;
-} __packed;
-
-static int prm_umc_norm_to_addr(guid_t guid, struct param_buf *p_buf)
+int prm_umc_norm_to_addr(guid_t guid, struct param_buf *p_buf)
{
int ret;
@@ -46,9 +38,11 @@ unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long
{
unsigned long sys_addr;
struct param_buf p_buf = {
- .norm_addr = addr,
- .socket = socket_id,
- .bank_id = bank_id,
+ .addr = {
+ .addr = addr,
+ .socket_id = socket_id,
+ .ipid = bank_id,
+ },
.out_buf = &sys_addr,
};
int ret;
diff --git a/drivers/ras/amd/atl/umc.c b/drivers/ras/amd/atl/umc.c
index befc616d5e8a..91c02ef5dc11 100644
--- a/drivers/ras/amd/atl/umc.c
+++ b/drivers/ras/amd/atl/umc.c
@@ -416,3 +416,45 @@ unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
return norm_to_sys_addr(socket_id, die_id, coh_st_inst_id, addr);
}
+
+/*
+ * Translate a UMC MCA error address into one or more representations as
+ * requested by the caller.
+ *
+ * The caller sets the input values and requests one or more operations
+ * through @err->requested. @err->valid is cleared on entry. Each operation
+ * is attempted independently. The corresponding bit in @err->valid is set
+ * and the related output field is filled for each operation that succeeds.
+ * The caller must check @err->valid before consuming an output value.
+ *
+ * The PRM handlers consume @err->umc_addr directly. Only MI300 needs its
+ * MCA_ADDR value converted to a normalized address first; see get_addr().
+ * MI300 platforms provide no PRM handlers, so the conversion is left to the
+ * native fallback path.
+ *
+ * Registered with the RAS core as the UMC address translator; see
+ * amd_translate_umc_mca_addr().
+ */
+void amd_atl_umc_translate_addr(struct atl_err *err)
+{
+ err->socket_id = topology_physical_package_id(err->cpu);
+ err->valid = 0;
+
+ if (err->requested & ATL_OP_SPA) {
+ struct param_buf p_buf = {
+ .addr = err->umc_addr,
+ .out_buf = &err->spa,
+ };
+
+ if (!prm_umc_norm_to_addr(norm_to_sys_guid, &p_buf)) {
+ err->valid |= ATL_OP_SPA;
+ } else if (!df_cfg.flags.prm_only) {
+ unsigned long spa = convert_umc_mca_addr_to_sys_addr(err);
+
+ if (!IS_ERR_VALUE(spa)) {
+ err->spa = spa;
+ err->valid |= ATL_OP_SPA;
+ }
+ }
+ }
+}
diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
index 03df3db62334..20e23560dee5 100644
--- a/drivers/ras/ras.c
+++ b/drivers/ras/ras.c
@@ -39,6 +39,34 @@ unsigned long amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
return amd_atl_umc_na_to_spa(err);
}
EXPORT_SYMBOL_GPL(amd_convert_umc_mca_addr_to_sys_addr);
+
+/*
+ * Set by the library module when it loads. Left registered while the module is
+ * resident; consumers keep no direct dependency on the library, so translation
+ * is simply skipped when it is not loaded.
+ */
+static void (*amd_atl_umc_translate)(struct atl_err *err);
+
+void amd_atl_register_umc_translator(void (*f)(struct atl_err *))
+{
+ amd_atl_umc_translate = f;
+}
+EXPORT_SYMBOL_GPL(amd_atl_register_umc_translator);
+
+void amd_atl_unregister_umc_translator(void)
+{
+ amd_atl_umc_translate = NULL;
+}
+EXPORT_SYMBOL_GPL(amd_atl_unregister_umc_translator);
+
+void amd_translate_umc_mca_addr(struct atl_err *err)
+{
+ err->valid = 0;
+
+ if (amd_atl_umc_translate)
+ amd_atl_umc_translate(err);
+}
+EXPORT_SYMBOL_GPL(amd_translate_umc_mca_addr);
#endif /* CONFIG_AMD_ATL */
#define CREATE_TRACE_POINTS
diff --git a/include/linux/ras.h b/include/linux/ras.h
index 468941bfe855..eac8cf39ddd5 100644
--- a/include/linux/ras.h
+++ b/include/linux/ras.h
@@ -3,6 +3,8 @@
#define __RAS_H__
#include <asm/errno.h>
+#include <linux/bits.h>
+#include <linux/stddef.h>
#include <linux/uuid.h>
#include <linux/cper.h>
@@ -35,10 +37,26 @@ static inline void
log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev) { return; }
#endif
+/* Operations requested and completed through amd_translate_umc_mca_addr(). */
+#define ATL_OP_SPA BIT(0) /* System Physical Address */
+
struct atl_err {
- u64 addr;
- u64 ipid;
+ /* Identifiers; layout mirrors the PRM parameter buffer inputs */
+ __struct_group(atl_umc_addr, umc_addr, __packed,
+ u64 addr;
+ u8 socket_id; /* Filled by the library from @cpu */
+ u64 ipid;
+ );
u32 cpu;
+
+ /* Requested operations (input) */
+ u8 requested;
+
+ /* Completed operations (output) */
+ u8 valid;
+
+ /* Outputs */
+ u64 spa; /* Valid if (@valid & ATL_OP_SPA) */
};
#if IS_ENABLED(CONFIG_AMD_ATL)
@@ -46,10 +64,16 @@ void amd_atl_register_decoder(unsigned long (*f)(struct atl_err *));
void amd_atl_unregister_decoder(void);
void amd_retire_dram_row(struct atl_err *err);
unsigned long amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err);
+
+void amd_atl_register_umc_translator(void (*f)(struct atl_err *));
+void amd_atl_unregister_umc_translator(void);
+void amd_translate_umc_mca_addr(struct atl_err *err);
#else
static inline void amd_retire_dram_row(struct atl_err *err) { }
static inline unsigned long
amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err) { return -EINVAL; }
+static inline void
+amd_translate_umc_mca_addr(struct atl_err *err) { err->valid = 0; }
#endif /* CONFIG_AMD_ATL */
#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v10 4/7] RAS/AMD, EDAC/amd64: Use unified interface for SPA translation
2026-09-22 20:23 [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Yazen Ghannam
` (2 preceding siblings ...)
2026-09-22 20:23 ` [PATCH v10 3/7] RAS/AMD/ATL: Add unified UMC address translation interface Yazen Ghannam
@ 2026-09-22 20:23 ` Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 5/7] RAS/AMD/ATL: Remove the standalone SPA translation interface Yazen Ghannam
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-09-22 20:23 UTC (permalink / raw)
To: bp, linux-edac; +Cc: linux-kernel, Yazen Ghannam
Switch all users of the ATL SPA translation function to the new unified
interface.
No functional change intended.
Assisted-by: LLM
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
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 91c02ef5dc11..522378c1d9f2 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.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v10 5/7] RAS/AMD/ATL: Remove the standalone SPA translation interface
2026-09-22 20:23 [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Yazen Ghannam
` (3 preceding siblings ...)
2026-09-22 20:23 ` [PATCH v10 4/7] RAS/AMD, EDAC/amd64: Use unified interface for SPA translation Yazen Ghannam
@ 2026-09-22 20:23 ` Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 6/7] RAS/AMD/ATL: Add DRAM address translation via PRM Yazen Ghannam
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-09-22 20:23 UTC (permalink / raw)
To: bp, linux-edac; +Cc: linux-kernel, Yazen Ghannam
All consumers now use the unified amd_translate_umc_mca_addr() interface,
which is routed through the RAS core in the same way. The older
amd_convert_umc_mca_addr_to_sys_addr() interface and its separate
register/unregister pair are no longer used.
Remove amd_convert_umc_mca_addr_to_sys_addr() together with
amd_atl_register_decoder()/amd_atl_unregister_decoder() and the associated
function pointer.
The unified interface performs the PRM translation itself, so
convert_umc_mca_addr_to_sys_addr() is now only the native Data Fabric
fallback. Make it static and drop its PRM attempt. Have it use the socket
ID that amd_atl_umc_translate_addr() already stores in struct atl_err.
The prm_umc_norm_to_sys_addr() wrapper has no remaining users. Remove it.
No functional change intended.
Assisted-by: LLM
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
drivers/ras/amd/atl/core.c | 2 --
drivers/ras/amd/atl/internal.h | 2 --
drivers/ras/amd/atl/prm.c | 20 --------------------
drivers/ras/amd/atl/umc.c | 9 ++-------
drivers/ras/ras.c | 29 -----------------------------
include/linux/ras.h | 5 -----
6 files changed, 2 insertions(+), 65 deletions(-)
diff --git a/drivers/ras/amd/atl/core.c b/drivers/ras/amd/atl/core.c
index b754eaef8585..cb944d3473ba 100644
--- a/drivers/ras/amd/atl/core.c
+++ b/drivers/ras/amd/atl/core.c
@@ -209,7 +209,6 @@ static int __init amd_atl_init(void)
/* Increment this module's recount so that it can't be easily unloaded. */
__module_get(THIS_MODULE);
- amd_atl_register_decoder(convert_umc_mca_addr_to_sys_addr);
amd_atl_register_umc_translator(amd_atl_umc_translate_addr);
pr_info("AMD Address Translation Library initialized\n");
@@ -222,7 +221,6 @@ static int __init amd_atl_init(void)
*/
static void __exit amd_atl_exit(void)
{
- amd_atl_unregister_decoder();
amd_atl_unregister_umc_translator();
}
diff --git a/drivers/ras/amd/atl/internal.h b/drivers/ras/amd/atl/internal.h
index 0c86f40a094b..ed8d176a05e3 100644
--- a/drivers/ras/amd/atl/internal.h
+++ b/drivers/ras/amd/atl/internal.h
@@ -279,7 +279,6 @@ int denormalize_address(struct addr_ctx *ctx);
int dehash_address(struct addr_ctx *ctx);
unsigned long norm_to_sys_addr(u8 socket_id, u8 die_id, u8 coh_st_inst_id, unsigned long addr);
-unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err);
void amd_atl_umc_translate_addr(struct atl_err *err);
u64 add_base_and_hole(struct addr_ctx *ctx, u64 addr);
@@ -295,7 +294,6 @@ struct param_buf {
} __packed;
int prm_umc_norm_to_addr(guid_t guid, struct param_buf *p_buf);
-unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 umc_bank_inst_id, unsigned long addr);
/*
* Make a gap in @data that is @num_bits long starting at @bit_num.
diff --git a/drivers/ras/amd/atl/prm.c b/drivers/ras/amd/atl/prm.c
index 0635215f220a..ed357ae1607a 100644
--- a/drivers/ras/amd/atl/prm.c
+++ b/drivers/ras/amd/atl/prm.c
@@ -33,23 +33,3 @@ int prm_umc_norm_to_addr(guid_t guid, struct param_buf *p_buf)
return ret;
}
-
-unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
-{
- unsigned long sys_addr;
- struct param_buf p_buf = {
- .addr = {
- .addr = addr,
- .socket_id = socket_id,
- .ipid = bank_id,
- },
- .out_buf = &sys_addr,
- };
- int ret;
-
- ret = prm_umc_norm_to_addr(norm_to_sys_guid, &p_buf);
- if (ret)
- return ret;
-
- return sys_addr;
-}
diff --git a/drivers/ras/amd/atl/umc.c b/drivers/ras/amd/atl/umc.c
index 522378c1d9f2..32748d47ae8d 100644
--- a/drivers/ras/amd/atl/umc.c
+++ b/drivers/ras/amd/atl/umc.c
@@ -401,21 +401,16 @@ static u8 get_coh_st_inst_id(struct atl_err *err)
return FIELD_GET(UMC_CHANNEL_NUM, err->ipid);
}
-unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
+static unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
{
- u8 socket_id = topology_physical_package_id(err->cpu);
u8 coh_st_inst_id = get_coh_st_inst_id(err);
unsigned long addr = get_addr(err->addr);
+ u8 socket_id = err->socket_id;
u8 die_id = get_die_id(err);
- unsigned long ret_addr;
pr_debug("socket_id=0x%x die_id=0x%x coh_st_inst_id=0x%x addr=0x%016lx",
socket_id, die_id, coh_st_inst_id, addr);
- ret_addr = prm_umc_norm_to_sys_addr(socket_id, err->ipid, addr);
- if (!IS_ERR_VALUE(ret_addr) || df_cfg.flags.prm_only)
- return ret_addr;
-
return norm_to_sys_addr(socket_id, die_id, coh_st_inst_id, addr);
}
diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
index 20e23560dee5..c92b6d599792 100644
--- a/drivers/ras/ras.c
+++ b/drivers/ras/ras.c
@@ -11,35 +11,6 @@
#include <linux/uuid.h>
#if IS_ENABLED(CONFIG_AMD_ATL)
-/*
- * Once set, this function pointer should never be unset.
- *
- * The library module will set this pointer if it successfully loads. The module
- * should not be unloaded except for testing and debug purposes.
- */
-static unsigned long (*amd_atl_umc_na_to_spa)(struct atl_err *err);
-
-void amd_atl_register_decoder(unsigned long (*f)(struct atl_err *))
-{
- amd_atl_umc_na_to_spa = f;
-}
-EXPORT_SYMBOL_GPL(amd_atl_register_decoder);
-
-void amd_atl_unregister_decoder(void)
-{
- amd_atl_umc_na_to_spa = NULL;
-}
-EXPORT_SYMBOL_GPL(amd_atl_unregister_decoder);
-
-unsigned long amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
-{
- if (!amd_atl_umc_na_to_spa)
- return -EINVAL;
-
- return amd_atl_umc_na_to_spa(err);
-}
-EXPORT_SYMBOL_GPL(amd_convert_umc_mca_addr_to_sys_addr);
-
/*
* Set by the library module when it loads. Left registered while the module is
* resident; consumers keep no direct dependency on the library, so translation
diff --git a/include/linux/ras.h b/include/linux/ras.h
index eac8cf39ddd5..f0afacdcebcf 100644
--- a/include/linux/ras.h
+++ b/include/linux/ras.h
@@ -60,18 +60,13 @@ struct atl_err {
};
#if IS_ENABLED(CONFIG_AMD_ATL)
-void amd_atl_register_decoder(unsigned long (*f)(struct atl_err *));
-void amd_atl_unregister_decoder(void);
void amd_retire_dram_row(struct atl_err *err);
-unsigned long amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err);
void amd_atl_register_umc_translator(void (*f)(struct atl_err *));
void amd_atl_unregister_umc_translator(void);
void amd_translate_umc_mca_addr(struct atl_err *err);
#else
static inline void amd_retire_dram_row(struct atl_err *err) { }
-static inline unsigned long
-amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err) { return -EINVAL; }
static inline void
amd_translate_umc_mca_addr(struct atl_err *err) { err->valid = 0; }
#endif /* CONFIG_AMD_ATL */
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v10 6/7] RAS/AMD/ATL: Add DRAM address translation via PRM
2026-09-22 20:23 [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Yazen Ghannam
` (4 preceding siblings ...)
2026-09-22 20:23 ` [PATCH v10 5/7] RAS/AMD/ATL: Remove the standalone SPA translation interface Yazen Ghannam
@ 2026-09-22 20:23 ` Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 7/7] EDAC/amd64: Include DRAM address in output Yazen Ghannam
2026-09-28 5:30 ` [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Borislav Petkov
7 siblings, 0 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-09-22 20:23 UTC (permalink / raw)
To: bp, linux-edac; +Cc: linux-kernel, Yazen Ghannam
On AMD's Zen-based SoCs, a Unified Memory Controller (UMC) relative
"normalized" address is reported through the MCA_ADDR of UMC SMCA banks on
occurrence of a DRAM ECC error. This address can be converted into a DRAM
address to decode additional information about the error.
Add support to convert a normalized address into a DRAM address using the
appropriate PRM handler. Expose it as a new operation, ATL_OP_DA, on the
unified interface.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=220577
Assisted-by: LLM
Originally-by: Avadhut Naik <avadhut.naik@amd.com>
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
drivers/ras/amd/atl/internal.h | 1 +
drivers/ras/amd/atl/system.c | 4 ++++
drivers/ras/amd/atl/umc.c | 10 ++++++++++
include/linux/ras.h | 13 +++++++++++++
4 files changed, 28 insertions(+)
diff --git a/drivers/ras/amd/atl/internal.h b/drivers/ras/amd/atl/internal.h
index ed8d176a05e3..bbca0cfca716 100644
--- a/drivers/ras/amd/atl/internal.h
+++ b/drivers/ras/amd/atl/internal.h
@@ -286,6 +286,7 @@ u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr);
/* GUIDs for PRM handlers */
extern const guid_t norm_to_sys_guid;
+extern const guid_t norm_to_dram_guid;
/* See "PRM Parameter Buffer" in the AMD ACPI Porting Guide. */
struct param_buf {
diff --git a/drivers/ras/amd/atl/system.c b/drivers/ras/amd/atl/system.c
index 812a30e21d3a..1315bcc63e30 100644
--- a/drivers/ras/amd/atl/system.c
+++ b/drivers/ras/amd/atl/system.c
@@ -18,6 +18,10 @@ const guid_t norm_to_sys_guid = GUID_INIT(0xE7180659, 0xA65D, 0x451D,
0x92, 0xCD, 0x2B, 0x56, 0xF1,
0x2B, 0xEB, 0xA6);
+const guid_t norm_to_dram_guid = GUID_INIT(0x7626C6AE, 0xF973, 0x429C,
+ 0xA9, 0x1C, 0x10, 0x7D, 0x7B,
+ 0xE2, 0x98, 0xB0);
+
int determine_node_id(struct addr_ctx *ctx, u8 socket_id, u8 die_id)
{
u16 socket_id_bits, die_id_bits;
diff --git a/drivers/ras/amd/atl/umc.c b/drivers/ras/amd/atl/umc.c
index 32748d47ae8d..4495dce3f21e 100644
--- a/drivers/ras/amd/atl/umc.c
+++ b/drivers/ras/amd/atl/umc.c
@@ -454,4 +454,14 @@ void amd_atl_umc_translate_addr(struct atl_err *err)
}
}
}
+
+ if (err->requested & ATL_OP_DA) {
+ struct param_buf p_buf = {
+ .addr = err->umc_addr,
+ .out_buf = &err->da,
+ };
+
+ if (!prm_umc_norm_to_addr(norm_to_dram_guid, &p_buf))
+ err->valid |= ATL_OP_DA;
+ }
}
diff --git a/include/linux/ras.h b/include/linux/ras.h
index f0afacdcebcf..6589b4e3ff0c 100644
--- a/include/linux/ras.h
+++ b/include/linux/ras.h
@@ -37,8 +37,20 @@ static inline void
log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev) { return; }
#endif
+/* See "NA to DA Output Buffer" in the AMD ACPI Porting Guide. */
+struct atl_dram_addr {
+ u8 chip_select;
+ u8 bank_group;
+ u8 bank_addr;
+ u32 row_addr;
+ u16 col_addr;
+ u8 rank_mul;
+ u8 sub_ch;
+} __packed;
+
/* Operations requested and completed through amd_translate_umc_mca_addr(). */
#define ATL_OP_SPA BIT(0) /* System Physical Address */
+#define ATL_OP_DA BIT(1) /* DRAM address components */
struct atl_err {
/* Identifiers; layout mirrors the PRM parameter buffer inputs */
@@ -57,6 +69,7 @@ struct atl_err {
/* Outputs */
u64 spa; /* Valid if (@valid & ATL_OP_SPA) */
+ struct atl_dram_addr da; /* Valid if (@valid & ATL_OP_DA) */
};
#if IS_ENABLED(CONFIG_AMD_ATL)
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v10 7/7] EDAC/amd64: Include DRAM address in output
2026-09-22 20:23 [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Yazen Ghannam
` (5 preceding siblings ...)
2026-09-22 20:23 ` [PATCH v10 6/7] RAS/AMD/ATL: Add DRAM address translation via PRM Yazen Ghannam
@ 2026-09-22 20:23 ` Yazen Ghannam
2026-09-28 5:30 ` [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Borislav Petkov
7 siblings, 0 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-09-22 20:23 UTC (permalink / raw)
To: bp, linux-edac; +Cc: linux-kernel, Yazen Ghannam
The DRAM address of an error is used by tooling to find failure patterns,
e.g. for off-system analysis or to offline a page affected by a bad row.
Other EDAC modules (GHES and SKX) already provide it. AMD64 could not,
because the translation is system-specific.
Request the DRAM address in addition to the System Physical Address when
translating a UMC error. The SPA is required to log the error. The DRAM
address is best-effort and only added when its translation succeeds.
Add the DRAM address to the EDAC "other_detail" field, along with the
socket and IPID that tooling needs to translate it back into an SPA.
Assisted-by: LLM
Originally-by: Avadhut Naik <avadhut.naik@amd.com>
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
drivers/edac/amd64_edac.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index f428d815bff1..7d7d116dbb75 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2704,11 +2704,15 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome)
return map_err_sym_to_channel(err_sym, pvt->ecc_sym_sz);
}
+#define MSG_SIZE 256
static void __log_ecc_error(struct mem_ctl_info *mci, struct err_info *err,
u8 ecc_type)
{
enum hw_event_mc_err_type err_type;
const char *string;
+ char s[MSG_SIZE];
+
+ s[0] = '\0';
if (ecc_type == 2)
err_type = HW_EVENT_ERR_CORRECTED;
@@ -2745,10 +2749,27 @@ static void __log_ecc_error(struct mem_ctl_info *mci, struct err_info *err,
break;
}
+ if (err->a_err.valid & ATL_OP_DA) {
+ struct atl_dram_addr *da = &err->a_err.da;
+ char *p = s, *end = p + sizeof(s);
+
+ /* Include a version prefix in case the format needs to change later. */
+ p += scnprintf(p, end - p, "[AMDv1]");
+ p += scnprintf(p, end - p, " SocketId:0x%x", err->a_err.socket_id);
+ p += scnprintf(p, end - p, " IPID:0x%llx", err->a_err.ipid);
+ p += scnprintf(p, end - p, " ChipSelect:0x%x", da->chip_select);
+ p += scnprintf(p, end - p, " Row:0x%x", da->row_addr);
+ p += scnprintf(p, end - p, " Column:0x%x", da->col_addr);
+ p += scnprintf(p, end - p, " Bank:0x%x", da->bank_addr);
+ p += scnprintf(p, end - p, " BankGroup:0x%x", da->bank_group);
+ p += scnprintf(p, end - p, " RankMul:0x%x", da->rank_mul);
+ p += scnprintf(p, end - p, " SubChannel:0x%x", da->sub_ch);
+ }
+
edac_mc_handle_error(err_type, mci, 1,
err->page, err->offset, err->syndrome,
err->csrow, err->channel, -1,
- string, "");
+ string, s);
}
static inline void decode_bus_error(int node_id, struct mce *m)
@@ -2844,7 +2865,7 @@ static void decode_umc_error(int node_id, struct mce *m)
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;
+ err.a_err.requested = ATL_OP_SPA | ATL_OP_DA;
amd_translate_umc_mca_addr(&err.a_err);
if (!(err.a_err.valid & ATL_OP_SPA)) {
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v10 0/7] Incorporate DRAM address in EDAC messages
2026-09-22 20:23 [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Yazen Ghannam
` (6 preceding siblings ...)
2026-09-22 20:23 ` [PATCH v10 7/7] EDAC/amd64: Include DRAM address in output Yazen Ghannam
@ 2026-09-28 5:30 ` Borislav Petkov
2026-09-28 15:12 ` Yazen Ghannam
7 siblings, 1 reply; 10+ messages in thread
From: Borislav Petkov @ 2026-09-28 5:30 UTC (permalink / raw)
To: Yazen Ghannam; +Cc: linux-edac, linux-kernel
On Tue, Sep 22, 2026 at 03:23:10PM -0500, Yazen Ghannam wrote:
> This revision addresses a couple comments from Boris. Also, the couple
> of patches originally by Avadhut have gone through a few revisions. So I
> updated the attributions.
One Sashiko question here:
https://sashiko.dev/#/patchset/20260922202318.4079080-1-yazen.ghannam%40amd.com
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v10 0/7] Incorporate DRAM address in EDAC messages
2026-09-28 5:30 ` [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Borislav Petkov
@ 2026-09-28 15:12 ` Yazen Ghannam
0 siblings, 0 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-09-28 15:12 UTC (permalink / raw)
To: Borislav Petkov; +Cc: linux-edac, linux-kernel
On Sun, Sep 27, 2026 at 10:30:40PM -0700, Borislav Petkov wrote:
> On Tue, Sep 22, 2026 at 03:23:10PM -0500, Yazen Ghannam wrote:
> > This revision addresses a couple comments from Boris. Also, the couple
> > of patches originally by Avadhut have gone through a few revisions. So I
> > updated the attributions.
>
> One Sashiko question here:
>
> https://sashiko.dev/#/patchset/20260922202318.4079080-1-yazen.ghannam%40amd.com
>
Looks like a false positive.
The question is on a struct that was added in patch 3. And that patch
was reviewed as good.
Also, pahole shows that the nested struct is packed. Sashiko said is
isn't.
Nested struct => struct atl_umc_addr
$ pahole build/drivers/ras/amd/atl/prm.o
struct atl_umc_addr {
u64 addr; /* 0 8 */
u8 socket_id; /* 8 1 */
u64 ipid; /* 9 8 */
/* size: 17, cachelines: 1, members: 3 */
/* last cacheline: 17 bytes */
} __attribute__((__packed__));
struct param_buf {
struct atl_umc_addr addr; /* 0 17 */
void * out_buf; /* 17 8 */
/* size: 25, cachelines: 1, members: 2 */
/* last cacheline: 25 bytes */
} __attribute__((__packed__));
Thanks,
Yazen
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-09-28 15:13 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-22 20:23 [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 1/7] RAS/AMD/ATL: Make PRM address translation support builtin Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 2/7] RAS/AMD/ATL: Refactor PRM address translation into a common helper Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 3/7] RAS/AMD/ATL: Add unified UMC address translation interface Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 4/7] RAS/AMD, EDAC/amd64: Use unified interface for SPA translation Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 5/7] RAS/AMD/ATL: Remove the standalone SPA translation interface Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 6/7] RAS/AMD/ATL: Add DRAM address translation via PRM Yazen Ghannam
2026-09-22 20:23 ` [PATCH v10 7/7] EDAC/amd64: Include DRAM address in output Yazen Ghannam
2026-09-28 5:30 ` [PATCH v10 0/7] Incorporate DRAM address in EDAC messages Borislav Petkov
2026-09-28 15:12 ` Yazen Ghannam
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®