[PATCH 05/11] powerpc/powernv: Return failure for some uses of dma_set_mask()
Reza Arbab
arbab at linux.ibm.com
Thu Oct 31 03:59:54 AEDT 2019
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 <arbab at linux.ibm.com>
Cc: Christoph Hellwig <hch at 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
More information about the Linuxppc-dev
mailing list