1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun // Copyright (C) 2018, Advanced Micro Devices, Inc.
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun #include <linux/cper.h>
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun /*
7*4882a593Smuzhiyun * We don't need a "CPER_IA" prefix since these are all locally defined.
8*4882a593Smuzhiyun * This will save us a lot of line space.
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun #define VALID_LAPIC_ID BIT_ULL(0)
11*4882a593Smuzhiyun #define VALID_CPUID_INFO BIT_ULL(1)
12*4882a593Smuzhiyun #define VALID_PROC_ERR_INFO_NUM(bits) (((bits) & GENMASK_ULL(7, 2)) >> 2)
13*4882a593Smuzhiyun #define VALID_PROC_CXT_INFO_NUM(bits) (((bits) & GENMASK_ULL(13, 8)) >> 8)
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #define INFO_ERR_STRUCT_TYPE_CACHE \
16*4882a593Smuzhiyun GUID_INIT(0xA55701F5, 0xE3EF, 0x43DE, 0xAC, 0x72, 0x24, 0x9B, \
17*4882a593Smuzhiyun 0x57, 0x3F, 0xAD, 0x2C)
18*4882a593Smuzhiyun #define INFO_ERR_STRUCT_TYPE_TLB \
19*4882a593Smuzhiyun GUID_INIT(0xFC06B535, 0x5E1F, 0x4562, 0x9F, 0x25, 0x0A, 0x3B, \
20*4882a593Smuzhiyun 0x9A, 0xDB, 0x63, 0xC3)
21*4882a593Smuzhiyun #define INFO_ERR_STRUCT_TYPE_BUS \
22*4882a593Smuzhiyun GUID_INIT(0x1CF3F8B3, 0xC5B1, 0x49a2, 0xAA, 0x59, 0x5E, 0xEF, \
23*4882a593Smuzhiyun 0x92, 0xFF, 0xA6, 0x3C)
24*4882a593Smuzhiyun #define INFO_ERR_STRUCT_TYPE_MS \
25*4882a593Smuzhiyun GUID_INIT(0x48AB7F57, 0xDC34, 0x4f6c, 0xA7, 0xD3, 0xB0, 0xB5, \
26*4882a593Smuzhiyun 0xB0, 0xA7, 0x43, 0x14)
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #define INFO_VALID_CHECK_INFO BIT_ULL(0)
29*4882a593Smuzhiyun #define INFO_VALID_TARGET_ID BIT_ULL(1)
30*4882a593Smuzhiyun #define INFO_VALID_REQUESTOR_ID BIT_ULL(2)
31*4882a593Smuzhiyun #define INFO_VALID_RESPONDER_ID BIT_ULL(3)
32*4882a593Smuzhiyun #define INFO_VALID_IP BIT_ULL(4)
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define CHECK_VALID_TRANS_TYPE BIT_ULL(0)
35*4882a593Smuzhiyun #define CHECK_VALID_OPERATION BIT_ULL(1)
36*4882a593Smuzhiyun #define CHECK_VALID_LEVEL BIT_ULL(2)
37*4882a593Smuzhiyun #define CHECK_VALID_PCC BIT_ULL(3)
38*4882a593Smuzhiyun #define CHECK_VALID_UNCORRECTED BIT_ULL(4)
39*4882a593Smuzhiyun #define CHECK_VALID_PRECISE_IP BIT_ULL(5)
40*4882a593Smuzhiyun #define CHECK_VALID_RESTARTABLE_IP BIT_ULL(6)
41*4882a593Smuzhiyun #define CHECK_VALID_OVERFLOW BIT_ULL(7)
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #define CHECK_VALID_BUS_PART_TYPE BIT_ULL(8)
44*4882a593Smuzhiyun #define CHECK_VALID_BUS_TIME_OUT BIT_ULL(9)
45*4882a593Smuzhiyun #define CHECK_VALID_BUS_ADDR_SPACE BIT_ULL(10)
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun #define CHECK_VALID_BITS(check) (((check) & GENMASK_ULL(15, 0)))
48*4882a593Smuzhiyun #define CHECK_TRANS_TYPE(check) (((check) & GENMASK_ULL(17, 16)) >> 16)
49*4882a593Smuzhiyun #define CHECK_OPERATION(check) (((check) & GENMASK_ULL(21, 18)) >> 18)
50*4882a593Smuzhiyun #define CHECK_LEVEL(check) (((check) & GENMASK_ULL(24, 22)) >> 22)
51*4882a593Smuzhiyun #define CHECK_PCC BIT_ULL(25)
52*4882a593Smuzhiyun #define CHECK_UNCORRECTED BIT_ULL(26)
53*4882a593Smuzhiyun #define CHECK_PRECISE_IP BIT_ULL(27)
54*4882a593Smuzhiyun #define CHECK_RESTARTABLE_IP BIT_ULL(28)
55*4882a593Smuzhiyun #define CHECK_OVERFLOW BIT_ULL(29)
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun #define CHECK_BUS_PART_TYPE(check) (((check) & GENMASK_ULL(31, 30)) >> 30)
58*4882a593Smuzhiyun #define CHECK_BUS_TIME_OUT BIT_ULL(32)
59*4882a593Smuzhiyun #define CHECK_BUS_ADDR_SPACE(check) (((check) & GENMASK_ULL(34, 33)) >> 33)
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun #define CHECK_VALID_MS_ERR_TYPE BIT_ULL(0)
62*4882a593Smuzhiyun #define CHECK_VALID_MS_PCC BIT_ULL(1)
63*4882a593Smuzhiyun #define CHECK_VALID_MS_UNCORRECTED BIT_ULL(2)
64*4882a593Smuzhiyun #define CHECK_VALID_MS_PRECISE_IP BIT_ULL(3)
65*4882a593Smuzhiyun #define CHECK_VALID_MS_RESTARTABLE_IP BIT_ULL(4)
66*4882a593Smuzhiyun #define CHECK_VALID_MS_OVERFLOW BIT_ULL(5)
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun #define CHECK_MS_ERR_TYPE(check) (((check) & GENMASK_ULL(18, 16)) >> 16)
69*4882a593Smuzhiyun #define CHECK_MS_PCC BIT_ULL(19)
70*4882a593Smuzhiyun #define CHECK_MS_UNCORRECTED BIT_ULL(20)
71*4882a593Smuzhiyun #define CHECK_MS_PRECISE_IP BIT_ULL(21)
72*4882a593Smuzhiyun #define CHECK_MS_RESTARTABLE_IP BIT_ULL(22)
73*4882a593Smuzhiyun #define CHECK_MS_OVERFLOW BIT_ULL(23)
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun #define CTX_TYPE_MSR 1
76*4882a593Smuzhiyun #define CTX_TYPE_MMREG 7
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun enum err_types {
79*4882a593Smuzhiyun ERR_TYPE_CACHE = 0,
80*4882a593Smuzhiyun ERR_TYPE_TLB,
81*4882a593Smuzhiyun ERR_TYPE_BUS,
82*4882a593Smuzhiyun ERR_TYPE_MS,
83*4882a593Smuzhiyun N_ERR_TYPES
84*4882a593Smuzhiyun };
85*4882a593Smuzhiyun
cper_get_err_type(const guid_t * err_type)86*4882a593Smuzhiyun static enum err_types cper_get_err_type(const guid_t *err_type)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun if (guid_equal(err_type, &INFO_ERR_STRUCT_TYPE_CACHE))
89*4882a593Smuzhiyun return ERR_TYPE_CACHE;
90*4882a593Smuzhiyun else if (guid_equal(err_type, &INFO_ERR_STRUCT_TYPE_TLB))
91*4882a593Smuzhiyun return ERR_TYPE_TLB;
92*4882a593Smuzhiyun else if (guid_equal(err_type, &INFO_ERR_STRUCT_TYPE_BUS))
93*4882a593Smuzhiyun return ERR_TYPE_BUS;
94*4882a593Smuzhiyun else if (guid_equal(err_type, &INFO_ERR_STRUCT_TYPE_MS))
95*4882a593Smuzhiyun return ERR_TYPE_MS;
96*4882a593Smuzhiyun else
97*4882a593Smuzhiyun return N_ERR_TYPES;
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun static const char * const ia_check_trans_type_strs[] = {
101*4882a593Smuzhiyun "Instruction",
102*4882a593Smuzhiyun "Data Access",
103*4882a593Smuzhiyun "Generic",
104*4882a593Smuzhiyun };
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun static const char * const ia_check_op_strs[] = {
107*4882a593Smuzhiyun "generic error",
108*4882a593Smuzhiyun "generic read",
109*4882a593Smuzhiyun "generic write",
110*4882a593Smuzhiyun "data read",
111*4882a593Smuzhiyun "data write",
112*4882a593Smuzhiyun "instruction fetch",
113*4882a593Smuzhiyun "prefetch",
114*4882a593Smuzhiyun "eviction",
115*4882a593Smuzhiyun "snoop",
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun static const char * const ia_check_bus_part_type_strs[] = {
119*4882a593Smuzhiyun "Local Processor originated request",
120*4882a593Smuzhiyun "Local Processor responded to request",
121*4882a593Smuzhiyun "Local Processor observed",
122*4882a593Smuzhiyun "Generic",
123*4882a593Smuzhiyun };
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun static const char * const ia_check_bus_addr_space_strs[] = {
126*4882a593Smuzhiyun "Memory Access",
127*4882a593Smuzhiyun "Reserved",
128*4882a593Smuzhiyun "I/O",
129*4882a593Smuzhiyun "Other Transaction",
130*4882a593Smuzhiyun };
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun static const char * const ia_check_ms_error_type_strs[] = {
133*4882a593Smuzhiyun "No Error",
134*4882a593Smuzhiyun "Unclassified",
135*4882a593Smuzhiyun "Microcode ROM Parity Error",
136*4882a593Smuzhiyun "External Error",
137*4882a593Smuzhiyun "FRC Error",
138*4882a593Smuzhiyun "Internal Unclassified",
139*4882a593Smuzhiyun };
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun static const char * const ia_reg_ctx_strs[] = {
142*4882a593Smuzhiyun "Unclassified Data",
143*4882a593Smuzhiyun "MSR Registers (Machine Check and other MSRs)",
144*4882a593Smuzhiyun "32-bit Mode Execution Context",
145*4882a593Smuzhiyun "64-bit Mode Execution Context",
146*4882a593Smuzhiyun "FXSAVE Context",
147*4882a593Smuzhiyun "32-bit Mode Debug Registers (DR0-DR7)",
148*4882a593Smuzhiyun "64-bit Mode Debug Registers (DR0-DR7)",
149*4882a593Smuzhiyun "Memory Mapped Registers",
150*4882a593Smuzhiyun };
151*4882a593Smuzhiyun
print_bool(char * str,const char * pfx,u64 check,u64 bit)152*4882a593Smuzhiyun static inline void print_bool(char *str, const char *pfx, u64 check, u64 bit)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun printk("%s%s: %s\n", pfx, str, (check & bit) ? "true" : "false");
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
print_err_info_ms(const char * pfx,u16 validation_bits,u64 check)157*4882a593Smuzhiyun static void print_err_info_ms(const char *pfx, u16 validation_bits, u64 check)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_MS_ERR_TYPE) {
160*4882a593Smuzhiyun u8 err_type = CHECK_MS_ERR_TYPE(check);
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun printk("%sError Type: %u, %s\n", pfx, err_type,
163*4882a593Smuzhiyun err_type < ARRAY_SIZE(ia_check_ms_error_type_strs) ?
164*4882a593Smuzhiyun ia_check_ms_error_type_strs[err_type] : "unknown");
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_MS_PCC)
168*4882a593Smuzhiyun print_bool("Processor Context Corrupt", pfx, check, CHECK_MS_PCC);
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_MS_UNCORRECTED)
171*4882a593Smuzhiyun print_bool("Uncorrected", pfx, check, CHECK_MS_UNCORRECTED);
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_MS_PRECISE_IP)
174*4882a593Smuzhiyun print_bool("Precise IP", pfx, check, CHECK_MS_PRECISE_IP);
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_MS_RESTARTABLE_IP)
177*4882a593Smuzhiyun print_bool("Restartable IP", pfx, check, CHECK_MS_RESTARTABLE_IP);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_MS_OVERFLOW)
180*4882a593Smuzhiyun print_bool("Overflow", pfx, check, CHECK_MS_OVERFLOW);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
print_err_info(const char * pfx,u8 err_type,u64 check)183*4882a593Smuzhiyun static void print_err_info(const char *pfx, u8 err_type, u64 check)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun u16 validation_bits = CHECK_VALID_BITS(check);
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun /*
188*4882a593Smuzhiyun * The MS Check structure varies a lot from the others, so use a
189*4882a593Smuzhiyun * separate function for decoding.
190*4882a593Smuzhiyun */
191*4882a593Smuzhiyun if (err_type == ERR_TYPE_MS)
192*4882a593Smuzhiyun return print_err_info_ms(pfx, validation_bits, check);
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_TRANS_TYPE) {
195*4882a593Smuzhiyun u8 trans_type = CHECK_TRANS_TYPE(check);
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun printk("%sTransaction Type: %u, %s\n", pfx, trans_type,
198*4882a593Smuzhiyun trans_type < ARRAY_SIZE(ia_check_trans_type_strs) ?
199*4882a593Smuzhiyun ia_check_trans_type_strs[trans_type] : "unknown");
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_OPERATION) {
203*4882a593Smuzhiyun u8 op = CHECK_OPERATION(check);
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun /*
206*4882a593Smuzhiyun * CACHE has more operation types than TLB or BUS, though the
207*4882a593Smuzhiyun * name and the order are the same.
208*4882a593Smuzhiyun */
209*4882a593Smuzhiyun u8 max_ops = (err_type == ERR_TYPE_CACHE) ? 9 : 7;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun printk("%sOperation: %u, %s\n", pfx, op,
212*4882a593Smuzhiyun op < max_ops ? ia_check_op_strs[op] : "unknown");
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_LEVEL)
216*4882a593Smuzhiyun printk("%sLevel: %llu\n", pfx, CHECK_LEVEL(check));
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_PCC)
219*4882a593Smuzhiyun print_bool("Processor Context Corrupt", pfx, check, CHECK_PCC);
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_UNCORRECTED)
222*4882a593Smuzhiyun print_bool("Uncorrected", pfx, check, CHECK_UNCORRECTED);
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_PRECISE_IP)
225*4882a593Smuzhiyun print_bool("Precise IP", pfx, check, CHECK_PRECISE_IP);
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_RESTARTABLE_IP)
228*4882a593Smuzhiyun print_bool("Restartable IP", pfx, check, CHECK_RESTARTABLE_IP);
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_OVERFLOW)
231*4882a593Smuzhiyun print_bool("Overflow", pfx, check, CHECK_OVERFLOW);
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun if (err_type != ERR_TYPE_BUS)
234*4882a593Smuzhiyun return;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_BUS_PART_TYPE) {
237*4882a593Smuzhiyun u8 part_type = CHECK_BUS_PART_TYPE(check);
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun printk("%sParticipation Type: %u, %s\n", pfx, part_type,
240*4882a593Smuzhiyun part_type < ARRAY_SIZE(ia_check_bus_part_type_strs) ?
241*4882a593Smuzhiyun ia_check_bus_part_type_strs[part_type] : "unknown");
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_BUS_TIME_OUT)
245*4882a593Smuzhiyun print_bool("Time Out", pfx, check, CHECK_BUS_TIME_OUT);
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun if (validation_bits & CHECK_VALID_BUS_ADDR_SPACE) {
248*4882a593Smuzhiyun u8 addr_space = CHECK_BUS_ADDR_SPACE(check);
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun printk("%sAddress Space: %u, %s\n", pfx, addr_space,
251*4882a593Smuzhiyun addr_space < ARRAY_SIZE(ia_check_bus_addr_space_strs) ?
252*4882a593Smuzhiyun ia_check_bus_addr_space_strs[addr_space] : "unknown");
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
cper_print_proc_ia(const char * pfx,const struct cper_sec_proc_ia * proc)256*4882a593Smuzhiyun void cper_print_proc_ia(const char *pfx, const struct cper_sec_proc_ia *proc)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun int i;
259*4882a593Smuzhiyun struct cper_ia_err_info *err_info;
260*4882a593Smuzhiyun struct cper_ia_proc_ctx *ctx_info;
261*4882a593Smuzhiyun char newpfx[64], infopfx[64];
262*4882a593Smuzhiyun u8 err_type;
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun if (proc->validation_bits & VALID_LAPIC_ID)
265*4882a593Smuzhiyun printk("%sLocal APIC_ID: 0x%llx\n", pfx, proc->lapic_id);
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun if (proc->validation_bits & VALID_CPUID_INFO) {
268*4882a593Smuzhiyun printk("%sCPUID Info:\n", pfx);
269*4882a593Smuzhiyun print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, proc->cpuid,
270*4882a593Smuzhiyun sizeof(proc->cpuid), 0);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun snprintf(newpfx, sizeof(newpfx), "%s ", pfx);
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun err_info = (struct cper_ia_err_info *)(proc + 1);
276*4882a593Smuzhiyun for (i = 0; i < VALID_PROC_ERR_INFO_NUM(proc->validation_bits); i++) {
277*4882a593Smuzhiyun printk("%sError Information Structure %d:\n", pfx, i);
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun err_type = cper_get_err_type(&err_info->err_type);
280*4882a593Smuzhiyun printk("%sError Structure Type: %s\n", newpfx,
281*4882a593Smuzhiyun err_type < ARRAY_SIZE(cper_proc_error_type_strs) ?
282*4882a593Smuzhiyun cper_proc_error_type_strs[err_type] : "unknown");
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun if (err_type >= N_ERR_TYPES) {
285*4882a593Smuzhiyun printk("%sError Structure Type: %pUl\n", newpfx,
286*4882a593Smuzhiyun &err_info->err_type);
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun if (err_info->validation_bits & INFO_VALID_CHECK_INFO) {
290*4882a593Smuzhiyun printk("%sCheck Information: 0x%016llx\n", newpfx,
291*4882a593Smuzhiyun err_info->check_info);
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun if (err_type < N_ERR_TYPES) {
294*4882a593Smuzhiyun snprintf(infopfx, sizeof(infopfx), "%s ",
295*4882a593Smuzhiyun newpfx);
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun print_err_info(infopfx, err_type,
298*4882a593Smuzhiyun err_info->check_info);
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun if (err_info->validation_bits & INFO_VALID_TARGET_ID) {
303*4882a593Smuzhiyun printk("%sTarget Identifier: 0x%016llx\n",
304*4882a593Smuzhiyun newpfx, err_info->target_id);
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun if (err_info->validation_bits & INFO_VALID_REQUESTOR_ID) {
308*4882a593Smuzhiyun printk("%sRequestor Identifier: 0x%016llx\n",
309*4882a593Smuzhiyun newpfx, err_info->requestor_id);
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun if (err_info->validation_bits & INFO_VALID_RESPONDER_ID) {
313*4882a593Smuzhiyun printk("%sResponder Identifier: 0x%016llx\n",
314*4882a593Smuzhiyun newpfx, err_info->responder_id);
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun if (err_info->validation_bits & INFO_VALID_IP) {
318*4882a593Smuzhiyun printk("%sInstruction Pointer: 0x%016llx\n",
319*4882a593Smuzhiyun newpfx, err_info->ip);
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun err_info++;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun ctx_info = (struct cper_ia_proc_ctx *)err_info;
326*4882a593Smuzhiyun for (i = 0; i < VALID_PROC_CXT_INFO_NUM(proc->validation_bits); i++) {
327*4882a593Smuzhiyun int size = sizeof(*ctx_info) + ctx_info->reg_arr_size;
328*4882a593Smuzhiyun int groupsize = 4;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun printk("%sContext Information Structure %d:\n", pfx, i);
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun printk("%sRegister Context Type: %s\n", newpfx,
333*4882a593Smuzhiyun ctx_info->reg_ctx_type < ARRAY_SIZE(ia_reg_ctx_strs) ?
334*4882a593Smuzhiyun ia_reg_ctx_strs[ctx_info->reg_ctx_type] : "unknown");
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun printk("%sRegister Array Size: 0x%04x\n", newpfx,
337*4882a593Smuzhiyun ctx_info->reg_arr_size);
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun if (ctx_info->reg_ctx_type == CTX_TYPE_MSR) {
340*4882a593Smuzhiyun groupsize = 8; /* MSRs are 8 bytes wide. */
341*4882a593Smuzhiyun printk("%sMSR Address: 0x%08x\n", newpfx,
342*4882a593Smuzhiyun ctx_info->msr_addr);
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun if (ctx_info->reg_ctx_type == CTX_TYPE_MMREG) {
346*4882a593Smuzhiyun printk("%sMM Register Address: 0x%016llx\n", newpfx,
347*4882a593Smuzhiyun ctx_info->mm_reg_addr);
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun printk("%sRegister Array:\n", newpfx);
351*4882a593Smuzhiyun print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, groupsize,
352*4882a593Smuzhiyun (ctx_info + 1), ctx_info->reg_arr_size, 0);
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun ctx_info = (struct cper_ia_proc_ctx *)((long)ctx_info + size);
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun }
357