← Documents Documentation/firmware-guide/acpi/apei/einj.rst GitHub 원문 ↗

Linux 6.18.37 · Firmware

APEI Error INJection

APEI EINJ의 target parameter, EINJv2·CXL·SGX injection을 다룬 전문 번역입니다.

Source pathDocumentation/firmware-guide/acpi/apei/einj.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

einj.rst:1-271

EINJ는 BIOS ACPI table과 debugfs interface를 통해 processor·memory·PCIe·platform·CXL hardware error를 주입한다. 실제 crash와 data loss를 일으킬 수 있으므로 격리된 RAS test system에서만 사용하고 `error_inject` write는 모든 target parameter 검토 후 마지막에 수행한다.

`flags`는 param1..4와 EINJv2 extension의 validity를 지정한다. `notrigger`는 firmware trigger를 생략하며, vendor·CXL·SGX 경로는 generic memory example과 다른 interface·실행 context를 요구한다.

Injection 후에는 dmesg의 EDAC·MCE address, topology, syndrome을 설정값과 대조해야 한다. 지원 type과 target encoding은 BIOS ACPI version, vendor documentation과 `drivers/acpi/apei/einj.c`를 함께 기준으로 삼는다.

안전한 EINJ test
격리된 test host와 복구 절차 준비BIOS table·kernel CONFIG·available type 확인Error type·target·flags 설정모든 parameter와 side effect 재검토error_inject로 실행EDAC·MCE·CXL log 검증 후 환경 복구

