ACK: [PATCH] powerpc/powernv: Fix TCE kill on NVLink2
Thadeu Lima de Souza Cascardo
cascardo at canonical.com
Tue May 16 19:51:51 UTC 2017
On Thu, May 11, 2017 at 11:26:21AM -0300, Breno Leitao wrote:
> From: Alistair Popple <alistair at popple.id.au>
>
> BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1690155
>
> 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 at vger.kernel.org # v4.11+
> Signed-off-by: Alistair Popple <alistair at popple.id.au>
> Signed-off-by: Michael Ellerman <mpe at ellerman.id.au>
> (cherry picked from commit 6b3d12a948d27977816a15eb48409a298902a548)
> Signed-off-by: Breno Leitao <breno.leitao at gmail.com>
> ---
> arch/powerpc/platforms/powernv/npu-dma.c | 8 ++++----
> arch/powerpc/platforms/powernv/pci-ioda.c | 10 +++++++++-
> arch/powerpc/platforms/powernv/pci.h | 2 +-
> 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 73b155fd4481..34339c7e676b 100644
> --- a/arch/powerpc/platforms/powernv/npu-dma.c
> +++ b/arch/powerpc/platforms/powernv/npu-dma.c
> @@ -180,7 +180,7 @@ long pnv_npu_set_window(struct pnv_ioda_pe *npe, int num,
> pe_err(npe, "Failed to configure TCE table, err %lld\n", rc);
> return rc;
> }
> - pnv_pci_phb3_tce_invalidate_entire(phb, false);
> + pnv_pci_ioda2_tce_invalidate_entire(phb, false);
>
> /* Add the table to the list so its TCE cache will get invalidated */
> pnv_pci_link_table_and_group(phb->hose->node, num,
> @@ -204,7 +204,7 @@ long pnv_npu_unset_window(struct pnv_ioda_pe *npe, int num)
> pe_err(npe, "Unmapping failed, ret = %lld\n", rc);
> return rc;
> }
> - pnv_pci_phb3_tce_invalidate_entire(phb, false);
> + pnv_pci_ioda2_tce_invalidate_entire(phb, false);
>
> pnv_pci_unlink_table_and_group(npe->table_group.tables[num],
> &npe->table_group);
> @@ -270,7 +270,7 @@ static int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe)
> 0 /* bypass base */, top);
>
> if (rc == OPAL_SUCCESS)
> - pnv_pci_phb3_tce_invalidate_entire(phb, false);
> + pnv_pci_ioda2_tce_invalidate_entire(phb, false);
>
> return rc;
> }
> @@ -334,7 +334,7 @@ void pnv_npu_take_ownership(struct pnv_ioda_pe *npe)
> pe_err(npe, "Failed to disable bypass, err %lld\n", rc);
> return;
> }
> - pnv_pci_phb3_tce_invalidate_entire(npe->phb, false);
> + pnv_pci_ioda2_tce_invalidate_entire(npe->phb, false);
> }
>
> struct 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 5c448a3568ac..c01e51c2e303 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -1879,7 +1879,7 @@ static struct iommu_table_ops pnv_ioda1_iommu_ops = {
> #define PHB3_TCE_KILL_INVAL_PE PPC_BIT(1)
> #define PHB3_TCE_KILL_INVAL_ONE PPC_BIT(2)
>
> -void pnv_pci_phb3_tce_invalidate_entire(struct pnv_phb *phb, bool rm)
> +static void pnv_pci_phb3_tce_invalidate_entire(struct pnv_phb *phb, bool rm)
> {
> __be64 __iomem *invalidate = pnv_ioda_get_inval_reg(phb, rm);
> const unsigned long val = PHB3_TCE_KILL_INVAL_ALL;
> @@ -1975,6 +1975,14 @@ static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl,
> }
> }
>
> +void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_phb *phb, bool rm)
> +{
> + if (phb->model == PNV_PHB_MODEL_NPU || phb->model == PNV_PHB_MODEL_PHB3)
> + pnv_pci_phb3_tce_invalidate_entire(phb, rm);
> + else
> + opal_pci_tce_kill(phb->opal_id, OPAL_PCI_TCE_KILL, 0, 0, 0, 0);
> +}
> +
> static int pnv_ioda2_tce_build(struct iommu_table *tbl, long index,
> long npages, unsigned long uaddr,
> enum dma_data_direction direction,
> diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
> index e1d3e5526b54..5d6599373f32 100644
> --- a/arch/powerpc/platforms/powernv/pci.h
> +++ b/arch/powerpc/platforms/powernv/pci.h
> @@ -229,7 +229,7 @@ extern void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
>
> /* Nvlink functions */
> extern void pnv_npu_try_dma_set_bypass(struct pci_dev *gpdev, bool bypass);
> -extern void pnv_pci_phb3_tce_invalidate_entire(struct pnv_phb *phb, bool rm);
> +extern void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_phb *phb, bool rm);
> extern struct pnv_ioda_pe *pnv_pci_npu_setup_iommu(struct pnv_ioda_pe *npe);
> extern long pnv_npu_set_window(struct pnv_ioda_pe *npe, int num,
> struct iommu_table *tbl);
> --
> 2.11.0
>
>
> --
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
Affects very specific architecture.
Acked-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
More information about the kernel-team
mailing list