diff options
| author | Yazen Ghannam <Yazen.Ghannam@amd.com> | 2016-09-12 03:59:34 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-13 09:23:10 -0400 |
| commit | 5896820e0aa32572ad03b30563c539655b6c6375 (patch) | |
| tree | 5ba0adc4ecbf9cca585cb1eeb8c4c53a7b5bdc7a /arch/x86/kernel/cpu | |
| parent | 856095b1794be487527771dbd2fe28e34e94b266 (diff) | |
x86/mce/AMD, EDAC/mce_amd: Define and use tables for known SMCA IP types
Scalable MCA defines a number of IP types. An MCA bank on an SMCA
system is defined as one of these IP types. A bank's type is uniquely
identified by the combination of the HWID and MCATYPE values read from
its MCA_IPID register.
Add the required tables in order to be able to lookup error descriptions
based on a bank's type and the error's extended error code.
[ bp: Align comments, simplify a bit. ]
Signed-off-by: Yazen Ghannam <Yazen.Ghannam@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: http://lkml.kernel.org/r/1472741832-1690-1-git-send-email-Yazen.Ghannam@amd.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/cpu')
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd.c | 104 |
1 files changed, 79 insertions, 25 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 9da92fb2e073..3b74b62d0808 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
| @@ -63,34 +63,55 @@ static const char * const th_names[] = { | |||
| 63 | "execution_unit", | 63 | "execution_unit", |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | /* Define HWID to IP type mappings for Scalable MCA */ | 66 | struct smca_bank_name smca_bank_names[] = { |
| 67 | struct amd_hwid amd_hwids[] = { | 67 | [SMCA_LS] = { "load_store", "Load Store Unit" }, |
| 68 | [SMCA_F17H_CORE] = { "f17h_core", 0xB0 }, | 68 | [SMCA_IF] = { "insn_fetch", "Instruction Fetch Unit" }, |
| 69 | [SMCA_DF] = { "data_fabric", 0x2E }, | 69 | [SMCA_L2_CACHE] = { "l2_cache", "L2 Cache" }, |
| 70 | [SMCA_UMC] = { "umc", 0x96 }, | 70 | [SMCA_DE] = { "decode_unit", "Decode Unit" }, |
| 71 | [SMCA_PB] = { "param_block", 0x5 }, | 71 | [SMCA_EX] = { "execution_unit", "Execution Unit" }, |
| 72 | [SMCA_PSP] = { "psp", 0xFF }, | 72 | [SMCA_FP] = { "floating_point", "Floating Point Unit" }, |
| 73 | [SMCA_SMU] = { "smu", 0x1 }, | 73 | [SMCA_L3_CACHE] = { "l3_cache", "L3 Cache" }, |
| 74 | [SMCA_CS] = { "coherent_slave", "Coherent Slave" }, | ||
| 75 | [SMCA_PIE] = { "pie", "Power, Interrupts, etc." }, | ||
| 76 | [SMCA_UMC] = { "umc", "Unified Memory Controller" }, | ||
| 77 | [SMCA_PB] = { "param_block", "Parameter Block" }, | ||
| 78 | [SMCA_PSP] = { "psp", "Platform Security Processor" }, | ||
| 79 | [SMCA_SMU] = { "smu", "System Management Unit" }, | ||
| 74 | }; | 80 | }; |
| 75 | EXPORT_SYMBOL_GPL(amd_hwids); | 81 | EXPORT_SYMBOL_GPL(smca_bank_names); |
| 76 | 82 | ||
| 77 | const char * const amd_core_mcablock_names[] = { | 83 | static struct smca_hwid_mcatype smca_hwid_mcatypes[] = { |
| 78 | [SMCA_LS] = "load_store", | 84 | /* { bank_type, hwid_mcatype, xec_bitmap } */ |
| 79 | [SMCA_IF] = "insn_fetch", | 85 | |
| 80 | [SMCA_L2_CACHE] = "l2_cache", | 86 | /* ZN Core (HWID=0xB0) MCA types */ |
| 81 | [SMCA_DE] = "decode_unit", | 87 | { SMCA_LS, HWID_MCATYPE(0xB0, 0x0), 0x1FFFEF }, |
| 82 | [RES] = "", | 88 | { SMCA_IF, HWID_MCATYPE(0xB0, 0x1), 0x3FFF }, |
| 83 | [SMCA_EX] = "execution_unit", | 89 | { SMCA_L2_CACHE, HWID_MCATYPE(0xB0, 0x2), 0xF }, |
| 84 | [SMCA_FP] = "floating_point", | 90 | { SMCA_DE, HWID_MCATYPE(0xB0, 0x3), 0x1FF }, |
| 85 | [SMCA_L3_CACHE] = "l3_cache", | 91 | /* HWID 0xB0 MCATYPE 0x4 is Reserved */ |
| 86 | }; | 92 | { SMCA_EX, HWID_MCATYPE(0xB0, 0x5), 0x7FF }, |
| 87 | EXPORT_SYMBOL_GPL(amd_core_mcablock_names); | 93 | { SMCA_FP, HWID_MCATYPE(0xB0, 0x6), 0x7F }, |
| 94 | { SMCA_L3_CACHE, HWID_MCATYPE(0xB0, 0x7), 0xFF }, | ||
| 95 | |||
| 96 | /* Data Fabric MCA types */ | ||
| 97 | { SMCA_CS, HWID_MCATYPE(0x2E, 0x0), 0x1FF }, | ||
| 98 | { SMCA_PIE, HWID_MCATYPE(0x2E, 0x1), 0xF }, | ||
| 99 | |||
| 100 | /* Unified Memory Controller MCA type */ | ||
| 101 | { SMCA_UMC, HWID_MCATYPE(0x96, 0x0), 0x3F }, | ||
| 102 | |||
| 103 | /* Parameter Block MCA type */ | ||
| 104 | { SMCA_PB, HWID_MCATYPE(0x05, 0x0), 0x1 }, | ||
| 88 | 105 | ||
| 89 | const char * const amd_df_mcablock_names[] = { | 106 | /* Platform Security Processor MCA type */ |
| 90 | [SMCA_CS] = "coherent_slave", | 107 | { SMCA_PSP, HWID_MCATYPE(0xFF, 0x0), 0x1 }, |
| 91 | [SMCA_PIE] = "pie", | 108 | |
| 109 | /* System Management Unit MCA type */ | ||
| 110 | { SMCA_SMU, HWID_MCATYPE(0x01, 0x0), 0x1 }, | ||
| 92 | }; | 111 | }; |
| 93 | EXPORT_SYMBOL_GPL(amd_df_mcablock_names); | 112 | |
| 113 | struct smca_bank_info smca_banks[MAX_NR_BANKS]; | ||
| 114 | EXPORT_SYMBOL_GPL(smca_banks); | ||
| 94 | 115 | ||
| 95 | static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks); | 116 | static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks); |
| 96 | static DEFINE_PER_CPU(unsigned int, bank_map); /* see which banks are on */ | 117 | static DEFINE_PER_CPU(unsigned int, bank_map); /* see which banks are on */ |
| @@ -108,6 +129,36 @@ void (*deferred_error_int_vector)(void) = default_deferred_error_interrupt; | |||
| 108 | * CPU Initialization | 129 | * CPU Initialization |
| 109 | */ | 130 | */ |
| 110 | 131 | ||
| 132 | static void get_smca_bank_info(unsigned int bank) | ||
| 133 | { | ||
| 134 | unsigned int i, hwid_mcatype, cpu = smp_processor_id(); | ||
| 135 | struct smca_hwid_mcatype *type; | ||
| 136 | u32 high, instanceId; | ||
| 137 | u16 hwid, mcatype; | ||
| 138 | |||
| 139 | /* Collect bank_info using CPU 0 for now. */ | ||
| 140 | if (cpu) | ||
| 141 | return; | ||
| 142 | |||
| 143 | if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_IPID(bank), &instanceId, &high)) { | ||
| 144 | pr_warn("Failed to read MCA_IPID for bank %d\n", bank); | ||
| 145 | return; | ||
| 146 | } | ||
| 147 | |||
| 148 | hwid = high & MCI_IPID_HWID; | ||
| 149 | mcatype = (high & MCI_IPID_MCATYPE) >> 16; | ||
| 150 | hwid_mcatype = HWID_MCATYPE(hwid, mcatype); | ||
| 151 | |||
| 152 | for (i = 0; i < ARRAY_SIZE(smca_hwid_mcatypes); i++) { | ||
| 153 | type = &smca_hwid_mcatypes[i]; | ||
| 154 | if (hwid_mcatype == type->hwid_mcatype) { | ||
| 155 | smca_banks[bank].type = type; | ||
| 156 | smca_banks[bank].type_instance = instanceId; | ||
| 157 | break; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 111 | struct thresh_restart { | 162 | struct thresh_restart { |
| 112 | struct threshold_block *b; | 163 | struct threshold_block *b; |
| 113 | int reset; | 164 | int reset; |
| @@ -425,6 +476,9 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
| 425 | int offset = -1; | 476 | int offset = -1; |
| 426 | 477 | ||
| 427 | for (bank = 0; bank < mca_cfg.banks; ++bank) { | 478 | for (bank = 0; bank < mca_cfg.banks; ++bank) { |
| 479 | if (mce_flags.smca) | ||
| 480 | get_smca_bank_info(bank); | ||
| 481 | |||
| 428 | for (block = 0; block < NR_BLOCKS; ++block) { | 482 | for (block = 0; block < NR_BLOCKS; ++block) { |
| 429 | address = get_block_address(cpu, address, low, high, bank, block); | 483 | address = get_block_address(cpu, address, low, high, bank, block); |
| 430 | if (!address) | 484 | if (!address) |
