AMD MCE injection improvs
Subsystems (3)
cover AMD MCE injection improvs
From: Borislav Petkov <[email protected]>
So this basically moves the mce-inject module to arch/x86/ras/ and adds a bunch of features to it.
More importantly, though, it creates all the glue to add the arch/x86/ras/ directory to Kconfig. The idea is to gradually collect RAS-related stuff there.
Tony, please take a look and let me know how do you find the general layout, etc.
Thanks.
Borislav Petkov (6):
x86, RAS: Add a barebones RAS subtree
x86, RAS: Move AMD MCE injection code into ras/ x86, RAS: Convert mce-inject module to debugfs x86, RAS: Add function enabling direct writes to MCE MSRs x86, RAS: Add attributes needed for HW injection x86, RAS: Add an injector function
arch/x86/Kconfig | 10 ++ arch/x86/Makefile | 3 + arch/x86/ras/Kconfig | 14 +++ arch/x86/ras/Makefile | 2 + arch/x86/ras/amd/Makefile | 3 + arch/x86/ras/amd/mce-inject.c | 274 ++++++++++++++++++++++++++++++++++++++++++ drivers/edac/Kconfig | 10 -- drivers/edac/mce_amd_inj.c | 173 -------------------------- 8 files changed, 306 insertions(+), 183 deletions(-) create mode 100644 arch/x86/ras/Kconfig create mode 100644 arch/x86/ras/Makefile create mode 100644 arch/x86/ras/amd/Makefile create mode 100644 arch/x86/ras/amd/mce-inject.c create mode 100644 arch/x86/ras/ras.c delete mode 100644 drivers/edac/mce_amd_inj.c
Signature · 1 line
1.8.0.rc0.18.gf84667d
PATCH 1/6 x86, RAS: Add a barebones RAS subtree
From: Borislav Petkov <[email protected]>
This should collect all x86 RAS-related stuff.
--- arch/x86/Kconfig | 8 ++++++++ arch/x86/Makefile | 3 +++ arch/x86/ras/Makefile | 1 + 3 files changed, 12 insertions(+) create mode 100644 arch/x86/ras/Makefile create mode 100644 arch/x86/ras/ras.c
arch/x86/Kconfig +8 -0
@@ -687,6 +687,14 @@ config X86_CYCLONE_TIMER def_bool y depends on X86_SUMMIT +config X86_RAS + def_bool y + prompt "X86 RAS features" + ---help--- + A collection of Reliability, Availability and Serviceability software + features which enable hardware error logging and reporting. Leave it + at 'y' unless you really know what you're doing. + source "arch/x86/Kconfig.cpu" config HPET_TIMER
arch/x86/Makefile +3 -0
@@ -163,6 +163,9 @@ libs-y += arch/x86/lib/ # See arch/x86/Kbuild for content of core part of the kernel core-y += arch/x86/ +# RAS support +core-$(CONFIG_X86_RAS) += arch/x86/ras/ + # drivers-y are linked after core-y drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/ drivers-$(CONFIG_PCI) += arch/x86/pci/
arch/x86/ras/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-y := ras.o
arch/x86/ras/ras.c new file +0 -0
Signature · 1 line
1.8.0.rc0.18.gf84667d
Tony Luck
maintainerRe: [PATCH 1/6] x86, RAS: Add a barebones RAS subtree
arch/x86/Kconfig config X86_CYCLONE_TIMER · line 697
Quoted 8 lines · Borislav Petkov
arch/x86/Kconfig +8
-0+config X86_RAS + def_bool y + prompt "X86 RAS features" + ---help--- + A collection of Reliability, Availability and Serviceability software + features which enable hardware error logging and reporting. Leave it + at 'y' unless you really know what you're doing. +
The intent of "X86_RAS" is just to show/hide all the menu options for the individual features - which will all use
depends on X86_RAS
right? Having this set to "y" doesn't actually enable any of the features - they all have their own CONFIG_* variables.
Perhaps we could make that clearer in the help text? And ditch the "Leave it at 'y' ... ", I don't think it helps anyone.
-Tony
Re: [PATCH 1/6] x86, RAS: Add a barebones RAS subtree
Quoted 16 lines · Tony Luck
Review
Quoted 8 lines · Borislav Petkov
(quoted diff) +8
-0+config X86_RAS + def_bool y + prompt "X86 RAS features" + ---help--- + A collection of Reliability, Availability and Serviceability software + features which enable hardware error logging and reporting. Leave it + at 'y' unless you really know what you're doing. +The intent of "
X86_RAS" is just to show/hide all the menu options for the individual features - which will all use
depends onX86_RAS
right? Having this set to "y" doesn't actually enable any of the features - they all have their own CONFIG_* variables.
Quoted 2 lines
Perhaps we could make that clearer in the help text? And ditch the "Leave it at 'y' ... ", I don't think it helps anyone.
Good point. I've changed it to a simple bool which opens a submenu when enabled (diff ontop):
arch/x86/Kconfig +2 -4
@@ -688,12 +688,10 @@ config X86_CYCLONE_TIMER depends on X86_SUMMIT config X86_RAS - def_bool y - prompt "X86 RAS features" + bool "X86 RAS features" ---help--- A collection of Reliability, Availability and Serviceability software - features which enable hardware error logging and reporting. Leave it - at 'y' unless you really know what you're doing. + features which enable hardware error logging and reporting.
The def_bool y intent was from earlier but it materialized in a patch which I sent last week or so which makes CONFIG_X86_MCE enabled by default so no need to enable those additional RAS stuff by default.
Thanks.
Signature · 8 lines
Regards/Gruss, Boris. Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach GM: Alberto Bozzo Reg: Dornach, Landkreis Muenchen HRB Nr. 43632 WEEE Registernr: 129 19551
PATCH 2/6 x86, RAS: Move AMD MCE injection code into ras/
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
This is the code collecting all AMD MCE injection methods.
No functionality change.
--- arch/x86/Kconfig | 2 ++ arch/x86/ras/Kconfig | 11 +++++++++++ arch/x86/ras/Makefile | 3 ++- arch/x86/ras/amd/Makefile | 3 +++ drivers/edac/mce_amd_inj.c => arch/x86/ras/amd/mce-inject.c | 2 +- drivers/edac/Kconfig | 10 ---------- 6 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 arch/x86/ras/Kconfig create mode 100644 arch/x86/ras/amd/Makefile rename drivers/edac/mce_amd_inj.c => arch/x86/ras/amd/mce-inject.c (99%)
arch/x86/Kconfig +2 -0
@@ -695,6 +695,8 @@ config X86_RAS features which enable hardware error logging and reporting. Leave it at 'y' unless you really know what you're doing. +source "arch/x86/ras/Kconfig" + source "arch/x86/Kconfig.cpu" config HPET_TIMER
arch/x86/ras/Kconfig new file +11 -0
@@ -0,0 +1,11 @@ +menu "AMD RAS features" + depends on X86_RAS && CPU_SUP_AMD + +config X86_AMD_MCE_INJECT + tristate "Simple MCE injection interface over /sysfs" + default n + help + This is a simple interface to inject MCEs over /sysfs and test + the MCE decoding code. + +endmenu
arch/x86/ras/Makefile +2 -1
@@ -1 +1,2 @@ -obj-y := ras.o +obj-y := ras.o +obj-$(CONFIG_X86_MCE) += amd/
arch/x86/ras/amd/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +amd_mce_inject-y := mce-inject.o +obj-$(CONFIG_X86_AMD_MCE_INJECT) += amd_mce_inject.o +
arch/x86/ras/amd/mce-inject.c renamed from drivers/edac/mce_amd_inj.c +1 -1
@@ -16,7 +16,7 @@#include <linux/module.h> #include <asm/mce.h> -#include "mce_amd.h" +#include "../../../drivers/edac/mce_amd.h" struct edac_mce_attr {struct attribute attr;
drivers/edac/Kconfig +0 -10
@@ -59,16 +59,6 @@ config EDAC_DECODE_MCE which occur really early upon boot, before the module infrastructure has been initialized. -config EDAC_MCE_INJ - tristate "Simple MCE injection interface over /sysfs" - depends on EDAC_DECODE_MCE - default n - help - This is a simple interface to inject MCEs over /sysfs and test - the MCE decoding code in EDAC. - - This is currently AMD-only. - config EDAC_MM_EDAC tristate "Main Memory EDAC (Error Detection And Correction) reporting" help
Signature · 1 line
1.8.0.rc0.18.gf84667d
PATCH 3/6 x86, RAS: Convert mce-inject module to debugfs
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
This is a module which is used for debugging MCE decoding paths so its userspace interface should go to debugfs, where it belongs conceptually.
While at it, add a warning to the Kconfig text that this interface is unstable and no userspace scripts should rely all too much on it.
--- arch/x86/ras/Kconfig | 11 ++- arch/x86/ras/amd/mce-inject.c | 182 ++++++++++++++++++------------------------ 2 files changed, 86 insertions(+), 107 deletions(-)
arch/x86/ras/Kconfig +7 -4
@@ -2,10 +2,13 @@ menu "AMD RAS features" depends on X86_RAS && CPU_SUP_AMD config X86_AMD_MCE_INJECT - tristate "Simple MCE injection interface over /sysfs" + tristate "Inject MCEs" + depends on DEBUG_FS default n - help - This is a simple interface to inject MCEs over /sysfs and test - the MCE decoding code. + ---help--- + This is a simple debugfs interface to inject MCEs and test different + aspects of the MCE handling code. + + WARNING: Do not even assume that this interface is staying stable! endmenu
arch/x86/ras/amd/mce-inject.c +79 -103
252 lines not on this page · raw message
Signature · 1 line
1.8.0.rc0.18.gf84667d
PATCH 4/6 x86, RAS: Add function enabling direct writes to MCE MSRs
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
Normally, writing to MCE MSRs causes a #GP. Add a function to enable direct accesses to those MSRs.
--- arch/x86/ras/amd/mce-inject.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
arch/x86/ras/amd/mce-inject.c +24 -0
@@ -55,6 +55,30 @@ DEFINE_SIMPLE_ATTRIBUTE(misc_fops, inj_misc_get, inj_misc_set, "%llx\n");DEFINE_SIMPLE_ATTRIBUTE (addr_fops, inj_addr_get, inj_addr_set,"%llx\n" );/* +* Caller needs to be make sure this cpu doesn't disappear +* from under us, i.e.: get_cpu/put_cpu. +*/ +static int toggle_hw_mce_inject (unsigned int cpu,bool enable) +{ +u32 l, h; +int err; + + err =rdmsr_on_cpu (cpu,MSR_K7_HWCR , &l, &h); +if (err) { +pr_err ("%s: error reading HWCR\n" , __func__); +return err; + } + + enable ? (l |=BIT (18 )) : (l &= ~BIT (18 )); + + err =wrmsr_on_cpu (cpu,MSR_K7_HWCR , l, h); +if (err) +pr_err ("%s: error writing HWCR\n" , __func__); + +return err; +} + +/* * This denotes into which bank we're injecting and triggers * the injection, at the same time. */
Signature · 1 line
1.8.0.rc0.18.gf84667d
PATCH 5/6 x86, RAS: Add attributes needed for HW injection
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
hw_inject denotes whether we want to do a hardware or a software injection and, in the case of hardware injection, we want to do that on a particular cpu, thus the 'cpu' attribute.
--- arch/x86/ras/amd/mce-inject.c | 55 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
arch/x86/ras/amd/mce-inject.c +55 -0
@@ -79,6 +79,59 @@ static int toggle_hw_mce_inject(unsigned int cpu, bool enable) }/* +* HW or SW injection +*/ +static int hw_inj_get (void *data,u64 *val) +{ +struct mce *m = (struct mce *)data; + + *val = !!(m->inject_flags &MCJ_EXCEPTION ); + +return 0 ; +} + +static int hw_inj_set (void *data,u64 val) +{ +struct mce *m = (struct mce *)data; + +switch (val) { +case 0 : + m->inject_flags &= (u8 )~MCJ_EXCEPTION ; +break ; + +case 1 : + m->inject_flags |=MCJ_EXCEPTION ; +break ; + +default : +pr_err ("%s: Only 0 or 1 allowed!\n" , __func__); +return -EINVAL ; + } +return 0 ; +} + +DEFINE_SIMPLE_ATTRIBUTE (hw_inj_fops, hw_inj_get, hw_inj_set,"%llu\n" ); + +/* +* On which CPU to inject? +*/ +MCE_INJECT_GET (extcpu); + +static int inj_extcpu_set (void *data,u64 val) +{ +struct mce *m = (struct mce *)data; + +if (val >= nr_cpu_ids || !cpu_online (val)) { +pr_err ("%s: Invalid CPU: %llu\n" , __func__, val); +return -EINVAL ; + } + m->extcpu = val; +return 0 ; +} + +DEFINE_SIMPLE_ATTRIBUTE (extcpu_fops, inj_extcpu_get, inj_extcpu_set,"%llu\n" ); + +/* * This denotes into which bank we're injecting and triggers * the injection, at the same time. */
@@ -119,6 +172,8 @@ struct dfs_node { { .name = "misc", .fops = &misc_fops }, { .name = "addr", .fops = &addr_fops }, { .name = "bank", .fops = &bank_fops }, + { .name = "hw_inject", .fops = &hw_inj_fops }, + { .name = "cpu", .fops = &extcpu_fops }, };static int __init init_mce_inject (void )
Signature · 1 line
1.8.0.rc0.18.gf84667d
PATCH 6/6 x86, RAS: Add an injector function
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
Selectively inject either a real MCE or a sw-only version which exercises the decoding code only. The hardware-injected MCE triggers a machine check exception (#MC) so that the MCE handler can be bothered to do something too.
--- arch/x86/ras/amd/mce-inject.c | 50 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-)
arch/x86/ras/amd/mce-inject.c +48 -2
@@ -131,6 +131,53 @@ static int inj_extcpu_set(void *data, u64 val)DEFINE_SIMPLE_ATTRIBUTE (extcpu_fops, inj_extcpu_get, inj_extcpu_set,"%llu\n" ); +static void trigger_mce (void *info) +{ + asmvolatile ("int $18" ); +} + +static void do_inject (void ) +{ +u64 mcg_status =0 ; +unsigned int cpu = i_mce.extcpu; +int this_cpu; +u8 b = i_mce.bank; + +if (!(i_mce.inject_flags &MCJ_EXCEPTION )) { +amd_decode_mce (NULL ,0 , &i_mce); +return ; + } + +/* prep MCE global settings for the injection */ + mcg_status =MCG_STATUS_MCIP |MCG_STATUS_EIPV ; + +if (!(i_mce.status &MCI_STATUS_PCC )) + mcg_status |=MCG_STATUS_RIPV ; + + this_cpu =get_cpu (); + +toggle_hw_mce_inject (cpu, true); + +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 )); + +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 )); + +toggle_hw_mce_inject (cpu, false); + +smp_call_function_single (cpu, trigger_mce,NULL ,0 ); + +put_cpu (); + +} +/* * This denotes into which bank we're injecting and triggers * the injection, at the same time.
@@ -147,8 +194,7 @@ static int inj_bank_set(void *data, u64 val) } m->bank = val; - -amd_decode_mce (NULL ,0 , m); +do_inject ();return 0 ; }
Signature · 1 line
1.8.0.rc0.18.gf84667d
Tony Luck
maintainerQuoted 1 line · Borislav Petkov
create mode 100644 arch/x86/ras/ras.c
Overall it looks good - but I'm a bit puzzled by this ras.c file that gets created as an empty file in part1, and is still empty at the end of the series.
What is going to go into it?
-Tony
Quoted 8 lines · Tony Luck
Quoted 1 line · Borislav Petkov
create mode 100644 arch/x86/ras/ras.cOverall it looks good - but I'm a bit puzzled by this
ras.cfile that gets created as an empty file in part1, and is still empty at the end of the series.What is going to go into it?
Yeah, maybe it should be called core.c and all the shared functionality would go there. I put it there initially for the first patch but I realize now, we won't need it just yet - I'll drop it.
Thanks.
Signature · 8 lines
Regards/Gruss, Boris. Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach GM: Alberto Bozzo Reg: Dornach, Landkreis Muenchen HRB Nr. 43632 WEEE Registernr: 129 19551