mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v7 0/3] Incorporate DRAM address in EDAC messages
@ 2026-06-30 21:06 Yazen Ghannam
  2026-06-30 21:06 ` [PATCH v7 1/3] RAS/AMD/ATL: Directly export address translation helper Yazen Ghannam
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-06-30 21:06 UTC (permalink / raw)
  To: bp, linux-edac; +Cc: linux-kernel, Avadhut Naik

Hi all,

This revision includes a new pre-patch based on the diff from Boris in
the last revision. The subsequent patches were fixed up as needed. There
were some minor changes due to formatting, etc. Boris, please do adjust
the attributions as you see fit.

The first patch has an Assisted-by tag due to help spotting and fixing a
build issue with a particular Kconfig combination.

Thanks,
Yazen

Cc: Avadhut Naik <avanaik92@gmail.com>

Link:
https://lore.kernel.org/20260629150731.1009605-1-yazen.ghannam@amd.com

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.

Avadhut Naik (2):
  RAS/AMD/ATL: Translate UMC normalized address to DRAM address using
    PRM
  EDAC/amd64: Include DRAM address in output

Yazen Ghannam (1):
  RAS/AMD/ATL: Directly export address translation helper

 drivers/edac/amd64_edac.c      | 34 ++++++++++++++++++++++++++++++++--
 drivers/edac/amd64_edac.h      |  3 +++
 drivers/ras/amd/atl/core.c     | 23 ++++++++++++-----------
 drivers/ras/amd/atl/internal.h | 11 ++++++++++-
 drivers/ras/amd/atl/prm.c      | 32 ++++++++++++++++++++++++++++----
 drivers/ras/amd/atl/system.c   |  3 +++
 drivers/ras/amd/atl/umc.c      | 11 ++++++++++-
 drivers/ras/amd/fmpm.c         |  2 +-
 drivers/ras/ras.c              | 31 -------------------------------
 include/linux/ras.h            | 22 +++++++++++++++++-----
 10 files changed, 116 insertions(+), 56 deletions(-)


base-commit: 1129f95c19e50823398822a775c9adc141113196
-- 
2.53.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v7 1/3] RAS/AMD/ATL: Directly export address translation helper
  2026-06-30 21:06 [PATCH v7 0/3] Incorporate DRAM address in EDAC messages Yazen Ghannam
@ 2026-06-30 21:06 ` Yazen Ghannam
  2026-06-30 21:06 ` [PATCH v7 2/3] RAS/AMD/ATL: Translate UMC normalized address to DRAM address using PRM Yazen Ghannam
  2026-06-30 21:06 ` [PATCH v7 3/3] EDAC/amd64: Include DRAM address in output Yazen Ghannam
  2 siblings, 0 replies; 10+ messages in thread
From: Yazen Ghannam @ 2026-06-30 21:06 UTC (permalink / raw)
  To: bp, linux-edac; +Cc: linux-kernel, Avadhut Naik, Yazen Ghannam

Currently, the address translation function is accessed indirectly
through a function pointer set at module init. This is useful to allow
the translation library to be built as an optional module independent of
its consumers.

However, it becomes cumbersome to add new functions in this way.

Remove the indirection and export the current helper function.

This introduces a linker issue when AMD_ATL=m and a consumer module is
built-in. Address this issue by using the IS_REACHABLE() config guard.

Also, shorten the helper function name a bit.

Assisted-by: Claude:claude-opus-4-8
Originally-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
 drivers/edac/amd64_edac.c  |  2 +-
 drivers/ras/amd/atl/core.c | 17 ++++++-----------
 drivers/ras/amd/atl/umc.c  |  2 +-
 drivers/ras/amd/fmpm.c     |  2 +-
 drivers/ras/ras.c          | 31 -------------------------------
 include/linux/ras.h        |  8 +++-----
 6 files changed, 12 insertions(+), 50 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index c6aa69dbd9fb..880036599456 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2847,7 +2847,7 @@ static void decode_umc_error(int node_id, struct mce *m)
 	a_err.ipid = m->ipid;
 	a_err.cpu  = m->extcpu;
 
-	sys_addr = amd_convert_umc_mca_addr_to_sys_addr(&a_err);
+	sys_addr = amd_convert_umc_addr_to_sys_addr(&a_err);
 	if (IS_ERR_VALUE(sys_addr)) {
 		err.err_code = ERR_NORM_ADDR;
 		goto log_error;
diff --git a/drivers/ras/amd/atl/core.c b/drivers/ras/amd/atl/core.c
index 0f7cd6dab0b0..49695313f850 100644
--- a/drivers/ras/amd/atl/core.c
+++ b/drivers/ras/amd/atl/core.c
@@ -192,6 +192,12 @@ static const struct x86_cpu_id amd_atl_cpuids[] = {
 };
 MODULE_DEVICE_TABLE(x86cpu, amd_atl_cpuids);
 
+unsigned long amd_convert_umc_addr_to_sys_addr(struct atl_err *err)
+{
+	return convert_umc_mca_addr_to_sys_addr(err);
+}
+EXPORT_SYMBOL_GPL(amd_convert_umc_addr_to_sys_addr);
+
 static int __init amd_atl_init(void)
 {
 	int ret;
@@ -210,23 +216,12 @@ 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);
 
 	pr_info("AMD Address Translation Library initialized\n");
 	return 0;
 }
 
