RAS changes for v4.9
Linus,
Please pull the latest ras-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git ras-core-for-linus
# HEAD: b199ac6c4943aa0db246163bf6b483e2bb53431b x86/RAS/mce_amd_inj: Remove debugfs dir recursively on exit
The main changes were:
- Lots of enhancements for AMD SMCA (Scalable MCA features/extensions) systems:
extract, decode and print more hardware error information and add matching support on the injection/testing side as well. (Yazn Ghannam)
- Various MCE handling improvements on modern Intel Xeons. (Tony Luck)
- Plus misc fixes and enhancements.
Thanks,
Ingo
------------------>
Borislav Petkov (2):
x86/RAS/mce_amd_inj: Fix some W= warnings x86/RAS/mce_amd_inj: Remove debugfs dir recursively on exit
Colin Ian King (1):
x86/RAS/mce_amd_inj: Fix signed wrap around when decrementing index 'i'
Tony Luck (4):
locking/static_keys: Provide DECLARE and well as DEFINE macros x86/mce: Add PCI quirks to identify Xeons with machine check recovery x86/mce: Improve memcpy_mcsafe()
x86/mce: Drop X86_FEATURE_MCE_RECOVERY and the related model string test
Yazen Ghannam (14):
x86/mce/AMD: Use msr_ops.misc() in allocate_threshold_blocks() x86/mce: Add support for new MCA_SYND register
EDAC/mce_amd: Print syndrome register value on SMCA systems x86/RAS: Add syndrome support to mce_amd_inj
x86/mce/AMD: Read MSRs on the CPU allocating the threshold blocks EDAC/mce_amd: Add missing SMCA error descriptions
EDAC/mce_amd: Use SMCA prefix for error descriptions arrays x86/mce/AMD, EDAC/mce_amd: Define and use tables for known SMCA IP types x86/mce/AMD: Update sysfs bank names for SMCA systems
x86/mce/AMD: Ensure the deferred error interrupt is of type APIC on SMCA systems x86/mce/AMD: Save MCA_IPID in MCE struct on SMCA systems
x86/mce, EDAC/mce_amd: Print MCA_SYND and MCA_IPID during MCE on SMCA systems x86/mce/AMD: Extract the error address on SMCA systems x86/MCE/AMD, EDAC: Handle reserved bank 4 on Fam17h properly
arch/x86/include/asm/cpufeatures.h | 1 - arch/x86/include/asm/mce.h | 66 +++++----- arch/x86/include/asm/pmem.h | 5 +- arch/x86/include/asm/string_64.h | 19 ++- arch/x86/include/uapi/asm/mce.h | 2 + arch/x86/kernel/cpu/mcheck/mce.c | 44 +++++-- arch/x86/kernel/cpu/mcheck/mce_amd.c | 204 +++++++++++++++++++++++------ arch/x86/kernel/quirks.c | 31 +++++ arch/x86/kernel/x8664_ksyms_64.c | 2 +- arch/x86/lib/memcpy_64.S | 6 +- arch/x86/ras/mce_amd_inj.c | 54 ++++---- drivers/edac/mce_amd.c | 244 ++++++++++------------------------- include/linux/jump_label.h | 6 + include/trace/events/mce.h | 9 +- 14 files changed, 407 insertions(+), 286 deletions(-)
arch/x86/include/asm/cpufeatures.h +0 -1
@@ -106,7 +106,6 @@#define X86_FEATURE_APERFMPERF ( 3*32+28)/* APERFMPERF */ #define X86_FEATURE_EAGER_FPU ( 3*32+29)/* "eagerfpu" Non lazy FPU restore */ #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30)/* TSC doesn't stop in S3 state */ -#define X86_FEATURE_MCE_RECOVERY ( 3*32+31)/* cpu has recoverable machine checks */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 ( 4*32+ 0)/* "pni" SSE-3 */
arch/x86/include/asm/mce.h +36 -30
101 lines not on this page · raw message
arch/x86/include/asm/pmem.h +1 -4
@@ -46,10 +46,7 @@ static inline void arch_memcpy_to_pmem(void *dst, const void *src, size_t n)static inline int arch_memcpy_from_pmem (void *dst,const void *src,size_t n) { -if (static_cpu_has (X86_FEATURE_MCE_RECOVERY )) -return memcpy_mcsafe (dst, src, n); -memcpy (dst, src, n); -return 0 ; +return memcpy_mcsafe (dst, src, n); }/**
arch/x86/include/asm/string_64.h +18 -1
@@ -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,9 @@ int strcmp(const char *cs, const char *ct);#define memset (s, c, n) __memset(s, c, n)#endif +__must_check int memcpy_mcsafe_unrolled (void *dst,const void *src,size_t cnt); +DECLARE_STATIC_KEY_FALSE (mcsafe_key); +/** * memcpy_mcsafe - copy memory with indication if a machine check happened *
@@ -86,10 +90,23 @@ int strcmp(const char *cs, const char *ct);* @cnt: number of bytes to copy * * Low level memory copy function that catches machine checks +* We only call into the "safe" function on systems that can +* actually do machine check recovery. Everyone else can just +* use memcpy(). * * Return 0 for success, -EFAULT for fail */ -int memcpy_mcsafe (void *dst,const void *src,size_t cnt); +static __always_inline __must_check int +memcpy_mcsafe (void *dst,const void *src,size_t cnt) +{ +#ifdef CONFIG_X86_MCE +if (static_branch_unlikely (&mcsafe_key)) +return memcpy_mcsafe_unrolled (dst, src, cnt); + else +#endif +memcpy (dst, src, cnt); +return 0 ; +}#endif /* __KERNEL__ */
arch/x86/include/uapi/asm/mce.h +2 -0
@@ -26,6 +26,8 @@ struct mce {__u32 socketid;/* CPU socket ID */ __u32 apicid;/* CPU initial apic ID */ __u64 mcgcap;/* MCGCAP MSR: machine check capabilities of CPU */ +__u64 synd;/* MCA_SYND MSR: only valid on SMCA systems */ +__u64 ipid;/* MCA_IPID MSR: only valid on SMCA systems */ };#define MCE_GET_RECORD_LEN _IOR('M', 1, int)
arch/x86/kernel/cpu/mcheck/mce.c +33 -11
88 lines not on this page · raw message
arch/x86/kernel/cpu/mcheck/mce_amd.c +167 -37
306 lines not on this page · raw message
arch/x86/kernel/quirks.c +31 -0
@@ -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
arch/x86/kernel/x8664_ksyms_64.c +1 -1
@@ -38,7 +38,7 @@ EXPORT_SYMBOL(__copy_user_nocache);EXPORT_SYMBOL (_copy_from_user);EXPORT_SYMBOL (_copy_to_user); -EXPORT_SYMBOL_GPL (memcpy_mcsafe); +EXPORT_SYMBOL_GPL (memcpy_mcsafe_unrolled);EXPORT_SYMBOL (copy_page);EXPORT_SYMBOL (clear_page);
arch/x86/lib/memcpy_64.S +3 -3
@@ -181,11 +181,11 @@ ENDPROC(memcpy_orig) #ifndef CONFIG_UML /* - * memcpy_mcsafe - memory copy with machine check exception handling + * memcpy_mcsafe_unrolled - memory copy with machine check exception handling * Note that we only catch machine checks when reading the source addresses. * Writes to target are posted and don't generate machine checks. */ -ENTRY(memcpy_mcsafe) +ENTRY(memcpy_mcsafe_unrolled) cmpl $8, %edx /* Less than 8 bytes? Go to byte copy loop */ jb .L_no_whole_words
@@ -273,7 +273,7 @@ ENTRY(memcpy_mcsafe) .L_done_memcpy_trap: xorq %rax, %rax ret -ENDPROC(memcpy_mcsafe) +ENDPROC(memcpy_mcsafe_unrolled) .section .fixup, "ax" /* Return -EFAULT for any failure */
arch/x86/ras/mce_amd_inj.c +31 -23
132 lines not on this page · raw message
drivers/edac/mce_amd.c +71 -173
366 lines not on this page · raw message
include/linux/jump_label.h +6 -0
@@ -267,9 +267,15 @@ struct static_key_false {#define DEFINE_STATIC_KEY_TRUE (name) \ struct static_key_true name = STATIC_KEY_TRUE_INIT +#define DECLARE_STATIC_KEY_TRUE (name) \ + extern struct static_key_true name +#define DEFINE_STATIC_KEY_FALSE (name) \ struct static_key_false name = STATIC_KEY_FALSE_INIT +#define DECLARE_STATIC_KEY_FALSE (name) \ + extern struct static_key_false name +extern bool ____wrong_branch_error (void );#define static_key_enabled (x) \
include/trace/events/mce.h +7 -2
@@ -20,6 +20,8 @@ TRACE_EVENT(mce_record, __field( u64, status ) __field( u64, addr ) __field( u64, misc ) + __field( u64, synd ) + __field( u64, ipid ) __field( u64, ip ) __field( u64, tsc )__field ( u64, walltime )
@@ -38,6 +40,8 @@ TRACE_EVENT(mce_record, __entry->status = m->status; __entry->addr = m->addr; __entry->misc = m->misc; + __entry->synd = m->synd; + __entry->ipid = m->ipid; __entry->ip = m->ip; __entry->tsc = m->tsc; __entry->walltime = m->time;
@@ -50,11 +54,12 @@ TRACE_EVENT(mce_record, __entry->cpuvendor = m->cpuvendor; ), - TP_printk("CPU: %d, MCGc/s: %llx/%llx, MC%d: %016Lx, ADDR/MISC: %016Lx/%016Lx, RIP: %02x:<%016Lx>, TSC: %llx, PROCESSOR: %u:%x, TIME: %llu, SOCKET: %u, APIC: %x", + TP_printk("CPU: %d, MCGc/s: %llx/%llx, MC%d: %016Lx, IPID: %016Lx, ADDR/MISC/SYND: %016Lx/%016Lx/%016Lx, RIP: %02x:<%016Lx>, TSC: %llx, PROCESSOR: %u:%x, TIME: %llu, SOCKET: %u, APIC: %x", __entry->cpu, __entry->mcgcap, __entry->mcgstatus, __entry->bank, __entry->status, - __entry->addr, __entry->misc, + __entry->ipid, + __entry->addr, __entry->misc, __entry->synd, __entry->cs, __entry->ip, __entry->tsc, __entry->cpuvendor, __entry->cpuid,