tee: Correct inappropriate usage of TEE_SHM_DMA_BUF flag
authorSumit Garg <sumit.garg@linaro.org>
Mon, 14 Jun 2021 22:33:15 +0000 (17:33 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 15 Aug 2021 12:00:24 +0000 (14:00 +0200)
[ Upstream commit 376e4199e327a5cf29b8ec8fb0f64f3d8b429819 ]

Currently TEE_SHM_DMA_BUF flag has been inappropriately used to not
register shared memory allocated for private usage by underlying TEE
driver: OP-TEE in this case. So rather add a new flag as TEE_SHM_PRIV
that can be utilized by underlying TEE drivers for private allocation
and usage of shared memory.

With this corrected, allow tee_shm_alloc_kernel_buf() to allocate a
shared memory region without the backing of dma-buf.

Cc: stable@vger.kernel.org
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Co-developed-by: Tyler Hicks <tyhicks@linux.microsoft.com>
Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/tee/optee/call.c
drivers/tee/optee/core.c
drivers/tee/optee/rpc.c
drivers/tee/optee/shm_pool.c
drivers/tee/tee_shm.c
include/linux/tee_drv.h

index 1231ce56e71231cc6319005da4e1c3a9aa80ec97..f8f1594bea435f6cd5b91db3527cbebf73d8202f 100644 (file)
@@ -181,7 +181,7 @@ static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
        struct optee_msg_arg *ma;
 
        shm = tee_shm_alloc(ctx, OPTEE_MSG_GET_ARG_SIZE(num_params),
-                           TEE_SHM_MAPPED);
+                           TEE_SHM_MAPPED | TEE_SHM_PRIV);
        if (IS_ERR(shm))
                return shm;
 
index 7b17248f1527c701136b39a66e8dff6487c72d3d..823a81d8ff0ed49187296d4e408793155d6ac451 100644 (file)
@@ -278,7 +278,8 @@ static void optee_release(struct tee_context *ctx)
        if (!ctxdata)
                return;
 
-       shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg), TEE_SHM_MAPPED);
+       shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg),
+                           TEE_SHM_MAPPED | TEE_SHM_PRIV);
        if (!IS_ERR(shm)) {
                arg = tee_shm_get_va(shm, 0);
                /*
index 6cbb3643c6c48f600612d1172d3045080a95698d..9dbdd783d6f2d3b15c4bff071bc153f147ebcd58 100644 (file)
@@ -313,7 +313,7 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
                shm = cmd_alloc_suppl(ctx, sz);
                break;
        case OPTEE_MSG_RPC_SHM_TYPE_KERNEL:
-               shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED);
+               shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
                break;
        default:
                arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -501,7 +501,8 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
 
        switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
        case OPTEE_SMC_RPC_FUNC_ALLOC:
-               shm = tee_shm_alloc(ctx, param->a1, TEE_SHM_MAPPED);
+               shm = tee_shm_alloc(ctx, param->a1,
+                                   TEE_SHM_MAPPED | TEE_SHM_PRIV);
                if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
                        reg_pair_from_64(&param->a1, &param->a2, pa);
                        reg_pair_from_64(&param->a4, &param->a5,
index da06ce9b9313e4ff39352a132e6e4638836dea94..c41a9a501a6e9d8fcf5efce43259aca6466368b6 100644 (file)
@@ -27,7 +27,11 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
        shm->paddr = page_to_phys(page);
        shm->size = PAGE_SIZE << order;
 
-       if (shm->flags & TEE_SHM_DMA_BUF) {
+       /*
+        * Shared memory private to the OP-TEE driver doesn't need
+        * to be registered with OP-TEE.
+        */
+       if (!(shm->flags & TEE_SHM_PRIV)) {
                unsigned int nr_pages = 1 << order, i;
                struct page **pages;
 
@@ -60,7 +64,7 @@ err:
 static void pool_op_free(struct tee_shm_pool_mgr *poolm,
                         struct tee_shm *shm)
 {
-       if (shm->flags & TEE_SHM_DMA_BUF)
+       if (!(shm->flags & TEE_SHM_PRIV))
                optee_shm_unregister(shm->ctx, shm);
 
        free_pages((unsigned long)shm->kaddr, get_order(shm->size));
index c65e44707cd69637b98cce14ba6f65489583fcb2..8a9384a64f3e2914336209914c9026acd9fea3de 100644 (file)
@@ -117,7 +117,7 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
                return ERR_PTR(-EINVAL);
        }
 
-       if ((flags & ~(TEE_SHM_MAPPED | TEE_SHM_DMA_BUF))) {
+       if ((flags & ~(TEE_SHM_MAPPED | TEE_SHM_DMA_BUF | TEE_SHM_PRIV))) {
                dev_err(teedev->dev.parent, "invalid shm flags 0x%x", flags);
                return ERR_PTR(-EINVAL);
        }
@@ -207,7 +207,7 @@ EXPORT_SYMBOL_GPL(tee_shm_alloc);
  */
 struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size)
 {
-       return tee_shm_alloc(ctx, size, TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
+       return tee_shm_alloc(ctx, size, TEE_SHM_MAPPED);
 }
 EXPORT_SYMBOL_GPL(tee_shm_alloc_kernel_buf);
 
index 9b24cc3d3024f8c4f22f8569bb8e671883b44465..459e9a76d7e6ff39b37e7bf50353140ad8ef3742 100644 (file)
@@ -27,6 +27,7 @@
 #define TEE_SHM_USER_MAPPED    BIT(4)  /* Memory mapped in user space */
 #define TEE_SHM_POOL           BIT(5)  /* Memory allocated from pool */
 #define TEE_SHM_KERNEL_MAPPED  BIT(6)  /* Memory mapped in kernel space */
+#define TEE_SHM_PRIV           BIT(7)  /* Memory private to TEE driver */
 
 struct device;
 struct tee_device;