-/*
- * Exit function is only needed for testing and debug. Module unload must be
- * forced to override refcount check.
- */
-static void __exit amd_atl_exit(void)
-{
-	amd_atl_unregister_decoder();
-}
-
 module_init(amd_atl_init);
-module_exit(amd_atl_exit);
 
 MODULE_DESCRIPTION("AMD Address Translation Library");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ras/amd/atl/umc.c b/drivers/ras/amd/atl/umc.c
index befc616d5e8a..b59556ded2c8 100644
--- a/drivers/ras/amd/atl/umc.c
+++ b/drivers/ras/amd/atl/umc.c
@@ -318,7 +318,7 @@ static void _retire_row_mi300(struct atl_err *a_err)
 		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);
+		addr = amd_convert_umc_addr_to_sys_addr(a_err);
 		if (IS_ERR_VALUE(addr))
 			continue;
 
diff --git a/drivers/ras/amd/fmpm.c b/drivers/ras/amd/fmpm.c
index 4ccaaf7b70bf..48ca7f598387 100644
--- a/drivers/ras/amd/fmpm.c
+++ b/drivers/ras/amd/fmpm.c
@@ -334,7 +334,7 @@ static void save_spa(struct fru_rec *rec, unsigned int entry,
 	a_err.ipid = id;
 	a_err.cpu  = cpu;
 
-	spa = amd_convert_umc_mca_addr_to_sys_addr(&a_err);
+	spa = amd_convert_umc_addr_to_sys_addr(&a_err);
 	if (IS_ERR_VALUE(spa)) {
 		pr_debug("Failed to get system address\n");
 		return;
diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
index 03df3db62334..011de2c257b1 100644
--- a/drivers/ras/ras.c
+++ b/drivers/ras/ras.c
@@ -10,37 +10,6 @@
 #include <linux/ras.h>
 #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);
-#endif /* CONFIG_AMD_ATL */
-
 #define CREATE_TRACE_POINTS
 #define TRACE_INCLUDE_PATH ../../include/ras
 #include <ras/ras_event.h>
diff --git a/include/linux/ras.h b/include/linux/ras.h
index 468941bfe855..4b095ddb9071 100644
--- a/include/linux/ras.h
+++ b/include/linux/ras.h
@@ -41,15 +41,13 @@ struct atl_err {
 	u32 cpu;
 };
 
-#if IS_ENABLED(CONFIG_AMD_ATL)
-void amd_atl_register_decoder(unsigned long (*f)(struct atl_err *));
-void amd_atl_unregister_decoder(void);
+#if IS_REACHABLE(CONFIG_AMD_ATL)
 void amd_retire_dram_row(struct atl_err *err);
-unsigned long amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err);
+unsigned long amd_convert_umc_addr_to_sys_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; }
+amd_convert_umc_addr_to_sys_addr(struct atl_err *err) { return -EINVAL; }
 #endif /* CONFIG_AMD_ATL */
 
 #if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
-- 
2.53.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v7 2/3] RAS/AMD/ATL: Translate UMC normalized address to DRAM address using PRM
  2026-06-30 21:06 [PATCH v7 0/3] Incorporate DRAM address in EDAC messages Yazen Ghannam
  2026-06-30 21:06 ` [PATCH v7 1/3] RAS/AMD/ATL: Directly export address translation helper Yazen Ghannam
@ 2026-06-30 21:06 ` Yazen Ghannam
  2026-07-07  0:32   ` Borislav Petkov
  2026-06-30 21:06 ` [PATCH v7 3/3] EDAC/amd64: Include DRAM address in output Yazen Ghannam
  2 siblings, 1 reply; 10+ messages in thread
From: Yazen Ghannam @ 2026-06-30 21:06 UTC (permalink / raw)
  To: bp, linux-edac; +Cc: linux-kernel, Avadhut Naik, Yazen Ghannam

From: Avadhut Naik <avadhut.naik@amd.com>

Modern AMD SOCs provide UEFI PRM module that implements various address
translation PRM handlers.[1] These handlers can be invoked by the OS or
hypervisor at runtime to perform address translations.

On AMD's Zen-based SOCs, Unified Memory Controller (UMC) relative
"normalized" address is reported through MCA_ADDR of UMC SMCA bank type
on occurrence of a DRAM ECC error. This address must be converted into
system physical address and DRAM address to export additional information
about the error.

Add support to convert normalized address into DRAM address through the
appropriate PRM handler. Instead of logging the translated DRAM address
locally, export the translating function when the Address Translation
library is initialized. Modules like amd64_edac can then invoke the PRM
handler to add the DRAM address to their error records. Additionally, it
can also be exported through the RAS tracepont.

[1] https://bugzilla.kernel.org/show_bug.cgi?id=220577

[Yazen: Remove 'handler available' check]

Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
 drivers/ras/amd/atl/core.c     |  6 ++++++
 drivers/ras/amd/atl/internal.h | 11 ++++++++++-
 drivers/ras/amd/atl/prm.c      | 32 ++++++++++++++++++++++++++++----
 drivers/ras/amd/atl/system.c   |  3 +++
 drivers/ras/amd/atl/umc.c      |  9 +++++++++
 include/linux/ras.h            | 14 ++++++++++++++
 6 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/drivers/ras/amd/atl/core.c b/drivers/ras/amd/atl/core.c
