Merge "iommu: Add iommu_map_sg() function"
This commit is contained in:
commit
633eae512c
|
@ -3440,6 +3440,7 @@ static struct iommu_ops amd_iommu_ops = {
|
|||
.detach_dev = amd_iommu_detach_device,
|
||||
.map = amd_iommu_map,
|
||||
.unmap = amd_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = amd_iommu_iova_to_phys,
|
||||
.domain_has_cap = amd_iommu_domain_has_cap,
|
||||
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
|
||||
|
|
|
@ -1604,6 +1604,7 @@ static struct iommu_ops arm_smmu_ops = {
|
|||
.detach_dev = arm_smmu_detach_dev,
|
||||
.map = arm_smmu_map,
|
||||
.unmap = arm_smmu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = arm_smmu_iova_to_phys,
|
||||
.domain_has_cap = arm_smmu_domain_has_cap,
|
||||
.add_device = arm_smmu_add_device,
|
||||
|
|
|
@ -1061,6 +1061,7 @@ static struct iommu_ops exynos_iommu_ops = {
|
|||
.detach_dev = &exynos_iommu_detach_device,
|
||||
.map = &exynos_iommu_map,
|
||||
.unmap = &exynos_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = &exynos_iommu_iova_to_phys,
|
||||
.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
|
||||
};
|
||||
|
|
|
@ -4241,6 +4241,7 @@ static struct iommu_ops intel_iommu_ops = {
|
|||
.detach_dev = intel_iommu_detach_device,
|
||||
.map = intel_iommu_map,
|
||||
.unmap = intel_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = intel_iommu_iova_to_phys,
|
||||
.domain_has_cap = intel_iommu_domain_has_cap,
|
||||
.add_device = intel_iommu_add_device,
|
||||
|
|
|
@ -908,6 +908,31 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(iommu_unmap);
|
||||
|
||||
size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
|
||||
struct scatterlist *sg, unsigned int nents, int prot)
|
||||
{
|
||||
int ret;
|
||||
size_t mapped = 0;
|
||||
unsigned int i;
|
||||
struct scatterlist *s;
|
||||
|
||||
for_each_sg(sg, s, nents, i) {
|
||||
phys_addr_t phys = page_to_phys(sg_page(s));
|
||||
size_t page_len = s->offset + s->length;
|
||||
|
||||
ret = iommu_map(domain, iova + mapped, phys, page_len, prot);
|
||||
if (ret) {
|
||||
/* undo mappings already done */
|
||||
iommu_unmap(domain, iova, mapped);
|
||||
mapped = 0;
|
||||
break;
|
||||
}
|
||||
mapped += page_len;
|
||||
}
|
||||
|
||||
return mapped;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(default_iommu_map_sg);
|
||||
|
||||
int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
|
||||
phys_addr_t paddr, u64 size, int prot)
|
||||
|
|
|
@ -1261,6 +1261,7 @@ static struct iommu_ops omap_iommu_ops = {
|
|||
.detach_dev = omap_iommu_detach_dev,
|
||||
.map = omap_iommu_map,
|
||||
.unmap = omap_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = omap_iommu_iova_to_phys,
|
||||
.domain_has_cap = omap_iommu_domain_has_cap,
|
||||
.pgsize_bitmap = OMAP_IOMMU_PGSIZES,
|
||||
|
|
|
@ -361,6 +361,7 @@ static struct iommu_ops shmobile_iommu_ops = {
|
|||
.detach_dev = shmobile_iommu_detach_device,
|
||||
.map = shmobile_iommu_map,
|
||||
.unmap = shmobile_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = shmobile_iommu_iova_to_phys,
|
||||
.add_device = shmobile_iommu_add_device,
|
||||
.pgsize_bitmap = SZ_1M | SZ_64K | SZ_4K,
|
||||
|
|
|
@ -954,6 +954,7 @@ static struct iommu_ops smmu_iommu_ops = {
|
|||
.detach_dev = smmu_iommu_detach_dev,
|
||||
.map = smmu_iommu_map,
|
||||
.unmap = smmu_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = smmu_iommu_iova_to_phys,
|
||||
.domain_has_cap = smmu_iommu_domain_has_cap,
|
||||
.pgsize_bitmap = SMMU_IOMMU_PGSIZES,
|
||||
|
|
|
@ -81,6 +81,8 @@ enum iommu_attr {
|
|||
* @detach_dev: detach device from an iommu domain
|
||||
* @map: map a physically contiguous memory region to an iommu domain
|
||||
* @unmap: unmap a physically contiguous memory region from an iommu domain
|
||||
* @map_sg: map a scatter-gather list of physically contiguous memory chunks
|
||||
* to an iommu domain
|
||||
* @iova_to_phys: translate iova to physical address
|
||||
* @domain_has_cap: domain capabilities query
|
||||
* @add_device: add device to iommu grouping
|
||||
|
@ -102,6 +104,8 @@ struct iommu_ops {
|
|||
struct scatterlist *sg, unsigned int len, int prot);
|
||||
int (*unmap_range)(struct iommu_domain *domain, unsigned int iova,
|
||||
unsigned int len);
|
||||
size_t (*map_sg)(struct iommu_domain *domain, unsigned long iova,
|
||||
struct scatterlist *sg, unsigned int nents, int prot);
|
||||
phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
|
||||
int (*domain_has_cap)(struct iommu_domain *domain,
|
||||
unsigned long cap);
|
||||
|
@ -150,6 +154,9 @@ extern int iommu_map_range(struct iommu_domain *domain, unsigned int iova,
|
|||
struct scatterlist *sg, unsigned int len, int prot);
|
||||
extern int iommu_unmap_range(struct iommu_domain *domain, unsigned int iova,
|
||||
unsigned int len);
|
||||
extern size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
|
||||
struct scatterlist *sg,unsigned int nents,
|
||||
int prot);
|
||||
extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova);
|
||||
extern int iommu_domain_has_cap(struct iommu_domain *domain,
|
||||
unsigned long cap);
|
||||
|
@ -231,6 +238,13 @@ static inline int report_iommu_fault(struct iommu_domain *domain,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline size_t iommu_map_sg(struct iommu_domain *domain,
|
||||
unsigned long iova, struct scatterlist *sg,
|
||||
unsigned int nents, int prot)
|
||||
{
|
||||
return domain->ops->map_sg(domain, iova, sg, nents, prot);
|
||||
}
|
||||
|
||||
#else /* CONFIG_IOMMU_API */
|
||||
|
||||
struct iommu_ops {};
|
||||
|
@ -273,6 +287,13 @@ static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline size_t iommu_map_sg(struct iommu_domain *domain,
|
||||
unsigned long iova, struct scatterlist *sg,
|
||||
unsigned int nents, int prot)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int iommu_domain_window_enable(struct iommu_domain *domain,
|
||||
u32 wnd_nr, phys_addr_t paddr,
|
||||
u64 size, int prot)
|
||||
|
|
Loading…
Reference in New Issue