diff --git a/drivers/firmware/qtee_shmbridge.c b/drivers/firmware/qtee_shmbridge.c index 7b7737be677c..72699c0e9f79 100644 --- a/drivers/firmware/qtee_shmbridge.c +++ b/drivers/firmware/qtee_shmbridge.c @@ -2,7 +2,7 @@ /* * QTI TEE shared memory bridge driver * - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ #include @@ -15,6 +15,7 @@ #include #include #include +#include #include "qtee_shmbridge_internal.h" @@ -80,6 +81,7 @@ struct bridge_list_entry { static struct bridge_info default_bridge; static struct bridge_list bridge_list_head; static bool qtee_shmbridge_enabled; +static bool support_hyp; /* enable shared memory bridge mechanism in HYP */ static int32_t qtee_shmbridge_enable(bool enable) @@ -206,6 +208,11 @@ int32_t qtee_shmbridge_register( ipfn_and_s_perm_flags = UPDATE_IPFN_AND_S_PERM_FLAGS(paddr, tz_perm); size_and_flags = UPDATE_SIZE_AND_FLAGS(size, ns_vmid_num); + if (support_hyp) { + size_and_flags |= SELF_OWNER_BIT << 1; + size_and_flags |= (VM_PERM_R | VM_PERM_W) << 2; + } + pr_debug("%s: desc.args[0] %llx, args[1] %llx, args[2] %llx, args[3] %llx\n", __func__, pfn_and_ns_perm_flags, ipfn_and_s_perm_flags, size_and_flags, ns_vmids); @@ -328,9 +335,18 @@ EXPORT_SYMBOL(qtee_shmbridge_inv_shm_buf); static int qtee_shmbridge_init(struct platform_device *pdev) { int ret = 0; - uint32_t ns_vm_ids[] = {VMID_HLOS}; + uint32_t *ns_vm_ids; + uint32_t ns_vm_ids_hlos[] = {VMID_HLOS}; + uint32_t ns_vm_ids_hyp[] = {}; uint32_t ns_vm_perms[] = {VM_PERM_R|VM_PERM_W}; + support_hyp = of_property_read_bool((&pdev->dev)->of_node, + "qcom,support-hypervisor"); + if (support_hyp) + ns_vm_ids = ns_vm_ids_hyp; + else + ns_vm_ids = ns_vm_ids_hlos; + if (default_bridge.vaddr) { pr_warn("qtee shmbridge is already initialized\n"); return 0; @@ -374,8 +390,7 @@ static int qtee_shmbridge_init(struct platform_device *pdev) mutex_init(&bridge_list_head.lock); INIT_LIST_HEAD(&bridge_list_head.head); - /* temporarily disable shm bridge mechanism */ - ret = qtee_shmbridge_enable(false); + ret = qtee_shmbridge_enable(true); if (ret) { /* keep the mem pool and return if failed to enable bridge */ ret = 0; @@ -383,10 +398,17 @@ static int qtee_shmbridge_init(struct platform_device *pdev) } /*register default bridge*/ - ret = qtee_shmbridge_register(default_bridge.paddr, + if (support_hyp) + ret = qtee_shmbridge_register(default_bridge.paddr, + default_bridge.size, ns_vm_ids, + ns_vm_perms, 0, VM_PERM_R|VM_PERM_W, + &default_bridge.handle); + else + ret = qtee_shmbridge_register(default_bridge.paddr, default_bridge.size, ns_vm_ids, ns_vm_perms, 1, VM_PERM_R|VM_PERM_W, &default_bridge.handle); + if (ret) { pr_err("Failed to register default bridge, size %zu\n", default_bridge.size); diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 199e919a5930..ddab0b8f0eb3 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -1286,14 +1286,14 @@ static int qseecom_create_bridge_for_secbuf(int ion_fd, struct dma_buf *dmabuf, pr_debug("bridge exists\n"); return 0; } -/* - * nelems = ion_get_flags_num_vm_elems(dma_buf_flags); - * if (nelems == 0) { - * pr_err("failed to get vm num from flag = %x\n", dma_buf_flags); - * ret = -EINVAL; - * goto exit; - * } - */ + + nelems = ion_get_flags_num_vm_elems(dma_buf_flags); + if (nelems == 0) { + pr_err("failed to get vm num from flag = %x\n", dma_buf_flags); + ret = -EINVAL; + goto exit; + } + vmid_list = kcalloc(nelems, sizeof(*vmid_list), GFP_KERNEL); if (!vmid_list) { @@ -1301,11 +1301,11 @@ static int qseecom_create_bridge_for_secbuf(int ion_fd, struct dma_buf *dmabuf, goto exit; } -/* - * ret = ion_populate_vm_list(dma_buf_flags, vmid_list, nelems); - * if (ret) - * goto exit_free_vmid_list; - */ + + ret = ion_populate_vm_list(dma_buf_flags, vmid_list, nelems); + if (ret) + goto exit_free_vmid_list; + perms_list = kcalloc(nelems, sizeof(*perms_list), GFP_KERNEL); if (!perms_list) {