From: Isaac J. Manjarres <[email protected]> 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. Signed-off-by: Isaac J. Manjarres <[email protected]> Tested-by: Sai Prakash Ranjan <[email protected]> [ cel: adjusted new iotlb_sync_map call site ] Signed-off-by: Chuck Lever <[email protected]> --- drivers/iommu/iommu.c | 12 ++++++++++++ include/linux/iommu.h | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index ed879a4d7fac..bd7adbd0339b 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2551,6 +2551,18 @@ static size_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); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index cd5f35022a25..667edc7b034a 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -192,6 +192,8 @@ struct iommu_iotlb_gather { * @attach_dev: attach device to an iommu domain * @detach_dev: detach device from an iommu domain * @map: map a physically contiguous memory region 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 * @flush_iotlb_all: Synchronously flush all hardware TLBs for this domain * @iotlb_sync_map: Sync mappings created recently using @map to the hardware @@ -243,6 +245,9 @@ struct iommu_ops { void (*detach_dev)(struct iommu_domain *domain, struct device *dev); int (*map)(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot, gfp_t gfp); + 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); void (*flush_iotlb_all)(struct iommu_domain *domain); _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
