1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018, Advanced Micro Devices, Inc.
4 #include <linux/cper.h>
5 #include <linux/acpi.h>
8 * We don't need a "CPER_IA" prefix since these are all locally defined.
9 * This will save us a lot of line space.
11 #define VALID_LAPIC_ID BIT_ULL(0)
12 #define VALID_CPUID_INFO BIT_ULL(1)
13 #define VALID_PROC_ERR_INFO_NUM(bits) (((bits) & GENMASK_ULL(7, 2)) >> 2)
14 #define VALID_PROC_CXT_INFO_NUM(bits) (((bits) & GENMASK_ULL(13, 8)) >> 8)
16 #define INFO_ERR_STRUCT_TYPE_CACHE \
17 GUID_INIT(0xA55701F5, 0xE3EF, 0x43DE, 0xAC, 0x72, 0x24, 0x9B, \
18 0x57, 0x3F, 0xAD, 0x2C)
19 #define INFO_ERR_STRUCT_TYPE_TLB \
20 GUID_INIT(0xFC06B535, 0x5E1F, 0x4562, 0x9F, 0x25, 0x0A, 0x3B, \
21 0x9A, 0xDB, 0x63, 0xC3)
22 #define INFO_ERR_STRUCT_TYPE_BUS \
23 GUID_INIT(0x1CF3F8B3, 0xC5B1, 0x49a2, 0xAA, 0x59, 0x5E, 0xEF, \
24 0x92, 0xFF, 0xA6, 0x3C)
25 #define INFO_ERR_STRUCT_TYPE_MS \
26 GUID_INIT(0x48AB7F57, 0xDC34, 0x4f6c, 0xA7, 0xD3, 0xB0, 0xB5, \
27 0xB0, 0xA7, 0x43, 0x14)
29 #define INFO_VALID_CHECK_INFO BIT_ULL(0)
30 #define INFO_VALID_TARGET_ID BIT_ULL(1)
31 #define INFO_VALID_REQUESTOR_ID BIT_ULL(2)
32 #define INFO_VALID_RESPONDER_ID BIT_ULL(3)
33 #define INFO_VALID_IP BIT_ULL(4)
35 #define CHECK_VALID_TRANS_TYPE BIT_ULL(0)
36 #define CHECK_VALID_OPERATION BIT_ULL(1)
37 #define CHECK_VALID_LEVEL BIT_ULL(2)
38 #define CHECK_VALID_PCC BIT_ULL(3)
39 #define CHECK_VALID_UNCORRECTED BIT_ULL(4)
40 #define CHECK_VALID_PRECISE_IP BIT_ULL(5)
41 #define CHECK_VALID_RESTARTABLE_IP BIT_ULL(6)
42 #define CHECK_VALID_OVERFLOW BIT_ULL(7)
44 #define CHECK_VALID_BUS_PART_TYPE BIT_ULL(8)
45 #define CHECK_VALID_BUS_TIME_OUT BIT_ULL(9)
46 #define CHECK_VALID_BUS_ADDR_SPACE BIT_ULL(10)
48 #define CHECK_VALID_BITS(check) (((check) & GENMASK_ULL(15, 0)))
49 #define CHECK_TRANS_TYPE(check) (((check) & GENMASK_ULL(17, 16)) >> 16)
50 #define CHECK_OPERATION(check) (((check) & GENMASK_ULL(21, 18)) >> 18)
51 #define CHECK_LEVEL(check) (((check) & GENMASK_ULL(24, 22)) >> 22)
52 #define CHECK_PCC BIT_ULL(25)
53 #define CHECK_UNCORRECTED BIT_ULL(26)
54 #define CHECK_PRECISE_IP BIT_ULL(27)
55 #define CHECK_RESTARTABLE_IP BIT_ULL(28)
56 #define CHECK_OVERFLOW BIT_ULL(29)
58 #define CHECK_BUS_PART_TYPE(check) (((check) & GENMASK_ULL(31, 30)) >> 30)
59 #define CHECK_BUS_TIME_OUT BIT_ULL(32)
60 #define CHECK_BUS_ADDR_SPACE(check) (((check) & GENMASK_ULL(34, 33)) >> 33)
62 #define CHECK_VALID_MS_ERR_TYPE BIT_ULL(0)
63 #define CHECK_VALID_MS_PCC BIT_ULL(1)
64 #define CHECK_VALID_MS_UNCORRECTED BIT_ULL(2)
65 #define CHECK_VALID_MS_PRECISE_IP BIT_ULL(3)
66 #define CHECK_VALID_MS_RESTARTABLE_IP BIT_ULL(4)
67 #define CHECK_VALID_MS_OVERFLOW BIT_ULL(5)
69 #define CHECK_MS_ERR_TYPE(check) (((check) & GENMASK_ULL(18, 16)) >> 16)
70 #define CHECK_MS_PCC BIT_ULL(19)
71 #define CHECK_MS_UNCORRECTED BIT_ULL(20)
72 #define CHECK_MS_PRECISE_IP BIT_ULL(21)
73 #define CHECK_MS_RESTARTABLE_IP BIT_ULL(22)
74 #define CHECK_MS_OVERFLOW BIT_ULL(23)
76 #define CTX_TYPE_MSR 1
77 #define CTX_TYPE_MMREG 7
87 static enum err_types
cper_get_err_type(const guid_t
*err_type
)
89 if (guid_equal(err_type
, &INFO_ERR_STRUCT_TYPE_CACHE
))
90 return ERR_TYPE_CACHE
;
91 else if (guid_equal(err_type
, &INFO_ERR_STRUCT_TYPE_TLB
))
93 else if (guid_equal(err_type
, &INFO_ERR_STRUCT_TYPE_BUS
))
95 else if (guid_equal(err_type
, &INFO_ERR_STRUCT_TYPE_MS
))
101 static const char * const ia_check_trans_type_strs
[] = {
107 static const char * const ia_check_op_strs
[] = {
119 static const char * const ia_check_bus_part_type_strs
[] = {
120 "Local Processor originated request",
121 "Local Processor responded to request",
122 "Local Processor observed",
126 static const char * const ia_check_bus_addr_space_strs
[] = {
133 static const char * const ia_check_ms_error_type_strs
[] = {
136 "Microcode ROM Parity Error",
139 "Internal Unclassified",
142 static const char * const ia_reg_ctx_strs
[] = {
144 "MSR Registers (Machine Check and other MSRs)",
145 "32-bit Mode Execution Context",
146 "64-bit Mode Execution Context",
148 "32-bit Mode Debug Registers (DR0-DR7)",
149 "64-bit Mode Debug Registers (DR0-DR7)",
150 "Memory Mapped Registers",
153 static inline void print_bool(char *str
, const char *pfx
, u64 check
, u64 bit
)
155 printk("%s%s: %s\n", pfx
, str
, (check
& bit
) ? "true" : "false");
158 static void print_err_info_ms(const char *pfx
, u16 validation_bits
, u64 check
)
160 if (validation_bits
& CHECK_VALID_MS_ERR_TYPE
) {
161 u8 err_type
= CHECK_MS_ERR_TYPE(check
);
163 printk("%sError Type: %u, %s\n", pfx
, err_type
,
164 err_type
< ARRAY_SIZE(ia_check_ms_error_type_strs
) ?
165 ia_check_ms_error_type_strs
[err_type
] : "unknown");
168 if (validation_bits
& CHECK_VALID_MS_PCC
)
169 print_bool("Processor Context Corrupt", pfx
, check
, CHECK_MS_PCC
);
171 if (validation_bits
& CHECK_VALID_MS_UNCORRECTED
)
172 print_bool("Uncorrected", pfx
, check
, CHECK_MS_UNCORRECTED
);
174 if (validation_bits
& CHECK_VALID_MS_PRECISE_IP
)
175 print_bool("Precise IP", pfx
, check
, CHECK_MS_PRECISE_IP
);
177 if (validation_bits
& CHECK_VALID_MS_RESTARTABLE_IP
)
178 print_bool("Restartable IP", pfx
, check
, CHECK_MS_RESTARTABLE_IP
);
180 if (validation_bits
& CHECK_VALID_MS_OVERFLOW
)
181 print_bool("Overflow", pfx
, check
, CHECK_MS_OVERFLOW
);
184 static void print_err_info(const char *pfx
, u8 err_type
, u64 check
)
186 u16 validation_bits
= CHECK_VALID_BITS(check
);
189 * The MS Check structure varies a lot from the others, so use a
190 * separate function for decoding.
192 if (err_type
== ERR_TYPE_MS
)
193 return print_err_info_ms(pfx
, validation_bits
, check
);
195 if (validation_bits
& CHECK_VALID_TRANS_TYPE
) {
196 u8 trans_type
= CHECK_TRANS_TYPE(check
);
198 printk("%sTransaction Type: %u, %s\n", pfx
, trans_type
,
199 trans_type
< ARRAY_SIZE(ia_check_trans_type_strs
) ?
200 ia_check_trans_type_strs
[trans_type
] : "unknown");
203 if (validation_bits
& CHECK_VALID_OPERATION
) {
204 u8 op
= CHECK_OPERATION(check
);
207 * CACHE has more operation types than TLB or BUS, though the
208 * name and the order are the same.
210 u8 max_ops
= (err_type
== ERR_TYPE_CACHE
) ? 9 : 7;
212 printk("%sOperation: %u, %s\n", pfx
, op
,
213 op
< max_ops
? ia_check_op_strs
[op
] : "unknown");
216 if (validation_bits
& CHECK_VALID_LEVEL
)
217 printk("%sLevel: %llu\n", pfx
, CHECK_LEVEL(check
));
219 if (validation_bits
& CHECK_VALID_PCC
)
220 print_bool("Processor Context Corrupt", pfx
, check
, CHECK_PCC
);
222 if (validation_bits
& CHECK_VALID_UNCORRECTED
)
223 print_bool("Uncorrected", pfx
, check
, CHECK_UNCORRECTED
);
225 if (validation_bits
& CHECK_VALID_PRECISE_IP
)
226 print_bool("Precise IP", pfx
, check
, CHECK_PRECISE_IP
);
228 if (validation_bits
& CHECK_VALID_RESTARTABLE_IP
)
229 print_bool("Restartable IP", pfx
, check
, CHECK_RESTARTABLE_IP
);
231 if (validation_bits
& CHECK_VALID_OVERFLOW
)
232 print_bool("Overflow", pfx
, check
, CHECK_OVERFLOW
);
234 if (err_type
!= ERR_TYPE_BUS
)
237 if (validation_bits
& CHECK_VALID_BUS_PART_TYPE
) {
238 u8 part_type
= CHECK_BUS_PART_TYPE(check
);
240 printk("%sParticipation Type: %u, %s\n", pfx
, part_type
,
241 part_type
< ARRAY_SIZE(ia_check_bus_part_type_strs
) ?
242 ia_check_bus_part_type_strs
[part_type
] : "unknown");
245 if (validation_bits
& CHECK_VALID_BUS_TIME_OUT
)
246 print_bool("Time Out", pfx
, check
, CHECK_BUS_TIME_OUT
);
248 if (validation_bits
& CHECK_VALID_BUS_ADDR_SPACE
) {
249 u8 addr_space
= CHECK_BUS_ADDR_SPACE(check
);
251 printk("%sAddress Space: %u, %s\n", pfx
, addr_space
,
252 addr_space
< ARRAY_SIZE(ia_check_bus_addr_space_strs
) ?
253 ia_check_bus_addr_space_strs
[addr_space
] : "unknown");
257 void cper_print_proc_ia(const char *pfx
, const struct cper_sec_proc_ia
*proc
)
260 struct cper_ia_err_info
*err_info
;
261 struct cper_ia_proc_ctx
*ctx_info
;
262 char newpfx
[64], infopfx
[64];
265 if (proc
->validation_bits
& VALID_LAPIC_ID
)
266 printk("%sLocal APIC_ID: 0x%llx\n", pfx
, proc
->lapic_id
);
268 if (proc
->validation_bits
& VALID_CPUID_INFO
) {
269 printk("%sCPUID Info:\n", pfx
);
270 print_hex_dump(pfx
, "", DUMP_PREFIX_OFFSET
, 16, 4, proc
->cpuid
,
271 sizeof(proc
->cpuid
), 0);
274 snprintf(newpfx
, sizeof(newpfx
), "%s ", pfx
);
276 err_info
= (struct cper_ia_err_info
*)(proc
+ 1);
277 for (i
= 0; i
< VALID_PROC_ERR_INFO_NUM(proc
->validation_bits
); i
++) {
278 printk("%sError Information Structure %d:\n", pfx
, i
);
280 err_type
= cper_get_err_type(&err_info
->err_type
);
281 printk("%sError Structure Type: %s\n", newpfx
,
282 err_type
< ARRAY_SIZE(cper_proc_error_type_strs
) ?
283 cper_proc_error_type_strs
[err_type
] : "unknown");
285 if (err_type
>= N_ERR_TYPES
) {
286 printk("%sError Structure Type: %pUl\n", newpfx
,
287 &err_info
->err_type
);
290 if (err_info
->validation_bits
& INFO_VALID_CHECK_INFO
) {
291 printk("%sCheck Information: 0x%016llx\n", newpfx
,
292 err_info
->check_info
);
294 if (err_type
< N_ERR_TYPES
) {
295 snprintf(infopfx
, sizeof(infopfx
), "%s ",
298 print_err_info(infopfx
, err_type
,
299 err_info
->check_info
);
303 if (err_info
->validation_bits
& INFO_VALID_TARGET_ID
) {
304 printk("%sTarget Identifier: 0x%016llx\n",
305 newpfx
, err_info
->target_id
);
308 if (err_info
->validation_bits
& INFO_VALID_REQUESTOR_ID
) {
309 printk("%sRequestor Identifier: 0x%016llx\n",
310 newpfx
, err_info
->requestor_id
);
313 if (err_info
->validation_bits
& INFO_VALID_RESPONDER_ID
) {
314 printk("%sResponder Identifier: 0x%016llx\n",
315 newpfx
, err_info
->responder_id
);
318 if (err_info
->validation_bits
& INFO_VALID_IP
) {
319 printk("%sInstruction Pointer: 0x%016llx\n",
320 newpfx
, err_info
->ip
);
326 ctx_info
= (struct cper_ia_proc_ctx
*)err_info
;
327 for (i
= 0; i
< VALID_PROC_CXT_INFO_NUM(proc
->validation_bits
); i
++) {
328 int size
= sizeof(*ctx_info
) + ctx_info
->reg_arr_size
;
331 printk("%sContext Information Structure %d:\n", pfx
, i
);
333 printk("%sRegister Context Type: %s\n", newpfx
,
334 ctx_info
->reg_ctx_type
< ARRAY_SIZE(ia_reg_ctx_strs
) ?
335 ia_reg_ctx_strs
[ctx_info
->reg_ctx_type
] : "unknown");
337 printk("%sRegister Array Size: 0x%04x\n", newpfx
,
338 ctx_info
->reg_arr_size
);
340 if (ctx_info
->reg_ctx_type
== CTX_TYPE_MSR
) {
341 groupsize
= 8; /* MSRs are 8 bytes wide. */
342 printk("%sMSR Address: 0x%08x\n", newpfx
,
346 if (ctx_info
->reg_ctx_type
== CTX_TYPE_MMREG
) {
347 printk("%sMM Register Address: 0x%016llx\n", newpfx
,
348 ctx_info
->mm_reg_addr
);
351 if (ctx_info
->reg_ctx_type
!= CTX_TYPE_MSR
||
352 arch_apei_report_x86_error(ctx_info
, proc
->lapic_id
)) {
353 printk("%sRegister Array:\n", newpfx
);
354 print_hex_dump(newpfx
, "", DUMP_PREFIX_OFFSET
, 16,
355 groupsize
, (ctx_info
+ 1),
356 ctx_info
->reg_arr_size
, 0);
359 ctx_info
= (struct cper_ia_proc_ctx
*)((long)ctx_info
+ size
);