index 49695313f850..52d4d973f4ad 100644
--- a/drivers/ras/amd/atl/core.c
+++ b/drivers/ras/amd/atl/core.c
@@ -198,6 +198,12 @@ unsigned long amd_convert_umc_addr_to_sys_addr(struct atl_err *err)
 }
 EXPORT_SYMBOL_GPL(amd_convert_umc_addr_to_sys_addr);
 
+int amd_convert_umc_addr_to_dram_addr(struct atl_err *err, struct atl_dram_addr *dram_addr)
+{
+	return convert_umc_mca_addr_to_dram_addr(err, dram_addr);
+}
+EXPORT_SYMBOL_GPL(amd_convert_umc_addr_to_dram_addr);
+
 static int __init amd_atl_init(void)
 {
 	int ret;
diff --git a/drivers/ras/amd/atl/internal.h b/drivers/ras/amd/atl/internal.h
index 82a56d9c2be1..b6ca5fef6ec7 100644
--- a/drivers/ras/amd/atl/internal.h
+++ b/drivers/ras/amd/atl/internal.h
@@ -280,23 +280,32 @@ 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);
+int convert_umc_mca_addr_to_dram_addr(struct atl_err *err, struct atl_dram_addr *dram_addr);
 
 u64 add_base_and_hole(struct addr_ctx *ctx, u64 addr);
 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;
 
 #ifdef CONFIG_AMD_ATL_PRM
 unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 umc_bank_inst_id, unsigned long addr);
+int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id,
+			      unsigned long addr, struct atl_dram_addr *dram_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
 
+static inline int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id,
+					    unsigned long addr, struct atl_dram_addr *dram_addr)
+{
+	return -ENODEV;
+}
+#endif
 /*
  * Make a gap in @data that is @num_bits long starting at @bit_num.
  * e.g. data		= 11111111'b
diff --git a/drivers/ras/amd/atl/prm.c b/drivers/ras/amd/atl/prm.c
index 0f9bfa96e16a..c69158f66639 100644
--- a/drivers/ras/amd/atl/prm.c
+++ b/drivers/ras/amd/atl/prm.c
@@ -19,10 +19,11 @@
 #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.
+ * PRM parameter buffer - normalized to system physical address and normalized
+ * to DRAM address, as described in the "PRM Parameter Buffer" section of the
+ * AMD ACPI Porting Guide.
  */
-struct norm_to_sys_param_buf {
+struct prm_parameter_buffer {
 	u64 norm_addr;
 	u8 socket;
 	u64 bank_id;
@@ -31,7 +32,7 @@ struct norm_to_sys_param_buf {
 
 unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
 {
-	struct norm_to_sys_param_buf p_buf;
+	struct prm_parameter_buffer p_buf;
 	unsigned long ret_addr;
 	int ret;
 
@@ -51,3 +52,26 @@ unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long
 
 	return ret;
 }
+
+int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id,
+			      unsigned long addr, struct atl_dram_addr *dram_addr)
+{
+	struct prm_parameter_buffer p_buf;
+	int ret;
+
+	p_buf.norm_addr	= addr;
+	p_buf.socket	= socket_id;
+	p_buf.bank_id	= bank_id;
+	p_buf.out_buf	= dram_addr;
+
+	ret = acpi_call_prm_handler(norm_to_dram_guid, &p_buf);
+	if (!ret)
+		return ret;
+
+	if (ret == -ENODEV)
+		pr_debug("PRM module/handler not available.\n");
+	else
+		pr_notice_once("PRM DRAM Address Translation failed.\n");
+
+	return ret;
+}
diff --git a/drivers/ras/amd/atl/system.c b/drivers/ras/amd/atl/system.c
index 812a30e21d3a..33a04f3e7da8 100644
--- a/drivers/ras/amd/atl/system.c
+++ b/drivers/ras/amd/atl/system.c
@@ -17,6 +17,9 @@
 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)
 {
diff --git a/drivers/ras/amd/atl/umc.c b/drivers/ras/amd/atl/umc.c
index b59556ded2c8..f8470d74a9b0 100644
--- a/drivers/ras/amd/atl/umc.c
+++ b/drivers/ras/amd/atl/umc.c
@@ -416,3 +416,12 @@ 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);
 }
+
+int convert_umc_mca_addr_to_dram_addr(struct atl_err *err, struct atl_dram_addr *dram_addr)
+{
+	u8 socket_id = topology_physical_package_id(err->cpu);
+	unsigned long addr = get_addr(err->addr);
+	u64 bank_id = err->ipid;
+
+	return prm_umc_norm_to_dram_addr(socket_id, bank_id, addr, dram_addr);
+}
diff --git a/include/linux/ras.h b/include/linux/ras.h
index 4b095ddb9071..205ceb447e23 100644
--- a/include/linux/ras.h
+++ b/include/linux/ras.h
@@ -41,13 +41,27 @@ struct atl_err {
 	u32 cpu;
 };
 
