Skip to contentSkip to conversation

RAS changes for v4.9

GIT PULL Ingo Molnar 1 participant 1 message Oct 3, 2016

Subsystems (6)
x86 PCI Tracing EDAC-core +2 more subsystems
lore
Share & tools
lore
#0 lore raw

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
index 92a8308b96f6..1188bc849ee3 100644
@@ -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
index 643eba42d620..2c1ebeb4d737 100644
@@ -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
index 90dbbd9666d4..a164862d77e3 100644
@@ -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
index 2184943341bf..69a6e07e3149 100644
@@ -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
index cc457ff818ad..51402a7e4ca6 100644
@@ -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
index 95e49f6e4fc3..b2cee3d19477 100644
@@ -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
index 2ec0b0abbfaa..49e6ebac7e73 100644
@@ -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
index 661af564fae8..595fb46213fc 100644
@@ -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
index 4cbbcef6baa8..70f02149808c 100644
@@ -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,