Capability 확인부터 RAS log 검증과 복구까지의 전체 흐름이다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ====================
4 APEI Error INJection
5 ====================
6
7 EINJ provides a hardware error injection mechanism. It is very useful
8 for debugging and testing APEI and RAS features in general.
9
10 You need to check whether your BIOS supports EINJ first. For that, look
11 for early boot messages similar to this one::
12
13 ACPI: EINJ 0x000000007370A000 000150 (v01 INTEL 00000001 INTL 00000001)
14
15 which shows that the BIOS is exposing an EINJ table - it is the
16 mechanism through which the injection is done.
17
18 Alternatively, look in /sys/firmware/acpi/tables for an "EINJ" file,
19 which is a different representation of the same thing.
20
21 It doesn't necessarily mean that EINJ is not supported if those above
22 don't exist: before you give up, go into BIOS setup to see if the BIOS
23 has an option to enable error injection. Look for something called WHEA
24 or similar. Often, you need to enable an ACPI5 support option prior, in
25 order to see the APEI,EINJ,... functionality supported and exposed by
26 the BIOS menu.
27
28 To use EINJ, make sure the following are options enabled in your kernel
29 configuration::
30
31 CONFIG_DEBUG_FS
32 CONFIG_ACPI_APEI
33 CONFIG_ACPI_APEI_EINJ
34
35 ...and to (optionally) enable CXL protocol error injection set::
36
37 CONFIG_ACPI_APEI_EINJ_CXL
38
39 The EINJ user interface is in <debugfs mount point>/apei/einj.
40
41 The following files belong to it:
42
43 - available_error_type
44
45 This file shows which error types are supported:
46
47 ================ ===================================
48 Error Type Value Error Description
49 ================ ===================================
50 0x00000001 Processor Correctable
51 0x00000002 Processor Uncorrectable non-fatal
52 0x00000004 Processor Uncorrectable fatal
53 0x00000008 Memory Correctable
54 0x00000010 Memory Uncorrectable non-fatal
55 0x00000020 Memory Uncorrectable fatal
56 0x00000040 PCI Express Correctable
57 0x00000080 PCI Express Uncorrectable non-fatal
58 0x00000100 PCI Express Uncorrectable fatal
59 0x00000200 Platform Correctable
60 0x00000400 Platform Uncorrectable non-fatal
61 0x00000800 Platform Uncorrectable fatal
62 V2_0x00000001 EINJV2 Processor Error
63 V2_0x00000002 EINJV2 Memory Error
64 V2_0x00000004 EINJV2 PCI Express Error
65 ================ ===================================
66
67 The format of the file contents are as above, except present are only
68 the available error types.
69
70 - error_type
71
72 Set the value of the error type being injected. Possible error types
73 are defined in the file available_error_type above.
74
75 - error_inject
76
77 Write any integer to this file to trigger the error injection. Make
78 sure you have specified all necessary error parameters, i.e. this
79 write should be the last step when injecting errors.
80
81 - flags
82
83 Present for kernel versions 3.13 and above. Used to specify which
84 of param{1..4} are valid and should be used by the firmware during
85 injection. Value is a bitmask as specified in ACPI5.0 spec for the
86 SET_ERROR_TYPE_WITH_ADDRESS data structure:
87
88 Bit 0
89 Processor APIC field valid (see param3 below).
90 Bit 1
91 Memory address and mask valid (param1 and param2).
92 Bit 2
93 PCIe (seg,bus,dev,fn) valid (see param4 below).
94 Bit 3
95 EINJv2 extension structure is valid
96
97 If set to zero, legacy behavior is mimicked where the type of
98 injection specifies just one bit set, and param1 is multiplexed.
99
100 - param1
101
102 This file is used to set the first error parameter value. Its effect
103 depends on the error type specified in error_type. For example, if
104 error type is memory related type, the param1 should be a valid
105 physical memory address. [Unless "flag" is set - see above]
106
107 - param2
108
109 Same use as param1 above. For example, if error type is of memory
110 related type, then param2 should be a physical memory address mask.
111 Linux requires page or narrower granularity, say, 0xfffffffffffff000.
112
113 - param3
114
115 Used when the 0x1 bit is set in "flags" to specify the APIC id
116
117 - param4
118 Used when the 0x4 bit is set in "flags" to specify target PCIe device
119
120 - notrigger
121
122 The error injection mechanism is a two-step process. First inject the
123 error, then perform some actions to trigger it. Setting "notrigger"
124 to 1 skips the trigger phase, which *may* allow the user to cause the
125 error in some other context by a simple access to the CPU, memory
126 location, or device that is the target of the error injection. Whether
127 this actually works depends on what operations the BIOS actually
128 includes in the trigger phase.
129
130 - component_id0 .. component_idN, component_syndrome0 .. component_syndromeN
131
132 These files are used to set the "Component Array" field
133 of the EINJv2 Extension Structure. Each holds a 128-bit
134 hex value. Writing just a newline to any of these files
135 sets an invalid (all-ones) value.
136
137 CXL error types are supported from ACPI 6.5 onwards (given a CXL port
138 is present). The EINJ user interface for CXL error types is at
139 <debugfs mount point>/cxl. The following files belong to it:
140
141 - einj_types:
142
143 Provides the same functionality as available_error_types above, but
144 for CXL error types
145
146 - $dport_dev/einj_inject:
147
148 Injects a CXL error type into the CXL port represented by $dport_dev,
149 where $dport_dev is the name of the CXL port (usually a PCIe device name).
150 Error injections targeting a CXL 2.0+ port can use the legacy interface
151 under <debugfs mount point>/apei/einj, while CXL 1.1/1.0 port injections
152 must use this file.
153
154
155 BIOS versions based on the ACPI 4.0 specification have limited options
156 in controlling where the errors are injected. Your BIOS may support an
157 extension (enabled with the param_extension=1 module parameter, or boot
158 command line einj.param_extension=1). This allows the address and mask
159 for memory injections to be specified by the param1 and param2 files in
160 apei/einj.
161
162 BIOS versions based on the ACPI 5.0 specification have more control over
163 the target of the injection. For processor-related errors (type 0x1, 0x2
164 and 0x4), you can set flags to 0x3 (param3 for bit 0, and param1 and
165 param2 for bit 1) so that you have more information added to the error
166 signature being injected. The actual data passed is this::
167
168 memory_address = param1;
169 memory_address_range = param2;
170 apicid = param3;
171 pcie_sbdf = param4;
172
173 For memory errors (type 0x8, 0x10 and 0x20) the address is set using
174 param1 with a mask in param2 (0x0 is equivalent to all ones). For PCI
175 express errors (type 0x40, 0x80 and 0x100) the segment, bus, device and
176 function are specified using param1::
177
178 31 24 23 16 15 11 10 8 7 0
179 +-------------------------------------------------+
180 | segment | bus | device | function | reserved |
181 +-------------------------------------------------+
182
183 Anyway, you get the idea, if there's doubt just take a look at the code
184 in drivers/acpi/apei/einj.c.
185
186 An ACPI 5.0 BIOS may also allow vendor-specific errors to be injected.
187 In this case a file named vendor will contain identifying information
188 from the BIOS that hopefully will allow an application wishing to use
189 the vendor-specific extension to tell that they are running on a BIOS
190 that supports it. All vendor extensions have the 0x80000000 bit set in
191 error_type. A file vendor_flags controls the interpretation of param1
192 and param2 (1 = PROCESSOR, 2 = MEMORY, 4 = PCI). See your BIOS vendor
193 documentation for details (and expect changes to this API if vendors
194 creativity in using this feature expands beyond our expectations).
195
196
197 An error injection example::
198
199 # cd /sys/kernel/debug/apei/einj
200 # cat available_error_type # See which errors can be injected
201 0x00000002 Processor Uncorrectable non-fatal
202 0x00000008 Memory Correctable
203 0x00000010 Memory Uncorrectable non-fatal
204 # echo 0x12345000 > param1 # Set memory address for injection
205 # echo 0xfffffffffffff000 > param2 # Mask - anywhere in this page
206 # echo 0x8 > error_type # Choose correctable memory error
207 # echo 1 > error_inject # Inject now
208
209 An EINJv2 error injection example::
210
211 # cd /sys/kernel/debug/apei/einj
212 # cat available_error_type # See which errors can be injected
213 0x00000002 Processor Uncorrectable non-fatal
214 0x00000008 Memory Correctable
215 0x00000010 Memory Uncorrectable non-fatal
216 V2_0x00000001 EINJV2 Processor Error
217 V2_0x00000002 EINJV2 Memory Error
218
219 # echo 0x12345000 > param1 # Set memory address for injection
220 # echo 0xfffffffffffff000 > param2 # Range - anywhere in this page
221 # echo 0x1 > component_id0 # First device ID
222 # echo 0x4 > component_syndrome0 # First error syndrome
223 # echo 0x2 > component_id1 # Second device ID
224 # echo 0x4 > component_syndrome1 # Second error syndrome
225 # echo '' > component_id2 # Mark id2 invalid to terminate list
226 # echo V2_0x2 > error_type # Choose EINJv2 memory error
227 # echo 0xa > flags # set flags to indicate EINJv2
228 # echo 1 > error_inject # Inject now
229
230 You should see something like this in dmesg::
231
232 [22715.830801] EDAC sbridge MC3: HANDLING MCE MEMORY ERROR
233 [22715.834759] EDAC sbridge MC3: CPU 0: Machine Check Event: 0 Bank 7: 8c00004000010090
234 [22715.834759] EDAC sbridge MC3: TSC 0
235 [22715.834759] EDAC sbridge MC3: ADDR 12345000 EDAC sbridge MC3: MISC 144780c86
236 [22715.834759] EDAC sbridge MC3: PROCESSOR 0:306e7 TIME 1422553404 SOCKET 0 APIC 0
237 [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)
238
239 A CXL error injection example with $dport_dev=0000:e0:01.1::
240
241 # cd /sys/kernel/debug/cxl/
242 # ls
243 0000:e0:01.1 0000:0c:00.0
244 # cat einj_types # See which errors can be injected
245 0x00008000 CXL.mem Protocol Correctable
246 0x00010000 CXL.mem Protocol Uncorrectable non-fatal
247 0x00020000 CXL.mem Protocol Uncorrectable fatal
248 # cd 0000:e0:01.1 # Navigate to dport to inject into
249 # echo 0x8000 > einj_inject # Inject error
250
251 Special notes for injection into SGX enclaves:
252
253 There may be a separate BIOS setup option to enable SGX injection.
254
255 The injection process consists of setting some special memory controller
256 trigger that will inject the error on the next write to the target
257 address. But the h/w prevents any software outside of an SGX enclave
258 from accessing enclave pages (even BIOS SMM mode).
259
260 The following sequence can be used:
261 1) Determine physical address of enclave page
262 2) Use "notrigger=1" mode to inject (this will setup
263 the injection address, but will not actually inject)
264 3) Enter the enclave
265 4) Store data to the virtual address matching physical address from step 1
266 5) Execute CLFLUSH for that virtual address
267 6) Spin delay for 250ms
268 7) Read from the virtual address. This will trigger the error
269
270 For more information about EINJ, please refer to ACPI specification
271 version 4.0, section 17.5 and ACPI 5.0, section 18.6.
272

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

