diff options
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r-- | arch/ia64/kernel/mca_drv.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 37c88eb55873..ca6666b51ccb 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c | |||
@@ -62,6 +62,11 @@ typedef enum { | |||
62 | ISOLATE_NONE | 62 | ISOLATE_NONE |
63 | } isolate_status_t; | 63 | } isolate_status_t; |
64 | 64 | ||
65 | typedef enum { | ||
66 | MCA_NOT_RECOVERED = 0, | ||
67 | MCA_RECOVERED = 1 | ||
68 | } recovery_status_t; | ||
69 | |||
65 | /* | 70 | /* |
66 | * This pool keeps pointers to the section part of SAL error record | 71 | * This pool keeps pointers to the section part of SAL error record |
67 | */ | 72 | */ |
@@ -71,6 +76,18 @@ static struct { | |||
71 | int max_idx; /* Maximum index of section pointer list pool */ | 76 | int max_idx; /* Maximum index of section pointer list pool */ |
72 | } slidx_pool; | 77 | } slidx_pool; |
73 | 78 | ||
79 | static int | ||
80 | fatal_mca(const char *fmt, ...) | ||
81 | { | ||
82 | va_list args; | ||
83 | |||
84 | va_start(args, fmt); | ||
85 | vprintk(fmt, args); | ||
86 | va_end(args); | ||
87 | |||
88 | return MCA_NOT_RECOVERED; | ||
89 | } | ||
90 | |||
74 | /** | 91 | /** |
75 | * mca_page_isolate - isolate a poisoned page in order not to use it later | 92 | * mca_page_isolate - isolate a poisoned page in order not to use it later |
76 | * @paddr: poisoned memory location | 93 | * @paddr: poisoned memory location |
@@ -424,7 +441,7 @@ recover_from_read_error(slidx_table_t *slidx, | |||
424 | 441 | ||
425 | /* Is target address valid? */ | 442 | /* Is target address valid? */ |
426 | if (!pbci->tv) | 443 | if (!pbci->tv) |
427 | return 0; | 444 | return fatal_mca(KERN_ALERT "MCA: target address not valid\n"); |
428 | 445 | ||
429 | /* | 446 | /* |
430 | * cpu read or memory-mapped io read | 447 | * cpu read or memory-mapped io read |
@@ -442,7 +459,7 @@ recover_from_read_error(slidx_table_t *slidx, | |||
442 | 459 | ||
443 | /* Is minstate valid? */ | 460 | /* Is minstate valid? */ |
444 | if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate)) | 461 | if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate)) |
445 | return 0; | 462 | return fatal_mca(KERN_ALERT "MCA: minstate not valid\n"); |
446 | psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr); | 463 | psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr); |
447 | psr2 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_xpsr); | 464 | psr2 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_xpsr); |
448 | 465 | ||
@@ -476,12 +493,13 @@ recover_from_read_error(slidx_table_t *slidx, | |||
476 | psr2->bn = 1; | 493 | psr2->bn = 1; |
477 | psr2->i = 0; | 494 | psr2->i = 0; |
478 | 495 | ||
479 | return 1; | 496 | return MCA_RECOVERED; |
480 | } | 497 | } |
481 | 498 | ||
482 | } | 499 | } |
483 | 500 | ||
484 | return 0; | 501 | return fatal_mca(KERN_ALERT "MCA: kernel context not recovered," |
502 | " iip 0x%lx\n", pmsa->pmsa_iip); | ||
485 | } | 503 | } |
486 | 504 | ||
487 | /** | 505 | /** |
@@ -567,13 +585,13 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, | |||
567 | * The machine check is corrected. | 585 | * The machine check is corrected. |
568 | */ | 586 | */ |
569 | if (psp->cm == 1) | 587 | if (psp->cm == 1) |
570 | return 1; | 588 | return MCA_RECOVERED; |
571 | 589 | ||
572 | /* | 590 | /* |
573 | * The error was not contained. Software must be reset. | 591 | * The error was not contained. Software must be reset. |
574 | */ | 592 | */ |
575 | if (psp->us || psp->ci == 0) | 593 | if (psp->us || psp->ci == 0) |
576 | return 0; | 594 | return fatal_mca(KERN_ALERT "MCA: error not contained\n"); |
577 | 595 | ||
578 | /* | 596 | /* |
579 | * The cache check and bus check bits have four possible states | 597 | * The cache check and bus check bits have four possible states |
@@ -584,20 +602,22 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, | |||
584 | * 1 1 Memory error, attempt recovery | 602 | * 1 1 Memory error, attempt recovery |
585 | */ | 603 | */ |
586 | if (psp->bc == 0 || pbci == NULL) | 604 | if (psp->bc == 0 || pbci == NULL) |
587 | return 0; | 605 | return fatal_mca(KERN_ALERT "MCA: No bus check\n"); |
588 | 606 | ||
589 | /* | 607 | /* |
590 | * Sorry, we cannot handle so many. | 608 | * Sorry, we cannot handle so many. |
591 | */ | 609 | */ |
592 | if (peidx_bus_check_num(peidx) > 1) | 610 | if (peidx_bus_check_num(peidx) > 1) |
593 | return 0; | 611 | return fatal_mca(KERN_ALERT "MCA: Too many bus checks\n"); |
594 | /* | 612 | /* |
595 | * Well, here is only one bus error. | 613 | * Well, here is only one bus error. |
596 | */ | 614 | */ |
597 | if (pbci->ib || pbci->cc) | 615 | if (pbci->ib) |
598 | return 0; | 616 | return fatal_mca(KERN_ALERT "MCA: Internal Bus error\n"); |
617 | if (pbci->cc) | ||
618 | return fatal_mca(KERN_ALERT "MCA: Cache-cache error\n"); | ||
599 | if (pbci->eb && pbci->bsi > 0) | 619 | if (pbci->eb && pbci->bsi > 0) |
600 | return 0; | 620 | return fatal_mca(KERN_ALERT "MCA: External bus check fatal status\n"); |
601 | 621 | ||
602 | /* | 622 | /* |
603 | * This is a local MCA and estimated as recoverble external bus error. | 623 | * This is a local MCA and estimated as recoverble external bus error. |
@@ -609,7 +629,7 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, | |||
609 | /* | 629 | /* |
610 | * On account of strange SAL error record, we cannot recover. | 630 | * On account of strange SAL error record, we cannot recover. |
611 | */ | 631 | */ |
612 | return 0; | 632 | return fatal_mca(KERN_ALERT "MCA: Strange SAL record\n"); |
613 | } | 633 | } |
614 | 634 | ||
615 | /** | 635 | /** |
@@ -638,12 +658,10 @@ mca_try_to_recover(void *rec, struct ia64_sal_os_state *sos) | |||
638 | 658 | ||
639 | /* Now, OS can recover when there is one processor error section */ | 659 | /* Now, OS can recover when there is one processor error section */ |
640 | if (n_proc_err > 1) | 660 | if (n_proc_err > 1) |
641 | return 0; | 661 | return fatal_mca(KERN_ALERT "MCA: Too Many Errors\n"); |
642 | else if (n_proc_err == 0) { | 662 | else if (n_proc_err == 0) |
643 | /* Weird SAL record ... We need not to recover */ | 663 | /* Weird SAL record ... We need not to recover */ |
644 | 664 | return fatal_mca(KERN_ALERT "MCA: Weird SAL record\n"); | |
645 | return 1; | ||
646 | } | ||
647 | 665 | ||
648 | /* Make index of processor error section */ | 666 | /* Make index of processor error section */ |
649 | mca_make_peidx((sal_log_processor_info_t*) | 667 | mca_make_peidx((sal_log_processor_info_t*) |
@@ -654,7 +672,7 @@ mca_try_to_recover(void *rec, struct ia64_sal_os_state *sos) | |||
654 | 672 | ||
655 | /* Check whether MCA is global or not */ | 673 | /* Check whether MCA is global or not */ |
656 | if (is_mca_global(&peidx, &pbci, sos)) | 674 | if (is_mca_global(&peidx, &pbci, sos)) |
657 | return 0; | 675 | return fatal_mca(KERN_ALERT "MCA: global MCA\n"); |
658 | 676 | ||
659 | /* Try to recover a processor error */ | 677 | /* Try to recover a processor error */ |
660 | return recover_from_processor_error(platform_err, &slidx, &peidx, | 678 | return recover_from_processor_error(platform_err, &slidx, &peidx, |