|
@@ -114,7 +114,6 @@ static struct work_struct mce_work;
|
|
static struct irq_work mce_irq_work;
|
|
static struct irq_work mce_irq_work;
|
|
|
|
|
|
static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
|
|
static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
|
|
-static int mce_usable_address(struct mce *m);
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* CPU/chipset specific EDAC code can register a notifier call here to print
|
|
* CPU/chipset specific EDAC code can register a notifier call here to print
|
|
@@ -475,6 +474,28 @@ static void mce_report_event(struct pt_regs *regs)
|
|
irq_work_queue(&mce_irq_work);
|
|
irq_work_queue(&mce_irq_work);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Check if the address reported by the CPU is in a format we can parse.
|
|
|
|
+ * It would be possible to add code for most other cases, but all would
|
|
|
|
+ * be somewhat complicated (e.g. segment offset would require an instruction
|
|
|
|
+ * parser). So only support physical addresses up to page granuality for now.
|
|
|
|
+ */
|
|
|
|
+static int mce_usable_address(struct mce *m)
|
|
|
|
+{
|
|
|
|
+ if (!(m->status & MCI_STATUS_MISCV) || !(m->status & MCI_STATUS_ADDRV))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ /* Checks after this one are Intel-specific: */
|
|
|
|
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ if (MCI_MISC_ADDR_LSB(m->misc) > PAGE_SHIFT)
|
|
|
|
+ return 0;
|
|
|
|
+ if (MCI_MISC_ADDR_MODE(m->misc) != MCI_MISC_ADDR_PHYS)
|
|
|
|
+ return 0;
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
static int srao_decode_notifier(struct notifier_block *nb, unsigned long val,
|
|
static int srao_decode_notifier(struct notifier_block *nb, unsigned long val,
|
|
void *data)
|
|
void *data)
|
|
{
|
|
{
|
|
@@ -930,23 +951,6 @@ reset:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * Check if the address reported by the CPU is in a format we can parse.
|
|
|
|
- * It would be possible to add code for most other cases, but all would
|
|
|
|
- * be somewhat complicated (e.g. segment offset would require an instruction
|
|
|
|
- * parser). So only support physical addresses up to page granuality for now.
|
|
|
|
- */
|
|
|
|
-static int mce_usable_address(struct mce *m)
|
|
|
|
-{
|
|
|
|
- if (!(m->status & MCI_STATUS_MISCV) || !(m->status & MCI_STATUS_ADDRV))
|
|
|
|
- return 0;
|
|
|
|
- if (MCI_MISC_ADDR_LSB(m->misc) > PAGE_SHIFT)
|
|
|
|
- return 0;
|
|
|
|
- if (MCI_MISC_ADDR_MODE(m->misc) != MCI_MISC_ADDR_PHYS)
|
|
|
|
- return 0;
|
|
|
|
- return 1;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void mce_clear_state(unsigned long *toclear)
|
|
static void mce_clear_state(unsigned long *toclear)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|