diff options
Diffstat (limited to 'arch/ia64/kernel/mca_drv.c')
-rw-r--r-- | arch/ia64/kernel/mca_drv.c | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index afc1403799c9..832cf1e647e8 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c | |||
@@ -602,11 +602,40 @@ recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, | |||
602 | default: | 602 | default: |
603 | break; | 603 | break; |
604 | } | 604 | } |
605 | } else if (psp->cc && !psp->bc) { /* Cache error */ | ||
606 | status = recover_from_read_error(slidx, peidx, pbci, sos); | ||
605 | } | 607 | } |
606 | 608 | ||
607 | return status; | 609 | return status; |
608 | } | 610 | } |
609 | 611 | ||
612 | /* | ||
613 | * recover_from_tlb_check | ||
614 | * @peidx: pointer of index of processor error section | ||
615 | * | ||
616 | * Return value: | ||
617 | * 1 on Success / 0 on Failure | ||
618 | */ | ||
619 | static int | ||
620 | recover_from_tlb_check(peidx_table_t *peidx) | ||
621 | { | ||
622 | sal_log_mod_error_info_t *smei; | ||
623 | pal_tlb_check_info_t *ptci; | ||
624 | |||
625 | smei = (sal_log_mod_error_info_t *)peidx_tlb_check(peidx, 0); | ||
626 | ptci = (pal_tlb_check_info_t *)&(smei->check_info); | ||
627 | |||
628 | /* | ||
629 | * Look for signature of a duplicate TLB DTC entry, which is | ||
630 | * a SW bug and always fatal. | ||
631 | */ | ||
632 | if (ptci->op == PAL_TLB_CHECK_OP_PURGE | ||
633 | && !(ptci->itr || ptci->dtc || ptci->itc)) | ||
634 | return fatal_mca("Duplicate TLB entry"); | ||
635 | |||
636 | return mca_recovered("TLB check recovered"); | ||
637 | } | ||
638 | |||
610 | /** | 639 | /** |
611 | * recover_from_processor_error | 640 | * recover_from_processor_error |
612 | * @platform: whether there are some platform error section or not | 641 | * @platform: whether there are some platform error section or not |
@@ -618,13 +647,6 @@ recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, | |||
618 | * Return value: | 647 | * Return value: |
619 | * 1 on Success / 0 on Failure | 648 | * 1 on Success / 0 on Failure |
620 | */ | 649 | */ |
621 | /* | ||
622 | * Later we try to recover when below all conditions are satisfied. | ||
623 | * 1. Only one processor error section is exist. | ||
624 | * 2. BUS_CHECK is exist and the others are not exist.(Except TLB_CHECK) | ||
625 | * 3. The entry of BUS_CHECK_INFO is 1. | ||
626 | * 4. "External bus error" flag is set and the others are not set. | ||
627 | */ | ||
628 | 650 | ||
629 | static int | 651 | static int |
630 | recover_from_processor_error(int platform, slidx_table_t *slidx, | 652 | recover_from_processor_error(int platform, slidx_table_t *slidx, |
@@ -652,38 +674,39 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, | |||
652 | return fatal_mca("error not contained"); | 674 | return fatal_mca("error not contained"); |
653 | 675 | ||
654 | /* | 676 | /* |
677 | * Look for recoverable TLB check | ||
678 | */ | ||
679 | if (psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc)) | ||
680 | return recover_from_tlb_check(peidx); | ||
681 | |||
682 | /* | ||
655 | * The cache check and bus check bits have four possible states | 683 | * The cache check and bus check bits have four possible states |
656 | * cc bc | 684 | * cc bc |
657 | * 0 0 Weird record, not recovered | ||
658 | * 1 0 Cache error, not recovered | ||
659 | * 0 1 I/O error, attempt recovery | ||
660 | * 1 1 Memory error, attempt recovery | 685 | * 1 1 Memory error, attempt recovery |
686 | * 1 0 Cache error, attempt recovery | ||
687 | * 0 1 I/O error, attempt recovery | ||
688 | * 0 0 Other error type, not recovered | ||
661 | */ | 689 | */ |
662 | if (psp->bc == 0 || pbci == NULL) | 690 | if (psp->cc == 0 && (psp->bc == 0 || pbci == NULL)) |
663 | return fatal_mca("No bus check"); | 691 | return fatal_mca("No cache or bus check"); |
664 | 692 | ||
665 | /* | 693 | /* |
666 | * Sorry, we cannot handle so many. | 694 | * Cannot handle more than one bus check. |
667 | */ | 695 | */ |
668 | if (peidx_bus_check_num(peidx) > 1) | 696 | if (peidx_bus_check_num(peidx) > 1) |
669 | return fatal_mca("Too many bus checks"); | 697 | return fatal_mca("Too many bus checks"); |
670 | /* | 698 | |
671 | * Well, here is only one bus error. | ||
672 | */ | ||
673 | if (pbci->ib) | 699 | if (pbci->ib) |
674 | return fatal_mca("Internal Bus error"); | 700 | return fatal_mca("Internal Bus error"); |
675 | if (pbci->cc) | ||
676 | return fatal_mca("Cache-cache error"); | ||
677 | if (pbci->eb && pbci->bsi > 0) | 701 | if (pbci->eb && pbci->bsi > 0) |
678 | return fatal_mca("External bus check fatal status"); | 702 | return fatal_mca("External bus check fatal status"); |
679 | 703 | ||
680 | /* | 704 | /* |
681 | * This is a local MCA and estimated as recoverble external bus error. | 705 | * This is a local MCA and estimated as a recoverble error. |
682 | * (e.g. a load from poisoned memory) | ||
683 | * This means "there are some platform errors". | ||
684 | */ | 706 | */ |
685 | if (platform) | 707 | if (platform) |
686 | return recover_from_platform_error(slidx, peidx, pbci, sos); | 708 | return recover_from_platform_error(slidx, peidx, pbci, sos); |
709 | |||
687 | /* | 710 | /* |
688 | * On account of strange SAL error record, we cannot recover. | 711 | * On account of strange SAL error record, we cannot recover. |
689 | */ | 712 | */ |