| From 3637efb00864f465baebd49464e58319fd295b65 Mon Sep 17 00:00:00 2001 |
| From: Tony Luck <tony.luck@intel.com> |
| Date: Thu, 1 Sep 2016 11:39:33 -0700 |
| Subject: [PATCH] x86/mce: Add PCI quirks to identify Xeons with machine check |
| recovery |
| |
| commit 3637efb00864f465baebd49464e58319fd295b65 upstream. |
| |
| Each Xeon includes a number of capability registers in PCI space that |
| describe some features not enumerated by CPUID. |
| |
| Use these to determine that we are running on a model that can recover from |
| machine checks. Hooks for Ivybridge ... Skylake provided. |
| |
| Signed-off-by: Tony Luck <tony.luck@intel.com> |
| Acked-by: Borislav Petkov <bp@suse.de> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Dan Williams <dan.j.williams@intel.com> |
| Cc: Boris Petkov <bp@suse.de> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org> |
| Link: http://lkml.kernel.org/r/abf331dc4a3e2a2d17444129bc51127437bcf4ba.1472754711.git.tony.luck@intel.com |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| |
| diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h |
| index 90dbbd9666d4..877a1dfbf770 100644 |
| --- a/arch/x86/include/asm/string_64.h |
| +++ b/arch/x86/include/asm/string_64.h |
| @@ -2,6 +2,7 @@ |
| #define _ASM_X86_STRING_64_H |
| |
| #ifdef __KERNEL__ |
| +#include <linux/jump_label.h> |
| |
| /* Written 2002 by Andi Kleen */ |
| |
| @@ -78,6 +79,8 @@ int strcmp(const char *cs, const char *ct); |
| #define memset(s, c, n) __memset(s, c, n) |
| #endif |
| |
| +DECLARE_STATIC_KEY_FALSE(mcsafe_key); |
| + |
| /** |
| * memcpy_mcsafe - copy memory with indication if a machine check happened |
| * |
| diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c |
| index 79d8ec849468..acccebcc836d 100644 |
| --- a/arch/x86/kernel/cpu/mcheck/mce.c |
| +++ b/arch/x86/kernel/cpu/mcheck/mce.c |
| @@ -41,6 +41,7 @@ |
| #include <linux/debugfs.h> |
| #include <linux/irq_work.h> |
| #include <linux/export.h> |
| +#include <linux/jump_label.h> |
| |
| #include <asm/processor.h> |
| #include <asm/traps.h> |
| @@ -2080,6 +2081,7 @@ void mce_disable_bank(int bank) |
| * mce=bootlog Log MCEs from before booting. Disabled by default on AMD. |
| * mce=nobootlog Don't log MCEs from before booting. |
| * mce=bios_cmci_threshold Don't program the CMCI threshold |
| + * mce=recovery force enable memcpy_mcsafe() |
| */ |
| static int __init mcheck_enable(char *str) |
| { |
| @@ -2676,8 +2678,14 @@ static int __init mcheck_debugfs_init(void) |
| static int __init mcheck_debugfs_init(void) { return -EINVAL; } |
| #endif |
| |
| +DEFINE_STATIC_KEY_FALSE(mcsafe_key); |
| +EXPORT_SYMBOL_GPL(mcsafe_key); |
| + |
| static int __init mcheck_late_init(void) |
| { |
| + if (mca_cfg.recovery) |
| + static_branch_inc(&mcsafe_key); |
| + |
| mcheck_debugfs_init(); |
| |
| /* |
| diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c |
| index cc457ff818ad..51402a7e4ca6 100644 |
| --- a/arch/x86/kernel/quirks.c |
| +++ b/arch/x86/kernel/quirks.c |
| @@ -626,3 +626,34 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3, |
| amd_disable_seq_and_redirect_scrub); |
| |
| #endif |
| + |
| +#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE) |
| +#include <linux/jump_label.h> |
| +#include <asm/string_64.h> |
| + |
| +/* Ivy Bridge, Haswell, Broadwell */ |
| +static void quirk_intel_brickland_xeon_ras_cap(struct pci_dev *pdev) |
| +{ |
| + u32 capid0; |
| + |
| + pci_read_config_dword(pdev, 0x84, &capid0); |
| + |
| + if (capid0 & 0x10) |
| + static_branch_inc(&mcsafe_key); |
| +} |
| + |
| +/* Skylake */ |
| +static void quirk_intel_purley_xeon_ras_cap(struct pci_dev *pdev) |
| +{ |
| + u32 capid0; |
| + |
| + pci_read_config_dword(pdev, 0x84, &capid0); |
| + |
| + if ((capid0 & 0xc0) == 0xc0) |
| + static_branch_inc(&mcsafe_key); |
| +} |
| +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0ec3, quirk_intel_brickland_xeon_ras_cap); |
| +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2fc0, quirk_intel_brickland_xeon_ras_cap); |
| +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, quirk_intel_brickland_xeon_ras_cap); |
| +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2083, quirk_intel_purley_xeon_ras_cap); |
| +#endif |
| -- |
| 2.15.0 |
| |