aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2017-05-02 23:24:08 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2017-05-03 06:45:55 -0400
commit6b3d12a948d27977816a15eb48409a298902a548 (patch)
tree348436d892cdb57f102ac47e924d72b8df3d92dd
parent3c9ac2bcc35453141f82461c71ed109ded152a6a (diff)
powerpc/powernv: Fix TCE kill on NVLink2
Commit 616badd2fb49 ("powerpc/powernv: Use OPAL call for TCE kill on NVLink2") forced all TCE kills to go via the OPAL call for NVLink2. However the PHB3 implementation of TCE kill was still being called directly from some functions which in some circumstances caused a machine check. This patch adds an equivalent IODA2 version of the function which uses the correct invalidation method depending on PHB model and changes all external callers to use it instead. Fixes: 616badd2fb49 ("powerpc/powernv: Use OPAL call for TCE kill on NVLink2") Cc: stable@vger.kernel.org # v4.11+ Signed-off-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/platforms/powernv/npu-dma.c8
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c10
-rw-r--r--arch/powerpc/platforms/powernv/pci.h2
3 files changed, 14 insertions, 6 deletions
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c
index 4c88c3e6ec9e..067defeea691 100644
--- a/arch/powerpc/platforms/powernv/npu-dma.c
+++ b/arch/powerpc/platforms/powernv/npu-dma.c
@@ -203,7 +203,7 @@ long pnv_npu_set_window(struct pnv_ioda_pe *npe, int num,
203 pe_err(npe, "Failed to configure TCE table, err %lld\n", rc); 203 pe_err(npe, "Failed to configure TCE table, err %lld\n", rc);
204 return rc; 204 return rc;
205 } 205 }
206 pnv_pci_phb3_tce_invalidate_entire(phb, false); 206 pnv_pci_ioda2_tce_invalidate_entire(phb, false);
207 207
208 /* Add the table to the list so its TCE cache will get invalidated */ 208 /* Add the table to the list so its TCE cache will get invalidated */
209 pnv_pci_link_table_and_group(phb->hose->node, num, 209 pnv_pci_link_table_and_group(phb->hose->node, num,
@@ -227,7 +227,7 @@ long pnv_npu_unset_window(struct pnv_ioda_pe *npe, int num)
227 pe_err(npe, "Unmapping failed, ret = %lld\n", rc); 227 pe_err(npe, "Unmapping failed, ret = %lld\n", rc);
228 return rc; 228 return rc;
229 } 229 }
230 pnv_pci_phb3_tce_invalidate_entire(phb, false); 230 pnv_pci_ioda2_tce_invalidate_entire(phb, false);
231 231
232 pnv_pci_unlink_table_and_group(npe->table_group.tables[num], 232 pnv_pci_unlink_table_and_group(npe->table_group.tables[num],
233 &npe->table_group); 233 &npe->table_group);
@@ -293,7 +293,7 @@ static int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe)
293 0 /* bypass base */, top); 293 0 /* bypass base */, top);
294 294
295 if (rc == OPAL_SUCCESS) 295 if (rc == OPAL_SUCCESS)
296 pnv_pci_phb3_tce_invalidate_entire(phb, false); 296 pnv_pci_ioda2_tce_invalidate_entire(phb, false);
297 297
298 return rc; 298 return rc;
299} 299}
@@ -357,7 +357,7 @@ void pnv_npu_take_ownership(struct pnv_ioda_pe *npe)
357 pe_err(npe, "Failed to disable bypass, err %lld\n", rc); 357 pe_err(npe, "Failed to disable bypass, err %lld\n", rc);
358 return; 358 return;
359 } 359 }
360 pnv_pci_phb3_tce_invalidate_entire(npe->phb, false); 360 pnv_pci_ioda2_tce_invalidate_entire(npe->phb, false);
361} 361}
362 362
363struct pnv_ioda_pe *pnv_pci_npu_setup_iommu(struct pnv_ioda_pe *npe) 363struct pnv_ioda_pe *pnv_pci_npu_setup_iommu(struct pnv_ioda_pe *npe)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 16fd322b2eea..6fdbd383f676 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1895,7 +1895,7 @@ static struct iommu_table_ops pnv_ioda1_iommu_ops = {
1895#define PHB3_TCE_KILL_INVAL_PE PPC_BIT(1) 1895#define PHB3_TCE_KILL_INVAL_PE PPC_BIT(1)
1896#define PHB3_TCE_KILL_INVAL_ONE PPC_BIT(2) 1896#define PHB3_TCE_KILL_INVAL_ONE PPC_BIT(2)
1897 1897
1898void pnv_pci_phb3_tce_invalidate_entire(struct pnv_phb *phb, bool rm) 1898static void pnv_pci_phb3_tce_invalidate_entire(struct pnv_phb *phb, bool rm)
1899{ 1899{
1900 __be64 __iomem *invalidate = pnv_ioda_get_inval_reg(phb, rm); 1900 __be64 __iomem *invalidate = pnv_ioda_get_inval_reg(phb, rm);
1901 const unsigned long val = PHB3_TCE_KILL_INVAL_ALL; 1901 const unsigned long val = PHB3_TCE_KILL_INVAL_ALL;
@@ -1991,6 +1991,14 @@ static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl,
1991 } 1991 }
1992} 1992}
1993 1993
1994void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_phb *phb, bool rm)
1995{
1996 if (phb->model == PNV_PHB_MODEL_NPU || phb->model == PNV_PHB_MODEL_PHB3)
1997 pnv_pci_phb3_tce_invalidate_entire(phb, rm);
1998 else
1999 opal_pci_tce_kill(phb->opal_id, OPAL_PCI_TCE_KILL, 0, 0, 0, 0);
2000}
2001
1994static int pnv_ioda2_tce_build(struct iommu_table *tbl, long index, 2002static int pnv_ioda2_tce_build(struct iommu_table *tbl, long index,
1995 long npages, unsigned long uaddr, 2003 long npages, unsigned long uaddr,
1996 enum dma_data_direction direction, 2004 enum dma_data_direction direction,
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 4eab713136d1..18c8a2fa03b8 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -242,7 +242,7 @@ extern void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
242 242
243/* Nvlink functions */ 243/* Nvlink functions */
244extern void pnv_npu_try_dma_set_bypass(struct pci_dev *gpdev, bool bypass); 244extern void pnv_npu_try_dma_set_bypass(struct pci_dev *gpdev, bool bypass);
245extern void pnv_pci_phb3_tce_invalidate_entire(struct pnv_phb *phb, bool rm); 245extern void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_phb *phb, bool rm);
246extern struct pnv_ioda_pe *pnv_pci_npu_setup_iommu(struct pnv_ioda_pe *npe); 246extern struct pnv_ioda_pe *pnv_pci_npu_setup_iommu(struct pnv_ioda_pe *npe);
247extern long pnv_npu_set_window(struct pnv_ioda_pe *npe, int num, 247extern long pnv_npu_set_window(struct pnv_ioda_pe *npe, int num,
248 struct iommu_table *tbl); 248 struct iommu_table *tbl);