x86/ras: RAS queue
Subsystems (3)
Borislav Petkov
maintainercover x86/ras: RAS queue
From: Borislav Petkov <[email protected]>
Hi,
here's the last pile that got ready. It is mostly SMCA enablement for future AMD F17h CPUs so the remaining families shouldn't be affected. Initial testing on what I have here looks ok, randconfigs pass too.
All is ontop of tip:ras/core.
Thanks.
Borislav Petkov (1):
x86/mce/AMD: Save an indentation level in prepare_threshold_block()
Yazen Ghannam (6):
x86/mce/AMD: Log Deferred Errors using SMCA MCA_DE{STAT,ADDR}
registers
x86/mce/AMD: Disable LogDeferredInMcaStat for SMCA systems x86/cpu: Add detection of AMD RAS Capabilities x86/mce: Update AMD mcheck init to use cpu_has() facilities EDAC, mce_amd: Detect SMCA using X86_FEATURE_SMCA x86/RAS: Add SMCA support to AMD Error Injector
arch/x86/include/asm/cpufeature.h | 1 + arch/x86/include/asm/cpufeatures.h | 7 ++- arch/x86/include/asm/mce.h | 4 ++ arch/x86/kernel/cpu/common.c | 10 ++-- arch/x86/kernel/cpu/mcheck/mce.c | 8 ++-- arch/x86/kernel/cpu/mcheck/mce_amd.c | 92 ++++++++++++++++++++++++------------ arch/x86/ras/mce_amd_inj.c | 31 +++++++++--- drivers/edac/mce_amd.c | 9 ++-- 8 files changed, 112 insertions(+), 50 deletions(-)
Signature · 1 line
2.7.3
Borislav Petkov
maintainerPATCH 1/7 x86/mce/AMD: Log Deferred Errors using SMCA MCA_DE{STAT,ADDR} registers
From: Yazen Ghannam <[email protected]>
Scalable MCA provides new registers for all banks for logging deferred
errors: MCA_DESTAT and MCA_DEADDR. Deferred errors are always logged to these registers.
Update the AMD deferred error handler to use these registers, if available.
--- arch/x86/include/asm/mce.h | 4 ++++ arch/x86/kernel/cpu/mcheck/mce_amd.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-)
arch/x86/include/asm/mce.h +4 -0
@@ -110,6 +110,8 @@#define MSR_AMD64_SMCA_MC0_MISC0 0xc0002003#define MSR_AMD64_SMCA_MC0_CONFIG 0xc0002004#define MSR_AMD64_SMCA_MC0_IPID 0xc0002005 +#define MSR_AMD64_SMCA_MC0_DESTAT 0xc0002008 +#define MSR_AMD64_SMCA_MC0_DEADDR 0xc0002009#define MSR_AMD64_SMCA_MC0_MISC1 0xc000200a#define MSR_AMD64_SMCA_MCx_CTL (x) (MSR_AMD64_SMCA_MC0_CTL + 0x10*(x))#define MSR_AMD64_SMCA_MCx_STATUS (x) (MSR_AMD64_SMCA_MC0_STATUS + 0x10*(x))
@@ -117,6 +119,8 @@#define MSR_AMD64_SMCA_MCx_MISC (x) (MSR_AMD64_SMCA_MC0_MISC0 + 0x10*(x))#define MSR_AMD64_SMCA_MCx_CONFIG (x) (MSR_AMD64_SMCA_MC0_CONFIG + 0x10*(x))#define MSR_AMD64_SMCA_MCx_IPID (x) (MSR_AMD64_SMCA_MC0_IPID + 0x10*(x)) +#define MSR_AMD64_SMCA_MCx_DESTAT (x) (MSR_AMD64_SMCA_MC0_DESTAT + 0x10*(x)) +#define MSR_AMD64_SMCA_MCx_DEADDR (x) (MSR_AMD64_SMCA_MC0_DEADDR + 0x10*(x))#define MSR_AMD64_SMCA_MCx_MISCy (x, y) ((MSR_AMD64_SMCA_MC0_MISC1 + y) + (0x10*(x)))/*
arch/x86/kernel/cpu/mcheck/mce_amd.c +24 -8
@@ -430,12 +430,23 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)deferred_error_interrupt_enable (c); } -static void __log_error (unsigned int bank,bool threshold_err,u64 misc) +static void +__log_error (unsigned int bank,bool deferred_err,bool threshold_err,u64 misc) { +u32 msr_status = msr_ops.status (bank); +u32 msr_addr = msr_ops.addr (bank);struct mce m;u64 status; -rdmsrl (msr_ops.status (bank), status); +WARN_ON_ONCE (deferred_err && threshold_err); + +if (deferred_err && mce_flags.smca) { + msr_status =MSR_AMD64_SMCA_MCx_DESTAT (bank); + msr_addr =MSR_AMD64_SMCA_MCx_DEADDR (bank); + } + +rdmsrl (msr_status, status); +if (!(status &MCI_STATUS_VAL ))return ;
@@ -448,10 +459,11 @@ static void __log_error(unsigned int bank, bool threshold_err, u64 misc) m.misc = misc;if (m.status &MCI_STATUS_ADDRV ) -rdmsrl (msr_ops.addr (bank), m.addr); +rdmsrl (msr_addr, m.addr);mce_log (&m); -wrmsrl (msr_ops.status (bank),0 ); + +wrmsrl (msr_status,0 ); }static inline void __smp_deferred_error_interrupt (void )
@@ -479,17 +491,21 @@ asmlinkage __visible void smp_trace_deferred_error_interrupt(void)/* APIC interrupt handler for deferred errors */ static void amd_deferred_error_interrupt (void ) { -u64 status;unsigned int bank; +u32 msr_status; +u64 status;for (bank =0 ; bank < mca_cfg.banks; ++bank) { -rdmsrl (msr_ops.status (bank), status); + msr_status = (mce_flags.smca) ?MSR_AMD64_SMCA_MCx_DESTAT (bank) + : msr_ops.status (bank); + +rdmsrl (msr_status, status);if (!(status &MCI_STATUS_VAL ) || !(status &MCI_STATUS_DEFERRED ))continue ; -__log_error (bank, false,0 ); +__log_error (bank, true, false,0 );break ; } }
@@ -544,7 +560,7 @@ static void amd_threshold_interrupt(void)return ; log: -__log_error (bank, true, ((u64 )high <<32 ) | low); +__log_error (bank, false, true, ((u64 )high <<32 ) | low); }/*
Signature · 1 line
2.7.3
tip-bot for Yazen Ghannam
merge bot[tip:ras/core] x86/mce/AMD: Log Deferred Errors using SMCA MCA_DE{STAT,ADDR} registers
x86/mce/AMD: Log Deferred Errors using SMCA MCA_DE{STAT,ADDR} registers
Commit-ID: 34102009580a047c02b21f089f7fc7f65e605887 Gitweb: http://git.kernel.org/tip/34102009580a047c02b21f089f7fc7f65e605887 Author: Yazen Ghannam <[email protected]> AuthorDate: Wed, 11 May 2016 14:58:23 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 12 May 2016 09:08:19 +0200
x86/mce/AMD: Log Deferred Errors using SMCA MCA_DE{STAT,ADDR} registers
Scalable MCA provides new registers for all banks for logging deferred
errors: MCA_DESTAT and MCA_DEADDR. Deferred errors are always logged to these registers.
Update the AMD deferred error handler to use these registers, if available.
--- arch/x86/include/asm/mce.h | 4 ++++ arch/x86/kernel/cpu/mcheck/mce_amd.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-)
arch/x86/include/asm/mce.h +4 -0
@@ -110,6 +110,8 @@#define MSR_AMD64_SMCA_MC0_MISC0 0xc0002003#define MSR_AMD64_SMCA_MC0_CONFIG 0xc0002004#define MSR_AMD64_SMCA_MC0_IPID 0xc0002005 +#define MSR_AMD64_SMCA_MC0_DESTAT 0xc0002008 +#define MSR_AMD64_SMCA_MC0_DEADDR 0xc0002009#define MSR_AMD64_SMCA_MC0_MISC1 0xc000200a#define MSR_AMD64_SMCA_MCx_CTL (x) (MSR_AMD64_SMCA_MC0_CTL + 0x10*(x))#define MSR_AMD64_SMCA_MCx_STATUS (x) (MSR_AMD64_SMCA_MC0_STATUS + 0x10*(x))
@@ -117,6 +119,8 @@#define MSR_AMD64_SMCA_MCx_MISC (x) (MSR_AMD64_SMCA_MC0_MISC0 + 0x10*(x))#define MSR_AMD64_SMCA_MCx_CONFIG (x) (MSR_AMD64_SMCA_MC0_CONFIG + 0x10*(x))#define MSR_AMD64_SMCA_MCx_IPID (x) (MSR_AMD64_SMCA_MC0_IPID + 0x10*(x)) +#define MSR_AMD64_SMCA_MCx_DESTAT (x) (MSR_AMD64_SMCA_MC0_DESTAT + 0x10*(x)) +#define MSR_AMD64_SMCA_MCx_DEADDR (x) (MSR_AMD64_SMCA_MC0_DEADDR + 0x10*(x))#define MSR_AMD64_SMCA_MCx_MISCy (x, y) ((MSR_AMD64_SMCA_MC0_MISC1 + y) + (0x10*(x)))/*
arch/x86/kernel/cpu/mcheck/mce_amd.c +24 -8
@@ -430,12 +430,23 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)deferred_error_interrupt_enable (c); } -static void __log_error (unsigned int bank,bool threshold_err,u64 misc) +static void +__log_error (unsigned int bank,bool deferred_err,bool threshold_err,u64 misc) { +u32 msr_status = msr_ops.status (bank); +u32 msr_addr = msr_ops.addr (bank);struct mce m;u64 status; -rdmsrl (msr_ops.status (bank), status); +WARN_ON_ONCE (deferred_err && threshold_err); + +if (deferred_err && mce_flags.smca) { + msr_status =MSR_AMD64_SMCA_MCx_DESTAT (bank); + msr_addr =MSR_AMD64_SMCA_MCx_DEADDR (bank); + } + +rdmsrl (msr_status, status); +if (!(status &MCI_STATUS_VAL ))return ;
@@ -448,10 +459,11 @@ static void __log_error(unsigned int bank, bool threshold_err, u64 misc) m.misc = misc;if (m.status &MCI_STATUS_ADDRV ) -rdmsrl (msr_ops.addr (bank), m.addr); +rdmsrl (msr_addr, m.addr);mce_log (&m); -wrmsrl (msr_ops.status (bank),0 ); + +wrmsrl (msr_status,0 ); }static inline void __smp_deferred_error_interrupt (void )
@@ -479,17 +491,21 @@ asmlinkage __visible void smp_trace_deferred_error_interrupt(void)/* APIC interrupt handler for deferred errors */ static void amd_deferred_error_interrupt (void ) { -u64 status;unsigned int bank; +u32 msr_status; +u64 status;for (bank =0 ; bank < mca_cfg.banks; ++bank) { -rdmsrl (msr_ops.status (bank), status); + msr_status = (mce_flags.smca) ?MSR_AMD64_SMCA_MCx_DESTAT (bank) + : msr_ops.status (bank); + +rdmsrl (msr_status, status);if (!(status &MCI_STATUS_VAL ) || !(status &MCI_STATUS_DEFERRED ))continue ; -__log_error (bank, false,0 ); +__log_error (bank, true, false,0 );break ; } }
@@ -544,7 +560,7 @@ static void amd_threshold_interrupt(void)return ; log: -__log_error (bank, true, ((u64 )high <<32 ) | low); +__log_error (bank, false, true, ((u64 )high <<32 ) | low); }/*
Borislav Petkov
maintainerPATCH 2/7 x86/mce/AMD: Disable LogDeferredInMcaStat for SMCA systems
In reply to Borislav PetkovFrom: Yazen Ghannam <[email protected]>
Disable Deferred Error logging in MCA_{STATUS,ADDR} additionally for SMCA systems as this information will retrieved from MCA_DE{STAT,ADDR} on those systems.
--- arch/x86/kernel/cpu/mcheck/mce_amd.c | 38 +++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-)
arch/x86/kernel/cpu/mcheck/mce_amd.c +29 -9
@@ -54,14 +54,6 @@/* Threshold LVT offset is at MSR0xC0000410[15:12] */ #define SMCA_THR_LVT_OFF 0xF000 -/* -* OS is required to set the MCAX bit to acknowledge that it is now using the -* new MSR ranges and new registers under each bank. It also means that the OS -* will configure deferred errors in the new MCx_CONFIG register. If the bit is -* not set, uncorrectable errors will cause a system panic. -*/ -#define SMCA_MCAX_EN_OFF 0x1 -static const char *const th_names[] = {"load_store" ,"insn_fetch" ,
@@ -374,7 +366,35 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,u32 smca_addr =MSR_AMD64_SMCA_MCx_CONFIG (bank);if (!rdmsr_safe (smca_addr, &smca_low, &smca_high)) { - smca_high |=SMCA_MCAX_EN_OFF ; +/* +* OS is required to set the MCAX bit to acknowledge +* that it is now using the new MSR ranges and new +* registers under each bank. It also means that the OS +* will configure deferred errors in the new MCx_CONFIG +* register. If the bit is not set, uncorrectable errors +* will cause a system panic. +* +* MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of +* the MSR.) +*/ + smca_high |=BIT (0 ); + +/* +* SMCA logs Deferred Error information in +* MCA_DE{STAT,ADDR} registers with the option of +* additionally logging to MCA_{STATUS,ADDR} if +* MCA_CONFIG[LogDeferredInMcaStat] is set. +* +* This bit is usually set by BIOS to retain the old +* behavior for OSes that don't use the new registers. +* Linux supports the new registers so let's disable +* that additional logging here. +* +* MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in +* the high portion of the MSR). +*/ + smca_high &= ~BIT (2 ); +wrmsr (smca_addr, smca_low, smca_high); }
Signature · 1 line
2.7.3
tip-bot for Yazen Ghannam
merge bot[tip:ras/core] x86/mce/AMD: Disable LogDeferredInMcaStat for SMCA systems
x86/mce/AMD: Disable LogDeferredInMcaStat for SMCA systems
Commit-ID: 32544f060326bffa60dade49ce4595652df4d3ab Gitweb: http://git.kernel.org/tip/32544f060326bffa60dade49ce4595652df4d3ab Author: Yazen Ghannam <[email protected]> AuthorDate: Wed, 11 May 2016 14:58:24 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 12 May 2016 09:08:20 +0200
x86/mce/AMD: Disable LogDeferredInMcaStat for SMCA systems
Disable Deferred Error logging in MCA_{STATUS,ADDR} additionally for SMCA systems as this information will retrieved from MCA_DE{STAT,ADDR} on those systems.
--- arch/x86/kernel/cpu/mcheck/mce_amd.c | 38 +++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-)
arch/x86/kernel/cpu/mcheck/mce_amd.c +29 -9
@@ -54,14 +54,6 @@/* Threshold LVT offset is at MSR0xC0000410[15:12] */ #define SMCA_THR_LVT_OFF 0xF000 -/* -* OS is required to set the MCAX bit to acknowledge that it is now using the -* new MSR ranges and new registers under each bank. It also means that the OS -* will configure deferred errors in the new MCx_CONFIG register. If the bit is -* not set, uncorrectable errors will cause a system panic. -*/ -#define SMCA_MCAX_EN_OFF 0x1 -static const char *const th_names[] = {"load_store" ,"insn_fetch" ,
@@ -374,7 +366,35 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,u32 smca_addr =MSR_AMD64_SMCA_MCx_CONFIG (bank);if (!rdmsr_safe (smca_addr, &smca_low, &smca_high)) { - smca_high |=SMCA_MCAX_EN_OFF ; +/* +* OS is required to set the MCAX bit to acknowledge +* that it is now using the new MSR ranges and new +* registers under each bank. It also means that the OS +* will configure deferred errors in the new MCx_CONFIG +* register. If the bit is not set, uncorrectable errors +* will cause a system panic. +* +* MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of +* the MSR.) +*/ + smca_high |=BIT (0 ); + +/* +* SMCA logs Deferred Error information in +* MCA_DE{STAT,ADDR} registers with the option of +* additionally logging to MCA_{STATUS,ADDR} if +* MCA_CONFIG[LogDeferredInMcaStat] is set. +* +* This bit is usually set by BIOS to retain the old +* behavior for OSes that don't use the new registers. +* Linux supports the new registers so let's disable +* that additional logging here. +* +* MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in +* the high portion of the MSR). +*/ + smca_high &= ~BIT (2 ); +wrmsr (smca_addr, smca_low, smca_high); }
Borislav Petkov
maintainerPATCH 3/7 x86/mce/AMD: Save an indentation level in prepare_threshold_block()
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
Do the !SMCA work first and then save us an indentation level for the SMCA code.
No functionality change.
--- arch/x86/kernel/cpu/mcheck/mce_amd.c | 78 ++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 40 deletions(-)
arch/x86/kernel/cpu/mcheck/mce_amd.c +38 -40
@@ -343,6 +343,7 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr, int offset, u32 misc_high) {unsigned int cpu =smp_processor_id (); +u32 smca_low, smca_high, smca_addr;struct threshold_block b;int new;
@@ -361,52 +362,49 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr, b.interrupt_enable =1 ; -if (mce_flags.smca) { -u32 smca_low, smca_high; -u32 smca_addr =MSR_AMD64_SMCA_MCx_CONFIG (bank); - -if (!rdmsr_safe (smca_addr, &smca_low, &smca_high)) { -/* -* OS is required to set the MCAX bit to acknowledge -* that it is now using the new MSR ranges and new -* registers under each bank. It also means that the OS -* will configure deferred errors in the new MCx_CONFIG -* register. If the bit is not set, uncorrectable errors -* will cause a system panic. -* -* MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of -* the MSR.) -*/ - smca_high |=BIT (0 ); +if (!mce_flags.smca) { + new = (misc_high &MASK_LVTOFF_HI ) >>20 ; + goto set_offset; + } -/* -* SMCA logs Deferred Error information in -* MCA_DE{STAT,ADDR} registers with the option of -* additionally logging to MCA_{STATUS,ADDR} if -* MCA_CONFIG[LogDeferredInMcaStat] is set. -* -* This bit is usually set by BIOS to retain the old -* behavior for OSes that don't use the new registers. -* Linux supports the new registers so let's disable -* that additional logging here. -* -* MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in -* the high portion of the MSR). -*/ - smca_high &= ~BIT (2 ); + smca_addr =MSR_AMD64_SMCA_MCx_CONFIG (bank); -wrmsr (smca_addr, smca_low, smca_high); - } +if (!rdmsr_safe (smca_addr, &smca_low, &smca_high)) { +/* +* OS is required to set the MCAX bit to acknowledge that it is +* now using the new MSR ranges and new registers under each +* bank. It also means that the OS will configure deferred +* errors in the new MCx_CONFIG register. If the bit is not set, +* uncorrectable errors will cause a system panic. +* +* MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of the MSR.) +*/ + smca_high |=BIT (0 ); -/* Gather LVT offset for thresholding: */ -if (rdmsr_safe (MSR_CU_DEF_ERR , &smca_low, &smca_high)) - goto out; +/* +* SMCA logs Deferred Error information in MCA_DE{STAT,ADDR} +* registers with the option of additionally logging to +* MCA_{STATUS,ADDR} if MCA_CONFIG[LogDeferredInMcaStat] is set. +* +* This bit is usually set by BIOS to retain the old behavior +* for OSes that don't use the new registers. Linux supports the +* new registers so let's disable that additional logging here. +* +* MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in the high +* portion of the MSR). +*/ + smca_high &= ~BIT (2 ); - new = (smca_low &SMCA_THR_LVT_OFF ) >>12 ; - }else { - new = (misc_high &MASK_LVTOFF_HI ) >>20 ; +wrmsr (smca_addr, smca_low, smca_high); } +/* Gather LVT offset for thresholding: */ +if (rdmsr_safe (MSR_CU_DEF_ERR , &smca_low, &smca_high)) + goto out; + + new = (smca_low &SMCA_THR_LVT_OFF ) >>12 ; + +set_offset: offset =setup_APIC_mce_threshold (offset, new);if ((offset == new) && (mce_threshold_vector != amd_threshold_interrupt))
Signature · 1 line
2.7.3
tip-bot for Borislav Petkov
merge bot[tip:ras/core] x86/mce/AMD: Save an indentation level in prepare_threshold_block()
x86/mce/AMD: Save an indentation level in prepare_threshold_block()
Commit-ID: e128b4f4833cc1e0ce46dfb978763b260f166188 Gitweb: http://git.kernel.org/tip/e128b4f4833cc1e0ce46dfb978763b260f166188 Author: Borislav Petkov <[email protected]> AuthorDate: Wed, 11 May 2016 14:58:25 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 12 May 2016 09:08:21 +0200
x86/mce/AMD: Save an indentation level in prepare_threshold_block()
Do the !SMCA work first and then save us an indentation level for the SMCA code.
No functionality change.
--- arch/x86/kernel/cpu/mcheck/mce_amd.c | 78 ++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 40 deletions(-)
arch/x86/kernel/cpu/mcheck/mce_amd.c +38 -40
@@ -343,6 +343,7 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr, int offset, u32 misc_high) {unsigned int cpu =smp_processor_id (); +u32 smca_low, smca_high, smca_addr;struct threshold_block b;int new;
@@ -361,52 +362,49 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr, b.interrupt_enable =1 ; -if (mce_flags.smca) { -u32 smca_low, smca_high; -u32 smca_addr =MSR_AMD64_SMCA_MCx_CONFIG (bank); - -if (!rdmsr_safe (smca_addr, &smca_low, &smca_high)) { -/* -* OS is required to set the MCAX bit to acknowledge -* that it is now using the new MSR ranges and new -* registers under each bank. It also means that the OS -* will configure deferred errors in the new MCx_CONFIG -* register. If the bit is not set, uncorrectable errors -* will cause a system panic. -* -* MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of -* the MSR.) -*/ - smca_high |=BIT (0 ); +if (!mce_flags.smca) { + new = (misc_high &MASK_LVTOFF_HI ) >>20 ; + goto set_offset; + } -/* -* SMCA logs Deferred Error information in -* MCA_DE{STAT,ADDR} registers with the option of -* additionally logging to MCA_{STATUS,ADDR} if -* MCA_CONFIG[LogDeferredInMcaStat] is set. -* -* This bit is usually set by BIOS to retain the old -* behavior for OSes that don't use the new registers. -* Linux supports the new registers so let's disable -* that additional logging here. -* -* MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in -* the high portion of the MSR). -*/ - smca_high &= ~BIT (2 ); + smca_addr =MSR_AMD64_SMCA_MCx_CONFIG (bank); -wrmsr (smca_addr, smca_low, smca_high); - } +if (!rdmsr_safe (smca_addr, &smca_low, &smca_high)) { +/* +* OS is required to set the MCAX bit to acknowledge that it is +* now using the new MSR ranges and new registers under each +* bank. It also means that the OS will configure deferred +* errors in the new MCx_CONFIG register. If the bit is not set, +* uncorrectable errors will cause a system panic. +* +* MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of the MSR.) +*/ + smca_high |=BIT (0 ); -/* Gather LVT offset for thresholding: */ -if (rdmsr_safe (MSR_CU_DEF_ERR , &smca_low, &smca_high)) - goto out; +/* +* SMCA logs Deferred Error information in MCA_DE{STAT,ADDR} +* registers with the option of additionally logging to +* MCA_{STATUS,ADDR} if MCA_CONFIG[LogDeferredInMcaStat] is set. +* +* This bit is usually set by BIOS to retain the old behavior +* for OSes that don't use the new registers. Linux supports the +* new registers so let's disable that additional logging here. +* +* MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in the high +* portion of the MSR). +*/ + smca_high &= ~BIT (2 ); - new = (smca_low &SMCA_THR_LVT_OFF ) >>12 ; - }else { - new = (misc_high &MASK_LVTOFF_HI ) >>20 ; +wrmsr (smca_addr, smca_low, smca_high); } +/* Gather LVT offset for thresholding: */ +if (rdmsr_safe (MSR_CU_DEF_ERR , &smca_low, &smca_high)) + goto out; + + new = (smca_low &SMCA_THR_LVT_OFF ) >>12 ; + +set_offset: offset =setup_APIC_mce_threshold (offset, new);if ((offset == new) && (mce_threshold_vector != amd_threshold_interrupt))
Borislav Petkov
maintainerPATCH 4/7 x86/cpu: Add detection of AMD RAS Capabilities
In reply to Borislav PetkovFrom: Yazen Ghannam <[email protected]>
Add a new CPUID leaf to hold the contents of CPUID 0x80000007_EBX (RasCap).
Define bits that are currently in use:
Bit 0: McaOverflowRecov
Bit 1: SUCCOR
Bit 3: ScalableMca
--- arch/x86/include/asm/cpufeature.h | 1 + arch/x86/include/asm/cpufeatures.h | 7 ++++++- arch/x86/kernel/cpu/common.c | 10 +++++++--- 3 files changed, 14 insertions(+), 4 deletions(-)
arch/x86/include/asm/cpufeature.h +1 -0
@@ -27,6 +27,7 @@ enum cpuid_leafsCPUID_6_EAX ,CPUID_8000_000A_EDX ,CPUID_7_ECX , + CPUID_8000_0007_EBX, };#ifdef CONFIG_X86_FEATURE_NAMES
arch/x86/include/asm/cpufeatures.h +6 -1
@@ -12,7 +12,7 @@/* * Defines x86 CPU feature bits */ -#define NCAPINTS 17/* N 32-bit words worth of info */ +#define NCAPINTS 18/* N 32-bit words worth of info */ #define NBUGINTS 1/* N 32-bit bug flags */ /*
@@ -280,6 +280,11 @@#define X86_FEATURE_PKU (16*32+ 3)/* Protection Keys for Userspace */ #define X86_FEATURE_OSPKE (16*32+ 4)/* OS Protection Keys Enable */ +/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */ +#define X86_FEATURE_OVERFLOW_RECOV (17*32+0)/* MCA overflow recovery support */ +#define X86_FEATURE_SUCCOR (17*32+1)/* Uncorrectable error containment and recovery */ +#define X86_FEATURE_SMCA (17*32+3)/* Scalable MCA */ +/* * BUG word(s) */
arch/x86/kernel/cpu/common.c +7 -3
@@ -717,6 +717,13 @@ void get_cpu_cap(struct cpuinfo_x86 *c) } } +if (c->extended_cpuid_level >=0x80000007 ) { +cpuid (0x80000007 , &eax, &ebx, &ecx, &edx); + + c->x86_capability[CPUID_8000_0007_EBX ] = ebx; + c->x86_power = edx; + } +if (c->extended_cpuid_level >=0x80000008 ) {cpuid (0x80000008 , &eax, &ebx, &ecx, &edx);
@@ -729,9 +736,6 @@ void get_cpu_cap(struct cpuinfo_x86 *c) c->x86_phys_bits =36 ;#endif -if (c->extended_cpuid_level >=0x80000007 ) - c->x86_power =cpuid_edx (0x80000007 ); -if (c->extended_cpuid_level >=0x8000000a ) c->x86_capability[CPUID_8000_000A_EDX ] =cpuid_edx (0x8000000a );
Signature · 1 line
2.7.3
tip-bot for Yazen Ghannam
merge bot[tip:ras/core] x86/cpu: Add detection of AMD RAS Capabilities
x86/cpu: Add detection of AMD RAS Capabilities
Commit-ID: 71faad43060d3d2040583635fbf7d1bdb3d04118 Gitweb: http://git.kernel.org/tip/71faad43060d3d2040583635fbf7d1bdb3d04118 Author: Yazen Ghannam <[email protected]> AuthorDate: Wed, 11 May 2016 14:58:26 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 12 May 2016 09:08:22 +0200
x86/cpu: Add detection of AMD RAS Capabilities
Add a new CPUID leaf to hold the contents of CPUID 0x80000007_EBX (RasCap).
Define bits that are currently in use:
Bit 0: McaOverflowRecov
Bit 1: SUCCOR
Bit 3: ScalableMca
--- arch/x86/include/asm/cpufeature.h | 1 + arch/x86/include/asm/cpufeatures.h | 7 ++++++- arch/x86/kernel/cpu/common.c | 10 +++++++--- 3 files changed, 14 insertions(+), 4 deletions(-)
arch/x86/include/asm/cpufeature.h +1 -0
@@ -27,6 +27,7 @@ enum cpuid_leafsCPUID_6_EAX ,CPUID_8000_000A_EDX ,CPUID_7_ECX , + CPUID_8000_0007_EBX, };#ifdef CONFIG_X86_FEATURE_NAMES
arch/x86/include/asm/cpufeatures.h +6 -1
@@ -12,7 +12,7 @@/* * Defines x86 CPU feature bits */ -#define NCAPINTS 17/* N 32-bit words worth of info */ +#define NCAPINTS 18/* N 32-bit words worth of info */ #define NBUGINTS 1/* N 32-bit bug flags */ /*
@@ -280,6 +280,11 @@#define X86_FEATURE_PKU (16*32+ 3)/* Protection Keys for Userspace */ #define X86_FEATURE_OSPKE (16*32+ 4)/* OS Protection Keys Enable */ +/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */ +#define X86_FEATURE_OVERFLOW_RECOV (17*32+0)/* MCA overflow recovery support */ +#define X86_FEATURE_SUCCOR (17*32+1)/* Uncorrectable error containment and recovery */ +#define X86_FEATURE_SMCA (17*32+3)/* Scalable MCA */ +/* * BUG word(s) */
arch/x86/kernel/cpu/common.c +7 -3
@@ -717,6 +717,13 @@ void get_cpu_cap(struct cpuinfo_x86 *c) } } +if (c->extended_cpuid_level >=0x80000007 ) { +cpuid (0x80000007 , &eax, &ebx, &ecx, &edx); + + c->x86_capability[CPUID_8000_0007_EBX ] = ebx; + c->x86_power = edx; + } +if (c->extended_cpuid_level >=0x80000008 ) {cpuid (0x80000008 , &eax, &ebx, &ecx, &edx);
@@ -729,9 +736,6 @@ void get_cpu_cap(struct cpuinfo_x86 *c) c->x86_phys_bits =36 ;#endif -if (c->extended_cpuid_level >=0x80000007 ) - c->x86_power =cpuid_edx (0x80000007 ); -if (c->extended_cpuid_level >=0x8000000a ) c->x86_capability[CPUID_8000_000A_EDX ] =cpuid_edx (0x8000000a );
Borislav Petkov
maintainerPATCH 5/7 x86/mce: Update AMD mcheck init to use cpu_has() facilities
In reply to Borislav PetkovFrom: Yazen Ghannam <[email protected]>
Use cpu_has() facilities to find available RAS features rather than directly reading CPUID 0x80000007_EBX.
--- arch/x86/kernel/cpu/mcheck/mce.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +3 -5
@@ -1683,11 +1683,9 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)break ;case X86_VENDOR_AMD : { -u32 ebx =cpuid_ebx (0x80000007 ); - - mce_flags.overflow_recov = !!(ebx &BIT (0 )); - mce_flags.succor = !!(ebx &BIT (1 )); - mce_flags.smca = !!(ebx &BIT (3 )); + mce_flags.overflow_recov = !!cpu_has (c,X86_FEATURE_OVERFLOW_RECOV ); + mce_flags.succor = !!cpu_has (c,X86_FEATURE_SUCCOR ); + mce_flags.smca = !!cpu_has (c,X86_FEATURE_SMCA );/* * Install proper ops for Scalable MCA enabled processors
Signature · 1 line
2.7.3
tip-bot for Yazen Ghannam
merge bot[tip:ras/core] x86/mce: Update AMD mcheck init to use cpu_has() facilities
x86/mce: Update AMD mcheck init to use cpu_has() facilities
Commit-ID: 14cddfd5308b0880abd6e58b6660f5cc8e8020f9 Gitweb: http://git.kernel.org/tip/14cddfd5308b0880abd6e58b6660f5cc8e8020f9 Author: Yazen Ghannam <[email protected]> AuthorDate: Wed, 11 May 2016 14:58:27 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 12 May 2016 09:08:22 +0200
x86/mce: Update AMD mcheck init to use cpu_has() facilities
Use cpu_has() facilities to find available RAS features rather than directly reading CPUID 0x80000007_EBX.
--- arch/x86/kernel/cpu/mcheck/mce.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +3 -5
@@ -1683,11 +1683,9 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)break ;case X86_VENDOR_AMD : { -u32 ebx =cpuid_ebx (0x80000007 ); - - mce_flags.overflow_recov = !!(ebx &BIT (0 )); - mce_flags.succor = !!(ebx &BIT (1 )); - mce_flags.smca = !!(ebx &BIT (3 )); + mce_flags.overflow_recov = !!cpu_has (c,X86_FEATURE_OVERFLOW_RECOV ); + mce_flags.succor = !!cpu_has (c,X86_FEATURE_SUCCOR ); + mce_flags.smca = !!cpu_has (c,X86_FEATURE_SMCA );/* * Install proper ops for Scalable MCA enabled processors
Borislav Petkov
maintainerPATCH 6/7 EDAC, mce_amd: Detect SMCA using X86_FEATURE_SMCA
In reply to Borislav PetkovFrom: Yazen Ghannam <[email protected]>
Use X86_FEATURE_SMCA when detecting if SMCA is available instead of directly using CPUID 0x80000007_EBX.
--- drivers/edac/mce_amd.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/edac/mce_amd.c +3 -6
@@ -1052,7 +1052,6 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)struct mce *m = (struct mce *)data;struct cpuinfo_x86 *c = &cpu_data (m->extcpu);int ecc; -u32 ebx =cpuid_ebx (0x80000007 );if (amd_filter_mce (m))return NOTIFY_STOP ;
@@ -1075,7 +1074,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) ((m->status &MCI_STATUS_DEFERRED ) ?"Deferred" :"-" ), ((m->status & MCI_STATUS_POISON) ? "Poison" : "-")); -if (!!(ebx &BIT (3 ))) { +if (boot_cpu_has (X86_FEATURE_SMCA )) {u32 low, high;u32 addr =MSR_AMD64_SMCA_MCx_CONFIG (m->bank);
@@ -1094,7 +1093,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)if (m->status &MCI_STATUS_ADDRV )pr_emerg (HW_ERR "MC%d Error Address: 0x%016llx\n" , m->bank, m->addr); -if (!!(ebx &BIT (3 ))) { +if (boot_cpu_has (X86_FEATURE_SMCA )) {decode_smca_errors (m); goto err_code; }
@@ -1149,7 +1148,6 @@ static struct notifier_block amd_mce_dec_nb = {static int __init mce_amd_init (void ) {struct cpuinfo_x86 *c = &boot_cpu_data; -u32 ebx;if (c->x86_vendor !=X86_VENDOR_AMD )return -ENODEV ;
@@ -1205,9 +1203,8 @@ static int __init mce_amd_init(void)break ;case 0x17 : - ebx =cpuid_ebx (0x80000007 ); xec_mask =0x3f ; -if (!(ebx &BIT (3 ))) { +if (!boot_cpu_has (X86_FEATURE_SMCA )) {printk (KERN_WARNING "Decoding supported only on Scalable MCA processors.\n" ); goto err_out; }
Signature · 1 line
2.7.3
tip-bot for Yazen Ghannam
merge bot[tip:ras/core] EDAC, mce_amd: Detect SMCA using X86_FEATURE_SMCA
EDAC, mce_amd: Detect SMCA using X86_FEATURE_SMCA
Commit-ID: a348ed83d9efe8c11ecc85c15d7329825b97431e Gitweb: http://git.kernel.org/tip/a348ed83d9efe8c11ecc85c15d7329825b97431e Author: Yazen Ghannam <[email protected]> AuthorDate: Wed, 11 May 2016 14:58:28 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 12 May 2016 09:08:23 +0200
EDAC, mce_amd: Detect SMCA using X86_FEATURE_SMCA
Use X86_FEATURE_SMCA when detecting if SMCA is available instead of directly using CPUID 0x80000007_EBX.
--- drivers/edac/mce_amd.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/edac/mce_amd.c +3 -6
@@ -1052,7 +1052,6 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)struct mce *m = (struct mce *)data;struct cpuinfo_x86 *c = &cpu_data (m->extcpu);int ecc; -u32 ebx =cpuid_ebx (0x80000007 );if (amd_filter_mce (m))return NOTIFY_STOP ;
@@ -1075,7 +1074,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) ((m->status &MCI_STATUS_DEFERRED ) ?"Deferred" :"-" ), ((m->status & MCI_STATUS_POISON) ? "Poison" : "-")); -if (!!(ebx &BIT (3 ))) { +if (boot_cpu_has (X86_FEATURE_SMCA )) {u32 low, high;u32 addr =MSR_AMD64_SMCA_MCx_CONFIG (m->bank);
@@ -1094,7 +1093,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)if (m->status &MCI_STATUS_ADDRV )pr_emerg (HW_ERR "MC%d Error Address: 0x%016llx\n" , m->bank, m->addr); -if (!!(ebx &BIT (3 ))) { +if (boot_cpu_has (X86_FEATURE_SMCA )) {decode_smca_errors (m); goto err_code; }
@@ -1149,7 +1148,6 @@ static struct notifier_block amd_mce_dec_nb = {static int __init mce_amd_init (void ) {struct cpuinfo_x86 *c = &boot_cpu_data; -u32 ebx;if (c->x86_vendor !=X86_VENDOR_AMD )return -ENODEV ;
@@ -1205,9 +1203,8 @@ static int __init mce_amd_init(void)break ;case 0x17 : - ebx =cpuid_ebx (0x80000007 ); xec_mask =0x3f ; -if (!(ebx &BIT (3 ))) { +if (!boot_cpu_has (X86_FEATURE_SMCA )) {printk (KERN_WARNING "Decoding supported only on Scalable MCA processors.\n" ); goto err_out; }
Borislav Petkov
maintainerPATCH 7/7 x86/RAS: Add SMCA support to AMD Error Injector
In reply to Borislav PetkovFrom: Yazen Ghannam <[email protected]>
Use SMCA MSRs when writing to MCA_{STATUS,ADDR,MISC} and MCA_DE{STAT,ADDR} when injecting Deferred Errors on SMCA platforms.
--- arch/x86/ras/mce_amd_inj.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-)
arch/x86/ras/mce_amd_inj.c +25 -6
@@ -290,14 +290,33 @@ static void do_inject(void)wrmsr_on_cpu (cpu,MSR_IA32_MCG_STATUS , (u32 )mcg_status, (u32)(mcg_status >>32 )); -wrmsr_on_cpu (cpu,MSR_IA32_MCx_STATUS (b), - (u32 )i_mce.status, (u32)(i_mce.status >>32 )); +if (boot_cpu_has (X86_FEATURE_SMCA )) { +if (inj_type ==DFR_INT_INJ ) { +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_DESTAT (b), + (u32 )i_mce.status, (u32)(i_mce.status >>32 )); + +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_DEADDR (b), + (u32 )i_mce.addr, (u32)(i_mce.addr >>32 )); + }else { +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_STATUS (b), + (u32 )i_mce.status, (u32)(i_mce.status >>32 )); + +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_ADDR (b), + (u32 )i_mce.addr, (u32)(i_mce.addr >>32 )); + } + +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_MISC (b), + (u32 )i_mce.misc, (u32)(i_mce.misc >>32 )); + }else { +wrmsr_on_cpu (cpu,MSR_IA32_MCx_STATUS (b), + (u32 )i_mce.status, (u32)(i_mce.status >>32 )); -wrmsr_on_cpu (cpu,MSR_IA32_MCx_ADDR (b), - (u32 )i_mce.addr, (u32)(i_mce.addr >>32 )); +wrmsr_on_cpu (cpu,MSR_IA32_MCx_ADDR (b), + (u32 )i_mce.addr, (u32)(i_mce.addr >>32 )); -wrmsr_on_cpu (cpu,MSR_IA32_MCx_MISC (b), - (u32 )i_mce.misc, (u32)(i_mce.misc >>32 )); +wrmsr_on_cpu (cpu,MSR_IA32_MCx_MISC (b), + (u32 )i_mce.misc, (u32)(i_mce.misc >>32 )); + }toggle_hw_mce_inject (cpu, false);
Signature · 1 line
2.7.3
tip-bot for Yazen Ghannam
merge bot[tip:ras/core] x86/RAS: Add SMCA support to AMD Error Injector
x86/RAS: Add SMCA support to AMD Error Injector
Commit-ID: 754a92305980b1fecffe033dd3fdc49c37f8e4b0 Gitweb: http://git.kernel.org/tip/754a92305980b1fecffe033dd3fdc49c37f8e4b0 Author: Yazen Ghannam <[email protected]> AuthorDate: Wed, 11 May 2016 14:58:29 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 12 May 2016 09:08:23 +0200
x86/RAS: Add SMCA support to AMD Error Injector
Use SMCA MSRs when writing to MCA_{STATUS,ADDR,MISC} and MCA_DE{STAT,ADDR} when injecting Deferred Errors on SMCA platforms.
--- arch/x86/ras/mce_amd_inj.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-)
arch/x86/ras/mce_amd_inj.c +25 -6
@@ -290,14 +290,33 @@ static void do_inject(void)wrmsr_on_cpu (cpu,MSR_IA32_MCG_STATUS , (u32 )mcg_status, (u32)(mcg_status >>32 )); -wrmsr_on_cpu (cpu,MSR_IA32_MCx_STATUS (b), - (u32 )i_mce.status, (u32)(i_mce.status >>32 )); +if (boot_cpu_has (X86_FEATURE_SMCA )) { +if (inj_type ==DFR_INT_INJ ) { +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_DESTAT (b), + (u32 )i_mce.status, (u32)(i_mce.status >>32 )); + +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_DEADDR (b), + (u32 )i_mce.addr, (u32)(i_mce.addr >>32 )); + }else { +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_STATUS (b), + (u32 )i_mce.status, (u32)(i_mce.status >>32 )); + +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_ADDR (b), + (u32 )i_mce.addr, (u32)(i_mce.addr >>32 )); + } + +wrmsr_on_cpu (cpu,MSR_AMD64_SMCA_MCx_MISC (b), + (u32 )i_mce.misc, (u32)(i_mce.misc >>32 )); + }else { +wrmsr_on_cpu (cpu,MSR_IA32_MCx_STATUS (b), + (u32 )i_mce.status, (u32)(i_mce.status >>32 )); -wrmsr_on_cpu (cpu,MSR_IA32_MCx_ADDR (b), - (u32 )i_mce.addr, (u32)(i_mce.addr >>32 )); +wrmsr_on_cpu (cpu,MSR_IA32_MCx_ADDR (b), + (u32 )i_mce.addr, (u32)(i_mce.addr >>32 )); -wrmsr_on_cpu (cpu,MSR_IA32_MCx_MISC (b), - (u32 )i_mce.misc, (u32)(i_mce.misc >>32 )); +wrmsr_on_cpu (cpu,MSR_IA32_MCx_MISC (b), + (u32 )i_mce.misc, (u32)(i_mce.misc >>32 )); + }toggle_hw_mce_inject (cpu, false);