iommu: Add a gfp parameter to iommu_map_sg()
authorJason Gunthorpe <jgg@nvidia.com>
Mon, 23 Jan 2023 20:35:56 +0000 (16:35 -0400)
committerJoerg Roedel <jroedel@suse.de>
Wed, 25 Jan 2023 10:52:03 +0000 (11:52 +0100)
Follow the pattern for iommu_map() and remove iommu_map_sg_atomic().

This allows __iommu_dma_alloc_noncontiguous() to use a GFP_KERNEL
allocation here, based on the provided gfp flags.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/3-v3-76b587fe28df+6e3-iommu_map_gfp_jgg@nvidia.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/dma-iommu.c
drivers/iommu/iommu.c
include/linux/iommu.h

index 7016db5..72cfa24 100644 (file)
@@ -833,7 +833,8 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct device *dev,
                        arch_dma_prep_coherent(sg_page(sg), sg->length);
        }
 
-       ret = iommu_map_sg_atomic(domain, iova, sgt->sgl, sgt->orig_nents, ioprot);
+       ret = iommu_map_sg(domain, iova, sgt->sgl, sgt->orig_nents, ioprot,
+                          GFP_ATOMIC);
        if (ret < 0 || ret < size)
                goto out_free_sg;
 
@@ -1281,7 +1282,7 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
         * We'll leave any physical concatenation to the IOMMU driver's
         * implementation - it knows better than we do.
         */
-       ret = iommu_map_sg_atomic(domain, iova, sg, nents, prot);
+       ret = iommu_map_sg(domain, iova, sg, nents, prot, GFP_ATOMIC);
        if (ret < 0 || ret < iova_len)
                goto out_free_iova;
 
index 19b1c33..1b7d069 100644 (file)
@@ -2470,9 +2470,9 @@ size_t iommu_unmap_fast(struct iommu_domain *domain,
 }
 EXPORT_SYMBOL_GPL(iommu_unmap_fast);
 
-static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
-               struct scatterlist *sg, unsigned int nents, int prot,
-               gfp_t gfp)
+ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
+                    struct scatterlist *sg, unsigned int nents, int prot,
+                    gfp_t gfp)
 {
        const struct iommu_domain_ops *ops = domain->ops;
        size_t len = 0, mapped = 0;
@@ -2480,6 +2480,13 @@ static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
        unsigned int i = 0;
        int ret;
 
+       might_sleep_if(gfpflags_allow_blocking(gfp));
+
+       /* Discourage passing strange GFP flags */
+       if (WARN_ON_ONCE(gfp & (__GFP_COMP | __GFP_DMA | __GFP_DMA32 |
+                               __GFP_HIGHMEM)))
+               return -EINVAL;
+
        while (i <= nents) {
                phys_addr_t s_phys = sg_phys(sg);
 
@@ -2519,21 +2526,8 @@ out_err:
 
        return ret;
 }
-
-ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
-                    struct scatterlist *sg, unsigned int nents, int prot)
-{
-       might_sleep();
-       return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_KERNEL);
-}
 EXPORT_SYMBOL_GPL(iommu_map_sg);
 
-ssize_t iommu_map_sg_atomic(struct iommu_domain *domain, unsigned long iova,
-                   struct scatterlist *sg, unsigned int nents, int prot)
-{
-       return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_ATOMIC);
-}
-
 /**
  * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework
  * @domain: the iommu domain where the fault has happened
index 521cd79..d5c16dc 100644 (file)
@@ -474,10 +474,8 @@ extern size_t iommu_unmap_fast(struct iommu_domain *domain,
                               unsigned long iova, size_t size,
                               struct iommu_iotlb_gather *iotlb_gather);
 extern ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
-               struct scatterlist *sg, unsigned int nents, int prot);
-extern ssize_t iommu_map_sg_atomic(struct iommu_domain *domain,
-                                  unsigned long iova, struct scatterlist *sg,
-                                  unsigned int nents, int prot);
+                           struct scatterlist *sg, unsigned int nents,
+                           int prot, gfp_t gfp);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova);
 extern void iommu_set_fault_handler(struct iommu_domain *domain,
                        iommu_fault_handler_t handler, void *token);
@@ -791,14 +789,7 @@ static inline size_t iommu_unmap_fast(struct iommu_domain *domain,
 
 static inline ssize_t iommu_map_sg(struct iommu_domain *domain,
                                   unsigned long iova, struct scatterlist *sg,
-                                  unsigned int nents, int prot)
-{
-       return -ENODEV;
-}
-
-static inline ssize_t iommu_map_sg_atomic(struct iommu_domain *domain,
-                                 unsigned long iova, struct scatterlist *sg,
-                                 unsigned int nents, int prot)
+                                  unsigned int nents, int prot, gfp_t gfp)
 {
        return -ENODEV;
 }
@@ -1109,7 +1100,8 @@ iommu_get_domain_for_dev_pasid(struct device *dev, ioasid_t pasid,
 static inline size_t iommu_map_sgtable(struct iommu_domain *domain,
                        unsigned long iova, struct sg_table *sgt, int prot)
 {
-       return iommu_map_sg(domain, iova, sgt->sgl, sgt->orig_nents, prot);
+       return iommu_map_sg(domain, iova, sgt->sgl, sgt->orig_nents, prot,
+                           GFP_KERNEL);
 }
 
 #ifdef CONFIG_IOMMU_DEBUGFS