BIOS 지원 확인과 kernel 설정

1-39

EINJ(Error INJection)는 hardware error를 의도적으로 주입하여 APEI(ACPI Platform Error Interface)와 RAS(Reliability, Availability, Serviceability) 기능을 debug·test하는 mechanism이다. 실제 machine check, memory·PCIe·platform error를 발생시킬 수 있으므로 production system이나 보존해야 할 data가 있는 환경이 아니라 격리된 test system에서만 사용해야 한다.

먼저 BIOS가 EINJ를 지원하는지 확인한다. Early boot log의 `ACPI: EINJ ...` message는 BIOS가 injection mechanism을 기술하는 EINJ ACPI table을 노출했다는 뜻이다. 같은 table의 다른 표현은 `/sys/firmware/acpi/tables/EINJ`에서 확인할 수 있다.

둘 다 보이지 않아도 곧바로 미지원이라고 단정하지 않는다. BIOS setup에서 error injection, WHEA 또는 유사한 option을 찾고, APEI·EINJ menu를 노출하기 전에 필요한 ACPI5 support option을 먼저 켜야 하는지도 확인한다.

Kernel에서는 `CONFIG_DEBUG_FS`, `CONFIG_ACPI_APEI`, `CONFIG_ACPI_APEI_EINJ`가 필요하다. CXL protocol error injection까지 사용하려면 `CONFIG_ACPI_APEI_EINJ_CXL`을 추가한다. 기본 interface는 `<debugfs mount point>/apei/einj`에 생성된다.

CONFIG_DEBUG_FS
CONFIG_ACPI_APEI
CONFIG_ACPI_APEI_EINJ
CONFIG_ACPI_APEI_EINJ_CXL  # optional CXL injection
EINJ 준비 확인
격리된 test system과 복구 계획 준비Early boot log에서 `ACPI: EINJ` 확인또는 `/sys/firmware/acpi/tables/EINJ` 확인없으면 BIOS의 WHEA·ACPI5·error injection option 확인필수 kernel CONFIG 활성화debugfs의 `/apei/einj` interface 확인

Firmware capability부터 debugfs interface까지 단계별로 검증한다.

EINJ kernel configuration
Option필수 여부역할
CONFIG_DEBUG_FS필수EINJ userspace file interface 제공
CONFIG_ACPI_APEI필수APEI core 활성화
CONFIG_ACPI_APEI_EINJ필수EINJ driver 활성화
CONFIG_ACPI_APEI_EINJ_CXLCXL에 선택CXL protocol error injection

기본 APEI injection과 선택 CXL injection에 필요한 option이다.

.. SPDX-License-Identifier: GPL-2.0

