When PE is created, its primary bus is cached to pe->bus. At later
point, the cached primary bus is returned from eeh_pe_bus_get().
However, we could get stale cached primary bus and run into kernel
crash in one case: full hotplug as part of fenced PHB error recovery
releases all PCI busses under the PHB at unplugging time and recreate
them at plugging time. pe->bus is still dereferencing the PCI bus
that was released.
This adds another PE flag (EEH_PE_PRI_BUS) to represent the validity
of pe->bus. pe->bus is updated when its first child EEH device is
online and the flag is set. Before unplugging in full hotplug for
error recovery, the flag is cleared.
Fixes: 8cdb2833 ("powerpc/eeh: Trace PCI bus from PE")
Cc: stable@vger.kernel.org #v3.11+
Reported-by: Andrew Donnellan <redacted>
Reported-by: Pradipta Ghosh <redacted>
Signed-off-by: Gavin Shan <redacted>
Tested-by: Andrew Donnellan <redacted>
---
arch/powerpc/include/asm/eeh.h | 1 +
arch/powerpc/kernel/eeh_driver.c | 3 +++
arch/powerpc/kernel/eeh_pe.c | 2 +-
arch/powerpc/platforms/powernv/eeh-powernv.c | 5 ++++-
4 files changed, 9 insertions(+), 2 deletions(-)
@@ -886,6 +888,7 @@ static void eeh_handle_special_event(void)continue;/* Notify all devices to be down */+eeh_pe_state_clear(pe,EEH_PE_PRI_BUS);bus=eeh_pe_bus_get(phb_pe);eeh_pe_dev_traverse(pe,eeh_report_failure,NULL);
The EEH debugfs handlers have same prototype. This introduces
a macro to define them, then to simplify the code. No logical
changes.
Signed-off-by: Gavin Shan <redacted>
---
arch/powerpc/platforms/powernv/eeh-powernv.c | 60 ++++++++++------------------
1 file changed, 22 insertions(+), 38 deletions(-)
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2016-02-17 12:41:28
On Tue, 2016-09-02 at 04:50:24 UTC, Gavin Shan wrote:
The EEH debugfs handlers have same prototype. This introduces
a macro to define them, then to simplify the code. No logical
changes.
Signed-off-by: Gavin Shan <redacted>
The original implementation is ugly: unnecessary if statements and
"out" tag. This reworks the function to avoid above weaknesses. No
functional changes introduced.
Signed-off-by: Gavin Shan <redacted>
Reviewed-by: Andrew Donnellan <redacted>
---
arch/powerpc/kernel/eeh_pe.c | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)
@@ -923,25 +923,21 @@ out:*/structpci_bus*eeh_pe_bus_get(structeeh_pe*pe){-structpci_bus*bus=NULL;structeeh_dev*edev;structpci_dev*pdev;-if(pe->type&EEH_PE_PHB){-bus=pe->phb->bus;-}elseif(pe->type&EEH_PE_BUS||-pe->type&EEH_PE_DEVICE){-if(pe->state&EEH_PE_PRI_BUS){-bus=pe->bus;-gotoout;-}+if(pe->type&EEH_PE_PHB)+returnpe->phb->bus;-edev=list_first_entry(&pe->edevs,structeeh_dev,list);-pdev=eeh_dev_to_pci_dev(edev);-if(pdev)-bus=pdev->bus;-}+/* The primary bus might be cached during probe time */+if(pe->state&EEH_PE_PRI_BUS)+returnpe->bus;-out:-returnbus;+/* Retrieve the parent PCI bus of first (top) PCI device */+edev=list_first_entry_or_null(&pe->edevs,structeeh_dev,list);+pdev=eeh_dev_to_pci_dev(edev);+if(pdev)+returnpdev->bus;++returnNULL;}
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2016-03-09 12:51:37
On Tue, 2016-09-02 at 04:50:23 UTC, Gavin Shan wrote:
The original implementation is ugly: unnecessary if statements and
"out" tag. This reworks the function to avoid above weaknesses. No
functional changes introduced.
Signed-off-by: Gavin Shan <redacted>
Reviewed-by: Andrew Donnellan <redacted>
When PCI bus is unplugged during full hotplug for EEH recovery,
the platform PE instance (struct pnv_ioda_pe) isn't released and
it dereferences the stale PCI bus that has been released. It leads
to kernel crash when referring to the stale PCI bus.
This fixes the issue by correcting the PE's primary bus when it's
oneline at plugging time, in pnv_pci_dma_bus_setup() which is to
be called by pcibios_fixup_bus().
Reported-by: Andrew Donnellan <redacted>
Reported-by: Pradipta Ghosh <redacted>
Signed-off-by: Gavin Shan <redacted>
Tested-by: Andrew Donnellan <redacted>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 1 +
arch/powerpc/platforms/powernv/pci.c | 20 ++++++++++++++++++++
arch/powerpc/platforms/powernv/pci.h | 1 +
3 files changed, 22 insertions(+)
From: Andrew Donnellan <hidden> Date: 2016-02-12 06:03:45
On 09/02/16 15:50, Gavin Shan wrote:
When PCI bus is unplugged during full hotplug for EEH recovery,
the platform PE instance (struct pnv_ioda_pe) isn't released and
it dereferences the stale PCI bus that has been released. It leads
to kernel crash when referring to the stale PCI bus.
This fixes the issue by correcting the PE's primary bus when it's
oneline at plugging time, in pnv_pci_dma_bus_setup() which is to
be called by pcibios_fixup_bus().
Reported-by: Andrew Donnellan <redacted>
Reported-by: Pradipta Ghosh <redacted>
Signed-off-by: Gavin Shan <redacted>
Tested-by: Andrew Donnellan <redacted>
I realise this has already been merged, but the following was found by
Coverity:
This condition is always false. I think the first "|" is supposed to be "&".
--
Andrew Donnellan Software Engineer, OzLabs
andrew.donnellan@au1.ibm.com Australia Development Lab, Canberra
+61 2 6201 8874 (work) IBM Australia Limited
On Fri, Feb 12, 2016 at 05:02:46PM +1100, Andrew Donnellan wrote:
On 09/02/16 15:50, Gavin Shan wrote:
quoted
When PCI bus is unplugged during full hotplug for EEH recovery,
the platform PE instance (struct pnv_ioda_pe) isn't released and
it dereferences the stale PCI bus that has been released. It leads
to kernel crash when referring to the stale PCI bus.
This fixes the issue by correcting the PE's primary bus when it's
oneline at plugging time, in pnv_pci_dma_bus_setup() which is to
be called by pcibios_fixup_bus().
Reported-by: Andrew Donnellan <redacted>
Reported-by: Pradipta Ghosh <redacted>
Signed-off-by: Gavin Shan <redacted>
Tested-by: Andrew Donnellan <redacted>
I realise this has already been merged, but the following was found by
Coverity:
This condition is always false. I think the first "|" is supposed to be "&".
Yeah, that should be "&". I think the problem isn't found when doing
testing in non-SRIOV environment. Thanks for pointing it out.
Michael, please let me know if I need send a follow-up revision to
correct this one? I found the first two patches have been put into
linux-next branch. I think we probably just need repost the correct
version for this one only.
Thanks,
Gavin
--
Andrew Donnellan Software Engineer, OzLabs
andrew.donnellan@au1.ibm.com Australia Development Lab, Canberra
+61 2 6201 8874 (work) IBM Australia Limited
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2016-02-15 10:38:35
On Fri, 2016-02-12 at 17:09 +1100, Gavin Shan wrote:
On Fri, Feb 12, 2016 at 05:02:46PM +1100, Andrew Donnellan wrote:
quoted
On 09/02/16 15:50, Gavin Shan wrote:
quoted
quoted
When PCI bus is unplugged during full hotplug for EEH recovery,
the platform PE instance (struct pnv_ioda_pe) isn't released and
it dereferences the stale PCI bus that has been released. It leads
to kernel crash when referring to the stale PCI bus.
This fixes the issue by correcting the PE's primary bus when it's
oneline at plugging time, in pnv_pci_dma_bus_setup() which is to
be called by pcibios_fixup_bus().
Reported-by: Andrew Donnellan <redacted>
Reported-by: Pradipta Ghosh <redacted>
Signed-off-by: Gavin Shan <redacted>
Tested-by: Andrew Donnellan <redacted>
I realise this has already been merged, but the following was found by
Coverity:
This condition is always false. I think the first "|" is supposed to be "&".
Yeah, that should be "&". I think the problem isn't found when doing
testing in non-SRIOV environment. Thanks for pointing it out.
Michael, please let me know if I need send a follow-up revision to
correct this one? I found the first two patches have been put into
linux-next branch. I think we probably just need repost the correct
version for this one only.
As it happens I needed to rebase my fixes branch anyway, so I've updated it and
rebased. No further action required :)
cheers
On Mon, Feb 15, 2016 at 09:38:35PM +1100, Michael Ellerman wrote:
On Fri, 2016-02-12 at 17:09 +1100, Gavin Shan wrote:
quoted
On Fri, Feb 12, 2016 at 05:02:46PM +1100, Andrew Donnellan wrote:
quoted
quoted
On 09/02/16 15:50, Gavin Shan wrote:
quoted
quoted
quoted
When PCI bus is unplugged during full hotplug for EEH recovery,
the platform PE instance (struct pnv_ioda_pe) isn't released and
it dereferences the stale PCI bus that has been released. It leads
to kernel crash when referring to the stale PCI bus.
This fixes the issue by correcting the PE's primary bus when it's
oneline at plugging time, in pnv_pci_dma_bus_setup() which is to
be called by pcibios_fixup_bus().
Reported-by: Andrew Donnellan <redacted>
Reported-by: Pradipta Ghosh <redacted>
Signed-off-by: Gavin Shan <redacted>
Tested-by: Andrew Donnellan <redacted>
I realise this has already been merged, but the following was found by
Coverity:
This condition is always false. I think the first "|" is supposed to be "&".
Yeah, that should be "&". I think the problem isn't found when doing
testing in non-SRIOV environment. Thanks for pointing it out.
Michael, please let me know if I need send a follow-up revision to
correct this one? I found the first two patches have been put into
linux-next branch. I think we probably just need repost the correct
version for this one only.
As it happens I needed to rebase my fixes branch anyway, so I've updated it and
rebased. No further action required :)
Thanks Michael. Sorry for the rebase :-)
Thanks,
Gavin