Skip to content

Commit 07f2d8c

Browse files
committed
Merge branch 'x86-ras-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 RAS changes from Ingo Molnar: "The main changes in this cycle were: - Simplify the CMCI storm logic on Intel CPUs after yet another report about a race in the code (Borislav Petkov) - Enable the MCE threshold irq on AMD CPUs by default (Aravind Gopalakrishnan) - Add AMD-specific MCE-severity grading function. Further error recovery actions will be based on its output (Aravind Gopalakrishnan) - Documentation updates (Borislav Petkov) - ... assorted fixes and cleanups" * 'x86-ras-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/mce/severity: Fix warning about indented braces x86/mce: Define mce_severity function pointer x86/mce: Add an AMD severities-grading function x86/mce: Reindent __mcheck_cpu_apply_quirks() properly x86/mce: Use safe MSR accesses for AMD quirk x86/MCE/AMD: Enable thresholding interrupts by default if supported x86/MCE: Make mce_panic() fatal machine check msg in the same pattern x86/MCE/intel: Cleanup CMCI storm logic Documentation/acpi/einj: Correct and streamline text x86/MCE/AMD: Drop bogus const modifier from AMD's bank4_names()
2 parents ee799f4 + cee8f5a commit 07f2d8c

File tree

7 files changed

+336
-181
lines changed

7 files changed

+336
-181
lines changed

Documentation/acpi/apei/einj.txt

Lines changed: 122 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,177 @@
11
APEI Error INJection
22
~~~~~~~~~~~~~~~~~~~~
33

4-
EINJ provides a hardware error injection mechanism
5-
It is very useful for debugging and testing of other APEI and RAS features.
4+
EINJ provides a hardware error injection mechanism. It is very useful
5+
for debugging and testing APEI and RAS features in general.
66

7-
To use EINJ, make sure the following are enabled in your kernel
7+
You need to check whether your BIOS supports EINJ first. For that, look
8+
for early boot messages similar to this one:
9+
10+
ACPI: EINJ 0x000000007370A000 000150 (v01 INTEL 00000001 INTL 00000001)
11+
12+
which shows that the BIOS is exposing an EINJ table - it is the
13+
mechanism through which the injection is done.
14+
15+
Alternatively, look in /sys/firmware/acpi/tables for an "EINJ" file,
16+
which is a different representation of the same thing.
17+
18+
It doesn't necessarily mean that EINJ is not supported if those above
19+
don't exist: before you give up, go into BIOS setup to see if the BIOS
20+
has an option to enable error injection. Look for something called WHEA
21+
or similar. Often, you need to enable an ACPI5 support option prior, in
22+
order to see the APEI,EINJ,... functionality supported and exposed by
23+
the BIOS menu.
24+
25+
To use EINJ, make sure the following are options enabled in your kernel
826
configuration:
927

1028
CONFIG_DEBUG_FS
1129
CONFIG_ACPI_APEI
1230
CONFIG_ACPI_APEI_EINJ
1331

14-
The user interface of EINJ is debug file system, under the
15-
directory apei/einj. The following files are provided.
32+
The EINJ user interface is in <debugfs mount point>/apei/einj.
33+
34+
The following files belong to it:
1635

1736
- available_error_type
18-
Reading this file returns the error injection capability of the
19-
platform, that is, which error types are supported. The error type
20-
definition is as follow, the left field is the error type value, the
21-
right field is error description.
22-
23-
0x00000001 Processor Correctable
24-
0x00000002 Processor Uncorrectable non-fatal
25-
0x00000004 Processor Uncorrectable fatal
26-
0x00000008 Memory Correctable
27-
0x00000010 Memory Uncorrectable non-fatal
28-
0x00000020 Memory Uncorrectable fatal
29-
0x00000040 PCI Express Correctable
30-
0x00000080 PCI Express Uncorrectable fatal
31-
0x00000100 PCI Express Uncorrectable non-fatal
32-
0x00000200 Platform Correctable
33-
0x00000400 Platform Uncorrectable non-fatal
34-
0x00000800 Platform Uncorrectable fatal
35-
36-
The format of file contents are as above, except there are only the
37-
available error type lines.
37+
38+
This file shows which error types are supported:
39+
40+
Error Type Value Error Description
41+
================ =================
42+
0x00000001 Processor Correctable
43+
0x00000002 Processor Uncorrectable non-fatal
44+
0x00000004 Processor Uncorrectable fatal
45+
0x00000008 Memory Correctable
46+
0x00000010 Memory Uncorrectable non-fatal
47+
0x00000020 Memory Uncorrectable fatal
48+
0x00000040 PCI Express Correctable
49+
0x00000080 PCI Express Uncorrectable fatal
50+
0x00000100 PCI Express Uncorrectable non-fatal
51+
0x00000200 Platform Correctable
52+
0x00000400 Platform Uncorrectable non-fatal
53+
0x00000800 Platform Uncorrectable fatal
54+
55+
The format of the file contents are as above, except present are only
56+
the available error types.
3857