+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;
+
 #if IS_REACHABLE(CONFIG_AMD_ATL)
 void amd_retire_dram_row(struct atl_err *err);
 unsigned long amd_convert_umc_addr_to_sys_addr(struct atl_err *err);
+int amd_convert_umc_addr_to_dram_addr(struct atl_err *err, struct atl_dram_addr *dram_addr);
 #else
 static inline void amd_retire_dram_row(struct atl_err *err) { }
 static inline unsigned long
 amd_convert_umc_addr_to_sys_addr(struct atl_err *err) { return -EINVAL; }
+static inline int
+amd_convert_umc_addr_to_dram_addr(struct atl_err *err,
+				  struct atl_dram_addr *dram_addr) { return -EINVAL; }
 #endif /* CONFIG_AMD_ATL */
 
 #if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
-- 
2.53.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v7 3/3] EDAC/amd64: Include DRAM address in output
  2026-06-30 21:06 [PATCH v7 0/3] Incorporate DRAM address in EDAC messages Yazen Ghannam
  2026-06-30 21:06 ` [PATCH v7 1/3] RAS/AMD/ATL: Directly export address translation helper Yazen Ghannam
  2026-06-30 21:06 ` [PATCH v7 2/3] RAS/AMD/ATL: Translate UMC normalized address to DRAM address using PRM Yazen Ghannam
@ 2026-06-30 21:06 ` Yazen Ghannam
  2026-07-07  0:37   ` Borislav Petkov
  2 siblings, 1 reply; 10+ messages in thread
From: Yazen Ghannam @ 2026-06-30 21:06 UTC (permalink / raw)
  To: bp, linux-edac; +Cc: linux-kernel, Avadhut Naik, Yazen Ghannam

From: Avadhut Naik <avadhut.naik@amd.com>

The DRAM address of an error is used by tooling to find failure
patterns. This information can be used for general analysis off system.
And it can be used on system to take action like offline a page affected
by a bad row.

Other EDAC modules (GHES and SKX) provide this information in their
output. The AMD64 EDAC module was not able to provide this information,
because system-specific translation is needed.

Recent AMD systems provide a PRM handler for DRAM address translation.

Use this PRM handler to get the DRAM address of an error. Include this
in the EDAC "other_detail" field.

Also include the Socket and IPID in the EDAC "other_detail" field. These
are needed by tooling to translate a DRAM address to a System Physical
Address.

[Yazen: Reformat other_detail string]

Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
Co-developed-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
 drivers/edac/amd64_edac.c | 32 +++++++++++++++++++++++++++++++-
 drivers/edac/amd64_edac.h |  3 +++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 880036599456..477c8bf620fc 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2704,11 +2704,16 @@ 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 512
+
 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];
+
+	memset(s, 0, sizeof(s));
 
 	if (ecc_type == 2)
 		err_type = HW_EVENT_ERR_CORRECTED;
@@ -2721,6 +2726,23 @@ static void __log_ecc_error(struct mem_ctl_info *mci, struct err_info *err,
 		return;
 	}
 
