Skip to content

Commit

Permalink
x86/mce/amd: Use AMD ATL
Browse files Browse the repository at this point in the history
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
  • Loading branch information
yghannam committed Apr 4, 2024
1 parent 76732c6 commit 6ddd8e9
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
1 change: 1 addition & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,7 @@ config X86_MCE_AMD
def_bool y
prompt "AMD MCE features"
depends on X86_MCE && X86_LOCAL_APIC && AMD_NB
imply AMD_ATL
help
Additional support for AMD specific MCE features such as
the DRAM Error Threshold.
Expand Down
34 changes: 32 additions & 2 deletions arch/x86/kernel/cpu/mce/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/cpu.h>
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/ras.h>

#include <asm/amd_nb.h>
#include <asm/traps.h>
Expand Down Expand Up @@ -877,8 +878,10 @@ bool amd_mce_is_memory_error(struct mce *m)
* a) Reported in legacy bank 4 with extended error code (XEC) 8.
* b) MCA_STATUS[43] is *not* defined as poison in legacy bank 4. Therefore,
* this bit should not be checked.
*
* NOTE: SMCA UMC memory errors fall into case #1.
* 4) SMCA UMC DRAM ECC errors
* a) Reported in UMC-type banks with extended error code (XEC) 0.
* b) MCA_ADDR must be translated to a usable value.
* c) Return 'true' if translation services are available.
*/
bool amd_mce_usable_address(struct mce *m)
{
Expand All @@ -894,10 +897,37 @@ bool amd_mce_usable_address(struct mce *m)
if (m->status & MCI_STATUS_POISON)
return true;

if (smca_mce_is_memory_error(m) && IS_REACHABLE(CONFIG_AMD_ATL))
return true;

/* Assume address is not usable for all others. */
return false;
}

void amd_mce_get_phys_addr(struct mce_hw_err *err)
{
unsigned long addr = err->m.addr;
struct atl_err a_err;

if (!amd_mce_usable_address(&err->m))
return;

if (!smca_mce_is_memory_error(&err->m))
goto out;

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

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

addr = amd_convert_umc_mca_addr_to_sys_addr(&a_err);
if (IS_ERR_VALUE(addr))
return;
out:
err->phys_addr = addr & MCI_ADDR_PHYSADDR;
}

DEFINE_IDTENTRY_SYSVEC(sysvec_deferred_error)
{
trace_deferred_error_apic_entry(DEFERRED_ERROR_VECTOR);
Expand Down
3 changes: 3 additions & 0 deletions arch/x86/kernel/cpu/mce/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,9 @@ static void mce_get_phys_addr(struct mce_hw_err *err)
if (!mce_usable_address(&err->m))
return;

if (err->m.cpuvendor == X86_VENDOR_AMD)
return amd_mce_get_phys_addr(err);

err->phys_addr = err->m.addr & MCI_ADDR_PHYSADDR;
}

Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/cpu/mce/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ void mce_setup_for_cpu(unsigned int cpu, struct mce *m);
extern bool amd_filter_mce(struct mce *m);
bool amd_mce_usable_address(struct mce *m);
void amd_handle_error(struct mce_hw_err *err);
void amd_mce_get_phys_addr(struct mce_hw_err *err);

/*
* If MCA_CONFIG[McaLsbInStatusSupported] is set, extract ErrAddr in bits
Expand Down Expand Up @@ -289,6 +290,7 @@ static __always_inline void smca_extract_err_addr(struct mce_hw_err *err)
static inline bool amd_filter_mce(struct mce *m) { return false; }
static inline bool amd_mce_usable_address(struct mce *m) { return false; }
static inline void amd_handle_error(struct mce_hw_err *err) { }
static inline void amd_mce_get_phys_addr(struct mce_hw_err *err) { }
static inline void smca_extract_err_addr(struct mce *m) { }
#endif

Expand Down

0 comments on commit 6ddd8e9

Please sign in to comment.