debuggers.hg

view xen/arch/x86/cpu/mcheck/mce.h @ 20998:50ea24db1f88

x86/mcheck: do not blindly de-reference dom0 et al

Since machine checks and CMCIs can happen before Dom0 even gets
constructed, the handlers of these events have to avoid de-referencing
respective pointers without checking.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Feb 17 12:04:50 2010 +0000 (2010-02-17)
parents ebd2495ec073
children 6384675aa29a
line source
1 #ifndef _MCE_H
3 #define _MCE_H
5 #include <xen/init.h>
6 #include <xen/smp.h>
7 #include <asm/types.h>
8 #include <asm/traps.h>
9 #include <asm/atomic.h>
10 #include <asm/percpu.h>
12 #include "x86_mca.h"
13 #include "mctelem.h"
15 #define MCE_QUIET 0
16 #define MCE_VERBOSE 1
17 /* !only for developer debug as printk is unsafe in MCE context */
18 #define MCE_CRITICAL 2
20 extern int mce_verbosity;
21 /* Define the default level of machine check related print.
22 * When set mce_verbosity=verbose, all mce debug information
23 * will be printed, otherwise, those information will not be
24 * printed.
25 */
26 #define mce_printk(v, s, a...) do { \
27 if ((v) <= mce_verbosity) \
28 printk(s, ##a); \
29 } while (0)
32 /* Init functions */
33 int amd_k7_mcheck_init(struct cpuinfo_x86 *c);
34 int amd_k8_mcheck_init(struct cpuinfo_x86 *c);
35 int amd_f10_mcheck_init(struct cpuinfo_x86 *c);
37 int intel_mcheck_init(struct cpuinfo_x86 *c);
39 void intel_mcheck_timer(struct cpuinfo_x86 *c);
40 void mce_intel_feature_init(struct cpuinfo_x86 *c);
41 void amd_nonfatal_mcheck_init(struct cpuinfo_x86 *c);
43 u64 mce_cap_init(void);
44 extern int firstbank;
45 int mca_ctl_conflict(struct mcinfo_bank *bank, struct domain *d);
47 int intel_mce_rdmsr(uint32_t msr, uint64_t *val);
48 int intel_mce_wrmsr(uint32_t msr, uint64_t val);
50 int mce_available(struct cpuinfo_x86 *c);
51 int mce_firstbank(struct cpuinfo_x86 *c);
52 /* Helper functions used for collecting error telemetry */
53 struct mc_info *x86_mcinfo_getptr(void);
54 void mc_panic(char *s);
55 void x86_mc_get_cpu_info(unsigned, uint32_t *, uint16_t *, uint16_t *,
56 uint32_t *, uint32_t *, uint32_t *, uint32_t *);
58 #define dom0_vmce_enabled() (dom0 && dom0->max_vcpus && dom0->vcpu[0] \
59 && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA))
61 /* Register a handler for machine check exceptions. */
62 typedef void (*x86_mce_vector_t)(struct cpu_user_regs *, long);
63 extern void x86_mce_vector_register(x86_mce_vector_t);
65 /* Common generic MCE handler that implementations may nominate
66 * via x86_mce_vector_register. */
67 extern void mcheck_cmn_handler(struct cpu_user_regs *, long, cpu_banks_t);
69 /* Register a handler for judging whether mce is recoverable. */
70 typedef int (*mce_recoverable_t)(u64 status);
71 extern void mce_recoverable_register(mce_recoverable_t);
73 /* Read an MSR, checking for an interposed value first */
74 extern struct intpose_ent *intpose_lookup(unsigned int, uint64_t,
75 uint64_t *);
76 extern void intpose_inval(unsigned int, uint64_t);
78 #define mca_rdmsrl(msr, var) do { \
79 if (intpose_lookup(smp_processor_id(), msr, &var) == NULL) \
80 rdmsrl(msr, var); \
81 } while (0)
83 /* Write an MSR, invalidating any interposed value */
84 #define mca_wrmsrl(msr, val) do { \
85 intpose_inval(smp_processor_id(), msr); \
86 wrmsrl(msr, val); \
87 } while (0)
90 /* Utility function to "logout" all architectural MCA telemetry from the MCA
91 * banks of the current processor. A cookie is returned which may be
92 * uses to reference the data so logged (the cookie can be NULL if
93 * no logout structures were available). The caller can also pass a pointer
94 * to a structure which will be completed with some summary information
95 * of the MCA data observed in the logout operation. */
97 enum mca_source {
98 MCA_MCE_HANDLER,
99 MCA_POLLER,
100 MCA_CMCI_HANDLER,
101 MCA_RESET,
102 MCA_MCE_SCAN
103 };
105 enum mca_extinfo {
106 MCA_EXTINFO_LOCAL,
107 MCA_EXTINFO_GLOBAL,
108 MCA_EXTINFO_IGNORED
109 };
111 struct mca_summary {
112 uint32_t errcnt; /* number of banks with valid errors */
113 int ripv; /* meaningful on #MC */
114 int eipv; /* meaningful on #MC */
115 uint32_t uc; /* bitmask of banks with UC */
116 uint32_t pcc; /* bitmask of banks with PCC */
117 /* bitmask of banks with software error recovery ability*/
118 uint32_t recoverable;
119 };
121 extern cpu_banks_t mca_allbanks;
122 void set_poll_bankmask(struct cpuinfo_x86 *c);
123 DECLARE_PER_CPU(cpu_banks_t, poll_bankmask);
124 DECLARE_PER_CPU(cpu_banks_t, no_cmci_banks);
125 extern int cmci_support;
126 extern int ser_support;
127 extern int is_mc_panic;
128 extern int mce_broadcast;
129 extern void mcheck_mca_clearbanks(cpu_banks_t);
131 extern mctelem_cookie_t mcheck_mca_logout(enum mca_source, cpu_banks_t,
132 struct mca_summary *, cpu_banks_t*);
134 /* Register a callback to be made during bank telemetry logout.
135 * This callback is only available to those machine check handlers
136 * that call to the common mcheck_cmn_handler or who use the common
137 * telemetry logout function mcheck_mca_logout in error polling.
138 *
139 * This can be used to collect additional information (typically non-
140 * architectural) provided by newer CPU families/models without the need
141 * to duplicate the whole handler resulting in various handlers each with
142 * its own tweaks and bugs. The callback receives an struct mc_info pointer
143 * which it can use with x86_mcinfo_add to add additional telemetry,
144 * the current MCA bank number we are reading telemetry from, and the
145 * MCi_STATUS value for that bank.
146 */
148 /* Register a handler for judging whether the bank need to be cleared */
149 typedef int (*mce_need_clearbank_t)(enum mca_source who, u64 status);
150 extern void mce_need_clearbank_register(mce_need_clearbank_t);
152 typedef enum mca_extinfo (*x86_mce_callback_t)
153 (struct mc_info *, uint16_t, uint64_t);
154 extern void x86_mce_callback_register(x86_mce_callback_t);
156 int x86_mcinfo_add(struct mc_info *mi, void *mcinfo);
157 void x86_mcinfo_dump(struct mc_info *mi);
159 #endif /* _MCE_H */