X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=arch%2Fia64%2Fkernel%2Fmca_drv.c;h=aba813c2c150670e808078a4e5866096f523a3db;hb=d85714d81cc0408daddb68c10f7fd69eafe7c213;hp=afc1403799c9511505503d564c6bb30f18df0ea4;hpb=40eb006685387b2861bd7196be0ab7144c5d5b71;p=linux-2.6-omap-h63xx.git diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index afc1403799c..aba813c2c15 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -439,7 +438,7 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci, * @peidx: pointer of index of processor error section * * Return value: - * target address on Success / 0 on Failue + * target address on Success / 0 on Failure */ static u64 get_target_identifier(peidx_table_t *peidx) @@ -602,11 +601,40 @@ recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, default: break; } + } else if (psp->cc && !psp->bc) { /* Cache error */ + status = recover_from_read_error(slidx, peidx, pbci, sos); } return status; } +/* + * recover_from_tlb_check + * @peidx: pointer of index of processor error section + * + * Return value: + * 1 on Success / 0 on Failure + */ +static int +recover_from_tlb_check(peidx_table_t *peidx) +{ + sal_log_mod_error_info_t *smei; + pal_tlb_check_info_t *ptci; + + smei = (sal_log_mod_error_info_t *)peidx_tlb_check(peidx, 0); + ptci = (pal_tlb_check_info_t *)&(smei->check_info); + + /* + * Look for signature of a duplicate TLB DTC entry, which is + * a SW bug and always fatal. + */ + if (ptci->op == PAL_TLB_CHECK_OP_PURGE + && !(ptci->itr || ptci->dtc || ptci->itc)) + return fatal_mca("Duplicate TLB entry"); + + return mca_recovered("TLB check recovered"); +} + /** * recover_from_processor_error * @platform: whether there are some platform error section or not @@ -618,13 +646,6 @@ recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, * Return value: * 1 on Success / 0 on Failure */ -/* - * Later we try to recover when below all conditions are satisfied. - * 1. Only one processor error section is exist. - * 2. BUS_CHECK is exist and the others are not exist.(Except TLB_CHECK) - * 3. The entry of BUS_CHECK_INFO is 1. - * 4. "External bus error" flag is set and the others are not set. - */ static int recover_from_processor_error(int platform, slidx_table_t *slidx, @@ -651,39 +672,40 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, if (psp->us || psp->ci == 0) return fatal_mca("error not contained"); + /* + * Look for recoverable TLB check + */ + if (psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc)) + return recover_from_tlb_check(peidx); + /* * The cache check and bus check bits have four possible states * cc bc - * 0 0 Weird record, not recovered - * 1 0 Cache error, not recovered - * 0 1 I/O error, attempt recovery * 1 1 Memory error, attempt recovery + * 1 0 Cache error, attempt recovery + * 0 1 I/O error, attempt recovery + * 0 0 Other error type, not recovered */ - if (psp->bc == 0 || pbci == NULL) - return fatal_mca("No bus check"); + if (psp->cc == 0 && (psp->bc == 0 || pbci == NULL)) + return fatal_mca("No cache or bus check"); /* - * Sorry, we cannot handle so many. + * Cannot handle more than one bus check. */ if (peidx_bus_check_num(peidx) > 1) return fatal_mca("Too many bus checks"); - /* - * Well, here is only one bus error. - */ + if (pbci->ib) return fatal_mca("Internal Bus error"); - if (pbci->cc) - return fatal_mca("Cache-cache error"); if (pbci->eb && pbci->bsi > 0) return fatal_mca("External bus check fatal status"); /* - * This is a local MCA and estimated as recoverble external bus error. - * (e.g. a load from poisoned memory) - * This means "there are some platform errors". + * This is a local MCA and estimated as a recoverable error. */ if (platform) return recover_from_platform_error(slidx, peidx, pbci, sos); + /* * On account of strange SAL error record, we cannot recover. */