Merge tag 'iommu-updates-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / iommu / dma-iommu.c
index d0bc8c0..896bea0 100644 (file)
@@ -523,7 +523,7 @@ static void __iommu_dma_unmap_swiotlb(struct device *dev, dma_addr_t dma_addr,
 
        __iommu_dma_unmap(dev, dma_addr, size);
 
-       if (unlikely(is_swiotlb_buffer(phys)))
+       if (unlikely(is_swiotlb_buffer(dev, phys)))
                swiotlb_tbl_unmap_single(dev, phys, size, dir, attrs);
 }
 
@@ -594,7 +594,7 @@ static dma_addr_t __iommu_dma_map_swiotlb(struct device *dev, phys_addr_t phys,
        }
 
        iova = __iommu_dma_map(dev, phys, aligned_size, prot, dma_mask);
-       if (iova == DMA_MAPPING_ERROR && is_swiotlb_buffer(phys))
+       if (iova == DMA_MAPPING_ERROR && is_swiotlb_buffer(dev, phys))
                swiotlb_tbl_unmap_single(dev, phys, org_size, dir, attrs);
        return iova;
 }
@@ -801,7 +801,7 @@ static void iommu_dma_sync_single_for_cpu(struct device *dev,
        if (!dev_is_dma_coherent(dev))
                arch_sync_dma_for_cpu(phys, size, dir);
 
-       if (is_swiotlb_buffer(phys))
+       if (is_swiotlb_buffer(dev, phys))
                swiotlb_sync_single_for_cpu(dev, phys, size, dir);
 }
 
@@ -814,7 +814,7 @@ static void iommu_dma_sync_single_for_device(struct device *dev,
                return;
 
        phys = iommu_iova_to_phys(iommu_get_dma_domain(dev), dma_handle);
-       if (is_swiotlb_buffer(phys))
+       if (is_swiotlb_buffer(dev, phys))
                swiotlb_sync_single_for_device(dev, phys, size, dir);
 
        if (!dev_is_dma_coherent(dev))
@@ -835,7 +835,7 @@ static void iommu_dma_sync_sg_for_cpu(struct device *dev,
                if (!dev_is_dma_coherent(dev))
                        arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir);
 
-               if (is_swiotlb_buffer(sg_phys(sg)))
+               if (is_swiotlb_buffer(dev, sg_phys(sg)))
                        swiotlb_sync_single_for_cpu(dev, sg_phys(sg),
                                                    sg->length, dir);
        }
@@ -852,7 +852,7 @@ static void iommu_dma_sync_sg_for_device(struct device *dev,
                return;
 
        for_each_sg(sgl, sg, nelems, i) {
-               if (is_swiotlb_buffer(sg_phys(sg)))
+               if (is_swiotlb_buffer(dev, sg_phys(sg)))
                        swiotlb_sync_single_for_device(dev, sg_phys(sg),
                                                       sg->length, dir);
 
@@ -990,7 +990,7 @@ static int iommu_dma_map_sg_swiotlb(struct device *dev, struct scatterlist *sg,
 
 out_unmap:
        iommu_dma_unmap_sg_swiotlb(dev, sg, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
-       return 0;
+       return -EIO;
 }
 
 /*
@@ -1011,11 +1011,13 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
        dma_addr_t iova;
        size_t iova_len = 0;
        unsigned long mask = dma_get_seg_boundary(dev);
+       ssize_t ret;
        int i;
 
-       if (static_branch_unlikely(&iommu_deferred_attach_enabled) &&
-           iommu_deferred_attach(dev, domain))
-               return 0;
+       if (static_branch_unlikely(&iommu_deferred_attach_enabled)) {
+               ret = iommu_deferred_attach(dev, domain);
+               goto out;
+       }
 
        if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
                iommu_dma_sync_sg_for_device(dev, sg, nents, dir);
@@ -1063,14 +1065,17 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
        }
 
        iova = iommu_dma_alloc_iova(domain, iova_len, dma_get_mask(dev), dev);
-       if (!iova)
+       if (!iova) {
+               ret = -ENOMEM;
                goto out_restore_sg;
+       }
 
        /*
         * We'll leave any physical concatenation to the IOMMU driver's
         * implementation - it knows better than we do.
         */
-       if (iommu_map_sg_atomic(domain, iova, sg, nents, prot) < iova_len)
+       ret = iommu_map_sg_atomic(domain, iova, sg, nents, prot);
+       if (ret < iova_len)
                goto out_free_iova;
 
        return __finalise_sg(dev, sg, nents, iova);
@@ -1079,7 +1084,10 @@ out_free_iova:
        iommu_dma_free_iova(cookie, iova, iova_len, NULL);
 out_restore_sg:
        __invalidate_sg(sg, nents);
-       return 0;
+out:
+       if (ret != -ENOMEM)
+               return -EINVAL;
+       return ret;
 }
 
 static void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg,