Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/xen/interface/xen-mca.h
26282 views
1
/* SPDX-License-Identifier: MIT */
2
/******************************************************************************
3
* arch-x86/mca.h
4
* Guest OS machine check interface to x86 Xen.
5
*
6
* Contributed by Advanced Micro Devices, Inc.
7
* Author: Christoph Egger <[email protected]>
8
*
9
* Updated by Intel Corporation
10
* Author: Liu, Jinsong <[email protected]>
11
*
12
* Permission is hereby granted, free of charge, to any person obtaining a copy
13
* of this software and associated documentation files (the "Software"), to
14
* deal in the Software without restriction, including without limitation the
15
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16
* sell copies of the Software, and to permit persons to whom the Software is
17
* furnished to do so, subject to the following conditions:
18
*
19
* The above copyright notice and this permission notice shall be included in
20
* all copies or substantial portions of the Software.
21
*
22
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28
* DEALINGS IN THE SOFTWARE.
29
*/
30
31
#ifndef __XEN_PUBLIC_ARCH_X86_MCA_H__
32
#define __XEN_PUBLIC_ARCH_X86_MCA_H__
33
34
/* Hypercall */
35
#define __HYPERVISOR_mca __HYPERVISOR_arch_0
36
37
#define XEN_MCA_INTERFACE_VERSION 0x01ecc003
38
39
/* IN: Dom0 calls hypercall to retrieve nonurgent error log entry */
40
#define XEN_MC_NONURGENT 0x1
41
/* IN: Dom0 calls hypercall to retrieve urgent error log entry */
42
#define XEN_MC_URGENT 0x2
43
/* IN: Dom0 acknowledges previosly-fetched error log entry */
44
#define XEN_MC_ACK 0x4
45
46
/* OUT: All is ok */
47
#define XEN_MC_OK 0x0
48
/* OUT: Domain could not fetch data. */
49
#define XEN_MC_FETCHFAILED 0x1
50
/* OUT: There was no machine check data to fetch. */
51
#define XEN_MC_NODATA 0x2
52
53
#ifndef __ASSEMBLY__
54
/* vIRQ injected to Dom0 */
55
#define VIRQ_MCA VIRQ_ARCH_0
56
57
/*
58
* mc_info entry types
59
* mca machine check info are recorded in mc_info entries.
60
* when fetch mca info, it can use MC_TYPE_... to distinguish
61
* different mca info.
62
*/
63
#define MC_TYPE_GLOBAL 0
64
#define MC_TYPE_BANK 1
65
#define MC_TYPE_EXTENDED 2
66
#define MC_TYPE_RECOVERY 3
67
68
struct mcinfo_common {
69
uint16_t type; /* structure type */
70
uint16_t size; /* size of this struct in bytes */
71
};
72
73
#define MC_FLAG_CORRECTABLE (1 << 0)
74
#define MC_FLAG_UNCORRECTABLE (1 << 1)
75
#define MC_FLAG_RECOVERABLE (1 << 2)
76
#define MC_FLAG_POLLED (1 << 3)
77
#define MC_FLAG_RESET (1 << 4)
78
#define MC_FLAG_CMCI (1 << 5)
79
#define MC_FLAG_MCE (1 << 6)
80
81
/* contains x86 global mc information */
82
struct mcinfo_global {
83
struct mcinfo_common common;
84
85
uint16_t mc_domid; /* running domain at the time in error */
86
uint16_t mc_vcpuid; /* virtual cpu scheduled for mc_domid */
87
uint32_t mc_socketid; /* physical socket of the physical core */
88
uint16_t mc_coreid; /* physical impacted core */
89
uint16_t mc_core_threadid; /* core thread of physical core */
90
uint32_t mc_apicid;
91
uint32_t mc_flags;
92
uint64_t mc_gstatus; /* global status */
93
};
94
95
/* contains x86 bank mc information */
96
struct mcinfo_bank {
97
struct mcinfo_common common;
98
99
uint16_t mc_bank; /* bank nr */
100
uint16_t mc_domid; /* domain referenced by mc_addr if valid */
101
uint64_t mc_status; /* bank status */
102
uint64_t mc_addr; /* bank address */
103
uint64_t mc_misc;
104
uint64_t mc_ctrl2;
105
uint64_t mc_tsc;
106
};
107
108
struct mcinfo_msr {
109
uint64_t reg; /* MSR */
110
uint64_t value; /* MSR value */
111
};
112
113
/* contains mc information from other or additional mc MSRs */
114
struct mcinfo_extended {
115
struct mcinfo_common common;
116
uint32_t mc_msrs; /* Number of msr with valid values. */
117
/*
118
* Currently Intel extended MSR (32/64) include all gp registers
119
* and E(R)FLAGS, E(R)IP, E(R)MISC, up to 11/19 of them might be
120
* useful at present. So expand this array to 16/32 to leave room.
121
*/
122
struct mcinfo_msr mc_msr[sizeof(void *) * 4];
123
};
124
125
/* Recovery Action flags. Giving recovery result information to DOM0 */
126
127
/* Xen takes successful recovery action, the error is recovered */
128
#define REC_ACTION_RECOVERED (0x1 << 0)
129
/* No action is performed by XEN */
130
#define REC_ACTION_NONE (0x1 << 1)
131
/* It's possible DOM0 might take action ownership in some case */
132
#define REC_ACTION_NEED_RESET (0x1 << 2)
133
134
/*
135
* Different Recovery Action types, if the action is performed successfully,
136
* REC_ACTION_RECOVERED flag will be returned.
137
*/
138
139
/* Page Offline Action */
140
#define MC_ACTION_PAGE_OFFLINE (0x1 << 0)
141
/* CPU offline Action */
142
#define MC_ACTION_CPU_OFFLINE (0x1 << 1)
143
/* L3 cache disable Action */
144
#define MC_ACTION_CACHE_SHRINK (0x1 << 2)
145
146
/*
147
* Below interface used between XEN/DOM0 for passing XEN's recovery action
148
* information to DOM0.
149
*/
150
struct page_offline_action {
151
/* Params for passing the offlined page number to DOM0 */
152
uint64_t mfn;
153
uint64_t status;
154
};
155
156
struct cpu_offline_action {
157
/* Params for passing the identity of the offlined CPU to DOM0 */
158
uint32_t mc_socketid;
159
uint16_t mc_coreid;
160
uint16_t mc_core_threadid;
161
};
162
163
#define MAX_UNION_SIZE 16
164
struct mcinfo_recovery {
165
struct mcinfo_common common;
166
uint16_t mc_bank; /* bank nr */
167
uint8_t action_flags;
168
uint8_t action_types;
169
union {
170
struct page_offline_action page_retire;
171
struct cpu_offline_action cpu_offline;
172
uint8_t pad[MAX_UNION_SIZE];
173
} action_info;
174
};
175
176
177
#define MCINFO_MAXSIZE 768
178
struct mc_info {
179
/* Number of mcinfo_* entries in mi_data */
180
uint32_t mi_nentries;
181
uint32_t flags;
182
uint64_t mi_data[(MCINFO_MAXSIZE - 1) / 8];
183
};
184
DEFINE_GUEST_HANDLE_STRUCT(mc_info);
185
186
#define __MC_MSR_ARRAYSIZE 8
187
#define __MC_NMSRS 1
188
#define MC_NCAPS 7
189
struct mcinfo_logical_cpu {
190
uint32_t mc_cpunr;
191
uint32_t mc_chipid;
192
uint16_t mc_coreid;
193
uint16_t mc_threadid;
194
uint32_t mc_apicid;
195
uint32_t mc_clusterid;
196
uint32_t mc_ncores;
197
uint32_t mc_ncores_active;
198
uint32_t mc_nthreads;
199
uint32_t mc_cpuid_level;
200
uint32_t mc_family;
201
uint32_t mc_vendor;
202
uint32_t mc_model;
203
uint32_t mc_step;
204
char mc_vendorid[16];
205
char mc_brandid[64];
206
uint32_t mc_cpu_caps[MC_NCAPS];
207
uint32_t mc_cache_size;
208
uint32_t mc_cache_alignment;
209
uint32_t mc_nmsrvals;
210
struct mcinfo_msr mc_msrvalues[__MC_MSR_ARRAYSIZE];
211
};
212
DEFINE_GUEST_HANDLE_STRUCT(mcinfo_logical_cpu);
213
214
/*
215
* Prototype:
216
* uint32_t x86_mcinfo_nentries(struct mc_info *mi);
217
*/
218
#define x86_mcinfo_nentries(_mi) \
219
((_mi)->mi_nentries)
220
/*
221
* Prototype:
222
* struct mcinfo_common *x86_mcinfo_first(struct mc_info *mi);
223
*/
224
#define x86_mcinfo_first(_mi) \
225
((struct mcinfo_common *)(_mi)->mi_data)
226
/*
227
* Prototype:
228
* struct mcinfo_common *x86_mcinfo_next(struct mcinfo_common *mic);
229
*/
230
#define x86_mcinfo_next(_mic) \
231
((struct mcinfo_common *)((uint8_t *)(_mic) + (_mic)->size))
232
233
/*
234
* Prototype:
235
* void x86_mcinfo_lookup(void *ret, struct mc_info *mi, uint16_t type);
236
*/
237
static inline void x86_mcinfo_lookup(struct mcinfo_common **ret,
238
struct mc_info *mi, uint16_t type)
239
{
240
uint32_t i;
241
struct mcinfo_common *mic;
242
bool found = 0;
243
244
if (!ret || !mi)
245
return;
246
247
mic = x86_mcinfo_first(mi);
248
for (i = 0; i < x86_mcinfo_nentries(mi); i++) {
249
if (mic->type == type) {
250
found = 1;
251
break;
252
}
253
mic = x86_mcinfo_next(mic);
254
}
255
256
*ret = found ? mic : NULL;
257
}
258
259
/*
260
* Fetch machine check data from hypervisor.
261
*/
262
#define XEN_MC_fetch 1
263
struct xen_mc_fetch {
264
/*
265
* IN: XEN_MC_NONURGENT, XEN_MC_URGENT,
266
* XEN_MC_ACK if ack'king an earlier fetch
267
* OUT: XEN_MC_OK, XEN_MC_FETCHAILED, XEN_MC_NODATA
268
*/
269
uint32_t flags;
270
uint32_t _pad0;
271
/* OUT: id for ack, IN: id we are ack'ing */
272
uint64_t fetch_id;
273
274
/* OUT variables. */
275
GUEST_HANDLE(mc_info) data;
276
};
277
DEFINE_GUEST_HANDLE_STRUCT(xen_mc_fetch);
278
279
280
/*
281
* This tells the hypervisor to notify a DomU about the machine check error
282
*/
283
#define XEN_MC_notifydomain 2
284
struct xen_mc_notifydomain {
285
/* IN variables */
286
uint16_t mc_domid; /* The unprivileged domain to notify */
287
uint16_t mc_vcpuid; /* The vcpu in mc_domid to notify */
288
289
/* IN/OUT variables */
290
uint32_t flags;
291
};
292
DEFINE_GUEST_HANDLE_STRUCT(xen_mc_notifydomain);
293
294
#define XEN_MC_physcpuinfo 3
295
struct xen_mc_physcpuinfo {
296
/* IN/OUT */
297
uint32_t ncpus;
298
uint32_t _pad0;
299
/* OUT */
300
GUEST_HANDLE(mcinfo_logical_cpu) info;
301
};
302
303
#define XEN_MC_msrinject 4
304
#define MC_MSRINJ_MAXMSRS 8
305
struct xen_mc_msrinject {
306
/* IN */
307
uint32_t mcinj_cpunr; /* target processor id */
308
uint32_t mcinj_flags; /* see MC_MSRINJ_F_* below */
309
uint32_t mcinj_count; /* 0 .. count-1 in array are valid */
310
uint32_t _pad0;
311
struct mcinfo_msr mcinj_msr[MC_MSRINJ_MAXMSRS];
312
};
313
314
/* Flags for mcinj_flags above; bits 16-31 are reserved */
315
#define MC_MSRINJ_F_INTERPOSE 0x1
316
317
#define XEN_MC_mceinject 5
318
struct xen_mc_mceinject {
319
unsigned int mceinj_cpunr; /* target processor id */
320
};
321
322
struct xen_mc {
323
uint32_t cmd;
324
uint32_t interface_version; /* XEN_MCA_INTERFACE_VERSION */
325
union {
326
struct xen_mc_fetch mc_fetch;
327
struct xen_mc_notifydomain mc_notifydomain;
328
struct xen_mc_physcpuinfo mc_physcpuinfo;
329
struct xen_mc_msrinject mc_msrinject;
330
struct xen_mc_mceinject mc_mceinject;
331
} u;
332
};
333
DEFINE_GUEST_HANDLE_STRUCT(xen_mc);
334
335
/*
336
* Fields are zero when not available. Also, this struct is shared with
337
* userspace mcelog and thus must keep existing fields at current offsets.
338
* Only add new fields to the end of the structure
339
*/
340
struct xen_mce {
341
__u64 status;
342
__u64 misc;
343
__u64 addr;
344
__u64 mcgstatus;
345
__u64 ip;
346
__u64 tsc; /* cpu time stamp counter */
347
__u64 time; /* wall time_t when error was detected */
348
__u8 cpuvendor; /* cpu vendor as encoded in system.h */
349
__u8 inject_flags; /* software inject flags */
350
__u16 pad;
351
__u32 cpuid; /* CPUID 1 EAX */
352
__u8 cs; /* code segment */
353
__u8 bank; /* machine check bank */
354
__u8 cpu; /* cpu number; obsolete; use extcpu now */
355
__u8 finished; /* entry is valid */
356
__u32 extcpu; /* linux cpu number that detected the error */
357
__u32 socketid; /* CPU socket ID */
358
__u32 apicid; /* CPU initial apic ID */
359
__u64 mcgcap; /* MCGCAP MSR: machine check capabilities of CPU */
360
__u64 synd; /* MCA_SYND MSR: only valid on SMCA systems */
361
__u64 ipid; /* MCA_IPID MSR: only valid on SMCA systems */
362
__u64 ppin; /* Protected Processor Inventory Number */
363
};
364
365
/*
366
* This structure contains all data related to the MCE log. Also
367
* carries a signature to make it easier to find from external
368
* debugging tools. Each entry is only valid when its finished flag
369
* is set.
370
*/
371
372
#define XEN_MCE_LOG_LEN 32
373
374
struct xen_mce_log {
375
char signature[12] __nonstring; /* "MACHINECHECK" */
376
unsigned len; /* = XEN_MCE_LOG_LEN */
377
unsigned next;
378
unsigned flags;
379
unsigned recordlen; /* length of struct xen_mce */
380
struct xen_mce entry[XEN_MCE_LOG_LEN];
381
};
382
383
#define XEN_MCE_OVERFLOW 0 /* bit 0 in flags means overflow */
384
385
#define XEN_MCE_LOG_SIGNATURE "MACHINECHECK"
386
387
#define MCE_GET_RECORD_LEN _IOR('M', 1, int)
388
#define MCE_GET_LOG_LEN _IOR('M', 2, int)
389
#define MCE_GETCLEAR_FLAGS _IOR('M', 3, int)
390
391
#endif /* __ASSEMBLY__ */
392
#endif /* __XEN_PUBLIC_ARCH_X86_MCA_H__ */
393
394