static void _release_tee_cmd(struct tee_session *sess, struct tee_cmd *cmd) { int idx; struct tee_context *ctx; BUG_ON(!cmd); BUG_ON(!sess); BUG_ON(!sess->ctx); BUG_ON(!sess->ctx->tee); ctx = sess->ctx; dev_dbg(_DEV_TEE, "%s: > free the temporary objects...\n", __func__); tee_shm_free(cmd->uuid); if (cmd->param.type_original == TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE)) goto out; for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) { int type = TEEC_PARAM_TYPE_GET(cmd->param.type_original, idx); struct tee_shm *shm; switch (type) { case TEEC_NONE: case TEEC_VALUE_INPUT: case TEEC_VALUE_OUTPUT: case TEEC_VALUE_INOUT: break; case TEEC_MEMREF_TEMP_INPUT: case TEEC_MEMREF_TEMP_OUTPUT: case TEEC_MEMREF_TEMP_INOUT: case TEEC_MEMREF_WHOLE: case TEEC_MEMREF_PARTIAL_INPUT: case TEEC_MEMREF_PARTIAL_OUTPUT: case TEEC_MEMREF_PARTIAL_INOUT: if (IS_ERR_OR_NULL(cmd->param.params[idx].shm)) break; shm = cmd->param.params[idx].shm; if (is_mapped_temp(shm->flags)) tee_shm_free(shm); else tee_shm_put(ctx, shm); break; default: BUG_ON(1); } } out: memset(cmd, 0, sizeof(struct tee_cmd)); dev_dbg(_DEV_TEE, "%s: <\n", __func__); }
static int _copy_ta_image(struct tee_session *sess, struct tee_cmd_io *cmd_io, struct tee_cmd *cmd) { int res = -EINVAL; dev_dbg(_DEV_TEE, "%s: > data=%p uuid=%p\n", __func__, cmd_io->data, cmd_io->uuid); if (((cmd_io->data != NULL) && (cmd_io->data_size == 0)) || ((cmd_io->data == NULL) && (cmd_io->data_size != 0))) goto out_failed; if ((cmd_io->data != NULL) && (cmd_io->data_size > 0)) { dev_dbg(_DEV_TEE, "%s: copy DATA image (s=%d)...\n", __func__, cmd_io->data_size); cmd->ta = tee_context_alloc_shm_tmp(sess->ctx, cmd_io->data_size, cmd_io->data, TEEC_MEM_INPUT); if (IS_ERR_OR_NULL(cmd->ta)) goto out_failed; } if (cmd_io->uuid != NULL) { dev_dbg(_DEV_TEE, "%s: copy UUID value...\n", __func__); cmd->uuid = tee_context_alloc_shm_tmp(sess->ctx, sizeof(*cmd_io->uuid), cmd_io->uuid, TEEC_MEM_INPUT); if (IS_ERR_OR_NULL(cmd->uuid)) goto out_failed; } res = 0; goto out; out_failed: tee_shm_free(cmd->uuid); tee_shm_free(cmd->ta); out: dev_dbg(_DEV_TEE, "%s: < res=%d", __func__, res); return res; }
void tee_shm_free_from_rpc(struct tee_shm *shm) { if (shm == NULL) return; if (shm->ctx == NULL) { mutex_lock(&shm->tee->lock); tee_dec_stats(&shm->tee->stats[TEE_STATS_SHM_IDX]); list_del(&shm->entry); mutex_unlock(&shm->tee->lock); } tee_shm_free(shm); }
void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *sharedMemory) { struct tee_shm *shm; if (!sharedMemory) return; if (sharedMemory->registered) return; /* TODO fixme will not work on 64-bit platform */ shm = (struct tee_shm *)(uintptr_t)sharedMemory->d.fd; pr_info("TEEC_ReleaseSharedMemory (vaddr = %p)\n", sharedMemory->buffer); iounmap(sharedMemory->buffer); sharedMemory->buffer = NULL; tee_shm_free(shm); }
TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context, TEEC_SharedMemory *sharedMem) { struct tee_shm *tee_shm; struct tee_context *ctx; if (!context || !sharedMem) return TEEC_ERROR_BAD_PARAMETERS; /* TODO fixme will not work on 64-bit platform */ ctx = (struct tee_context *)(uintptr_t)context->fd; tee_shm = tee_shm_alloc(ctx, sharedMem->size, sharedMem->flags); if (IS_ERR_OR_NULL(tee_shm)) { pr_err ("TEEC_AllocateSharedMemory: tee_shm_allocate(%zu) failed\n", sharedMem->size); return TEEC_ERROR_OUT_OF_MEMORY; } pr_info("TEEC_AllocateSharedMemory (%zu) => paddr = %p, flags %x\n", sharedMem->size, (void *)tee_shm->paddr, tee_shm->flags); sharedMem->buffer = ioremap_nocache(tee_shm->paddr, sharedMem->size); if (!sharedMem->buffer) { pr_err("TEEC_AllocateSharedMemory: ioremap_nocache(%p, %zu) failed\n", (void *)tee_shm->paddr, sharedMem->size); tee_shm_free(tee_shm); return TEEC_ERROR_OUT_OF_MEMORY; } sharedMem->registered = 0; sharedMem->flags |= tee_shm->flags; /* TODO fixme will not work on 64-bit platform */ sharedMem->d.fd = (int)(uintptr_t)tee_shm; BUG_ON(tee_shm != (struct tee_shm *)(uintptr_t)sharedMem->d.fd); return TEEC_SUCCESS; }
static void optee_rng_cleanup(struct hwrng *rng) { struct optee_rng_private *pvt_data = to_optee_rng_private(rng); tee_shm_free(pvt_data->entropy_shm_pool); }