@@ -2832,7 +2832,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 = convert_ras_la_to_spa(&a_err);
if (IS_ERR_VALUE(sys_addr)) {
err.err_code = ERR_NORM_ADDR;
goto log_error;
@@ -228,16 +228,16 @@ static void aest_node_pool_process(struct work_struct *work)
llist_for_each_entry(event, head, llnode) {
aest_print(event);
- /* TODO: translate Logical Addresses to System Physical Addresses */
+ addr = event->regs.err_addr & (1UL << CONFIG_ARM64_PA_BITS);
+
if (event->addressing_mode == AEST_ADDREESS_LA ||
- (event->regs.err_addr & ERR_ADDR_AI)) {
- pr_notice("Can not translate LA to SPA\n");
- addr = 0;
- } else
+ (event->regs.err_addr & ERR_ADDR_AI))
+ addr = convert_ras_la_to_spa(event);
+ else
addr = event->regs.err_addr & (1UL << CONFIG_ARM64_PA_BITS);
status = event->regs.err_status;
- if (addr && ((status & ERR_STATUS_UE) || (status & ERR_STATUS_DE)))
+ if (addr > 0 && ((status & ERR_STATUS_UE) || (status & ERR_STATUS_DE)))
aest_handle_memory_failure(addr);
blocking_notifier_call_chain(&aest_decoder_chain, 0, event);
@@ -207,7 +207,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);
+ atl_register_decoder(convert_umc_mca_addr_to_sys_addr);
pr_info("AMD Address Translation Library initialized\n");
return 0;
@@ -219,7 +219,7 @@ static int __init amd_atl_init(void)
*/
static void __exit amd_atl_exit(void)
{
- amd_atl_unregister_decoder();
+ atl_unregister_decoder();
}
module_init(amd_atl_init);
@@ -277,7 +277,7 @@ 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);
+unsigned long convert_umc_mca_addr_to_sys_addr(void *data);
u64 add_base_and_hole(struct addr_ctx *ctx, u64 addr);
u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr);
@@ -395,8 +395,9 @@ 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)
+unsigned long convert_umc_mca_addr_to_sys_addr(void *data)
{
+ struct atl_err *err = data;
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);
@@ -10,36 +10,34 @@
#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);
+static unsigned long (*atl_ras_la_to_spa)(void *err);
-void amd_atl_register_decoder(unsigned long (*f)(struct atl_err *))
+void atl_register_decoder(unsigned long (*f)(void *))
{
- amd_atl_umc_na_to_spa = f;
+ atl_ras_la_to_spa = f;
}
-EXPORT_SYMBOL_GPL(amd_atl_register_decoder);
+EXPORT_SYMBOL_GPL(atl_register_decoder);
-void amd_atl_unregister_decoder(void)
+void atl_unregister_decoder(void)
{
- amd_atl_umc_na_to_spa = NULL;
+ atl_ras_la_to_spa = NULL;
}
-EXPORT_SYMBOL_GPL(amd_atl_unregister_decoder);
+EXPORT_SYMBOL_GPL(atl_unregister_decoder);
-unsigned long amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
+unsigned long convert_ras_la_to_spa(void *err)
{
- if (!amd_atl_umc_na_to_spa)
+ if (!atl_ras_la_to_spa)
return -EINVAL;
- return amd_atl_umc_na_to_spa(err);
+ return atl_ras_la_to_spa(err);
}
-EXPORT_SYMBOL_GPL(amd_convert_umc_mca_addr_to_sys_addr);
-#endif /* CONFIG_AMD_ATL */
+EXPORT_SYMBOL_GPL(convert_ras_la_to_spa);
#define CREATE_TRACE_POINTS
#define TRACE_INCLUDE_PATH ../../include/ras
@@ -43,16 +43,15 @@ 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);
#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; }
#endif /* CONFIG_AMD_ATL */
+void atl_register_decoder(unsigned long (*f)(void *));
+void atl_unregister_decoder(void);
+unsigned long convert_ras_la_to_spa(void *err);
+
#if IS_ENABLED(CONFIG_AEST)
void aest_register_decode_chain(struct notifier_block *nb);
void aest_unregister_decode_chain(struct notifier_block *nb);
Translate device normalize address in AMD, also named logical address, to system physical address is a common interface in RAS. Provides common interface both for AMD and ARM. Signed-off-by: Ruidong Tian <tianruidong@linux.alibaba.com> --- drivers/edac/amd64_edac.c | 2 +- drivers/ras/aest/aest-core.c | 12 ++++++------ drivers/ras/amd/atl/core.c | 4 ++-- drivers/ras/amd/atl/internal.h | 2 +- drivers/ras/amd/atl/umc.c | 3 ++- drivers/ras/ras.c | 24 +++++++++++------------- include/linux/ras.h | 9 ++++----- 7 files changed, 27 insertions(+), 29 deletions(-)