1e4b86885SCheng Sean Ye /******************************************************************************
2349b53ddSStuart Maybee  * arch-x86/mca.h
3*55fea89dSDan Cross  *
4e4b86885SCheng Sean Ye  * Contributed by Advanced Micro Devices, Inc.
5e4b86885SCheng Sean Ye  * Author: Christoph Egger <Christoph.Egger@amd.com>
6e4b86885SCheng Sean Ye  *
7e4b86885SCheng Sean Ye  * Guest OS machine check interface to x86 Xen.
8*55fea89dSDan Cross  *
9e4b86885SCheng Sean Ye  * Permission is hereby granted, free of charge, to any person obtaining a copy
10e4b86885SCheng Sean Ye  * of this software and associated documentation files (the "Software"), to
11e4b86885SCheng Sean Ye  * deal in the Software without restriction, including without limitation the
12e4b86885SCheng Sean Ye  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
13e4b86885SCheng Sean Ye  * sell copies of the Software, and to permit persons to whom the Software is
14e4b86885SCheng Sean Ye  * furnished to do so, subject to the following conditions:
15e4b86885SCheng Sean Ye  *
16e4b86885SCheng Sean Ye  * The above copyright notice and this permission notice shall be included in
17e4b86885SCheng Sean Ye  * all copies or substantial portions of the Software.
18e4b86885SCheng Sean Ye  *
19e4b86885SCheng Sean Ye  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20e4b86885SCheng Sean Ye  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21e4b86885SCheng Sean Ye  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22e4b86885SCheng Sean Ye  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23e4b86885SCheng Sean Ye  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24e4b86885SCheng Sean Ye  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25e4b86885SCheng Sean Ye  * DEALINGS IN THE SOFTWARE.
26e4b86885SCheng Sean Ye  */
27e4b86885SCheng Sean Ye 
28e4b86885SCheng Sean Ye /* Full MCA functionality has the following Usecases from the guest side:
29e4b86885SCheng Sean Ye  *
30e4b86885SCheng Sean Ye  * Must have's:
31e4b86885SCheng Sean Ye  * 1. Dom0 and DomU register machine check trap callback handlers
32e4b86885SCheng Sean Ye  *    (already done via "set_trap_table" hypercall)
33e4b86885SCheng Sean Ye  * 2. Dom0 registers machine check event callback handler
34e4b86885SCheng Sean Ye  *    (doable via EVTCHNOP_bind_virq)
35e4b86885SCheng Sean Ye  * 3. Dom0 and DomU fetches machine check data
36e4b86885SCheng Sean Ye  * 4. Dom0 wants Xen to notify a DomU
37e4b86885SCheng Sean Ye  * 5. Dom0 gets DomU ID from physical address
38e4b86885SCheng Sean Ye  * 6. Dom0 wants Xen to kill DomU (already done for "xm destroy")
39e4b86885SCheng Sean Ye  *
40e4b86885SCheng Sean Ye  * Nice to have's:
41e4b86885SCheng Sean Ye  * 7. Dom0 wants Xen to deactivate a physical CPU
42e4b86885SCheng Sean Ye  *    This is better done as separate task, physical CPU hotplugging,
43e4b86885SCheng Sean Ye  *    and hypercall(s) should be sysctl's
44e4b86885SCheng Sean Ye  * 8. Page migration proposed from Xen NUMA work, where Dom0 can tell Xen to
45e4b86885SCheng Sean Ye  *    move a DomU (or Dom0 itself) away from a malicious page
46e4b86885SCheng Sean Ye  *    producing correctable errors.
47e4b86885SCheng Sean Ye  * 9. offlining physical page:
48e4b86885SCheng Sean Ye  *    Xen free's and never re-uses a certain physical page.
49e4b86885SCheng Sean Ye  * 10. Testfacility: Allow Dom0 to write values into machine check MSR's
50e4b86885SCheng Sean Ye  *     and tell Xen to trigger a machine check
51e4b86885SCheng Sean Ye  */
52e4b86885SCheng Sean Ye 
53e4b86885SCheng Sean Ye #ifndef __XEN_PUBLIC_ARCH_X86_MCA_H__
54e4b86885SCheng Sean Ye #define __XEN_PUBLIC_ARCH_X86_MCA_H__
55e4b86885SCheng Sean Ye 
56e4b86885SCheng Sean Ye /* Hypercall */
57e4b86885SCheng Sean Ye #define __HYPERVISOR_mca __HYPERVISOR_arch_0
58e4b86885SCheng Sean Ye 
59e4b86885SCheng Sean Ye /*
60e4b86885SCheng Sean Ye  * The xen-unstable repo has interface version 0x03000001; out interface
61e4b86885SCheng Sean Ye  * is incompatible with that and any future minor revisions, so we
62e4b86885SCheng Sean Ye  * choose a different version number range that is numerically less
63e4b86885SCheng Sean Ye  * than that used in xen-unstable.
64e4b86885SCheng Sean Ye  */
65ad09f8b8SMark Johnson #define XEN_MCA_INTERFACE_VERSION 0x01ecc003
66e4b86885SCheng Sean Ye 
67e4b86885SCheng Sean Ye /* IN: Dom0 calls hypercall to retrieve nonurgent telemetry */
68349b53ddSStuart Maybee #define XEN_MC_NONURGENT  0x0001
69349b53ddSStuart Maybee /* IN: Dom0/DomU calls hypercall to retrieve urgent telemetry */
70349b53ddSStuart Maybee #define XEN_MC_URGENT     0x0002
71e4b86885SCheng Sean Ye /* IN: Dom0 acknowledges previosly-fetched telemetry */
72349b53ddSStuart Maybee #define XEN_MC_ACK        0x0004
73e4b86885SCheng Sean Ye 
74349b53ddSStuart Maybee /* OUT: All is ok */
75349b53ddSStuart Maybee #define XEN_MC_OK           0x0
76e4b86885SCheng Sean Ye /* OUT: Domain could not fetch data. */
77349b53ddSStuart Maybee #define XEN_MC_FETCHFAILED  0x1
78e4b86885SCheng Sean Ye /* OUT: There was no machine check data to fetch. */
79349b53ddSStuart Maybee #define XEN_MC_NODATA       0x2
80e4b86885SCheng Sean Ye /* OUT: Between notification time and this hypercall an other
81e4b86885SCheng Sean Ye  *  (most likely) correctable error happened. The fetched data,
82e4b86885SCheng Sean Ye  *  does not match the original machine check data. */
83349b53ddSStuart Maybee #define XEN_MC_NOMATCH      0x4
84e4b86885SCheng Sean Ye 
85e4b86885SCheng Sean Ye /* OUT: DomU did not register MC NMI handler. Try something else. */
86349b53ddSStuart Maybee #define XEN_MC_CANNOTHANDLE 0x8
87e4b86885SCheng Sean Ye /* OUT: Notifying DomU failed. Retry later or try something else. */
88349b53ddSStuart Maybee #define XEN_MC_NOTDELIVERED 0x10
89349b53ddSStuart Maybee /* Note, XEN_MC_CANNOTHANDLE and XEN_MC_NOTDELIVERED are mutually exclusive. */
90349b53ddSStuart Maybee 
91e4b86885SCheng Sean Ye 
92e4b86885SCheng Sean Ye #ifndef __ASSEMBLY__
93e4b86885SCheng Sean Ye 
94e4b86885SCheng Sean Ye #define VIRQ_MCA VIRQ_ARCH_0 /* G. (DOM0) Machine Check Architecture */
95e4b86885SCheng Sean Ye 
96e4b86885SCheng Sean Ye /*
97e4b86885SCheng Sean Ye  * Machine Check Architecure:
98e4b86885SCheng Sean Ye  * structs are read-only and used to report all kinds of
99e4b86885SCheng Sean Ye  * correctable and uncorrectable errors detected by the HW.
100e4b86885SCheng Sean Ye  * Dom0 and DomU: register a handler to get notified.
101e4b86885SCheng Sean Ye  * Dom0 only: Correctable errors are reported via VIRQ_MCA
102e4b86885SCheng Sean Ye  * Dom0 and DomU: Uncorrectable errors are reported via nmi handlers
103e4b86885SCheng Sean Ye  */
104e4b86885SCheng Sean Ye #define MC_TYPE_GLOBAL          0
105e4b86885SCheng Sean Ye #define MC_TYPE_BANK            1
106e4b86885SCheng Sean Ye #define MC_TYPE_EXTENDED        2
107ad09f8b8SMark Johnson #define MC_TYPE_RECOVERY        3
108e4b86885SCheng Sean Ye 
109e4b86885SCheng Sean Ye struct mcinfo_common {
110349b53ddSStuart Maybee     uint16_t type;      /* structure type */
111e4b86885SCheng Sean Ye     uint16_t size;      /* size of this struct in bytes */
112e4b86885SCheng Sean Ye };
113e4b86885SCheng Sean Ye 
114e4b86885SCheng Sean Ye 
115349b53ddSStuart Maybee #define MC_FLAG_CORRECTABLE     (1 << 0)
116349b53ddSStuart Maybee #define MC_FLAG_UNCORRECTABLE   (1 << 1)
117349b53ddSStuart Maybee #define MC_FLAG_RECOVERABLE	(1 << 2)
118349b53ddSStuart Maybee #define MC_FLAG_POLLED		(1 << 3)
119349b53ddSStuart Maybee #define MC_FLAG_RESET		(1 << 4)
120349b53ddSStuart Maybee #define MC_FLAG_CMCI		(1 << 5)
121349b53ddSStuart Maybee #define MC_FLAG_MCE		(1 << 6)
122e4b86885SCheng Sean Ye /* contains global x86 mc information */
123e4b86885SCheng Sean Ye struct mcinfo_global {
124e4b86885SCheng Sean Ye     struct mcinfo_common common;
125e4b86885SCheng Sean Ye 
126e4b86885SCheng Sean Ye     /* running domain at the time in error (most likely the impacted one) */
127e4b86885SCheng Sean Ye     uint16_t mc_domid;
128ad09f8b8SMark Johnson     uint16_t mc_vcpuid; /* virtual cpu scheduled for mc_domid */
129e4b86885SCheng Sean Ye     uint32_t mc_socketid; /* physical socket of the physical core */
130e4b86885SCheng Sean Ye     uint16_t mc_coreid; /* physical impacted core */
131e4b86885SCheng Sean Ye     uint16_t mc_core_threadid; /* core thread of physical core */
132ad09f8b8SMark Johnson     uint32_t mc_apicid;
133349b53ddSStuart Maybee     uint32_t mc_flags;
134ad09f8b8SMark Johnson     uint64_t mc_gstatus; /* global status */
135e4b86885SCheng Sean Ye };
136e4b86885SCheng Sean Ye 
137e4b86885SCheng Sean Ye /* contains bank local x86 mc information */
138e4b86885SCheng Sean Ye struct mcinfo_bank {
139e4b86885SCheng Sean Ye     struct mcinfo_common common;
140e4b86885SCheng Sean Ye 
141e4b86885SCheng Sean Ye     uint16_t mc_bank; /* bank nr */
142e4b86885SCheng Sean Ye     uint16_t mc_domid; /* Usecase 5: domain referenced by mc_addr on dom0
143e4b86885SCheng Sean Ye                         * and if mc_addr is valid. Never valid on DomU. */
144e4b86885SCheng Sean Ye     uint64_t mc_status; /* bank status */
145e4b86885SCheng Sean Ye     uint64_t mc_addr;   /* bank address, only valid
146e4b86885SCheng Sean Ye                          * if addr bit is set in mc_status */
147e4b86885SCheng Sean Ye     uint64_t mc_misc;
148349b53ddSStuart Maybee     uint64_t mc_ctrl2;
149349b53ddSStuart Maybee     uint64_t mc_tsc;
150e4b86885SCheng Sean Ye };
151e4b86885SCheng Sean Ye 
152e4b86885SCheng Sean Ye 
153e4b86885SCheng Sean Ye struct mcinfo_msr {
154e4b86885SCheng Sean Ye     uint64_t reg;   /* MSR */
155e4b86885SCheng Sean Ye     uint64_t value; /* MSR value */
156e4b86885SCheng Sean Ye };
157e4b86885SCheng Sean Ye 
158e4b86885SCheng Sean Ye /* contains mc information from other
159*55fea89dSDan Cross  * or additional mc MSRs */
160e4b86885SCheng Sean Ye struct mcinfo_extended {
161e4b86885SCheng Sean Ye     struct mcinfo_common common;
162e4b86885SCheng Sean Ye 
163e4b86885SCheng Sean Ye     /* You can fill up to five registers.
164e4b86885SCheng Sean Ye      * If you need more, then use this structure
165e4b86885SCheng Sean Ye      * multiple times. */
166e4b86885SCheng Sean Ye 
167e4b86885SCheng Sean Ye     uint32_t mc_msrs; /* Number of msr with valid values. */
168349b53ddSStuart Maybee     /*
169ad09f8b8SMark Johnson      * Currently Intel extended MSR (32/64) include all gp registers
170ad09f8b8SMark Johnson      * and E(R)FLAGS, E(R)IP, E(R)MISC, up to 11/19 of them might be
171ad09f8b8SMark Johnson      * useful at present. So expand this array to 16/32 to leave room.
172ad09f8b8SMark Johnson      */
173ad09f8b8SMark Johnson     struct mcinfo_msr mc_msr[sizeof(void *) * 4];
174ad09f8b8SMark Johnson };
175ad09f8b8SMark Johnson 
176ad09f8b8SMark Johnson /* Recovery Action flags. Giving recovery result information to DOM0 */
177ad09f8b8SMark Johnson 
178ad09f8b8SMark Johnson /* Xen takes successful recovery action, the error is recovered */
179ad09f8b8SMark Johnson #define REC_ACTION_RECOVERED (0x1 << 0)
180ad09f8b8SMark Johnson /* No action is performed by XEN */
181ad09f8b8SMark Johnson #define REC_ACTION_NONE (0x1 << 1)
182ad09f8b8SMark Johnson /* It's possible DOM0 might take action ownership in some case */
183ad09f8b8SMark Johnson #define REC_ACTION_NEED_RESET (0x1 << 2)
184ad09f8b8SMark Johnson 
185ad09f8b8SMark Johnson /* Different Recovery Action types, if the action is performed successfully,
186ad09f8b8SMark Johnson  * REC_ACTION_RECOVERED flag will be returned.
187ad09f8b8SMark Johnson  */
188ad09f8b8SMark Johnson 
189ad09f8b8SMark Johnson /* Page Offline Action */
190ad09f8b8SMark Johnson #define MC_ACTION_PAGE_OFFLINE (0x1 << 0)
191ad09f8b8SMark Johnson /* CPU offline Action */
192ad09f8b8SMark Johnson #define MC_ACTION_CPU_OFFLINE (0x1 << 1)
193ad09f8b8SMark Johnson /* L3 cache disable Action */
194ad09f8b8SMark Johnson #define MC_ACTION_CACHE_SHRINK (0x1 << 2)
195ad09f8b8SMark Johnson 
196*55fea89dSDan Cross /* Below interface used between XEN/DOM0 for passing XEN's recovery action
197*55fea89dSDan Cross  * information to DOM0.
198ad09f8b8SMark Johnson  * usage Senario: After offlining broken page, XEN might pass its page offline
199*55fea89dSDan Cross  * recovery action result to DOM0. DOM0 will save the information in
200ad09f8b8SMark Johnson  * non-volatile memory for further proactive actions, such as offlining the
201ad09f8b8SMark Johnson  * easy broken page earlier when doing next reboot.
202ad09f8b8SMark Johnson */
203ad09f8b8SMark Johnson struct page_offline_action
204ad09f8b8SMark Johnson {
205ad09f8b8SMark Johnson     /* Params for passing the offlined page number to DOM0 */
206ad09f8b8SMark Johnson     uint64_t mfn;
207ad09f8b8SMark Johnson     uint64_t status;
208e4b86885SCheng Sean Ye };
209e4b86885SCheng Sean Ye 
210ad09f8b8SMark Johnson struct cpu_offline_action
211ad09f8b8SMark Johnson {
212ad09f8b8SMark Johnson     /* Params for passing the identity of the offlined CPU to DOM0 */
213ad09f8b8SMark Johnson     uint32_t mc_socketid;
214ad09f8b8SMark Johnson     uint16_t mc_coreid;
215ad09f8b8SMark Johnson     uint16_t mc_core_threadid;
216ad09f8b8SMark Johnson };
217ad09f8b8SMark Johnson 
218ad09f8b8SMark Johnson #define MAX_UNION_SIZE 16
219ad09f8b8SMark Johnson struct mcinfo_recovery
220ad09f8b8SMark Johnson {
221ad09f8b8SMark Johnson     struct mcinfo_common common;
222ad09f8b8SMark Johnson     uint16_t mc_bank; /* bank nr */
223ad09f8b8SMark Johnson     uint8_t action_flags;
224ad09f8b8SMark Johnson     uint8_t action_types;
225ad09f8b8SMark Johnson     union {
226ad09f8b8SMark Johnson         struct page_offline_action page_retire;
227ad09f8b8SMark Johnson         struct cpu_offline_action cpu_offline;
228ad09f8b8SMark Johnson         uint8_t pad[MAX_UNION_SIZE];
229ad09f8b8SMark Johnson     } action_info;
230ad09f8b8SMark Johnson };
231ad09f8b8SMark Johnson 
232ad09f8b8SMark Johnson 
233349b53ddSStuart Maybee #define MCINFO_HYPERCALLSIZE	1024
234e4b86885SCheng Sean Ye #define MCINFO_MAXSIZE		768
235e4b86885SCheng Sean Ye 
236349b53ddSStuart Maybee struct mc_info {
237e4b86885SCheng Sean Ye     /* Number of mcinfo_* entries in mi_data */
238e4b86885SCheng Sean Ye     uint32_t mi_nentries;
239ad09f8b8SMark Johnson     uint32_t _pad0;
240ad09f8b8SMark Johnson     uint64_t mi_data[(MCINFO_MAXSIZE - 1) / 8];
241349b53ddSStuart Maybee };
242349b53ddSStuart Maybee typedef struct mc_info mc_info_t;
243e4b86885SCheng Sean Ye DEFINE_XEN_GUEST_HANDLE(mc_info_t);
244e4b86885SCheng Sean Ye 
245e4b86885SCheng Sean Ye #define __MC_MSR_ARRAYSIZE 8
246e4b86885SCheng Sean Ye #define __MC_NMSRS 1
247e4b86885SCheng Sean Ye #define MC_NCAPS	7	/* 7 CPU feature flag words */
248e4b86885SCheng Sean Ye #define MC_CAPS_STD_EDX	0	/* cpuid level 0x00000001 (%edx) */
249e4b86885SCheng Sean Ye #define MC_CAPS_AMD_EDX	1	/* cpuid level 0x80000001 (%edx) */
250e4b86885SCheng Sean Ye #define MC_CAPS_TM	2	/* cpuid level 0x80860001 (TransMeta) */
251e4b86885SCheng Sean Ye #define MC_CAPS_LINUX	3	/* Linux-defined */
252e4b86885SCheng Sean Ye #define MC_CAPS_STD_ECX	4	/* cpuid level 0x00000001 (%ecx) */
253e4b86885SCheng Sean Ye #define MC_CAPS_VIA	5	/* cpuid level 0xc0000001 */
254e4b86885SCheng Sean Ye #define MC_CAPS_AMD_ECX	6	/* cpuid level 0x80000001 (%ecx) */
255e4b86885SCheng Sean Ye 
256ad09f8b8SMark Johnson struct mcinfo_logical_cpu {
257*55fea89dSDan Cross     uint32_t mc_cpunr;
258*55fea89dSDan Cross     uint32_t mc_chipid;
259e4b86885SCheng Sean Ye     uint16_t mc_coreid;
260e4b86885SCheng Sean Ye     uint16_t mc_threadid;
261349b53ddSStuart Maybee     uint32_t mc_apicid;
262349b53ddSStuart Maybee     uint32_t mc_clusterid;
263349b53ddSStuart Maybee     uint32_t mc_ncores;
264349b53ddSStuart Maybee     uint32_t mc_ncores_active;
265349b53ddSStuart Maybee     uint32_t mc_nthreads;
266349b53ddSStuart Maybee     int32_t mc_cpuid_level;
267349b53ddSStuart Maybee     uint32_t mc_family;
268349b53ddSStuart Maybee     uint32_t mc_vendor;
269349b53ddSStuart Maybee     uint32_t mc_model;
270349b53ddSStuart Maybee     uint32_t mc_step;
271e4b86885SCheng Sean Ye     char mc_vendorid[16];
272e4b86885SCheng Sean Ye     char mc_brandid[64];
273e4b86885SCheng Sean Ye     uint32_t mc_cpu_caps[MC_NCAPS];
274349b53ddSStuart Maybee     uint32_t mc_cache_size;
275349b53ddSStuart Maybee     uint32_t mc_cache_alignment;
276349b53ddSStuart Maybee     int32_t mc_nmsrvals;
277e4b86885SCheng Sean Ye     struct mcinfo_msr mc_msrvalues[__MC_MSR_ARRAYSIZE];
278ad09f8b8SMark Johnson };
279ad09f8b8SMark Johnson typedef struct mcinfo_logical_cpu xen_mc_logical_cpu_t;
280e4b86885SCheng Sean Ye DEFINE_XEN_GUEST_HANDLE(xen_mc_logical_cpu_t);
281e4b86885SCheng Sean Ye 
282349b53ddSStuart Maybee 
283*55fea89dSDan Cross /*
284e4b86885SCheng Sean Ye  * OS's should use these instead of writing their own lookup function
285e4b86885SCheng Sean Ye  * each with its own bugs and drawbacks.
286e4b86885SCheng Sean Ye  * We use macros instead of static inline functions to allow guests
287e4b86885SCheng Sean Ye  * to include this header in assembly files (*.S).
288e4b86885SCheng Sean Ye  */
289e4b86885SCheng Sean Ye /* Prototype:
290e4b86885SCheng Sean Ye  *    uint32_t x86_mcinfo_nentries(struct mc_info *mi);
291e4b86885SCheng Sean Ye  */
292e4b86885SCheng Sean Ye #define x86_mcinfo_nentries(_mi)    \
293e4b86885SCheng Sean Ye     (_mi)->mi_nentries
294e4b86885SCheng Sean Ye /* Prototype:
295e4b86885SCheng Sean Ye  *    struct mcinfo_common *x86_mcinfo_first(struct mc_info *mi);
296e4b86885SCheng Sean Ye  */
297e4b86885SCheng Sean Ye #define x86_mcinfo_first(_mi)       \
298ad09f8b8SMark Johnson     ((struct mcinfo_common *)(_mi)->mi_data)
299e4b86885SCheng Sean Ye /* Prototype:
300e4b86885SCheng Sean Ye  *    struct mcinfo_common *x86_mcinfo_next(struct mcinfo_common *mic);
301e4b86885SCheng Sean Ye  */
302e4b86885SCheng Sean Ye #define x86_mcinfo_next(_mic)       \
303ad09f8b8SMark Johnson     ((struct mcinfo_common *)((uint8_t *)(_mic) + (_mic)->size))
304e4b86885SCheng Sean Ye 
305e4b86885SCheng Sean Ye /* Prototype:
306e4b86885SCheng Sean Ye  *    void x86_mcinfo_lookup(void *ret, struct mc_info *mi, uint16_t type);
307e4b86885SCheng Sean Ye  */
308e4b86885SCheng Sean Ye #define x86_mcinfo_lookup(_ret, _mi, _type)    \
309e4b86885SCheng Sean Ye     do {                                                        \
310e4b86885SCheng Sean Ye         uint32_t found, i;                                      \
311e4b86885SCheng Sean Ye         struct mcinfo_common *_mic;                             \
312e4b86885SCheng Sean Ye                                                                 \
313e4b86885SCheng Sean Ye         found = 0;                                              \
314e4b86885SCheng Sean Ye 	(_ret) = NULL;						\
315e4b86885SCheng Sean Ye 	if (_mi == NULL) break;					\
316e4b86885SCheng Sean Ye         _mic = x86_mcinfo_first(_mi);                           \
317e4b86885SCheng Sean Ye         for (i = 0; i < x86_mcinfo_nentries(_mi); i++) {        \
318e4b86885SCheng Sean Ye             if (_mic->type == (_type)) {                        \
319e4b86885SCheng Sean Ye                 found = 1;                                      \
320e4b86885SCheng Sean Ye                 break;                                          \
321e4b86885SCheng Sean Ye             }                                                   \
322e4b86885SCheng Sean Ye             _mic = x86_mcinfo_next(_mic);                       \
323e4b86885SCheng Sean Ye         }                                                       \
324e4b86885SCheng Sean Ye         (_ret) = found ? _mic : NULL;                           \
325e4b86885SCheng Sean Ye     } while (0)
326e4b86885SCheng Sean Ye 
327e4b86885SCheng Sean Ye 
328e4b86885SCheng Sean Ye /* Usecase 1
329e4b86885SCheng Sean Ye  * Register machine check trap callback handler
330e4b86885SCheng Sean Ye  *    (already done via "set_trap_table" hypercall)
331e4b86885SCheng Sean Ye  */
332e4b86885SCheng Sean Ye 
333e4b86885SCheng Sean Ye /* Usecase 2
334e4b86885SCheng Sean Ye  * Dom0 registers machine check event callback handler
335e4b86885SCheng Sean Ye  * done by EVTCHNOP_bind_virq
336e4b86885SCheng Sean Ye  */
337e4b86885SCheng Sean Ye 
338e4b86885SCheng Sean Ye /* Usecase 3
339e4b86885SCheng Sean Ye  * Fetch machine check data from hypervisor.
340e4b86885SCheng Sean Ye  * Note, this hypercall is special, because both Dom0 and DomU must use this.
341e4b86885SCheng Sean Ye  */
342349b53ddSStuart Maybee #define XEN_MC_fetch            1
343e4b86885SCheng Sean Ye struct xen_mc_fetch {
344349b53ddSStuart Maybee     /* IN/OUT variables. */
345349b53ddSStuart Maybee     uint32_t flags;	/* IN: XEN_MC_NONURGENT, XEN_MC_URGENT,
346349b53ddSStuart Maybee                            XEN_MC_ACK if ack'ing an earlier fetch */
347349b53ddSStuart Maybee 			/* OUT: XEN_MC_OK, XEN_MC_FETCHFAILED,
348349b53ddSStuart Maybee 			   XEN_MC_NODATA, XEN_MC_NOMATCH */
349ad09f8b8SMark Johnson     uint32_t _pad0;
350349b53ddSStuart Maybee     uint64_t fetch_id;	/* OUT: id for ack, IN: id we are ack'ing */
351e4b86885SCheng Sean Ye 
352349b53ddSStuart Maybee     /* OUT variables. */
353e4b86885SCheng Sean Ye     XEN_GUEST_HANDLE(mc_info_t) data;
354e4b86885SCheng Sean Ye };
355e4b86885SCheng Sean Ye typedef struct xen_mc_fetch xen_mc_fetch_t;
356e4b86885SCheng Sean Ye DEFINE_XEN_GUEST_HANDLE(xen_mc_fetch_t);
357e4b86885SCheng Sean Ye 
358e4b86885SCheng Sean Ye 
359e4b86885SCheng Sean Ye /* Usecase 4
360e4b86885SCheng Sean Ye  * This tells the hypervisor to notify a DomU about the machine check error
361e4b86885SCheng Sean Ye  */
362349b53ddSStuart Maybee #define XEN_MC_notifydomain     2
363e4b86885SCheng Sean Ye struct xen_mc_notifydomain {
364e4b86885SCheng Sean Ye     /* IN variables. */
365349b53ddSStuart Maybee     uint16_t mc_domid;    /* The unprivileged domain to notify. */
366349b53ddSStuart Maybee     uint16_t mc_vcpuid;   /* The vcpu in mc_domid to notify.
367349b53ddSStuart Maybee                            * Usually echo'd value from the fetch hypercall. */
368e4b86885SCheng Sean Ye 
369e4b86885SCheng Sean Ye     /* IN/OUT variables. */
370349b53ddSStuart Maybee     uint32_t flags;
371349b53ddSStuart Maybee 
372349b53ddSStuart Maybee /* IN: XEN_MC_CORRECTABLE, XEN_MC_TRAP */
373349b53ddSStuart Maybee /* OUT: XEN_MC_OK, XEN_MC_CANNOTHANDLE, XEN_MC_NOTDELIVERED, XEN_MC_NOMATCH */
374e4b86885SCheng Sean Ye };
375e4b86885SCheng Sean Ye typedef struct xen_mc_notifydomain xen_mc_notifydomain_t;
376e4b86885SCheng Sean Ye DEFINE_XEN_GUEST_HANDLE(xen_mc_notifydomain_t);
377e4b86885SCheng Sean Ye 
378349b53ddSStuart Maybee #define XEN_MC_physcpuinfo 3
379e4b86885SCheng Sean Ye struct xen_mc_physcpuinfo {
380e4b86885SCheng Sean Ye 	/* IN/OUT */
381e4b86885SCheng Sean Ye 	uint32_t ncpus;
382ad09f8b8SMark Johnson 	uint32_t _pad0;
383e4b86885SCheng Sean Ye 	/* OUT */
384e4b86885SCheng Sean Ye 	XEN_GUEST_HANDLE(xen_mc_logical_cpu_t) info;
385e4b86885SCheng Sean Ye };
386e4b86885SCheng Sean Ye 
387349b53ddSStuart Maybee #define XEN_MC_msrinject    4
388349b53ddSStuart Maybee #define MC_MSRINJ_MAXMSRS       8
389e4b86885SCheng Sean Ye struct xen_mc_msrinject {
390349b53ddSStuart Maybee        /* IN */
391ad09f8b8SMark Johnson 	uint32_t mcinj_cpunr;           /* target processor id */
392349b53ddSStuart Maybee 	uint32_t mcinj_flags;           /* see MC_MSRINJ_F_* below */
393349b53ddSStuart Maybee 	uint32_t mcinj_count;           /* 0 .. count-1 in array are valid */
394ad09f8b8SMark Johnson 	uint32_t _pad0;
395e4b86885SCheng Sean Ye 	struct mcinfo_msr mcinj_msr[MC_MSRINJ_MAXMSRS];
396e4b86885SCheng Sean Ye };
397e4b86885SCheng Sean Ye 
398e4b86885SCheng Sean Ye /* Flags for mcinj_flags above; bits 16-31 are reserved */
399349b53ddSStuart Maybee #define MC_MSRINJ_F_INTERPOSE   0x1
400e4b86885SCheng Sean Ye 
401349b53ddSStuart Maybee #define XEN_MC_mceinject    5
402e4b86885SCheng Sean Ye struct xen_mc_mceinject {
403349b53ddSStuart Maybee 	unsigned int mceinj_cpunr;      /* target processor id */
404e4b86885SCheng Sean Ye };
405e4b86885SCheng Sean Ye 
406e4b86885SCheng Sean Ye struct xen_mc {
407e4b86885SCheng Sean Ye     uint32_t cmd;
408e4b86885SCheng Sean Ye     uint32_t interface_version; /* XEN_MCA_INTERFACE_VERSION */
409ad09f8b8SMark Johnson     union {
410ad09f8b8SMark Johnson         struct xen_mc_fetch        mc_fetch;
411ad09f8b8SMark Johnson         struct xen_mc_notifydomain mc_notifydomain;
412ad09f8b8SMark Johnson         struct xen_mc_physcpuinfo  mc_physcpuinfo;
413ad09f8b8SMark Johnson         struct xen_mc_msrinject    mc_msrinject;
414ad09f8b8SMark Johnson         struct xen_mc_mceinject    mc_mceinject;
415ad09f8b8SMark Johnson     } u;
416e4b86885SCheng Sean Ye };
417e4b86885SCheng Sean Ye typedef struct xen_mc xen_mc_t;
418e4b86885SCheng Sean Ye DEFINE_XEN_GUEST_HANDLE(xen_mc_t);
419e4b86885SCheng Sean Ye 
420e4b86885SCheng Sean Ye #endif /* __ASSEMBLY__ */
421e4b86885SCheng Sean Ye 
422e4b86885SCheng Sean Ye #endif /* __XEN_PUBLIC_ARCH_X86_MCA_H__ */
423