+	if (err->dram_addr) {
+		struct atl_dram_addr *da = err->dram_addr;
+		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, " %s:0x%x", "SocketId",	err->socketid);
+		p += scnprintf(p, end - p, " %s:0x%llx", "IPID",	err->ipid);
+		p += scnprintf(p, end - p, " %s:0x%x", "ChipSelect",	da->chip_select);
+		p += scnprintf(p, end - p, " %s:0x%x", "Row",		da->row_addr);
+		p += scnprintf(p, end - p, " %s:0x%x", "Column",	da->col_addr);
+		p += scnprintf(p, end - p, " %s:0x%x", "Bank",		da->bank_addr);
+		p += scnprintf(p, end - p, " %s:0x%x", "BankGroup",	da->bank_group);
+		p += scnprintf(p, end - p, " %s:0x%x", "RankMul",	da->rank_mul);
+		p += scnprintf(p, end - p, " %s:0x%x", "SubChannel",	da->sub_ch);
+	}
+
 	switch (err->err_code) {
 	case DECODE_OK:
 		string = "";
@@ -2748,7 +2770,7 @@ static void __log_ecc_error(struct mem_ctl_info *mci, struct err_info *err,
 	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)
@@ -2808,6 +2830,7 @@ static void umc_get_err_info(struct mce *m, struct err_info *err)
 static void decode_umc_error(int node_id, struct mce *m)
 {
 	u8 ecc_type = (m->status >> 45) & 0x3;
+	struct atl_dram_addr dram_addr;
 	struct mem_ctl_info *mci;
 	unsigned long sys_addr;
 	struct amd64_pvt *pvt;
@@ -2822,8 +2845,12 @@ static void decode_umc_error(int node_id, struct mce *m)
 
 	pvt = mci->pvt_info;
 
+	memset(&dram_addr, 0, sizeof(dram_addr));
 	memset(&err, 0, sizeof(err));
 
+	err.socketid = m->socketid;
+	err.ipid     = m->ipid;
+
 	if (m->status & MCI_STATUS_DEFERRED)
 		ecc_type = 3;
 
@@ -2853,6 +2880,9 @@ static void decode_umc_error(int node_id, struct mce *m)
 		goto log_error;
 	}
 
+	if (!amd_convert_umc_addr_to_dram_addr(&a_err, &dram_addr))
+		err.dram_addr = &dram_addr;
+
 	error_address_to_page_and_offset(sys_addr, &err);
 
 log_error:
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 1757c1b99fc8..39c1b6471909 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -400,6 +400,9 @@ struct err_info {
 	u16 syndrome;
 	u32 page;
 	u32 offset;
+	struct atl_dram_addr *dram_addr;
+	u32 socketid;
+	u64 ipid;
 };
 
 static inline u32 get_umc_base(u8 channel)
-- 
2.53.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v7 2/3] RAS/AMD/ATL: Translate UMC normalized address to DRAM address using PRM
  2026-06-30 21:06 ` [PATCH v7 2/3] RAS/AMD/ATL: Translate UMC normalized address to DRAM address using PRM Yazen Ghannam
@ 2026-07-07  0:32   ` Borislav Petkov
  2026-07-07 13:57     ` Yazen Ghannam
  0 siblings, 1 reply; 10+ messages in thread
From: Borislav Petkov @ 2026-07-07  0:32 UTC (permalink / raw)
  To: Yazen Ghannam; +Cc: linux-edac, linux-kernel, Avadhut Naik

On Tue, Jun 30, 2026 at 05:06:39PM -0400, Yazen Ghannam wrote:
> From: Avadhut Naik <avadhut.naik@amd.com>
> 
> Modern AMD SOCs provide UEFI PRM module that implements various address
> translation PRM handlers.[1] These handlers can be invoked by the OS or
> hypervisor at runtime to perform address translations.
> 
> On AMD's Zen-based SOCs, Unified Memory Controller (UMC) relative
> "normalized" address is reported through MCA_ADDR of UMC SMCA bank type
> on occurrence of a DRAM ECC error. This address must be converted into
> system physical address and DRAM address to export additional information
> about the error.
> 
> Add support to convert normalized address into DRAM address through the
> appropriate PRM handler. Instead of logging the translated DRAM address
> locally, export the translating function when the Address Translation
> library is initialized. Modules like amd64_edac can then invoke the PRM
> handler to add the DRAM address to their error records. Additionally, it
> can also be exported through the RAS tracepont.

Use this commit message for this patch:

    Modern AMD SOCs provide an UEFI PRM module that implements various address
    translation PRM handlers¹. These handlers can be invoked by the OS or
    the hypervisor at runtime to perform address translations.
    
    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 must be converted into
    a system physical address and DRAM address in order to decode additional
    information about the error.
    
    Add support to convert a normalized address into a DRAM address using
    such PRM handler.
    
    ¹https://bugzilla.kernel.org/show_bug.cgi?id=220577

or run it through AI because I'm tired of adding pronouns left and right and
removing text which regurgitates the code in the patch.

> [1] https://bugzilla.kernel.org/show_bug.cgi?id=220577
> 
> [Yazen: Remove 'handler available' check]
> 
> Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
> Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
> ---
>  drivers/ras/amd/atl/core.c     |  6 ++++++
>  drivers/ras/amd/atl/internal.h | 11 ++++++++++-
>  drivers/ras/amd/atl/prm.c      | 32 ++++++++++++++++++++++++++++----
>  drivers/ras/amd/atl/system.c   |  3 +++
>  drivers/ras/amd/atl/umc.c      |  9 +++++++++
>  include/linux/ras.h            | 14 ++++++++++++++
>  6 files changed, 70 insertions(+), 5 deletions(-)

...

> +static inline int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id,
> +					    unsigned long addr, struct atl_dram_addr *dram_addr)

... int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id, unsigned long addr,
				  struct atl_dram_addr *dram_addr)

> +{
> +	return -ENODEV;
> +}
> +#endif
>  /*
>   * Make a gap in @data that is @num_bits long starting at @bit_num.
>   * e.g. data		= 11111111'b
> diff --git a/drivers/ras/amd/atl/prm.c b/drivers/ras/amd/atl/prm.c
> index 0f9bfa96e16a..c69158f66639 100644
> --- a/drivers/ras/amd/atl/prm.c
> +++ b/drivers/ras/amd/atl/prm.c
> @@ -19,10 +19,11 @@
>  #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.
> + * PRM parameter buffer - normalized to system physical address and normalized
> + * to DRAM address, as described in the "PRM Parameter Buffer" section of the
> + * AMD ACPI Porting Guide.
>   */
> -struct norm_to_sys_param_buf {
> +struct prm_parameter_buffer {

struct param_buf {

This is not BIOS code.

>  	u64 norm_addr;
>  	u8 socket;
>  	u64 bank_id;
> @@ -31,7 +32,7 @@ struct norm_to_sys_param_buf {
>  
>  unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
>  {
> -	struct norm_to_sys_param_buf p_buf;
> +	struct prm_parameter_buffer p_buf;
>  	unsigned long ret_addr;
>  	int ret;
>  
> @@ -51,3 +52,26 @@ unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long
>  
>  	return ret;
>  }
> +
> +int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id,
> +			      unsigned long addr, struct atl_dram_addr *dram_addr)

int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id, unsigned long addr,
			      struct atl_dram_addr *dram_addr)

> +{
> +	struct prm_parameter_buffer p_buf;
> +	int ret;
> +
> +	p_buf.norm_addr	= addr;
> +	p_buf.socket	= socket_id;
> +	p_buf.bank_id	= bank_id;
> +	p_buf.out_buf	= dram_addr;
> +
> +	ret = acpi_call_prm_handler(norm_to_dram_guid, &p_buf);
> +	if (!ret)
> +		return ret;
> +
> +	if (ret == -ENODEV)
> +		pr_debug("PRM module/handler not available.\n");
> +	else
> +		pr_notice_once("PRM DRAM Address Translation failed.\n");

Dump ret here.

Also, this function is an almost identical copy to prm_umc_norm_to_sys_addr().
Merge the two pls.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v7 3/3] EDAC/amd64: Include DRAM address in output
  2026-06-30 21:06 ` [PATCH v7 3/3] EDAC/amd64: Include DRAM address in output Yazen Ghannam