3958
- error_type
40-
This file is used to set the error type value. The error type value
41-
is defined in "available_error_type" description.
59+
60+
Set the value of the error type being injected. Possible error types
61+
are defined in the file available_error_type above.
4262

4363
- error_inject
44-
Write any integer to this file to trigger the error
45-
injection. Before this, please specify all necessary error
46-
parameters.
64+
65+
Write any integer to this file to trigger the error injection. Make
66+
sure you have specified all necessary error parameters, i.e. this
67+
write should be the last step when injecting errors.
4768

4869
- flags
49-
Present for kernel version 3.13 and above. Used to specify which
50-
of param{1..4} are valid and should be used by BIOS during injection.
51-
Value is a bitmask as specified in ACPI5.0 spec for the
70+
71+
Present for kernel versions 3.13 and above. Used to specify which
72+
of param{1..4} are valid and should be used by the firmware during
73+
injection. Value is a bitmask as specified in ACPI5.0 spec for the
5274
SET_ERROR_TYPE_WITH_ADDRESS data structure:
53-
Bit 0 - Processor APIC field valid (see param3 below)
54-
Bit 1 - Memory address and mask valid (param1 and param2)
55-
Bit 2 - PCIe (seg,bus,dev,fn) valid (param4 below)
56-
If set to zero, legacy behaviour is used where the type of injection
57-
specifies just one bit set, and param1 is multiplexed.
75+
76+
Bit 0 - Processor APIC field valid (see param3 below).
77+
Bit 1 - Memory address and mask valid (param1 and param2).
78+
Bit 2 - PCIe (seg,bus,dev,fn) valid (see param4 below).
79+
80+
If set to zero, legacy behavior is mimicked where the type of
81+
injection specifies just one bit set, and param1 is multiplexed.
5882

5983
- param1
60-
This file is used to set the first error parameter value. Effect of
61-
parameter depends on error_type specified. For example, if error
62-
type is memory related type, the param1 should be a valid physical
63-
memory address. [Unless "flag" is set - see above]
84+
85+
This file is used to set the first error parameter value. Its effect
86+
depends on the error type specified in error_type. For example, if
87+
error type is memory related type, the param1 should be a valid
88+
physical memory address. [Unless "flag" is set - see above]
6489

6590
- param2
66-
This file is used to set the second error parameter value. Effect of
67-
parameter depends on error_type specified. For example, if error
68-
type is memory related type, the param2 should be a physical memory
69-
address mask. Linux requires page or narrower granularity, say,
70-
0xfffffffffffff000.
91+
92+
Same use as param1 above. For example, if error type is of memory
93+
related type, then param2 should be a physical memory address mask.
94+
Linux requires page or narrower granularity, say, 0xfffffffffffff000.
7195

7296
- param3
73-
Used when the 0x1 bit is set in "flag" to specify the APIC id
97+
98+
Used when the 0x1 bit is set in "flags" to specify the APIC id
7499

75100
- param4
76-
Used when the 0x4 bit is set in "flag" to specify target PCIe device
101+
Used when the 0x4 bit is set in "flags" to specify target PCIe device
77102