====================
APEI Error INJection
====================

EINJ provides a hardware error injection mechanism. It is very useful
for debugging and testing APEI and RAS features in general.

You need to check whether your BIOS supports EINJ first. For that, look
for early boot messages similar to this one::

  ACPI: EINJ 0x000000007370A000 000150 (v01 INTEL           00000001 INTL 00000001)

which shows that the BIOS is exposing an EINJ table - it is the
mechanism through which the injection is done.

Alternatively, look in /sys/firmware/acpi/tables for an "EINJ" file,
which is a different representation of the same thing.

It doesn't necessarily mean that EINJ is not supported if those above
don't exist: before you give up, go into BIOS setup to see if the BIOS
has an option to enable error injection. Look for something called WHEA
or similar. Often, you need to enable an ACPI5 support option prior, in
order to see the APEI,EINJ,... functionality supported and exposed by
the BIOS menu.

To use EINJ, make sure the following are options enabled in your kernel
configuration::

  CONFIG_DEBUG_FS
  CONFIG_ACPI_APEI
  CONFIG_ACPI_APEI_EINJ

...and to (optionally) enable CXL protocol error injection set::

  CONFIG_ACPI_APEI_EINJ_CXL

The EINJ user interface is in <debugfs mount point>/apei/einj.

지원 error type과 최종 trigger

40-80

`available_error_type`은 현재 BIOS와 platform이 지원하는 error type만 표 형식으로 보여 준다. Processor, memory, PCI Express, platform 범주는 각각 correctable, uncorrectable non-fatal, uncorrectable fatal bit를 가지며 EINJv2는 processor·memory·PCI Express extension type을 별도로 표시한다.

EINJ error type 값
범주심각도·형식
0x00000001ProcessorCorrectable
0x00000002ProcessorUncorrectable non-fatal
0x00000004ProcessorUncorrectable fatal
0x00000008MemoryCorrectable
0x00000010MemoryUncorrectable non-fatal
0x00000020MemoryUncorrectable fatal
0x00000040PCI ExpressCorrectable
0x00000080PCI ExpressUncorrectable non-fatal
0x00000100PCI ExpressUncorrectable fatal
0x00000200PlatformCorrectable
0x00000400PlatformUncorrectable non-fatal
0x00000800PlatformUncorrectable fatal
V2_0x00000001EINJv2 ProcessorExtension structure
V2_0x00000002EINJv2 MemoryExtension structure
V2_0x00000004EINJv2 PCI ExpressExtension structure

원문의 error type bit와 설명을 구조화한 표다.

`error_type`에 `available_error_type`에 실제로 표시된 값 중 주입할 type을 쓴다. 문서의 전체 표에 값이 있어도 현재 platform file에 없으면 지원한다고 가정하면 안 된다.

`error_inject`에 임의의 integer를 쓰면 injection이 실행된다. 이 write는 되돌릴 수 없는 최종 trigger이므로 address, mask, APIC ID, PCIe target, component array, flags와 `notrigger`를 모두 설정하고 검토한 뒤 마지막에 수행해야 한다.

Error injection commit 순서
`available_error_type`에서 실제 지원값 확인`error_type`과 target parameter 결정`flags`로 유효 field 지정Address·mask·APIC·PCIe·component 값 재검토필요하면 `notrigger` 설정마지막으로 `error_inject`에 integer write

`error_inject` write 전 모든 parameter를 확정하는 안전한 순서다.


The following files belong to it:

- available_error_type

  This file shows which error types are supported:

  ================  ===================================
  Error Type Value        Error Description
  ================  ===================================
  0x00000001        Processor Correctable
  0x00000002        Processor Uncorrectable non-fatal
  0x00000004        Processor Uncorrectable fatal
  0x00000008        Memory Correctable
  0x00000010        Memory Uncorrectable non-fatal
  0x00000020        Memory Uncorrectable fatal
  0x00000040        PCI Express Correctable
  0x00000080        PCI Express Uncorrectable non-fatal
  0x00000100        PCI Express Uncorrectable fatal
  0x00000200        Platform Correctable
  0x00000400        Platform Uncorrectable non-fatal
  0x00000800        Platform Uncorrectable fatal
  V2_0x00000001     EINJV2 Processor Error
  V2_0x00000002     EINJV2 Memory Error
  V2_0x00000004     EINJV2 PCI Express Error
  ================  ===================================

  The format of the file contents are as above, except present are only
  the available error types.

- error_type

  Set the value of the error type being injected. Possible error types
  are defined in the file available_error_type above.

- error_inject

  Write any integer to this file to trigger the error injection. Make
  sure you have specified all necessary error parameters, i.e. this
  write should be the last step when injecting errors.

flags와 param1..4 의미

81-119

Kernel 3.13 이상에서 `flags`는 firmware가 `param1`부터 `param4` 중 어떤 field를 유효하게 사용할지 나타내는 bitmask다. ACPI 5.0 `SET_ERROR_TYPE_WITH_ADDRESS` data structure의 validity bit를 그대로 따른다.

EINJ flags bit
BitMask유효해지는 field
00x1Processor APIC, param3
10x2Memory address와 mask, param1·param2
20x4PCIe segment·bus·device·function, param4
30x8EINJv2 extension structure