@ 2026-07-07  0:37   ` Borislav Petkov
  2026-07-07 14:02     ` Yazen Ghannam
  0 siblings, 1 reply; 10+ messages in thread
From: Borislav Petkov @ 2026-07-07  0:37 UTC (permalink / raw)
  To: Yazen Ghannam; +Cc: linux-edac, linux-kernel, Avadhut Naik

On Tue, Jun 30, 2026 at 05:06:40PM -0400, Yazen Ghannam wrote:
> From: Avadhut Naik <avadhut.naik@amd.com>
> 
> The DRAM address of an error is used by tooling to find failure
> patterns. This information can be used for general analysis off system.
> And it can be used on system to take action like offline a page affected
> by a bad row.
> 
> Other EDAC modules (GHES and SKX) provide this information in their
> output. The AMD64 EDAC module was not able to provide this information,
> because system-specific translation is needed.
> 
> Recent AMD systems provide a PRM handler for DRAM address translation.
> 
> Use this PRM handler to get the DRAM address of an error. Include this
> in the EDAC "other_detail" field.
> 
> Also include the Socket and IPID in the EDAC "other_detail" field. These
> are needed by tooling to translate a DRAM address to a System Physical
> Address.

    "Use the DRAM address translated by the PRM handler on AMD systems when
    reporting an error and add it to the error information that is being
    logged by EDAC. Also include the Socket and IPID which tooling needs to
    translate the DRAM address into a SPA (System Physical Address)."

Plain and simple.

> 
> [Yazen: Reformat other_detail string]
> 
> Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
> Co-developed-by: Yazen Ghannam <yazen.ghannam@amd.com>
> Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
> ---
>  drivers/edac/amd64_edac.c | 32 +++++++++++++++++++++++++++++++-
>  drivers/edac/amd64_edac.h |  3 +++
>  2 files changed, 34 insertions(+), 1 deletion(-)

...

> @@ -2853,6 +2880,9 @@ static void decode_umc_error(int node_id, struct mce *m)
>  		goto log_error;
>  	}
>  
> +	if (!amd_convert_umc_addr_to_dram_addr(&a_err, &dram_addr))
> +		err.dram_addr = &dram_addr;

I really hate the fact that we have to call PRM twice per error. Is there
a PRM that can give us both addresses in one go?

