@@ -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) {
@@ -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;
}
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@linux.ibm.com> Cc: Christoph Hellwig <hch@lst.de> --- arch/powerpc/kernel/dma-iommu.c | 19 +++++++++++++++---- arch/powerpc/platforms/powernv/pci-ioda.c | 8 ++++++-- 2 files changed, 21 insertions(+), 6 deletions(-)