Loading drivers/iommu/msm_iommu_sec.c +93 −35 Original line number Diff line number Diff line Loading @@ -49,7 +49,9 @@ #define IOMMU_SECURE_MAP 6 #define IOMMU_SECURE_UNMAP 7 #define IOMMU_SECURE_MAP2 0x0B #define IOMMU_SECURE_MAP2_FLAT 0x12 #define IOMMU_SECURE_UNMAP2 0x0C #define IOMMU_SECURE_UNMAP2_FLAT 0x13 #define IOMMU_TLBINVAL_FLAG 0x00000001 /* commands for SCM_SVC_UTIL */ Loading Loading @@ -339,7 +341,7 @@ static int msm_iommu_sec_ptbl_init(void) unsigned int paddr; unsigned int size; unsigned int spare; } pinit; } pinit = {0}; int psize[2] = {0, 0}; unsigned int spare; int ret, ptbl_ret = 0; Loading @@ -349,6 +351,7 @@ static int msm_iommu_sec_ptbl_init(void) void *cpu_addr; dma_addr_t paddr; DEFINE_DMA_ATTRS(attrs); struct scm_desc desc = {0}; for_each_matching_node(np, msm_smmu_list) if (of_find_property(np, "qcom,iommu-secure-id", NULL) && Loading @@ -365,12 +368,19 @@ static int msm_iommu_sec_ptbl_init(void) if (version >= MAKE_VERSION(1, 1, 1)) { struct msm_cp_pool_size psize; int retval; struct scm_desc desc = {0}; psize.size = MAXIMUM_VIRT_SIZE; psize.spare = 0; desc.args[0] = psize.size = MAXIMUM_VIRT_SIZE; desc.args[1] = psize.spare = 0; desc.arginfo = SCM_ARGS(2); ret = scm_call(SCM_SVC_MP, IOMMU_SET_CP_POOL_SIZE, &psize, sizeof(psize), &retval, sizeof(retval)); if (!is_scm_armv8()) ret = scm_call(SCM_SVC_MP, IOMMU_SET_CP_POOL_SIZE, &psize, sizeof(psize), &retval, sizeof(retval)); else ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SET_CP_POOL_SIZE), &desc); if (ret) { pr_err("scm call IOMMU_SET_CP_POOL_SIZE failed\n"); Loading @@ -379,8 +389,19 @@ static int msm_iommu_sec_ptbl_init(void) } if (!is_scm_armv8()) { ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_PTBL_SIZE, &spare, sizeof(spare), psize, sizeof(psize)); } else { struct scm_desc desc = {0}; desc.args[0] = spare; desc.arginfo = SCM_ARGS(1); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SECURE_PTBL_SIZE), &desc); psize[0] = desc.ret[0]; psize[1] = desc.ret[1]; } if (ret) { pr_err("scm call IOMMU_SECURE_PTBL_SIZE failed\n"); goto fail; Loading @@ -401,11 +422,19 @@ static int msm_iommu_sec_ptbl_init(void) goto fail; } pinit.paddr = (unsigned int)paddr; pinit.size = psize[0]; desc.args[0] = pinit.paddr = (unsigned int)paddr; desc.args[1] = pinit.size = psize[0]; desc.args[2] = pinit.spare; desc.arginfo = SCM_ARGS(3, SCM_RW, SCM_VAL, SCM_VAL); if (!is_scm_armv8()) { ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_PTBL_INIT, &pinit, sizeof(pinit), &ptbl_ret, sizeof(ptbl_ret)); } else { ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SECURE_PTBL_INIT), &desc); ptbl_ret = desc.ret[0]; } if (ret) { pr_err("scm call IOMMU_SECURE_PTBL_INIT failed\n"); goto fail_mem; Loading Loading @@ -443,6 +472,40 @@ int msm_iommu_sec_program_iommu(struct msm_iommu_drvdata *drvdata, return ret; } static int msm_iommu_sec_map2(struct msm_scm_map2_req *map) { struct scm_desc desc = {0}; u32 resp; int ret; desc.args[0] = map->plist.list; desc.args[1] = map->plist.list_size; desc.args[2] = map->plist.size; desc.args[3] = map->info.id; desc.args[4] = map->info.ctx_id; desc.args[5] = map->info.va; desc.args[6] = map->info.size; #ifdef CONFIG_MSM_IOMMU_TLBINVAL_ON_MAP desc.args[7] = map->flags = IOMMU_TLBINVAL_FLAG; #else desc.args[7] = map->flags = 0; #endif desc.arginfo = SCM_ARGS(8, SCM_RW, SCM_VAL, SCM_VAL, SCM_VAL, SCM_VAL, SCM_VAL, SCM_VAL, SCM_VAL); if (!is_scm_armv8()) { ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP2, map, sizeof(*map), &resp, sizeof(resp)); } else { ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SECURE_MAP2_FLAT), &desc); resp = desc.ret[0]; } if (ret || resp) return -EINVAL; return 0; } static int msm_iommu_sec_ptbl_map(struct msm_iommu_drvdata *iommu_drvdata, struct msm_iommu_ctx_drvdata *ctx_drvdata, unsigned long va, phys_addr_t pa, size_t len) Loading @@ -459,11 +522,7 @@ static int msm_iommu_sec_ptbl_map(struct msm_iommu_drvdata *iommu_drvdata, map.info.ctx_id = ctx_drvdata->num; map.info.va = va; map.info.size = len; #ifdef CONFIG_MSM_IOMMU_TLBINVAL_ON_MAP map.flags = IOMMU_TLBINVAL_FLAG; #else map.flags = 0; #endif flush_va = &pa; flush_pa = virt_to_phys(&pa); Loading @@ -472,9 +531,7 @@ static int msm_iommu_sec_ptbl_map(struct msm_iommu_drvdata *iommu_drvdata, */ dmac_clean_range(flush_va, flush_va + len); if (scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP2, &map, sizeof(map), &ret, sizeof(ret))) return -EINVAL; ret = msm_iommu_sec_map2(&map); if (ret) return -EINVAL; Loading Loading @@ -507,17 +564,12 @@ static int msm_iommu_sec_ptbl_map_range(struct msm_iommu_drvdata *iommu_drvdata, unsigned int pa, cnt; void *flush_va; unsigned int offset = 0, chunk_offset = 0; int ret, scm_ret; int ret; map.info.id = iommu_drvdata->sec_id; map.info.ctx_id = ctx_drvdata->num; map.info.va = va; map.info.size = len; #ifdef CONFIG_MSM_IOMMU_TLBINVAL_ON_MAP map.flags = IOMMU_TLBINVAL_FLAG; #else map.flags = 0; #endif if (sg->length == len) { pa = get_phys_addr(sg); Loading Loading @@ -567,8 +619,7 @@ static int msm_iommu_sec_ptbl_map_range(struct msm_iommu_drvdata *iommu_drvdata, dmac_clean_range(flush_va, flush_va + sizeof(unsigned long) * map.plist.list_size); ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP2, &map, sizeof(map), &scm_ret, sizeof(scm_ret)); ret = msm_iommu_sec_map2(&map); kfree(pa_list); trace_iommu_sec_ptbl_map_range_end(map.info.id, map.info.ctx_id, va, pa, Loading @@ -583,15 +634,22 @@ static int msm_iommu_sec_ptbl_unmap(struct msm_iommu_drvdata *iommu_drvdata, { struct msm_scm_unmap2_req unmap; int ret, scm_ret; struct scm_desc desc = {0}; desc.args[0] = unmap.info.id = iommu_drvdata->sec_id; desc.args[1] = unmap.info.ctx_id = ctx_drvdata->num; desc.args[2] = unmap.info.va = va; desc.args[3] = unmap.info.size = len; desc.args[4] = unmap.flags = IOMMU_TLBINVAL_FLAG; desc.arginfo = SCM_ARGS(5); if (!is_scm_armv8()) ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_UNMAP2, &unmap, sizeof(unmap), &scm_ret, sizeof(scm_ret)); else ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SECURE_UNMAP2_FLAT), &desc); unmap.info.id = iommu_drvdata->sec_id; unmap.info.ctx_id = ctx_drvdata->num; unmap.info.va = va; unmap.info.size = len; unmap.flags = IOMMU_TLBINVAL_FLAG; ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_UNMAP2, &unmap, sizeof(unmap), &scm_ret, sizeof(scm_ret)); return ret; } Loading Loading
drivers/iommu/msm_iommu_sec.c +93 −35 Original line number Diff line number Diff line Loading @@ -49,7 +49,9 @@ #define IOMMU_SECURE_MAP 6 #define IOMMU_SECURE_UNMAP 7 #define IOMMU_SECURE_MAP2 0x0B #define IOMMU_SECURE_MAP2_FLAT 0x12 #define IOMMU_SECURE_UNMAP2 0x0C #define IOMMU_SECURE_UNMAP2_FLAT 0x13 #define IOMMU_TLBINVAL_FLAG 0x00000001 /* commands for SCM_SVC_UTIL */ Loading Loading @@ -339,7 +341,7 @@ static int msm_iommu_sec_ptbl_init(void) unsigned int paddr; unsigned int size; unsigned int spare; } pinit; } pinit = {0}; int psize[2] = {0, 0}; unsigned int spare; int ret, ptbl_ret = 0; Loading @@ -349,6 +351,7 @@ static int msm_iommu_sec_ptbl_init(void) void *cpu_addr; dma_addr_t paddr; DEFINE_DMA_ATTRS(attrs); struct scm_desc desc = {0}; for_each_matching_node(np, msm_smmu_list) if (of_find_property(np, "qcom,iommu-secure-id", NULL) && Loading @@ -365,12 +368,19 @@ static int msm_iommu_sec_ptbl_init(void) if (version >= MAKE_VERSION(1, 1, 1)) { struct msm_cp_pool_size psize; int retval; struct scm_desc desc = {0}; psize.size = MAXIMUM_VIRT_SIZE; psize.spare = 0; desc.args[0] = psize.size = MAXIMUM_VIRT_SIZE; desc.args[1] = psize.spare = 0; desc.arginfo = SCM_ARGS(2); ret = scm_call(SCM_SVC_MP, IOMMU_SET_CP_POOL_SIZE, &psize, sizeof(psize), &retval, sizeof(retval)); if (!is_scm_armv8()) ret = scm_call(SCM_SVC_MP, IOMMU_SET_CP_POOL_SIZE, &psize, sizeof(psize), &retval, sizeof(retval)); else ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SET_CP_POOL_SIZE), &desc); if (ret) { pr_err("scm call IOMMU_SET_CP_POOL_SIZE failed\n"); Loading @@ -379,8 +389,19 @@ static int msm_iommu_sec_ptbl_init(void) } if (!is_scm_armv8()) { ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_PTBL_SIZE, &spare, sizeof(spare), psize, sizeof(psize)); } else { struct scm_desc desc = {0}; desc.args[0] = spare; desc.arginfo = SCM_ARGS(1); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SECURE_PTBL_SIZE), &desc); psize[0] = desc.ret[0]; psize[1] = desc.ret[1]; } if (ret) { pr_err("scm call IOMMU_SECURE_PTBL_SIZE failed\n"); goto fail; Loading @@ -401,11 +422,19 @@ static int msm_iommu_sec_ptbl_init(void) goto fail; } pinit.paddr = (unsigned int)paddr; pinit.size = psize[0]; desc.args[0] = pinit.paddr = (unsigned int)paddr; desc.args[1] = pinit.size = psize[0]; desc.args[2] = pinit.spare; desc.arginfo = SCM_ARGS(3, SCM_RW, SCM_VAL, SCM_VAL); if (!is_scm_armv8()) { ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_PTBL_INIT, &pinit, sizeof(pinit), &ptbl_ret, sizeof(ptbl_ret)); } else { ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SECURE_PTBL_INIT), &desc); ptbl_ret = desc.ret[0]; } if (ret) { pr_err("scm call IOMMU_SECURE_PTBL_INIT failed\n"); goto fail_mem; Loading Loading @@ -443,6 +472,40 @@ int msm_iommu_sec_program_iommu(struct msm_iommu_drvdata *drvdata, return ret; } static int msm_iommu_sec_map2(struct msm_scm_map2_req *map) { struct scm_desc desc = {0}; u32 resp; int ret; desc.args[0] = map->plist.list; desc.args[1] = map->plist.list_size; desc.args[2] = map->plist.size; desc.args[3] = map->info.id; desc.args[4] = map->info.ctx_id; desc.args[5] = map->info.va; desc.args[6] = map->info.size; #ifdef CONFIG_MSM_IOMMU_TLBINVAL_ON_MAP desc.args[7] = map->flags = IOMMU_TLBINVAL_FLAG; #else desc.args[7] = map->flags = 0; #endif desc.arginfo = SCM_ARGS(8, SCM_RW, SCM_VAL, SCM_VAL, SCM_VAL, SCM_VAL, SCM_VAL, SCM_VAL, SCM_VAL); if (!is_scm_armv8()) { ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP2, map, sizeof(*map), &resp, sizeof(resp)); } else { ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SECURE_MAP2_FLAT), &desc); resp = desc.ret[0]; } if (ret || resp) return -EINVAL; return 0; } static int msm_iommu_sec_ptbl_map(struct msm_iommu_drvdata *iommu_drvdata, struct msm_iommu_ctx_drvdata *ctx_drvdata, unsigned long va, phys_addr_t pa, size_t len) Loading @@ -459,11 +522,7 @@ static int msm_iommu_sec_ptbl_map(struct msm_iommu_drvdata *iommu_drvdata, map.info.ctx_id = ctx_drvdata->num; map.info.va = va; map.info.size = len; #ifdef CONFIG_MSM_IOMMU_TLBINVAL_ON_MAP map.flags = IOMMU_TLBINVAL_FLAG; #else map.flags = 0; #endif flush_va = &pa; flush_pa = virt_to_phys(&pa); Loading @@ -472,9 +531,7 @@ static int msm_iommu_sec_ptbl_map(struct msm_iommu_drvdata *iommu_drvdata, */ dmac_clean_range(flush_va, flush_va + len); if (scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP2, &map, sizeof(map), &ret, sizeof(ret))) return -EINVAL; ret = msm_iommu_sec_map2(&map); if (ret) return -EINVAL; Loading Loading @@ -507,17 +564,12 @@ static int msm_iommu_sec_ptbl_map_range(struct msm_iommu_drvdata *iommu_drvdata, unsigned int pa, cnt; void *flush_va; unsigned int offset = 0, chunk_offset = 0; int ret, scm_ret; int ret; map.info.id = iommu_drvdata->sec_id; map.info.ctx_id = ctx_drvdata->num; map.info.va = va; map.info.size = len; #ifdef CONFIG_MSM_IOMMU_TLBINVAL_ON_MAP map.flags = IOMMU_TLBINVAL_FLAG; #else map.flags = 0; #endif if (sg->length == len) { pa = get_phys_addr(sg); Loading Loading @@ -567,8 +619,7 @@ static int msm_iommu_sec_ptbl_map_range(struct msm_iommu_drvdata *iommu_drvdata, dmac_clean_range(flush_va, flush_va + sizeof(unsigned long) * map.plist.list_size); ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP2, &map, sizeof(map), &scm_ret, sizeof(scm_ret)); ret = msm_iommu_sec_map2(&map); kfree(pa_list); trace_iommu_sec_ptbl_map_range_end(map.info.id, map.info.ctx_id, va, pa, Loading @@ -583,15 +634,22 @@ static int msm_iommu_sec_ptbl_unmap(struct msm_iommu_drvdata *iommu_drvdata, { struct msm_scm_unmap2_req unmap; int ret, scm_ret; struct scm_desc desc = {0}; desc.args[0] = unmap.info.id = iommu_drvdata->sec_id; desc.args[1] = unmap.info.ctx_id = ctx_drvdata->num; desc.args[2] = unmap.info.va = va; desc.args[3] = unmap.info.size = len; desc.args[4] = unmap.flags = IOMMU_TLBINVAL_FLAG; desc.arginfo = SCM_ARGS(5); if (!is_scm_armv8()) ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_UNMAP2, &unmap, sizeof(unmap), &scm_ret, sizeof(scm_ret)); else ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, IOMMU_SECURE_UNMAP2_FLAT), &desc); unmap.info.id = iommu_drvdata->sec_id; unmap.info.ctx_id = ctx_drvdata->num; unmap.info.va = va; unmap.info.size = len; unmap.flags = IOMMU_TLBINVAL_FLAG; ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_UNMAP2, &unmap, sizeof(unmap), &scm_ret, sizeof(scm_ret)); return ret; } Loading