각 bit가 활성화하는 target parameter field다.

`flags=0`은 legacy behavior를 흉내 낸다. Injection type에는 bit 하나만 설정하고 `param1`을 type에 따라 multiplex한다. 명시적 target field를 쓰는 새 방식과 legacy 해석을 섞지 않도록 BIOS specification을 확인해야 한다.

`param1`은 error type에 따른 첫 parameter다. Memory error이면 valid physical address가 된다. `param2`는 같은 범주의 두 번째 parameter이며 memory error에서는 physical address mask다. Linux는 page 또는 그보다 좁은 granularity를 요구하며 예시는 `0xfffffffffffff000`이다.

`flags` bit 0, 즉 `0x1`이 설정되면 `param3`은 APIC ID를 지정한다. Bit 2, 즉 `0x4`가 설정되면 `param4`는 target PCIe device를 지정한다. Parameter 값을 써 두는 것만으로는 부족하고 대응 validity bit도 일치해야 firmware가 그 값을 사용한다.

EINJ parameter 역할
File대표 의미연결 flag
param1Memory physical address 또는 legacy multiplexed valueMemory validity bit 1
param2Memory physical address maskMemory validity bit 1
param3Processor APIC IDProcessor validity bit 0
param4Target PCIe devicePCIe validity bit 2

Error category와 flags에 따라 같은 file의 해석이 달라진다.

- flags

  Present for kernel versions 3.13 and above. Used to specify which
  of param{1..4} are valid and should be used by the firmware during
  injection. Value is a bitmask as specified in ACPI5.0 spec for the
  SET_ERROR_TYPE_WITH_ADDRESS data structure:

    Bit 0
      Processor APIC field valid (see param3 below).
    Bit 1
      Memory address and mask valid (param1 and param2).
    Bit 2
      PCIe (seg,bus,dev,fn) valid (see param4 below).
    Bit 3
      EINJv2 extension structure is valid

  If set to zero, legacy behavior is mimicked where the type of
  injection specifies just one bit set, and param1 is multiplexed.

- param1

  This file is used to set the first error parameter value. Its effect
  depends on the error type specified in error_type. For example, if
  error type is memory related type, the param1 should be a valid
  physical memory address. [Unless "flag" is set - see above]

- param2

  Same use as param1 above. For example, if error type is of memory
  related type, then param2 should be a physical memory address mask.
  Linux requires page or narrower granularity, say, 0xfffffffffffff000.

- param3

  Used when the 0x1 bit is set in "flags" to specify the APIC id

- param4
  Used when the 0x4 bit is set in "flags" to specify target PCIe device

notrigger·EINJv2 component·CXL interface

120-152

Error injection은 보통 error를 장치에 설정하는 단계와 실제 access 등으로 error를 trigger하는 두 단계로 이뤄진다. `notrigger=1`은 BIOS-defined trigger phase를 건너뛰어 사용자가 이후 CPU, memory location 또는 device access라는 다른 context에서 error를 발생시킬 가능성을 준다.

실제로 이 방식이 동작하는지는 BIOS trigger phase에 어떤 operation이 포함됐는지에 달려 있다. `notrigger`는 error 설정을 취소하는 option이 아니며, target에 대한 다음 access가 치명적 error를 일으킬 수 있으므로 injection state와 후속 operation을 통제해야 한다.

`component_id0..N`과 `component_syndrome0..N`은 EINJv2 Extension Structure의 Component Array를 설정한다. 각 file은 128-bit hexadecimal value 하나를 가지며, newline만 쓰면 all-ones invalid value가 되어 array의 유효 entry를 끝내는 데 사용할 수 있다.

CXL error type은 CXL port가 있을 때 ACPI 6.5부터 지원된다. `<debugfs mount point>/cxl/einj_types`는 CXL 지원 type을 보여 주고 `$dport_dev/einj_inject`는 해당 CXL port에 type을 주입한다. CXL 2.0 이상 port는 legacy `/apei/einj` interface도 쓸 수 있지만 CXL 1.1·1.0 port는 dport별 file을 사용해야 한다.

notrigger의 two-step injection
Target과 error parameter 설정`notrigger=1` 지정`error_inject`로 error mechanism armBIOS trigger phase는 생략사용자가 target CPU·memory·device accessPlatform이 지원하면 그 context에서 error 발생

Firmware trigger를 생략하고 target access로 error를 일으키는 경로다.

CXL EINJ interface 선택
대상지원 type 조회Injection path
CXL 공통`/sys/kernel/debug/cxl/einj_types`Dport directory 선택
CXL 2.0 이상CXL 또는 legacy capability 확인`/apei/einj` legacy interface도 가능
CXL 1.1·1.0CXL einj_types`/cxl/$dport_dev/einj_inject` 필수

CXL port generation에 따라 사용할 debugfs path가 다르다.

- notrigger

  The error injection mechanism is a two-step process. First inject the
  error, then perform some actions to trigger it. Setting "notrigger"
  to 1 skips the trigger phase, which *may* allow the user to cause the
  error in some other context by a simple access to the CPU, memory
  location, or device that is the target of the error injection. Whether
  this actually works depends on what operations the BIOS actually
  includes in the trigger phase.

