in amdtee/core.c [231:302]
int amdtee_open_session(struct tee_context *ctx,
struct tee_ioctl_open_session_arg *arg,
struct tee_param *param)
{
struct amdtee_context_data *ctxdata = ctx->data;
struct amdtee_session *sess = NULL;
u32 session_info, ta_handle;
size_t ta_size;
int rc, i;
void *ta;
if (arg->clnt_login != TEE_IOCTL_LOGIN_PUBLIC) {
pr_err("unsupported client login method\n");
return -EINVAL;
}
rc = copy_ta_binary(ctx, &arg->uuid[0], &ta, &ta_size);
if (rc) {
pr_err("failed to copy TA binary\n");
return rc;
}
/* Load the TA binary into TEE environment */
handle_load_ta(ta, ta_size, arg);
if (arg->ret != TEEC_SUCCESS)
goto out;
ta_handle = get_ta_handle(arg->session);
mutex_lock(&session_list_mutex);
sess = alloc_session(ctxdata, arg->session);
mutex_unlock(&session_list_mutex);
if (!sess) {
handle_unload_ta(ta_handle);
rc = -ENOMEM;
goto out;
}
/* Find an empty session index for the given TA */
spin_lock(&sess->lock);
i = find_first_zero_bit(sess->sess_mask, TEE_NUM_SESSIONS);
if (i < TEE_NUM_SESSIONS)
set_bit(i, sess->sess_mask);
spin_unlock(&sess->lock);
if (i >= TEE_NUM_SESSIONS) {
pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
handle_unload_ta(ta_handle);
kref_put(&sess->refcount, destroy_session);
rc = -ENOMEM;
goto out;
}
/* Open session with loaded TA */
handle_open_session(arg, &session_info, param);
if (arg->ret != TEEC_SUCCESS) {
pr_err("open_session failed %d\n", arg->ret);
spin_lock(&sess->lock);
clear_bit(i, sess->sess_mask);
spin_unlock(&sess->lock);
handle_unload_ta(ta_handle);
kref_put(&sess->refcount, destroy_session);
goto out;
}
sess->session_info[i] = session_info;
set_session_id(ta_handle, i, &arg->session);
out:
free_pages((u64)ta, get_order(ta_size));
return rc;
}