diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 121781627858..421020f1d7db 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -196,10 +196,32 @@ static void print_mce(struct mce *m) | |||
196 | "and contact your hardware vendor\n"); | 196 | "and contact your hardware vendor\n"); |
197 | } | 197 | } |
198 | 198 | ||
199 | #define PANIC_TIMEOUT 5 /* 5 seconds */ | ||
200 | |||
201 | static atomic_t mce_paniced; | ||
202 | |||
203 | /* Panic in progress. Enable interrupts and wait for final IPI */ | ||
204 | static void wait_for_panic(void) | ||
205 | { | ||
206 | long timeout = PANIC_TIMEOUT*USEC_PER_SEC; | ||
207 | preempt_disable(); | ||
208 | local_irq_enable(); | ||
209 | while (timeout-- > 0) | ||
210 | udelay(1); | ||
211 | panic("Panicing machine check CPU died"); | ||
212 | } | ||
213 | |||
199 | static void mce_panic(char *msg, struct mce *final, char *exp) | 214 | static void mce_panic(char *msg, struct mce *final, char *exp) |
200 | { | 215 | { |
201 | int i; | 216 | int i; |
202 | 217 | ||
218 | /* | ||
219 | * Make sure only one CPU runs in machine check panic | ||
220 | */ | ||
221 | if (atomic_add_return(1, &mce_paniced) > 1) | ||
222 | wait_for_panic(); | ||
223 | barrier(); | ||
224 | |||
203 | bust_spinlocks(1); | 225 | bust_spinlocks(1); |
204 | console_verbose(); | 226 | console_verbose(); |
205 | /* First print corrected ones that are still unlogged */ | 227 | /* First print corrected ones that are still unlogged */ |