From: Thierry Reding <tred...@nvidia.com>

Currently when the gather buffers are copied, they are copied to a
buffer that is allocated for the host1x client that wants to execute the
command streams in the buffers. However, the gather buffers will be read
by the host1x device, which causes SMMU faults if the DMA API is backed
by an IOMMU.

Fix this by allocating the gather buffer copy for the host1x device,
which makes sure that it will be mapped into the host1x's IOVA space if
the DMA API is backed by an IOMMU.

Signed-off-by: Thierry Reding <tred...@nvidia.com>
---
 drivers/gpu/host1x/job.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index 90dd592fdfca..2e0c3e0ca1fa 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -445,7 +445,8 @@ static int validate(struct host1x_firewall *fw, struct 
host1x_job_gather *g)
        return err;
 }
 
-static inline int copy_gathers(struct host1x_job *job, struct device *dev)
+static inline int copy_gathers(struct device *host, struct host1x_job *job,
+                              struct device *dev)
 {
        struct host1x_firewall fw;
        size_t size = 0;
@@ -468,12 +469,12 @@ static inline int copy_gathers(struct host1x_job *job, 
struct device *dev)
         * Try a non-blocking allocation from a higher priority pools first,
         * as awaiting for the allocation here is a major performance hit.
         */
-       job->gather_copy_mapped = dma_alloc_wc(dev, size, &job->gather_copy,
+       job->gather_copy_mapped = dma_alloc_wc(host, size, &job->gather_copy,
                                               GFP_NOWAIT);
 
        /* the higher priority allocation failed, try the generic-blocking */
        if (!job->gather_copy_mapped)
-               job->gather_copy_mapped = dma_alloc_wc(dev, size,
+               job->gather_copy_mapped = dma_alloc_wc(host, size,
                                                       &job->gather_copy,
                                                       GFP_KERNEL);
        if (!job->gather_copy_mapped)
@@ -521,7 +522,7 @@ int host1x_job_pin(struct host1x_job *job, struct device 
*dev)
                goto out;
 
        if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) {
-               err = copy_gathers(job, dev);
+               err = copy_gathers(host->dev, job, dev);
                if (err)
                        goto out;
        }
@@ -582,7 +583,7 @@ void host1x_job_unpin(struct host1x_job *job)
        job->num_unpins = 0;
 
        if (job->gather_copy_size)
-               dma_free_wc(job->channel->dev, job->gather_copy_size,
+               dma_free_wc(host->dev, job->gather_copy_size,
                            job->gather_copy_mapped, job->gather_copy);
 }
 EXPORT_SYMBOL(host1x_job_unpin);
-- 
2.23.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to