X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=drivers%2Fiommu%2Fiommu.c;h=f7718d73e98470bdbe139805860ddeb9e63722bf;hb=6f51ee709e4c6b56f2c2a071da2d056a109b9d26;hp=02e4313e937c3f281d8077a20e60e9c616da4c18;hpb=1888d2fa314033755026ceddee1fff8f80659fe4;p=sagit-ice-cold%2Fkernel_xiaomi_msm8998.git diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 02e4313e937c..f7718d73e984 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -737,7 +737,7 @@ static int add_iommu_group(struct device *dev, void *data) const struct iommu_ops *ops = cb->ops; if (!ops->add_device) - return -ENODEV; + return 0; WARN_ON(dev->iommu_group); @@ -1143,14 +1143,24 @@ size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova, { struct scatterlist *s; size_t mapped = 0; - unsigned int i; + unsigned int i, min_pagesz; int ret; - for_each_sg(sg, s, nents, i) { - phys_addr_t phys = page_to_phys(sg_page(s)); + if (unlikely(domain->ops->pgsize_bitmap == 0UL)) + return 0; - /* We are mapping on page boundarys, so offset must be 0 */ - if (s->offset) + min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap); + + for_each_sg(sg, s, nents, i) { + phys_addr_t phys = page_to_phys(sg_page(s)) + s->offset; + + /* + * We are mapping on IOMMU page boundaries, so offset within + * the page must be 0. However, the IOMMU may support pages + * smaller than PAGE_SIZE, so s->offset may still represent + * an offset of that boundary within the CPU page. + */ + if (!IS_ALIGNED(s->offset, min_pagesz)) goto out_err; ret = iommu_map(domain, iova + mapped, phys, s->length, prot);