Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpu: host1x: Allocate gather copy for host1x

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 <treding@nvidia.com>

+6 -5
+6 -5
drivers/gpu/host1x/job.c
··· 445 445 return err; 446 446 } 447 447 448 - static inline int copy_gathers(struct host1x_job *job, struct device *dev) 448 + static inline int copy_gathers(struct device *host, struct host1x_job *job, 449 + struct device *dev) 449 450 { 450 451 struct host1x_firewall fw; 451 452 size_t size = 0; ··· 469 468 * Try a non-blocking allocation from a higher priority pools first, 470 469 * as awaiting for the allocation here is a major performance hit. 471 470 */ 472 - job->gather_copy_mapped = dma_alloc_wc(dev, size, &job->gather_copy, 471 + job->gather_copy_mapped = dma_alloc_wc(host, size, &job->gather_copy, 473 472 GFP_NOWAIT); 474 473 475 474 /* the higher priority allocation failed, try the generic-blocking */ 476 475 if (!job->gather_copy_mapped) 477 - job->gather_copy_mapped = dma_alloc_wc(dev, size, 476 + job->gather_copy_mapped = dma_alloc_wc(host, size, 478 477 &job->gather_copy, 479 478 GFP_KERNEL); 480 479 if (!job->gather_copy_mapped) ··· 522 521 goto out; 523 522 524 523 if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) { 525 - err = copy_gathers(job, dev); 524 + err = copy_gathers(host->dev, job, dev); 526 525 if (err) 527 526 goto out; 528 527 } ··· 583 582 job->num_unpins = 0; 584 583 585 584 if (job->gather_copy_size) 586 - dma_free_wc(job->channel->dev, job->gather_copy_size, 585 + dma_free_wc(host->dev, job->gather_copy_size, 587 586 job->gather_copy_mapped, job->gather_copy); 588 587 } 589 588 EXPORT_SYMBOL(host1x_job_unpin);