map
size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) { size_t unmapped_page, unmapped = 0; unsigned int min_pagesz; unsigned long orig_iova = iova; if (unlikely(domain->ops->unmap == NULL || domain->ops->pgsize_bitmap == 0UL)) return -ENODEV; if (unlikely(!(domain->type & __IOMMU_DOMAIN_PAGING))) return -EINVAL;
/* find out the minimum page size supported */ min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);
/* * The virtual address, as well as the size of the mapping, must be * aligned (at least) to the size of the smallest page supported * by the hardware */ if (!IS_ALIGNED(iova | size, min_pagesz)) { pr_err("unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%x\n", iova, size, min_pagesz); return -EINVAL; } pr_debug("unmap this: iova 0x%lx size 0x%zx\n", iova, size);
/* * Keep iterating until we either unmap 'size' bytes (or more) * or we hit an area that isn't mapped. */ while (unmapped < size) { size_t pgsize = iommu_pgsize(domain, iova, size - unmapped); unmapped_page = domain->ops->unmap(domain, iova, pgsize); if (!unmapped_page) break;
pr_debug("unmapped: iova 0x%lx size 0x%zx\n", iova, unmapped_page); iova += unmapped_page; unmapped += unmapped_page; } trace_unmap(orig_iova, size, unmapped); return unmapped;
} EXPORT_SYMBOL_GPL(iommu_unmap);
static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order) { return -ENODEV; }