78103
- notrigger
79-
The EINJ mechanism is a two step process. First inject the error, then
80-
perform some actions to trigger it. Setting "notrigger" to 1 skips the
81-
trigger phase, which *may* allow the user to cause the error in some other
82-
context by a simple access to the cpu, memory location, or device that is
83-
the target of the error injection. Whether this actually works depends
84-
on what operations the BIOS actually includes in the trigger phase.
85-
86-
BIOS versions based in the ACPI 4.0 specification have limited options
87-
to control where the errors are injected. Your BIOS may support an
88-
extension (enabled with the param_extension=1 module parameter, or
89-
boot command line einj.param_extension=1). This allows the address
90-
and mask for memory injections to be specified by the param1 and
91-
param2 files in apei/einj.
92-
93-
BIOS versions using the ACPI 5.0 specification have more control over
94-
the target of the injection. For processor related errors (type 0x1,
95-
0x2 and 0x4) the APICID of the target should be provided using the
96-
param1 file in apei/einj. For memory errors (type 0x8, 0x10 and 0x20)
97-
the address is set using param1 with a mask in param2 (0x0 is equivalent
98-
to all ones). For PCI express errors (type 0x40, 0x80 and 0x100) the
99-
segment, bus, device and function are specified using param1:
104+
105+
The error injection mechanism is a two-step process. First inject the
106+
error, then perform some actions to trigger it. Setting "notrigger"
107+
to 1 skips the trigger phase, which *may* allow the user to cause the
108+
error in some other context by a simple access to the CPU, memory
109+
location, or device that is the target of the error injection. Whether
110+
this actually works depends on what operations the BIOS actually
111+
includes in the trigger phase.
112+
113+
BIOS versions based on the ACPI 4.0 specification have limited options
114+
in controlling where the errors are injected. Your BIOS may support an
115+
extension (enabled with the param_extension=1 module parameter, or boot
116+
command line einj.param_extension=1). This allows the address and mask
117+
for memory injections to be specified by the param1 and param2 files in
118+
apei/einj.
119+
120+
BIOS versions based on the ACPI 5.0 specification have more control over
121+
the target of the injection. For processor-related errors (type 0x1, 0x2
122+
and 0x4), you can set flags to 0x3 (param3 for bit 0, and param1 and
123+
param2 for bit 1) so that you have more information added to the error
124+
signature being injected. The actual data passed is this:
125+
126+
memory_address = param1;
127+
memory_address_range = param2;
128+
apicid = param3;
129+
pcie_sbdf = param4;
130+
131+
For memory errors (type 0x8, 0x10 and 0x20) the address is set using
132+
param1 with a mask in param2 (0x0 is equivalent to all ones). For PCI
133+
express errors (type 0x40, 0x80 and 0x100) the segment, bus, device and
134+
function are specified using param1:
100135

101136
31 24 23 16 15 11 10 8 7 0
102137
+-------------------------------------------------+
103138
| segment | bus | device | function | reserved |
104139
+-------------------------------------------------+
105140

106-
An ACPI 5.0 BIOS may also allow vendor specific errors to be injected.
141+
Anyway, you get the idea, if there's doubt just take a look at the code
142+
in drivers/acpi/apei/einj.c.
143+
144+
An ACPI 5.0 BIOS may also allow vendor-specific errors to be injected.
107145
In this case a file named vendor will contain identifying information
108146
from the BIOS that hopefully will allow an application wishing to use
109-
the vendor specific extension to tell that they are running on a BIOS
147+
the vendor-specific extension to tell that they are running on a BIOS
110148
that supports it. All vendor extensions have the 0x80000000 bit set in
111149
error_type. A file vendor_flags controls the interpretation of param1
112150
and param2 (1 = PROCESSOR, 2 = MEMORY, 4 = PCI). See your BIOS vendor
113151
documentation for details (and expect changes to this API if vendors
114152
creativity in using this feature expands beyond our expectations).
115153

116-
Example:
154+
155+
An error injection example:
156+
117157
# cd /sys/kernel/debug/apei/einj
118158
# cat available_error_type # See which errors can be injected
119159
0x00000002 Processor Uncorrectable non-fatal
120160
0x00000008 Memory Correctable
121161
0x00000010 Memory Uncorrectable non-fatal
122162
# echo 0x12345000 > param1 # Set memory address for injection
123-
# echo 0xfffffffffffff000 > param2 # Mask - anywhere in this page
163+
# echo $((-1 << 12)) > param2 # Mask 0xfffffffffffff000 - anywhere in this page
124164
# echo 0x8 > error_type # Choose correctable memory error
125165
# echo 1 > error_inject # Inject now
126166

167+
You should see something like this in dmesg:
168+
169+
[22715.830801] EDAC sbridge MC3: HANDLING MCE MEMORY ERROR
170+
[22715.834759] EDAC sbridge MC3: CPU 0: Machine Check Event: 0 Bank 7: 8c00004000010090
171+
[22715.834759] EDAC sbridge MC3: TSC 0
172+
[22715.834759] EDAC sbridge MC3: ADDR 12345000 EDAC sbridge MC3: MISC 144780c86
173+
[22715.834759] EDAC sbridge MC3: PROCESSOR 0:306e7 TIME 1422553404 SOCKET 0 APIC 0
174+
[22716.616173] EDAC MC3: 1 CE memory read error on CPU_SrcID#0_Channel#0_DIMM#0 (channel:0 slot:0 page:0x12345 offset:0x0 grain:32 syndrome:0x0 - area:DRAM err_code:0001:0090 socket:0 channel_mask:1 rank:0)
127175

