TEE_Result syscall_invoke_ta_command(unsigned long ta_sess,
			unsigned long cancel_req_to, unsigned long cmd_id,
			struct utee_params *usr_param, uint32_t *ret_orig)
{
	TEE_Result res;
	TEE_Result res2;
	uint32_t ret_o = TEE_ORIGIN_TEE;
	struct tee_ta_param param = { 0 };
	TEE_Identity clnt_id;
	struct tee_ta_session *sess;
	struct tee_ta_session *called_sess;
	struct mobj *mobj_param = NULL;
	void *tmp_buf_va[TEE_NUM_PARAMS] = { NULL };
	struct user_ta_ctx *utc;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;
	utc = to_user_ta_ctx(sess->ctx);

	called_sess = tee_ta_get_session(
				(vaddr_t)tee_svc_uref_to_kaddr(ta_sess), true,
				&utc->open_sessions);
	if (!called_sess)
		return TEE_ERROR_BAD_PARAMETERS;

	clnt_id.login = TEE_LOGIN_TRUSTED_APP;
	memcpy(&clnt_id.uuid, &sess->ctx->uuid, sizeof(TEE_UUID));

	res = tee_svc_copy_param(sess, called_sess, usr_param, &param,
				 tmp_buf_va, &mobj_param);
	if (res != TEE_SUCCESS)
		goto function_exit;

	res = tee_ta_invoke_command(&ret_o, called_sess, &clnt_id,
				    cancel_req_to, cmd_id, &param);

	res2 = tee_svc_update_out_param(&param, tmp_buf_va, usr_param);
	if (res2 != TEE_SUCCESS) {
		/*
		 * Spec for TEE_InvokeTACommand() says:
		 * "If the return origin is different from
		 * TEE_ORIGIN_TRUSTED_APP, then the function has failed
		 * before it could reach the destination Trusted
		 * Application."
		 *
		 * But if we can't update params to the caller we have no
		 * choice we need to return some error to indicate that
		 * parameters aren't updated as expected.
		 */
		ret_o = TEE_ORIGIN_TEE;
		res = res2;
	}

function_exit:
	tee_ta_put_session(called_sess);
	mobj_free(mobj_param);
	if (ret_orig)
		tee_svc_copy_to_user(ret_orig, &ret_o, sizeof(ret_o));
	return res;
}
TEE_Result syscall_invoke_ta_command(unsigned long ta_sess,
			unsigned long cancel_req_to, unsigned long cmd_id,
			struct utee_params *usr_param, uint32_t *ret_orig)
{
	TEE_Result res;
	TEE_Result res2;
	uint32_t ret_o = TEE_ORIGIN_TEE;
	struct tee_ta_param param = { 0 };
	TEE_Identity clnt_id;
	struct tee_ta_session *sess;
	struct tee_ta_session *called_sess;
	struct mobj *mobj_param = NULL;
	void *tmp_buf_va[TEE_NUM_PARAMS] = { NULL };
	struct user_ta_ctx *utc;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;
	utc = to_user_ta_ctx(sess->ctx);

	called_sess = tee_ta_get_session(
				(vaddr_t)tee_svc_uref_to_kaddr(ta_sess), true,
				&utc->open_sessions);
	if (!called_sess)
		return TEE_ERROR_BAD_PARAMETERS;

	clnt_id.login = TEE_LOGIN_TRUSTED_APP;
	memcpy(&clnt_id.uuid, &sess->ctx->uuid, sizeof(TEE_UUID));

	res = tee_svc_copy_param(sess, called_sess, usr_param, &param,
				 tmp_buf_va, &mobj_param);
	if (res != TEE_SUCCESS)
		goto function_exit;

	res = tee_ta_invoke_command(&ret_o, called_sess, &clnt_id,
				    cancel_req_to, cmd_id, &param);

	res2 = tee_svc_update_out_param(&param, tmp_buf_va, usr_param);
	if (res2 != TEE_SUCCESS) {
		 
		ret_o = TEE_ORIGIN_TEE;
		res = res2;
	}

function_exit:
	tee_ta_put_session(called_sess);
	mobj_free(mobj_param);
	if (ret_orig)
		tee_svc_copy_to_user(ret_orig, &ret_o, sizeof(ret_o));
	return res;
}