summaryrefslogtreecommitdiff
path: root/drivers/iommu
diff options
context:
space:
mode:
authorLaura Abbott <lauraa@codeaurora.org>2014-03-06 22:24:53 -0800
committerLaura Abbott <lauraa@codeaurora.org>2014-03-07 12:23:56 -0800
commitfeedc93dc0728de6f6a85b69a099c9a3b7c6fcc7 (patch)
tree325dd4349735738e2807297c7181b0ce3869da22 /drivers/iommu
parent500bff855dbfa811385b616410f85ed5cdac3433 (diff)
iommu: msm: Use dma memory for secure pagetable
Linux allocates memory for secure page tables which is passed to the secure world. This memory is later protected from reads/writes from Linux. Using kmalloc for this memory may allow speculative accesses to occur to secured memory. Avoid speculative faults by using dma_alloc_coherent with the NO_KERNEL_MAPPING attribute to avoid a non-secure mapping. Change-Id: I3fcd82b2a1e5b82442641961c70306560ee778d8 CRs-Fixed: 621723 Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/msm_iommu_sec.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index 5fca9e5eae5b..c6de1713bca7 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -26,6 +26,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/kmemleak.h>
+#include <linux/dma-mapping.h>
#include <soc/qcom/scm.h>
#include <asm/cacheflush.h>
@@ -330,11 +331,15 @@ static int msm_iommu_sec_ptbl_init(void)
unsigned int size;
unsigned int spare;
} pinit;
- unsigned int *buf;
int psize[2] = {0, 0};
unsigned int spare;
int ret, ptbl_ret = 0;
int version;
+ /* Use a dummy device for dma_alloc_coherent allocation */
+ struct device dev = { 0 };
+ void *cpu_addr;
+ dma_addr_t paddr;
+ DEFINE_DMA_ATTRS(attrs);
for_each_matching_node(np, msm_smmu_list)
if (of_find_property(np, "qcom,iommu-secure-id", NULL) &&
@@ -377,15 +382,17 @@ static int msm_iommu_sec_ptbl_init(void)
goto fail;
}
- buf = kmalloc(psize[0], GFP_KERNEL);
- if (!buf) {
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
+ dev.coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
+ cpu_addr = dma_alloc_attrs(&dev, psize[0], &paddr, GFP_KERNEL, &attrs);
+ if (!cpu_addr) {
pr_err("%s: Failed to allocate %d bytes for PTBL\n",
__func__, psize[0]);
ret = -ENOMEM;
goto fail;
}
- pinit.paddr = virt_to_phys(buf);
+ pinit.paddr = (unsigned int)paddr;
pinit.size = psize[0];
ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_PTBL_INIT, &pinit,
@@ -399,12 +406,10 @@ static int msm_iommu_sec_ptbl_init(void)
goto fail_mem;
}
- kmemleak_not_leak(buf);
-
return 0;
fail_mem:
- kfree(buf);
+ dma_free_coherent(&dev, psize[0], cpu_addr, paddr);
fail:
return ret;
}