128176
For more information about EINJ, please refer to ACPI specification
129177
version 4.0, section 17.5 and ACPI 5.0, section 18.6.

arch/x86/include/asm/mce.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ struct mca_config {
116116
u32 rip_msr;
117117
};
118118

119+
struct mce_vendor_flags {
120+
__u64 overflow_recov : 1, /* cpuid_ebx(80000007) */
121+
__reserved_0 : 63;
122+
};
123+
extern struct mce_vendor_flags mce_flags;
124+
119125
extern struct mca_config mca_cfg;
120126
extern void mce_register_decode_chain(struct notifier_block *nb);
121127
extern void mce_unregister_decode_chain(struct notifier_block *nb);
@@ -128,9 +134,11 @@ extern int mce_p5_enabled;
128134
#ifdef CONFIG_X86_MCE
129135
int mcheck_init(void);
130136
void mcheck_cpu_init(struct cpuinfo_x86 *c);
137+
void mcheck_vendor_init_severity(void);
131138
#else
132139
static inline int mcheck_init(void) { return 0; }
133140
static inline void mcheck_cpu_init(struct cpuinfo_x86 *c) {}
141+
static inline void mcheck_vendor_init_severity(void) {}
134142
#endif
135143

136144
#ifdef CONFIG_X86_ANCIENT_MCE
@@ -183,11 +191,11 @@ typedef DECLARE_BITMAP(mce_banks_t, MAX_NR_BANKS);
183191
DECLARE_PER_CPU(mce_banks_t, mce_poll_banks);
184192

185193
enum mcp_flags {
186-
MCP_TIMESTAMP = (1 << 0), /* log time stamp */
187-
MCP_UC = (1 << 1), /* log uncorrected errors */
188-
MCP_DONTLOG = (1 << 2), /* only clear, don't log */
194+
MCP_TIMESTAMP = BIT(0), /* log time stamp */
195+
MCP_UC = BIT(1), /* log uncorrected errors */
196+
MCP_DONTLOG = BIT(2), /* only clear, don't log */
189197
};
190-
void machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
198+
bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
191199

192200
int mce_notify_irq(void);
193201

arch/x86/kernel/cpu/mcheck/mce-internal.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ enum severity_level {
1414
};
1515

1616
#define ATTR_LEN 16
17+
#define INITIAL_CHECK_INTERVAL 5 * 60 /* 5 minutes */
1718

1819
/* One object for each MCE bank, shared by all CPUs */
1920
struct mce_bank {
@@ -23,20 +24,20 @@ struct mce_bank {
2324
char attrname[ATTR_LEN]; /* attribute name */
2425
};
2526

26-
int mce_severity(struct mce *a, int tolerant, char **msg, bool is_excp);
27+
extern int (*mce_severity)(struct mce *a, int tolerant, char **msg, bool is_excp);
2728
struct dentry *mce_get_debugfs_dir(void);
2829

2930
extern struct mce_bank *mce_banks;
3031
extern mce_banks_t mce_banks_ce_disabled;
3132

3233
#ifdef CONFIG_X86_MCE_INTEL
33-
unsigned long mce_intel_adjust_timer(unsigned long interval);
34-
void mce_intel_cmci_poll(void);
34+
unsigned long cmci_intel_adjust_timer(unsigned long interval);
35+
bool mce_intel_cmci_poll(void);
3536
void mce_intel_hcpu_update(unsigned long cpu);
3637
void cmci_disable_bank(int bank);
3738
#else
38-
# define mce_intel_adjust_timer mce_adjust_timer_default
39-
static inline void mce_intel_cmci_poll(void) { }
39+
# define cmci_intel_adjust_timer mce_adjust_timer_default
40+
static inline bool mce_intel_cmci_poll(void) { return false; }
4041
static inline void mce_intel_hcpu_update(unsigned long cpu) { }
4142
static inline void cmci_disable_bank(int bank) { }
4243
#endif

0 commit comments

Comments
 (0)