KVM: Provide current eip as part of emulator context.
[safe/jmp/linux-2.6] / arch / x86 / include / asm / mce.h
index b4a04b6..6c3fdd6 100644 (file)
@@ -9,12 +9,13 @@
  */
 
 #define MCG_BANKCNT_MASK       0xff         /* Number of Banks */
-#define MCG_CTL_P              (1ULL<<8)    /* MCG_CAP register available */
+#define MCG_CTL_P              (1ULL<<8)    /* MCG_CTL register available */
 #define MCG_EXT_P              (1ULL<<9)    /* Extended registers available */
 #define MCG_CMCI_P             (1ULL<<10)   /* CMCI supported */
 #define MCG_EXT_CNT_MASK       0xff0000     /* Number of Extended registers */
 #define MCG_EXT_CNT_SHIFT      16
 #define MCG_EXT_CNT(c)         (((c) & MCG_EXT_CNT_MASK) >> MCG_EXT_CNT_SHIFT)
+#define MCG_SER_P              (1ULL<<24)   /* MCA recovery/new status bits */
 
 #define MCG_STATUS_RIPV  (1ULL<<0)   /* restart ip valid */
 #define MCG_STATUS_EIPV  (1ULL<<1)   /* ip points to correct instruction */
 #define MCI_STATUS_MISCV (1ULL<<59)  /* misc error reg. valid */
 #define MCI_STATUS_ADDRV (1ULL<<58)  /* addr reg. valid */
 #define MCI_STATUS_PCC   (1ULL<<57)  /* processor context corrupt */
