Rework of pnv_pci_ioda_dma_set_mask() effectively reverted commit 253fd51e2f53 ("powerpc/powernv/pci: Return failure for some uses of dma_set_mask()").
Reintroduce the desired behavior that an unfulfilled request for a DMA mask between 32 and 64 bits will return error instead of silently falling back to 32 bits. Fixes: 2d6ad41b2c21 ("powerpc/powernv: use the generic iommu bypass code") Signed-off-by: Reza Arbab <ar...@linux.ibm.com> Cc: Christoph Hellwig <h...@lst.de> --- arch/powerpc/kernel/dma-iommu.c | 19 +++++++++++++++---- arch/powerpc/platforms/powernv/pci-ioda.c | 8 ++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index e486d1d78de2..e1693760654b 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -122,10 +122,21 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask) { struct iommu_table *tbl = get_iommu_table_base(dev); - if (dev_is_pci(dev) && dma_iommu_bypass_supported(dev, mask)) { - dev->archdata.iommu_bypass = true; - dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n"); - return 1; + if (dev_is_pci(dev)) { + if (dma_iommu_bypass_supported(dev, mask)) { + dev->archdata.iommu_bypass = true; + dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n"); + return 1; + } + + if (mask >> 32) { + dev_err(dev, "Warning: IOMMU dma bypass not supported: mask 0x%016llx\n", + mask); + + /* A 64-bit request falls back to default ops */ + if (mask != DMA_BIT_MASK(64)) + return 0; + } } if (!tbl) { diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 70e834635971..b78b5e81f941 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1863,8 +1863,12 @@ static bool pnv_pci_ioda_iommu_bypass_supported(struct pci_dev *pdev, bypass = true; } - /* Update peer npu devices */ - pnv_npu_try_dma_set_bypass(pdev, dma_mask); + /* + * Update peer npu devices. We also do this for the special case where + * a 64-bit dma mask can't be fulfilled and falls back to default. + */ + if (bypass || !(dma_mask >> 32) || dma_mask == DMA_BIT_MASK(64)) + pnv_npu_try_dma_set_bypass(pdev, dma_mask); return bypass; } -- 1.8.3.1