aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/ras/mce_amd_inj.c
diff options
context:
space:
mode:
authorAravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>2015-10-12 05:22:40 -0400
committerIngo Molnar <mingo@kernel.org>2015-10-12 10:15:48 -0400
commitfa20a2ed6fff717839ec03b6574ea0affcb58841 (patch)
treec1f69b1194ca74b819f6482a443bfc6d19e55c55 /arch/x86/ras/mce_amd_inj.c
parenta1300e50529795cd605da6a015d4944a18921db0 (diff)
x86/ras/mce_amd_inj: Inject bank 4 errors on the NBC
Bank 4 MCEs are logged and reported only on the node base core (NBC) in a socket. Refer to the D18F3x44[NbMcaToMstCpuEn] field in Fam10h and later BKDGs. The node base core (NBC) is the lowest numbered core in the node. This patch ensures that we inject the error on the NBC for bank 4 errors. Otherwise, triggering #MC or APIC interrupts on a core which is not the NBC would not have any effect on the system, i.e. we would not see any relevant output on kernel logs for the error we just injected. Signed-off-by: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com> [ Cleanup comments. ] [ Add a missing dependency on AMD_NB caught by Randy Dunlap. ] Signed-off-by: Borislav Petkov <bp@suse.de> Acked-by: Randy Dunlap <rdunlap@infradead.org> Cc: Borislav Petkov <bp@alien8.de> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tony Luck <tony.luck@intel.com> Link: http://lkml.kernel.org/r/1443190851-2172-4-git-send-email-Aravind.Gopalakrishnan@amd.com Link: http://lkml.kernel.org/r/1444641762-9437-5-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/ras/mce_amd_inj.c')
-rw-r--r--arch/x86/ras/mce_amd_inj.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/arch/x86/ras/mce_amd_inj.c b/arch/x86/ras/mce_amd_inj.c
index 4d3bafb540c2..55d38cfa46c2 100644
--- a/arch/x86/ras/mce_amd_inj.c
+++ b/arch/x86/ras/mce_amd_inj.c
@@ -17,8 +17,10 @@
17#include <linux/cpu.h> 17#include <linux/cpu.h>
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/uaccess.h> 19#include <linux/uaccess.h>
20#include <linux/pci.h>
20 21
21#include <asm/mce.h> 22#include <asm/mce.h>
23#include <asm/amd_nb.h>
22#include <asm/irq_vectors.h> 24#include <asm/irq_vectors.h>
23 25
24#include "../kernel/cpu/mcheck/mce-internal.h" 26#include "../kernel/cpu/mcheck/mce-internal.h"
@@ -32,6 +34,7 @@ static struct dentry *dfs_inj;
32static u8 n_banks; 34static u8 n_banks;
33 35
34#define MAX_FLAG_OPT_SIZE 3 36#define MAX_FLAG_OPT_SIZE 3
37#define NBCFG 0x44
35 38
36enum injection_type { 39enum injection_type {
37 SW_INJ = 0, /* SW injection, simply decode the error */ 40 SW_INJ = 0, /* SW injection, simply decode the error */
@@ -198,6 +201,45 @@ static void trigger_thr_int(void *info)
198 asm volatile("int %0" :: "i" (THRESHOLD_APIC_VECTOR)); 201 asm volatile("int %0" :: "i" (THRESHOLD_APIC_VECTOR));
199} 202}
200 203
204static u32 get_nbc_for_node(int node_id)
205{
206 struct cpuinfo_x86 *c = &boot_cpu_data;
207 u32 cores_per_node;
208
209 cores_per_node = c->x86_max_cores / amd_get_nodes_per_socket();
210
211 return cores_per_node * node_id;
212}
213
214static void toggle_nb_mca_mst_cpu(u16 nid)
215{
216 struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
217 u32 val;
218 int err;
219
220 if (!F3)
221 return;
222
223 err = pci_read_config_dword(F3, NBCFG, &val);
224 if (err) {
225 pr_err("%s: Error reading F%dx%03x.\n",
226 __func__, PCI_FUNC(F3->devfn), NBCFG);
227 return;
228 }
229
230 if (val & BIT(27))
231 return;
232
233 pr_err("%s: Set D18F3x44[NbMcaToMstCpuEn] which BIOS hasn't done.\n",
234 __func__);
235
236 val |= BIT(27);
237 err = pci_write_config_dword(F3, NBCFG, val);
238 if (err)
239 pr_err("%s: Error writing F%dx%03x.\n",
240 __func__, PCI_FUNC(F3->devfn), NBCFG);
241}
242
201static void do_inject(void) 243static void do_inject(void)
202{ 244{
203 u64 mcg_status = 0; 245 u64 mcg_status = 0;
@@ -228,6 +270,16 @@ static void do_inject(void)
228 i_mce.status |= (i_mce.status & ~MCI_STATUS_UC); 270 i_mce.status |= (i_mce.status & ~MCI_STATUS_UC);
229 } 271 }
230 272
273 /*
274 * For multi node CPUs, logging and reporting of bank 4 errors happens
275 * only on the node base core. Refer to D18F3x44[NbMcaToMstCpuEn] for
276 * Fam10h and later BKDGs.
277 */
278 if (static_cpu_has(X86_FEATURE_AMD_DCM) && b == 4) {
279 toggle_nb_mca_mst_cpu(amd_get_nb_id(cpu));
280 cpu = get_nbc_for_node(amd_get_nb_id(cpu));
281 }
282
231 get_online_cpus(); 283 get_online_cpus();
232 if (!cpu_online(cpu)) 284 if (!cpu_online(cpu))
233 goto err; 285 goto err;