msm: iommu: use sg_dma_address() in iommu_map_range()
Ion carveout and content protect buffers do not have
a struct page and thus sg_phys() cannot be used on them.
Try sg_dma_address() first and if it returns 0 then
use sg_phys().
Change-Id: I95ccb8f5a3c86cd09ecf2a2737c260f4996059ac
Signed-off-by: Jeremy Gebben <jgebben@codeaurora.org>
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index 853888a..a310ba0 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -685,6 +685,19 @@
return ret;
}
+static unsigned int get_phys_addr(struct scatterlist *sg)
+{
+ /*
+ * Try sg_dma_address first so that we can
+ * map carveout regions that do not have a
+ * struct page associated with them.
+ */
+ unsigned int pa = sg_dma_address(sg);
+ if (pa == 0)
+ pa = sg_phys(sg);
+ return pa;
+}
+
static int msm_iommu_map_range(struct iommu_domain *domain, unsigned int va,
struct scatterlist *sg, unsigned int len,
int prot)
@@ -722,7 +735,12 @@
sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
sl_offset = SL_OFFSET(va);
- chunk_pa = sg_phys(sg);
+ chunk_pa = get_phys_addr(sg);
+ if (chunk_pa == 0) {
+ pr_debug("No dma address for sg %p\n", sg);
+ ret = -EINVAL;
+ goto fail;
+ }
while (offset < len) {
/* Set up a 2nd level page table if one doesn't exist */
@@ -764,7 +782,13 @@
if (chunk_offset >= sg->length && offset < len) {
chunk_offset = 0;
sg = sg_next(sg);
- chunk_pa = sg_phys(sg);
+ chunk_pa = get_phys_addr(sg);
+ if (chunk_pa == 0) {
+ pr_debug("No dma address for sg %p\n",
+ sg);
+ ret = -EINVAL;
+ goto fail;
+ }
}
}