- component_id0 .. component_idN, component_syndrome0 .. component_syndromeN

  These files are used to set the "Component Array" field
  of the EINJv2 Extension Structure. Each holds a 128-bit
  hex value. Writing just a newline to any of these files
  sets an invalid (all-ones) value.

CXL error types are supported from ACPI 6.5 onwards (given a CXL port
is present). The EINJ user interface for CXL error types is at
<debugfs mount point>/cxl. The following files belong to it:

- einj_types:

  Provides the same functionality as available_error_types above, but
  for CXL error types

- $dport_dev/einj_inject:

  Injects a CXL error type into the CXL port represented by $dport_dev,
  where $dport_dev is the name of the CXL port (usually a PCIe device name).
  Error injections targeting a CXL 2.0+ port can use the legacy interface
  under <debugfs mount point>/apei/einj, while CXL 1.1/1.0 port injections
  must use this file.

ACPI 4.0·5.0 target 지정과 PCIe SBDF

153-184

ACPI 4.0 기반 BIOS는 injection target 제어가 제한적일 수 있다. BIOS extension을 지원하면 module parameter `param_extension=1` 또는 boot command line `einj.param_extension=1`로 켜고, `apei/einj`의 `param1`과 `param2`로 memory address와 mask를 지정한다.

ACPI 5.0 BIOS는 더 세밀한 target을 허용한다. Processor error type `0x1`, `0x2`, `0x4`에서 `flags=0x3`을 쓰면 bit 0의 `param3` APIC ID와 bit 1의 `param1` address·`param2` range를 error signature에 함께 넣는다.

SET_ERROR_TYPE_WITH_ADDRESS 전달값
Firmware fieldDebugfs source
memory_addressparam1
memory_address_rangeparam2
apicidparam3
pcie_sbdfparam4

Debugfs parameter가 firmware data structure field로 대응되는 관계다.

Memory error type `0x8`, `0x10`, `0x20`은 `param1`에 address, `param2`에 mask를 쓴다. Mask `0x0`은 all-ones와 동등하다. PCI Express error type `0x40`, `0x80`, `0x100`은 segment, bus, device, function을 packed value로 지정한다.

PCIe target packed field
BitField의미
31:24segmentPCI segment
23:16busPCI bus number
15:11devicePCI device number
10:8functionPCI function number
7:0reserved예약 field

원문의 32-bit diagram을 bit range 표로 정리한다.

BIOS 구현과 specification 해석이 의심스러우면 kernel source `drivers/acpi/apei/einj.c`를 확인한다. User interface 값, flags와 firmware method 호출의 실제 대응은 이 driver code가 최종 기준이다.

Target encoding 선택
BIOS ACPI version과 extension 확인Processor·memory·PCIe error category 선택Address·range·APIC·SBDF parameter 작성해당 field의 flags bit 설정Driver code와 available type으로 조합 검증마지막에 injection 실행

Error category에 맞는 parameter와 validity bit를 조합한다.



BIOS versions based on the ACPI 4.0 specification have limited options
in controlling where the errors are injected. Your BIOS may support an
extension (enabled with the param_extension=1 module parameter, or boot
command line einj.param_extension=1). This allows the address and mask
for memory injections to be specified by the param1 and param2 files in
apei/einj.

BIOS versions based on the ACPI 5.0 specification have more control over
the target of the injection. For processor-related errors (type 0x1, 0x2
and 0x4), you can set flags to 0x3 (param3 for bit 0, and param1 and
param2 for bit 1) so that you have more information added to the error
signature being injected. The actual data passed is this::

        memory_address = param1;
        memory_address_range = param2;
        apicid = param3;
        pcie_sbdf = param4;

For memory errors (type 0x8, 0x10 and 0x20) the address is set using
param1 with a mask in param2 (0x0 is equivalent to all ones). For PCI
express errors (type 0x40, 0x80 and 0x100) the segment, bus, device and
function are specified using param1::

         31     24 23    16 15    11 10      8  7        0
        +-------------------------------------------------+
        | segment |   bus  | device | function | reserved |
        +-------------------------------------------------+

Anyway, you get the idea, if there's doubt just take a look at the code
in drivers/acpi/apei/einj.c.

Vendor-specific error extension

185-196

ACPI 5.0 BIOS는 vendor-specific error injection을 제공할 수 있다. 이때 `vendor` file에는 application이 현재 BIOS가 해당 extension을 지원하는지 식별할 수 있도록 BIOS가 제공한 정보가 들어간다.

모든 vendor extension은 `error_type`의 `0x80000000` bit를 설정한다. `vendor_flags`는 `param1`과 `param2` 해석 범주를 정하며 값 1은 PROCESSOR, 2는 MEMORY, 4는 PCI를 뜻한다.

구체적인 parameter layout과 side effect는 BIOS vendor documentation을 따라야 한다. 원문도 vendor가 기능을 확장하는 방식에 따라 API가 바뀔 수 있다고 경고하므로 generic EINJ value를 vendor extension에 그대로 적용해서는 안 된다.

