aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/s390mach.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 3bf466603512..5ae14803091f 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -362,12 +362,19 @@ s390_revalidate_registers(struct mci *mci)
362 return kill_task; 362 return kill_task;
363} 363}
364 364
365#define MAX_IPD_COUNT 29
366#define MAX_IPD_TIME (5 * 60 * 100 * 1000) /* 5 minutes */
367
365/* 368/*
366 * machine check handler. 369 * machine check handler.
367 */ 370 */
368void 371void
369s390_do_machine_check(struct pt_regs *regs) 372s390_do_machine_check(struct pt_regs *regs)
370{ 373{
374 static DEFINE_SPINLOCK(ipd_lock);
375 static unsigned long long last_ipd;
376 static int ipd_count;
377 unsigned long long tmp;
371 struct mci *mci; 378 struct mci *mci;
372 struct mcck_struct *mcck; 379 struct mcck_struct *mcck;
373 int umode; 380 int umode;
@@ -404,11 +411,27 @@ s390_do_machine_check(struct pt_regs *regs)
404 s390_handle_damage("processing backup machine " 411 s390_handle_damage("processing backup machine "
405 "check with damage."); 412 "check with damage.");
406 } 413 }
407 if (!umode) 414
408 s390_handle_damage("processing backup machine " 415 /*
409 "check in kernel mode."); 416 * Nullifying exigent condition, therefore we might
410 mcck->kill_task = 1; 417 * retry this instruction.
411 mcck->mcck_code = *(unsigned long long *) mci; 418 */
419
420 spin_lock(&ipd_lock);
421
422 tmp = get_clock();
423
424 if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME)
425 ipd_count++;
426 else
427 ipd_count = 1;
428
429 last_ipd = tmp;
430
431 if (ipd_count == MAX_IPD_COUNT)
432 s390_handle_damage("too many ipd retries.");
433
434 spin_unlock(&ipd_lock);
412 } 435 }
413 else { 436 else {
414 /* Processing damage -> stopping machine */ 437 /* Processing damage -> stopping machine */