aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c22
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
201static atomic_t mce_paniced;
202
203/* Panic in progress. Enable interrupts and wait for final IPI */
204static 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
199static void mce_panic(char *msg, struct mce *final, char *exp) 214static 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 */