Vendor extension 식별
항목값·역할
vendorBIOS extension 식별 정보
error_type0x80000000 bit가 vendor extension 표시
vendor_flags=1PROCESSOR parameter 해석
vendor_flags=2MEMORY parameter 해석
vendor_flags=4PCI parameter 해석

Generic interface에서 vendor-specific payload를 구분하는 field다.


An ACPI 5.0 BIOS may also allow vendor-specific errors to be injected.
In this case a file named vendor will contain identifying information
from the BIOS that hopefully will allow an application wishing to use
the vendor-specific extension to tell that they are running on a BIOS
that supports it. All vendor extensions have the 0x80000000 bit set in
error_type. A file vendor_flags controls the interpretation of param1
and param2 (1 = PROCESSOR, 2 = MEMORY, 4 = PCI). See your BIOS vendor
documentation for details (and expect changes to this API if vendors
creativity in using this feature expands beyond our expectations).

Correctable memory error 예제

197-208

기본 예제는 debugfs EINJ directory로 이동해 `available_error_type`을 확인한 뒤 physical address `0x12345000`과 page mask `0xfffffffffffff000`을 설정한다. `error_type=0x8`은 correctable memory error다.

마지막 `echo 1 > error_inject`가 실제 injection을 실행한다. 예제 address가 현재 system에서 안전하거나 test memory에 속한다는 보장은 없으므로 그대로 실행하지 말고 physical allocation, NUMA·DIMM mapping과 workload 격리를 먼저 확인해야 한다.

# cd /sys/kernel/debug/apei/einj
# echo 0x12345000 > param1
# echo 0xfffffffffffff000 > param2
# echo 0x8 > error_type
# echo 1 > error_inject
기본 memory injection
`available_error_type`에서 0x8 지원 확인param1에 test physical address 설정param2에 page mask 설정error_type에 0x8 설정설정과 target을 다시 검토error_inject에 1을 써 실행

지원 type 조회부터 final trigger까지의 command 의미다.

기본 예제 parameter
File의미
param10x12345000Target physical address
param20xfffffffffffff000같은 page 범위 mask
error_type0x8Memory Correctable
error_inject1최종 injection trigger

각 command가 선택하는 memory target과 error다.

An error injection example::

  # cd /sys/kernel/debug/apei/einj
  # cat available_error_type                # See which errors can be injected
  0x00000002        Processor Uncorrectable non-fatal
  0x00000008        Memory Correctable
  0x00000010        Memory Uncorrectable non-fatal
  # echo 0x12345000 > param1                # Set memory address for injection
  # echo 0xfffffffffffff000 > param2                # Mask - anywhere in this page
  # echo 0x8 > error_type                        # Choose correctable memory error
  # echo 1 > error_inject                        # Inject now

EINJv2 component array와 dmesg 결과

209-238

EINJv2 예제는 address·range에 더해 두 component의 ID와 syndrome을 설정한다. `component_id0=0x1`, `component_syndrome0=0x4`, `component_id1=0x2`, `component_syndrome1=0x4`이며 `component_id2`에는 newline만 써 invalid marker로 component list를 끝낸다.

`error_type=V2_0x2`는 EINJv2 memory error를 선택한다. `flags=0xa`는 bit 1의 memory address·mask validity와 bit 3의 EINJv2 extension validity를 함께 설정한다. 모든 field 뒤에 `error_inject=1`로 실행한다.

EINJv2 memory injection
V2_0x2 지원 여부 확인param1·param2에 address와 range 설정component 0·1의 ID와 syndrome 작성component_id2에 newline을 써 list 종료error_type=V2_0x2, flags=0xaerror_inject=1로 실행

Address와 component array를 함께 firmware에 전달한다.

성공한 correctable memory injection은 dmesg에서 EDAC·Machine Check Event로 관찰할 수 있다. 예제 log는 `ADDR 12345000`, CPU·bank·socket·APIC, channel·DIMM·page·offset·syndrome을 포함해 지정 target과 실제 RAS report를 대조하게 한다.

dmesg 검증 지점
Log field검증 내용
HANDLING MCE MEMORY ERRORMemory error path 진입
ADDR 12345000주입 physical address 일치
CPU·Bank·Socket·APICProcessor topology와 error source
Channel·DIMM·Page·OffsetMemory topology와 location
Syndrome·err_codeError classification과 signature

Injection parameter가 RAS log에 반영됐는지 확인하는 field다.

An EINJv2 error injection example::

  # cd /sys/kernel/debug/apei/einj
  # cat available_error_type                        # See which errors can be injected
  0x00000002        Processor Uncorrectable non-fatal
  0x00000008        Memory Correctable
  0x00000010        Memory Uncorrectable non-fatal
  V2_0x00000001        EINJV2 Processor Error
  V2_0x00000002        EINJV2 Memory Error

  # echo 0x12345000 > param1                        # Set memory address for injection
  # echo 0xfffffffffffff000 > param2                # Range - anywhere in this page
  # echo 0x1 > component_id0                        # First device ID
  # echo 0x4 > component_syndrome0                # First error syndrome
  # echo 0x2 > component_id1                        # Second device ID
  # echo 0x4 > component_syndrome1                # Second error syndrome
  # echo '' > component_id2                        # Mark id2 invalid to terminate list
  # echo V2_0x2 > error_type                        # Choose EINJv2 memory error
  # echo 0xa > flags                                # set flags to indicate EINJv2
  # echo 1 > error_inject                        # Inject now

