aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2014-01-15 00:16:13 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-01-15 01:18:59 -0500
commitcb5b242c8c14a4b1dcd358400da28208fde78947 (patch)
treeb003655a84193071b8089d19b5bc1e9663574d1b /arch/powerpc
parent7e4e7867b1e551b7b8f326da3604c47332972bc6 (diff)
powerpc/eeh: Escalate error on non-existing PE
Sometimes, especially in sinario of loading another kernel with kdump, we got EEH error on non-existing PE. That means the PEEV / PEST in the corresponding PHB would be messy and we can't handle that case. The patch escalates the error to fenced PHB so that the PHB could be rested in order to revoer the errors on non-existing PEs. Reported-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Tested-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/powernv/eeh-ioda.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index 8dd16f4675a2..e1e71618b70c 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -713,11 +713,7 @@ static int ioda_eeh_get_pe(struct pci_controller *hose,
713 dev.phb = hose; 713 dev.phb = hose;
714 dev.pe_config_addr = pe_no; 714 dev.pe_config_addr = pe_no;
715 dev_pe = eeh_pe_get(&dev); 715 dev_pe = eeh_pe_get(&dev);
716 if (!dev_pe) { 716 if (!dev_pe) return -EEXIST;
717 pr_warning("%s: Can't find PE for PHB#%x - PE#%x\n",
718 __func__, hose->global_number, pe_no);
719 return -EEXIST;
720 }
721 717
722 *pe = dev_pe; 718 *pe = dev_pe;
723 return 0; 719 return 0;
@@ -831,12 +827,27 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
831 827
832 break; 828 break;
833 case OPAL_EEH_PE_ERROR: 829 case OPAL_EEH_PE_ERROR:
834 if (ioda_eeh_get_pe(hose, frozen_pe_no, pe)) 830 /*
835 break; 831 * If we can't find the corresponding PE, the
832 * PEEV / PEST would be messy. So we force an
833 * fenced PHB so that it can be recovered.
834 */
835 if (ioda_eeh_get_pe(hose, frozen_pe_no, pe)) {
836 if (!ioda_eeh_get_phb_pe(hose, pe)) {
837 pr_err("EEH: Escalated fenced PHB#%x "
838 "detected for PE#%llx\n",
839 hose->global_number,
840 frozen_pe_no);
841 ret = EEH_NEXT_ERR_FENCED_PHB;
842 } else {
843 ret = EEH_NEXT_ERR_NONE;
844 }
845 } else {
846 pr_err("EEH: Frozen PE#%x on PHB#%x detected\n",
847 (*pe)->addr, (*pe)->phb->global_number);
848 ret = EEH_NEXT_ERR_FROZEN_PE;
849 }
836 850
837 pr_err("EEH: Frozen PE#%x on PHB#%x detected\n",
838 (*pe)->addr, (*pe)->phb->global_number);
839 ret = EEH_NEXT_ERR_FROZEN_PE;
840 break; 851 break;
841 default: 852 default:
842 pr_warn("%s: Unexpected error type %d\n", 853 pr_warn("%s: Unexpected error type %d\n",