>  	error_address_to_page_and_offset(sys_addr, &err);
>  
>  log_error:
> diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
> index 1757c1b99fc8..39c1b6471909 100644
> --- a/drivers/edac/amd64_edac.h
> +++ b/drivers/edac/amd64_edac.h
> @@ -400,6 +400,9 @@ struct err_info {
>  	u16 syndrome;
>  	u32 page;
>  	u32 offset;
> +	struct atl_dram_addr *dram_addr;

If you embed it into the enclosing struct:

	struct atl_dram_addr dram_addr;

you'll save yourself a bunch of lines in this patch of noodling through the
error struct.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v7 2/3] RAS/AMD/ATL: Translate UMC normalized address to DRAM address using PRM
  2026-07-07  0:32   ` Borislav Petkov
@ 2026-07-07 13:57     ` Yazen Ghannam
  2026-07-08  1:58       ` Borislav Petkov
  0 siblings, 1 reply; 10+ messages in thread
From: Yazen Ghannam @ 2026-07-07 13:57 UTC (permalink / raw)
  To: Borislav Petkov; +Cc: linux-edac, linux-kernel, Avadhut Naik

On Mon, Jul 06, 2026 at 05:32:04PM -0700, Borislav Petkov wrote:
> On Tue, Jun 30, 2026 at 05:06:39PM -0400, Yazen Ghannam wrote:
> > From: Avadhut Naik <avadhut.naik@amd.com>
> > 
> > Modern AMD SOCs provide UEFI PRM module that implements various address
> > translation PRM handlers.[1] These handlers can be invoked by the OS or
> > hypervisor at runtime to perform address translations.
> > 
> > On AMD's Zen-based SOCs, Unified Memory Controller (UMC) relative
> > "normalized" address is reported through MCA_ADDR of UMC SMCA bank type
> > on occurrence of a DRAM ECC error. This address must be converted into
> > system physical address and DRAM address to export additional information
> > about the error.
> > 
> > Add support to convert normalized address into DRAM address through the
> > appropriate PRM handler. Instead of logging the translated DRAM address
> > locally, export the translating function when the Address Translation
> > library is initialized. Modules like amd64_edac can then invoke the PRM
> > handler to add the DRAM address to their error records. Additionally, it
> > can also be exported through the RAS tracepont.
> 
> Use this commit message for this patch:
> 
>     Modern AMD SOCs provide an UEFI PRM module that implements various address
>     translation PRM handlers¹. These handlers can be invoked by the OS or
>     the hypervisor at runtime to perform address translations.
>     
>     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 must be converted into
>     a system physical address and DRAM address in order to decode additional
>     information about the error.
>     
>     Add support to convert a normalized address into a DRAM address using
>     such PRM handler.
>     
>     ¹https://bugzilla.kernel.org/show_bug.cgi?id=220577
> 
> or run it through AI because I'm tired of adding pronouns left and right and
> removing text which regurgitates the code in the patch.
> 

Okay.

> > [1] https://bugzilla.kernel.org/show_bug.cgi?id=220577
> > 
> > [Yazen: Remove 'handler available' check]
> > 
> > Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
> > Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
> > ---
> >  drivers/ras/amd/atl/core.c     |  6 ++++++
> >  drivers/ras/amd/atl/internal.h | 11 ++++++++++-
> >  drivers/ras/amd/atl/prm.c      | 32 ++++++++++++++++++++++++++++----
> >  drivers/ras/amd/atl/system.c   |  3 +++
> >  drivers/ras/amd/atl/umc.c      |  9 +++++++++
> >  include/linux/ras.h            | 14 ++++++++++++++
> >  6 files changed, 70 insertions(+), 5 deletions(-)
> 
> ...
> 
> > +static inline int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id,
> > +					    unsigned long addr, struct atl_dram_addr *dram_addr)
> 
> ... int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id, unsigned long addr,
> 				  struct atl_dram_addr *dram_addr)
> 
> > +{
> > +	return -ENODEV;
> > +}
> > +#endif
> >  /*
> >   * Make a gap in @data that is @num_bits long starting at @bit_num.
> >   * e.g. data		= 11111111'b
> > diff --git a/drivers/ras/amd/atl/prm.c b/drivers/ras/amd/atl/prm.c
> > index 0f9bfa96e16a..c69158f66639 100644
> > --- a/drivers/ras/amd/atl/prm.c
> > +++ b/drivers/ras/amd/atl/prm.c
> > @@ -19,10 +19,11 @@
> >  #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.
> > + * PRM parameter buffer - normalized to system physical address and normalized
> > + * to DRAM address, as described in the "PRM Parameter Buffer" section of the
> > + * AMD ACPI Porting Guide.
> >   */
> > -struct norm_to_sys_param_buf {
> > +struct prm_parameter_buffer {
> 
> struct param_buf {
> 
> This is not BIOS code.
> 

Okay.

> >  	u64 norm_addr;
> >  	u8 socket;
> >  	u64 bank_id;
> > @@ -31,7 +32,7 @@ struct norm_to_sys_param_buf {
> >  
> >  unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
> >  {
> > -	struct norm_to_sys_param_buf p_buf;
> > +	struct prm_parameter_buffer p_buf;
> >  	unsigned long ret_addr;
> >  	int ret;
> >  
> > @@ -51,3 +52,26 @@ unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long
> >  
> >  	return ret;
> >  }
> > +
> > +int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id,
> > +			      unsigned long addr, struct atl_dram_addr *dram_addr)
> 
> int prm_umc_norm_to_dram_addr(u8 socket_id, u64 bank_id, unsigned long addr,
> 			      struct atl_dram_addr *dram_addr)
> 
> > +{
> > +	struct prm_parameter_buffer p_buf;
> > +	int ret;
> > +
> > +	p_buf.norm_addr	= addr;
> > +	p_buf.socket	= socket_id;
> > +	p_buf.bank_id	= bank_id;
> > +	p_buf.out_buf	= dram_addr;
> > +
> > +	ret = acpi_call_prm_handler(norm_to_dram_guid, &p_buf);
> > +	if (!ret)
> > +		return ret;
> > +
> > +	if (ret == -ENODEV)
> > +		pr_debug("PRM module/handler not available.\n");
> > +	else
> > +		pr_notice_once("PRM DRAM Address Translation failed.\n");
> 
> Dump ret here.

What do you mean? Print it or remove it?

> 
> Also, this function is an almost identical copy to prm_umc_norm_to_sys_addr().
> Merge the two pls.
> 

Okay, will do.

Thanks,
Yazen

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v7 3/3] EDAC/amd64: Include DRAM address in output
  2026-07-07  0:37   ` Borislav Petkov
@ 2026-07-07 14:02     ` Yazen Ghannam
  2026-07-08  2:00       ` Borislav Petkov
  0 siblings, 1 reply; 10+ messages in thread
From: Yazen Ghannam @ 2026-07-07 14:02 UTC (permalink / raw)
  To: Borislav Petkov; +Cc: linux-edac, linux-kernel, Avadhut Naik

