aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu
diff options
context:
space:
mode:
authorYazen Ghannam <Yazen.Ghannam@amd.com>2016-09-12 03:59:34 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-13 09:23:10 -0400
commit5896820e0aa32572ad03b30563c539655b6c6375 (patch)
tree5ba0adc4ecbf9cca585cb1eeb8c4c53a7b5bdc7a /arch/x86/kernel/cpu
parent856095b1794be487527771dbd2fe28e34e94b266 (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.c104
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 */ 66struct smca_bank_name smca_bank_names[] = {
67struct 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};
75EXPORT_SYMBOL_GPL(amd_hwids); 81EXPORT_SYMBOL_GPL(smca_bank_names);
76 82
77const char * const amd_core_mcablock_names[] = { 83static 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 },
87EXPORT_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
89const 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};
93EXPORT_SYMBOL_GPL(amd_df_mcablock_names); 112
113struct smca_bank_info smca_banks[MAX_NR_BANKS];
114EXPORT_SYMBOL_GPL(smca_banks);
94 115
95static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks); 116static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks);
96static DEFINE_PER_CPU(unsigned int, bank_map); /* see which banks are on */ 117static 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
132static 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
111struct thresh_restart { 162struct 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)