+#define MCI_STATUS_S    (1ULL<<56)  /* Signaled machine check */
+#define MCI_STATUS_AR   (1ULL<<55)  /* Action required */
+
+/* MISC register defines */
+#define MCM_ADDR_SEGOFF  0     /* segment offset */
+#define MCM_ADDR_LINEAR  1     /* linear address */
+#define MCM_ADDR_PHYS   2      /* physical address */
+#define MCM_ADDR_MEM    3      /* memory address */
+#define MCM_ADDR_GENERIC 7     /* generic */
+
+#define MCJ_CTX_MASK           3
+#define MCJ_CTX(flags)         ((flags) & MCJ_CTX_MASK)
+#define MCJ_CTX_RANDOM         0    /* inject context: random */
+#define MCJ_CTX_PROCESS                1    /* inject context: process */
+#define MCJ_CTX_IRQ            2    /* inject context: IRQ */
+#define MCJ_NMI_BROADCAST      4    /* do NMI broadcasting */
+#define MCJ_EXCEPTION          8    /* raise as exception */
 
 /* Fields are zero when not available */
 struct mce {
@@ -36,13 +54,19 @@ struct mce {
        __u64 mcgstatus;
        __u64 ip;
        __u64 tsc;      /* cpu time stamp counter */
-       __u64 res1;     /* for future extension */
-       __u64 res2;     /* dito. */
+       __u64 time;     /* wall time_t when error was detected */
+       __u8  cpuvendor;        /* cpu vendor as encoded in system.h */
+       __u8  inject_flags;     /* software inject flags */
+       __u16  pad;
+       __u32 cpuid;    /* CPUID 1 EAX */
        __u8  cs;               /* code segment */
        __u8  bank;     /* machine check bank */
        __u8  cpu;      /* cpu number; obsolete; use extcpu now */
        __u8  finished;   /* entry is valid */
        __u32 extcpu;   /* linux cpu number that detected the error */
+       __u32 socketid; /* CPU socket ID */
+       __u32 apicid;   /* CPU initial apic ID */
+       __u64 mcgcap;   /* MCGCAP MSR: machine check capabilities of CPU */
 };
 
 /*
@@ -84,25 +108,52 @@ struct mce_log {
 #define K8_MCE_THRESHOLD_BANK_5    (MCE_THRESHOLD_BASE + 5 * 9)
 #define K8_MCE_THRESHOLD_DRAM_ECC  (MCE_THRESHOLD_BANK_4 + 0)
 
+
 #ifdef __KERNEL__
 
-extern int mce_disabled;
+extern struct atomic_notifier_head x86_mce_decoder_chain;
 
-#include <asm/atomic.h>
 #include <linux/percpu.h>
+#include <linux/init.h>
+#include <asm/atomic.h>
+
+extern int mce_disabled;
+extern int mce_p5_enabled;
+
+#ifdef CONFIG_X86_MCE
+int mcheck_init(void);
+void mcheck_cpu_init(struct cpuinfo_x86 *c);
+#else
+static inline int mcheck_init(void) { return 0; }
+static inline void mcheck_cpu_init(struct cpuinfo_x86 *c) {}
+#endif
+
+#ifdef CONFIG_X86_ANCIENT_MCE
+void intel_p5_mcheck_init(struct cpuinfo_x86 *c);
+void winchip_mcheck_init(struct cpuinfo_x86 *c);
+static inline void enable_p5_mce(void) { mce_p5_enabled = 1; }
+#else
+static inline void intel_p5_mcheck_init(struct cpuinfo_x86 *c) {}
+static inline void winchip_mcheck_init(struct cpuinfo_x86 *c) {}
+static inline void enable_p5_mce(void) {}
+#endif
+
+extern void (*x86_mce_decode_callback)(struct mce *m);
 
 void mce_setup(struct mce *m);
 void mce_log(struct mce *m);
 DECLARE_PER_CPU(struct sys_device, mce_dev);
-extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
 
 /*
- * To support more than 128 would need to escape the predefined
- * Linux defined extended banks first.
+ * Maximum banks number.
+ * This is the limit of the current register layout on
+ * Intel CPUs.
  */
-#define MAX_NR_BANKS (MCE_EXTENDED_BANK - 1)
+#define MAX_NR_BANKS 32
 
 #ifdef CONFIG_X86_MCE_INTEL
+extern int mce_cmci_disabled;
+extern int mce_ignore_ce;
 void mce_intel_feature_init(struct cpuinfo_x86 *c);
 void cmci_clear(void);
 void cmci_reenable(void);
@@ -127,12 +178,8 @@ int mce_available(struct cpuinfo_x86 *c);
 DECLARE_PER_CPU(unsigned, mce_exception_count);
 DECLARE_PER_CPU(unsigned, mce_poll_count);
 
-void mce_log_therm_throt_event(__u64 status);
-
 extern atomic_t mce_entry;
 
-void do_machine_check(struct pt_regs *, long);
-
 typedef DECLARE_BITMAP(mce_banks_t, MAX_NR_BANKS);
 DECLARE_PER_CPU(mce_banks_t, mce_poll_banks);
 
@@ -143,18 +190,40 @@ enum mcp_flags {
 };
 void machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
 
-int mce_notify_user(void);
+int mce_notify_irq(void);
+void mce_notify_process(void);
 
 DECLARE_PER_CPU(struct mce, injectm);
 extern struct file_operations mce_chrdev_ops;
 
-#ifdef CONFIG_X86_MCE
-void mcheck_init(struct cpuinfo_x86 *c);
-#else
-#define mcheck_init(c) do { } while (0)
-#endif
+/*
+ * Exception handler
+ */
+
+/* Call the installed machine check handler for this CPU setup. */
+extern void (*machine_check_vector)(struct pt_regs *, long error_code);
+void do_machine_check(struct pt_regs *, long);
+
+/*
+ * Threshold handler
+ */
 
 extern void (*mce_threshold_vector)(void);
+extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
+
+/*
+ * Thermal handler
+ */
+
+void intel_init_thermal(struct cpuinfo_x86 *c);
+
+void mce_log_therm_throt_event(__u64 status);
+
+#ifdef CONFIG_X86_THERMAL_VECTOR
+extern void mcheck_intel_therm_init(void);
+#else
+static inline void mcheck_intel_therm_init(void) { }
+#endif
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_X86_MCE_H */