On Mon, Jul 06, 2026 at 05:37:35PM -0700, Borislav Petkov wrote:
> On Tue, Jun 30, 2026 at 05:06:40PM -0400, Yazen Ghannam wrote:
> > From: Avadhut Naik <avadhut.naik@amd.com>
> > 
> > The DRAM address of an error is used by tooling to find failure
> > patterns. This information can be used for general analysis off system.
> > And it can be used on system to take action like offline a page affected
> > by a bad row.
> > 
> > Other EDAC modules (GHES and SKX) provide this information in their
> > output. The AMD64 EDAC module was not able to provide this information,
> > because system-specific translation is needed.
> > 
> > Recent AMD systems provide a PRM handler for DRAM address translation.
> > 
> > Use this PRM handler to get the DRAM address of an error. Include this
> > in the EDAC "other_detail" field.
> > 
> > Also include the Socket and IPID in the EDAC "other_detail" field. These
> > are needed by tooling to translate a DRAM address to a System Physical
> > Address.
> 
>     "Use the DRAM address translated by the PRM handler on AMD systems when
>     reporting an error and add it to the error information that is being
>     logged by EDAC. Also include the Socket and IPID which tooling needs to
>     translate the DRAM address into a SPA (System Physical Address)."
> 
> Plain and simple.
> 

Okay.

> > 
> > [Yazen: Reformat other_detail string]
> > 
> > Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
> > Co-developed-by: Yazen Ghannam <yazen.ghannam@amd.com>
> > Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
> > ---
> >  drivers/edac/amd64_edac.c | 32 +++++++++++++++++++++++++++++++-
> >  drivers/edac/amd64_edac.h |  3 +++
> >  2 files changed, 34 insertions(+), 1 deletion(-)
> 
> ...
> 
> > @@ -2853,6 +2880,9 @@ static void decode_umc_error(int node_id, struct mce *m)
> >  		goto log_error;
> >  	}
> >  
> > +	if (!amd_convert_umc_addr_to_dram_addr(&a_err, &dram_addr))
> > +		err.dram_addr = &dram_addr;
> 
> I really hate the fact that we have to call PRM twice per error. Is there
> a PRM that can give us both addresses in one go?
> 

There is a one handler per operation. But we can wrap them however we
want. I'll add an AMD_ATL helper to do both translations in one call.

> >  	error_address_to_page_and_offset(sys_addr, &err);
> >  
> >  log_error:
> > diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
> > index 1757c1b99fc8..39c1b6471909 100644
> > --- a/drivers/edac/amd64_edac.h
> > +++ b/drivers/edac/amd64_edac.h
> > @@ -400,6 +400,9 @@ struct err_info {
> >  	u16 syndrome;
> >  	u32 page;
> >  	u32 offset;
> > +	struct atl_dram_addr *dram_addr;
> 
> If you embed it into the enclosing struct:
> 
> 	struct atl_dram_addr dram_addr;
> 
> you'll save yourself a bunch of lines in this patch of noodling through the
> error struct.
> 

Okay.

Thanks,
Yazen

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v7 2/3] RAS/AMD/ATL: Translate UMC normalized address to DRAM address using PRM
  2026-07-07 13:57     ` Yazen Ghannam
@ 2026-07-08  1:58       ` Borislav Petkov
  0 siblings, 0 replies; 10+ messages in thread
From: Borislav Petkov @ 2026-07-08  1:58 UTC (permalink / raw)
  To: Yazen Ghannam; +Cc: linux-edac, linux-kernel, Avadhut Naik

On Tue, Jul 07, 2026 at 09:57:56AM -0400, Yazen Ghannam wrote:
> What do you mean? Print it or remove it?

Print it so that the error message is more informative than now.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v7 3/3] EDAC/amd64: Include DRAM address in output
  2026-07-07 14:02     ` Yazen Ghannam
@ 2026-07-08  2:00       ` Borislav Petkov
  0 siblings, 0 replies; 10+ messages in thread
From: Borislav Petkov @ 2026-07-08  2:00 UTC (permalink / raw)
  To: Yazen Ghannam; +Cc: linux-edac, linux-kernel, Avadhut Naik

On Tue, Jul 07, 2026 at 10:02:08AM -0400, Yazen Ghannam wrote:
> There is a one handler per operation. But we can wrap them however we
> want. I'll add an AMD_ATL helper to do both translations in one call.

Yeah, sounds better.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-07-08  2:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-30 21:06 [PATCH v7 0/3] Incorporate DRAM address in EDAC messages Yazen Ghannam
2026-06-30 21:06 ` [PATCH v7 1/3] RAS/AMD/ATL: Directly export address translation helper Yazen Ghannam
2026-06-30 21:06 ` [PATCH v7 2/3] RAS/AMD/ATL: Translate UMC normalized address to DRAM address using PRM Yazen Ghannam
2026-07-07  0:32   ` Borislav Petkov
2026-07-07 13:57     ` Yazen Ghannam
2026-07-08  1:58       ` Borislav Petkov
2026-06-30 21:06 ` [PATCH v7 3/3] EDAC/amd64: Include DRAM address in output Yazen Ghannam
2026-07-07  0:37   ` Borislav Petkov
2026-07-07 14:02     ` Yazen Ghannam
2026-07-08  2:00       ` Borislav Petkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox