FROMLIST: iommu: Introduce map_sg() as an IOMMU op for IOMMU drivers

Add support for IOMMU drivers to have their own map_sg() callbacks.
This completes the path for having iommu_map_sg() invoke an IOMMU
driver's map_sg() callback, which can then invoke the io-pgtable
map_sg() callback with the entire scatter-gather list, so that it
can be processed entirely in the io-pgtable layer.

For IOMMU drivers that do not provide a callback, the default
implementation of iterating through the scatter-gather list, while
calling iommu_map() will be used.

Bug: 190544587
Link: https://lore.kernel.org/linux-iommu/1610376862-927-1-git-send-email-isaacm@codeaurora.org/T/#t
Change-Id: I3d5a8a9e8648649d8dcdda3fa1df41d72f87a528
Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Signed-off-by: Georgi Djakov <quic_c_gdjako@quicinc.com>
This commit is contained in:
Isaac J. Manjarres
2021-01-07 23:01:19 -08:00
committed by Todd Kjos
parent 536fdf792d
commit d2ca738f11
2 changed files with 17 additions and 0 deletions

View File

@@ -2666,6 +2666,18 @@ static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
unsigned int i = 0;
int ret;
if (ops->map_sg) {
ret = ops->map_sg(domain, iova, sg, nents, prot, gfp, &mapped);
if (ops->iotlb_sync_map)
ops->iotlb_sync_map(domain, iova, mapped);
if (ret)
goto out_err;
return mapped;
}
while (i <= nents) {
phys_addr_t s_phys = sg_phys(sg);

View File

@@ -212,6 +212,8 @@ struct iommu_iotlb_gather {
* @map: map a physically contiguous memory region to an iommu domain
* @map_pages: map a physically contiguous set of pages of the same size to
* an iommu domain.
* @map_sg: map a scatter-gather list of physically contiguous chunks to
* an iommu domain.
* @unmap: unmap a physically contiguous memory region from an iommu domain
* @unmap_pages: unmap a number of pages of the same size from an iommu domain
* @flush_iotlb_all: Synchronously flush all hardware TLBs for this domain
@@ -265,6 +267,9 @@ struct iommu_ops {
int (*map_pages)(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t pgsize, size_t pgcount,
int prot, gfp_t gfp, size_t *mapped);
int (*map_sg)(struct iommu_domain *domain, unsigned long iova,
struct scatterlist *sg, unsigned int nents, int prot,
gfp_t gfp, size_t *mapped);
size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
size_t size, struct iommu_iotlb_gather *iotlb_gather);
size_t (*unmap_pages)(struct iommu_domain *domain, unsigned long iova,