diff options
| -rw-r--r-- | arch/x86/include/asm/mce.h | 21 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-internal.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-severity.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 209 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_intel.c | 8 | ||||
| -rw-r--r-- | arch/x86/lguest/boot.c | 2 | ||||
| -rw-r--r-- | drivers/base/core.c | 21 | ||||
| -rw-r--r-- | include/linux/device.h | 7 |
8 files changed, 159 insertions, 115 deletions
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 54d73b1f00a0..d90c2fccc30c 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
| @@ -119,6 +119,23 @@ struct mce_log { | |||
| 119 | #define K8_MCE_THRESHOLD_BASE (MCE_EXTENDED_BANK + 1) | 119 | #define K8_MCE_THRESHOLD_BASE (MCE_EXTENDED_BANK + 1) |
| 120 | 120 | ||
| 121 | #ifdef __KERNEL__ | 121 | #ifdef __KERNEL__ |
| 122 | |||
| 123 | struct mca_config { | ||
| 124 | bool dont_log_ce; | ||
| 125 | bool cmci_disabled; | ||
| 126 | bool ignore_ce; | ||
| 127 | bool disabled; | ||
| 128 | bool ser; | ||
| 129 | bool bios_cmci_threshold; | ||
| 130 | u8 banks; | ||
| 131 | s8 bootlog; | ||
| 132 | int tolerant; | ||
| 133 | int monarch_timeout; | ||
| 134 | int panic_timeout; | ||
| 135 | u32 rip_msr; | ||
| 136 | }; | ||
| 137 | |||
| 138 | extern struct mca_config mca_cfg; | ||
| 122 | extern void mce_register_decode_chain(struct notifier_block *nb); | 139 | extern void mce_register_decode_chain(struct notifier_block *nb); |
| 123 | extern void mce_unregister_decode_chain(struct notifier_block *nb); | 140 | extern void mce_unregister_decode_chain(struct notifier_block *nb); |
| 124 | 141 | ||
| @@ -126,7 +143,6 @@ extern void mce_unregister_decode_chain(struct notifier_block *nb); | |||
| 126 | #include <linux/init.h> | 143 | #include <linux/init.h> |
| 127 | #include <linux/atomic.h> | 144 | #include <linux/atomic.h> |
| 128 | 145 | ||
| 129 | extern int mce_disabled; | ||
| 130 | extern int mce_p5_enabled; | 146 | extern int mce_p5_enabled; |
| 131 | 147 | ||
| 132 | #ifdef CONFIG_X86_MCE | 148 | #ifdef CONFIG_X86_MCE |
| @@ -159,9 +175,6 @@ DECLARE_PER_CPU(struct device *, mce_device); | |||
| 159 | #define MAX_NR_BANKS 32 | 175 | #define MAX_NR_BANKS 32 |
| 160 | 176 | ||
| 161 | #ifdef CONFIG_X86_MCE_INTEL | 177 | #ifdef CONFIG_X86_MCE_INTEL |
| 162 | extern int mce_cmci_disabled; | ||
| 163 | extern int mce_ignore_ce; | ||
| 164 | extern int mce_bios_cmci_threshold; | ||
| 165 | void mce_intel_feature_init(struct cpuinfo_x86 *c); | 178 | void mce_intel_feature_init(struct cpuinfo_x86 *c); |
| 166 | void cmci_clear(void); | 179 | void cmci_clear(void); |
| 167 | void cmci_reenable(void); | 180 | void cmci_reenable(void); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h index 6a05c1d327a9..5b7d4fa5d3b7 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-internal.h +++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h | |||
| @@ -24,8 +24,6 @@ struct mce_bank { | |||
| 24 | int mce_severity(struct mce *a, int tolerant, char **msg); | 24 | int mce_severity(struct mce *a, int tolerant, char **msg); |
| 25 | struct dentry *mce_get_debugfs_dir(void); | 25 | struct dentry *mce_get_debugfs_dir(void); |
| 26 | 26 | ||
| 27 | extern int mce_ser; | ||
| 28 | |||
| 29 | extern struct mce_bank *mce_banks; | 27 | extern struct mce_bank *mce_banks; |
| 30 | 28 | ||
| 31 | #ifdef CONFIG_X86_MCE_INTEL | 29 | #ifdef CONFIG_X86_MCE_INTEL |
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c index 13017626f9a8..beb1f1689e52 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-severity.c +++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c | |||
| @@ -193,9 +193,9 @@ int mce_severity(struct mce *m, int tolerant, char **msg) | |||
| 193 | continue; | 193 | continue; |
| 194 | if ((m->mcgstatus & s->mcgmask) != s->mcgres) | 194 | if ((m->mcgstatus & s->mcgmask) != s->mcgres) |
| 195 | continue; | 195 | continue; |
| 196 | if (s->ser == SER_REQUIRED && !mce_ser) | 196 | if (s->ser == SER_REQUIRED && !mca_cfg.ser) |
| 197 | continue; | 197 | continue; |
| 198 | if (s->ser == NO_SER && mce_ser) | 198 | if (s->ser == NO_SER && mca_cfg.ser) |
| 199 | continue; | 199 | continue; |
| 200 | if (s->context && ctx != s->context) | 200 | if (s->context && ctx != s->context) |
| 201 | continue; | 201 | continue; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 46cbf8689692..80dbda84f1c3 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -58,34 +58,26 @@ static DEFINE_MUTEX(mce_chrdev_read_mutex); | |||
| 58 | #define CREATE_TRACE_POINTS | 58 | #define CREATE_TRACE_POINTS |
| 59 | #include <trace/events/mce.h> | 59 | #include <trace/events/mce.h> |
| 60 | 60 | ||
| 61 | int mce_disabled __read_mostly; | ||
| 62 | |||
| 63 | #define SPINUNIT 100 /* 100ns */ | 61 | #define SPINUNIT 100 /* 100ns */ |
| 64 | 62 | ||
| 65 | atomic_t mce_entry; | 63 | atomic_t mce_entry; |
| 66 | 64 | ||
| 67 | DEFINE_PER_CPU(unsigned, mce_exception_count); | 65 | DEFINE_PER_CPU(unsigned, mce_exception_count); |
| 68 | 66 | ||
| 69 | /* | 67 | struct mce_bank *mce_banks __read_mostly; |
| 70 | * Tolerant levels: | 68 | |
| 71 | * 0: always panic on uncorrected errors, log corrected errors | 69 | struct mca_config mca_cfg __read_mostly = { |
| 72 | * 1: panic or SIGBUS on uncorrected errors, log corrected errors | 70 | .bootlog = -1, |
| 73 | * 2: SIGBUS or log uncorrected errors (if possible), log corrected errors | 71 | /* |
| 74 | * 3: never panic or SIGBUS, log all errors (for testing only) | 72 | * Tolerant levels: |
| 75 | */ | 73 | * 0: always panic on uncorrected errors, log corrected errors |
| 76 | static int tolerant __read_mostly = 1; | 74 | * 1: panic or SIGBUS on uncorrected errors, log corrected errors |
| 77 | static int banks __read_mostly; | 75 | * 2: SIGBUS or log uncorrected errors (if possible), log corr. errors |
| 78 | static int rip_msr __read_mostly; | 76 | * 3: never panic or SIGBUS, log all errors (for testing only) |
| 79 | static int mce_bootlog __read_mostly = -1; | 77 | */ |
| 80 | static int monarch_timeout __read_mostly = -1; | 78 | .tolerant = 1, |
| 81 | static int mce_panic_timeout __read_mostly; | 79 | .monarch_timeout = -1 |
| 82 | static int mce_dont_log_ce __read_mostly; | 80 | }; |
| 83 | int mce_cmci_disabled __read_mostly; | ||
| 84 | int mce_ignore_ce __read_mostly; | ||
| 85 | int mce_ser __read_mostly; | ||
| 86 | int mce_bios_cmci_threshold __read_mostly; | ||
| 87 | |||
| 88 | struct mce_bank *mce_banks __read_mostly; | ||
| 89 | 81 | ||
| 90 | /* User mode helper program triggered by machine check event */ | 82 | /* User mode helper program triggered by machine check event */ |
| 91 | static unsigned long mce_need_notify; | 83 | static unsigned long mce_need_notify; |
| @@ -302,7 +294,7 @@ static void wait_for_panic(void) | |||
| 302 | while (timeout-- > 0) | 294 | while (timeout-- > 0) |
| 303 | udelay(1); | 295 | udelay(1); |
| 304 | if (panic_timeout == 0) | 296 | if (panic_timeout == 0) |
| 305 | panic_timeout = mce_panic_timeout; | 297 | panic_timeout = mca_cfg.panic_timeout; |
| 306 | panic("Panicing machine check CPU died"); | 298 | panic("Panicing machine check CPU died"); |
| 307 | } | 299 | } |
| 308 | 300 | ||
| @@ -360,7 +352,7 @@ static void mce_panic(char *msg, struct mce *final, char *exp) | |||
| 360 | pr_emerg(HW_ERR "Machine check: %s\n", exp); | 352 | pr_emerg(HW_ERR "Machine check: %s\n", exp); |
| 361 | if (!fake_panic) { | 353 | if (!fake_panic) { |
| 362 | if (panic_timeout == 0) | 354 | if (panic_timeout == 0) |
| 363 | panic_timeout = mce_panic_timeout; | 355 | panic_timeout = mca_cfg.panic_timeout; |
| 364 | panic(msg); | 356 | panic(msg); |
| 365 | } else | 357 | } else |
| 366 | pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg); | 358 | pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg); |
| @@ -372,7 +364,7 @@ static int msr_to_offset(u32 msr) | |||
| 372 | { | 364 | { |
| 373 | unsigned bank = __this_cpu_read(injectm.bank); | 365 | unsigned bank = __this_cpu_read(injectm.bank); |
| 374 | 366 | ||
| 375 | if (msr == rip_msr) | 367 | if (msr == mca_cfg.rip_msr) |
| 376 | return offsetof(struct mce, ip); | 368 | return offsetof(struct mce, ip); |
| 377 | if (msr == MSR_IA32_MCx_STATUS(bank)) | 369 | if (msr == MSR_IA32_MCx_STATUS(bank)) |
| 378 | return offsetof(struct mce, status); | 370 | return offsetof(struct mce, status); |
| @@ -451,8 +443,8 @@ static inline void mce_gather_info(struct mce *m, struct pt_regs *regs) | |||
| 451 | m->cs |= 3; | 443 | m->cs |= 3; |
| 452 | } | 444 | } |
| 453 | /* Use accurate RIP reporting if available. */ | 445 | /* Use accurate RIP reporting if available. */ |
| 454 | if (rip_msr) | 446 | if (mca_cfg.rip_msr) |
| 455 | m->ip = mce_rdmsrl(rip_msr); | 447 | m->ip = mce_rdmsrl(mca_cfg.rip_msr); |
| 456 | } | 448 | } |
| 457 | } | 449 | } |
| 458 | 450 | ||
| @@ -513,7 +505,7 @@ static int mce_ring_add(unsigned long pfn) | |||
| 513 | 505 | ||
| 514 | int mce_available(struct cpuinfo_x86 *c) | 506 | int mce_available(struct cpuinfo_x86 *c) |
| 515 | { | ||