You should see something like this in dmesg::

  [22715.830801] EDAC sbridge MC3: HANDLING MCE MEMORY ERROR
  [22715.834759] EDAC sbridge MC3: CPU 0: Machine Check Event: 0 Bank 7: 8c00004000010090
  [22715.834759] EDAC sbridge MC3: TSC 0
  [22715.834759] EDAC sbridge MC3: ADDR 12345000 EDAC sbridge MC3: MISC 144780c86
  [22715.834759] EDAC sbridge MC3: PROCESSOR 0:306e7 TIME 1422553404 SOCKET 0 APIC 0
  [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)

CXL dport error injection 예제

239-250

CXL 예제의 target dport는 PCIe device name `0000:e0:01.1`이다. `/sys/kernel/debug/cxl/`에서 port directory를 나열하고 `einj_types`를 읽어 CXL.mem protocol correctable, uncorrectable non-fatal, fatal type의 지원 여부를 확인한다.

Target directory `0000:e0:01.1`로 이동해 `einj_inject`에 `0x8000`을 쓰면 CXL.mem Protocol Correctable error를 해당 port에 주입한다. Dport 이름과 type value는 system마다 다르므로 예제 값을 다른 machine에 그대로 사용하지 않는다.

# cd /sys/kernel/debug/cxl/
# cat einj_types
# cd 0000:e0:01.1
# echo 0x8000 > einj_inject
CXL dport injection
`/sys/kernel/debug/cxl/` 진입Port directory와 `einj_types` 확인Target `$dport_dev` 선택선택한 dport directory로 이동지원 error value를 `einj_inject`에 write

공통 type 조회 뒤 특정 downstream port file에서 error를 실행한다.

예제 CXL.mem type
Error type
0x00008000CXL.mem Protocol Correctable
0x00010000CXL.mem Protocol Uncorrectable non-fatal
0x00020000CXL.mem Protocol Uncorrectable fatal

원문 예제에서 보고된 protocol error value다.

A CXL error injection example with $dport_dev=0000:e0:01.1::

    # cd /sys/kernel/debug/cxl/
    # ls
    0000:e0:01.1 0000:0c:00.0
    # cat einj_types                # See which errors can be injected
        0x00008000  CXL.mem Protocol Correctable
        0x00010000  CXL.mem Protocol Uncorrectable non-fatal
        0x00020000  CXL.mem Protocol Uncorrectable fatal
    # cd 0000:e0:01.1               # Navigate to dport to inject into
    # echo 0x8000 > einj_inject     # Inject error

SGX enclave 대상 injection

251-271

SGX injection은 별도의 BIOS setup option을 요구할 수 있다. Memory controller의 special trigger는 target address에 대한 다음 write에서 error를 주입하지만, hardware는 BIOS SMM을 포함해 enclave 밖의 software가 enclave page에 접근하지 못하게 한다.

따라서 enclave 외부에서 target만 arm하고 실제 memory access는 enclave 안에서 수행한다. 먼저 enclave page의 physical address를 구한 뒤 `notrigger=1`로 injection address를 설정하되 즉시 trigger하지 않는다.

SGX enclave injection 순서
1. Enclave page의 physical address 결정2. `notrigger=1`로 target arm3. Enclave 진입4. 대응 virtual address에 data store5. 해당 virtual address에 `CLFLUSH` 실행6. 250ms spin delay7. Virtual address를 read하여 error trigger

원문의 7단계를 enclave 경계와 cache operation 중심으로 구조화했다.

Store와 `CLFLUSH`, 250ms delay 뒤 같은 virtual address를 read하면 error가 trigger된다. 이 절차는 enclave memory와 machine-check handling을 실제로 교란하므로 disposable test enclave와 system recovery path를 준비해야 한다.

더 자세한 protocol은 ACPI specification 4.0 section 17.5와 ACPI 5.0 section 18.6을 참고한다. Platform firmware version에 맞는 specification과 vendor guide를 함께 대조해야 한다.

SGX injection 경계
단계실행 context목적
Physical address 확인관리·test 환경Target page 식별
notrigger armEnclave 밖Memory controller에 target 설정
Store·CLFLUSH·delayEnclave 안실제 write와 cache eviction
ReadEnclave 안Armed error trigger

어떤 단계가 enclave 밖과 안에서 수행되는지 구분한다.

Special notes for injection into SGX enclaves:

There may be a separate BIOS setup option to enable SGX injection.

The injection process consists of setting some special memory controller
trigger that will inject the error on the next write to the target
address. But the h/w prevents any software outside of an SGX enclave
from accessing enclave pages (even BIOS SMM mode).

The following sequence can be used:
  1) Determine physical address of enclave page
  2) Use "notrigger=1" mode to inject (this will setup
     the injection address, but will not actually inject)
  3) Enter the enclave
  4) Store data to the virtual address matching physical address from step 1
  5) Execute CLFLUSH for that virtual address
  6) Spin delay for 250ms
  7) Read from the virtual address. This will trigger the error

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