static TEEC_Result do_counter_tests(TEEC_Session *session, TEEC_Context *context) { TEEC_Result ret; uint64_t previous_value; TEEC_SharedMemory inout_mem = {0}; uint64_t value; inout_mem.buffer = &value; inout_mem.size = sizeof(value); inout_mem.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; ret = TEEC_RegisterSharedMemory(context, &inout_mem); if (ret != TEE_SUCCESS) { printf("Failed to register shared memory"); goto end; } /* Get and increment the counter for the first time */ ret = invoke_command(session, &inout_mem, CMD_GET_CTR); if (ret != TEEC_SUCCESS) goto end; previous_value = value; printf("Value after the first get_counter: %d\n", (int)value); /* Increment it again and check that the value has changed */ ret = invoke_command(session, &inout_mem, CMD_GET_CTR); if (ret != TEEC_SUCCESS) goto end; printf("Value after the second get_counter: %d\n", (int)value); if (++previous_value != value) ret = TEEC_ERROR_GENERIC; end: TEEC_ReleaseSharedMemory(&inout_mem); return ret; }
/* * Called when a process writes to a dev file. */ static int tee_write(struct file *filp, const char __user *buffer, size_t length, loff_t *offset) { struct tee_session ku_buffer; struct tee_session *ts; int ret = 0; if (length != sizeof(struct tee_session)) { pr_err(TEED_PFX "[%s] error, incorrect input length\n", __func__); return -EINVAL; } if (copy_from_user(&ku_buffer, buffer, length)) { pr_err(TEED_PFX "[%s] error, tee_session " "copy_from_user failed\n", __func__); return -EINVAL; } ts = (struct tee_session *)(filp->private_data); if (ts == NULL) { pr_err(TEED_PFX "[%s] error, private_data not " "initialized\n", __func__); return -EINVAL; } mutex_lock(&sync); switch (ts->state) { case TEED_STATE_OPEN_DEV: ret = open_tee_device(ts, &ku_buffer); break; case TEED_STATE_OPEN_SESSION: switch (ku_buffer.driver_cmd) { case TEED_INVOKE: ret = invoke_command(ts, &ku_buffer, (struct tee_session *)buffer); break; case TEED_CLOSE_SESSION: /* no caching implemented yet... */ if (call_sec_world(ts, TEED_CLOSE_SESSION)) { set_emsg(ts, TEED_ERROR_COMMUNICATION, __LINE__); ret = -EINVAL; } kfree(ts->ta); ts->ta = NULL; reset_session(ts); break; default: set_emsg(ts, TEED_ERROR_BAD_PARAMETERS, __LINE__); ret = -EINVAL; } break; default: pr_err(TEED_PFX "[%s] unknown state\n", __func__); set_emsg(ts, TEED_ERROR_BAD_STATE, __LINE__); ret = -EINVAL; } /* * We expect that ret has value zero when reaching the end here. * If it has any other value some error must have occured. */ if (!ret) ret = length; else { pr_err(TEED_PFX "[%s], forcing error to -EINVAL\n", __func__); ret = -EINVAL; } mutex_unlock(&sync); return ret; }