Commit 1647a5ac authored by Jens Wiklander's avatar Jens Wiklander

optee: support asynchronous supplicant requests

Adds support for asynchronous supplicant requests, meaning that the
supplicant can process several requests in parallel or block in a
request for some time.
Acked-by: default avatarEtienne Carriere <etienne.carriere@linaro.org>
Tested-by: Etienne Carriere <etienne.carriere@linaro.org> (b2260 pager=y/n)
Signed-off-by: default avatarJens Wiklander <jens.wiklander@linaro.org>
parent f2aa9724
......@@ -187,12 +187,12 @@ static int optee_open(struct tee_context *ctx)
if (teedev == optee->supp_teedev) {
bool busy = true;
mutex_lock(&optee->supp.ctx_mutex);
mutex_lock(&optee->supp.mutex);
if (!optee->supp.ctx) {
busy = false;
optee->supp.ctx = ctx;
}
mutex_unlock(&optee->supp.ctx_mutex);
mutex_unlock(&optee->supp.mutex);
if (busy) {
kfree(ctxdata);
return -EBUSY;
......@@ -252,11 +252,8 @@ static void optee_release(struct tee_context *ctx)
ctx->data = NULL;
if (teedev == optee->supp_teedev) {
mutex_lock(&optee->supp.ctx_mutex);
optee->supp.ctx = NULL;
mutex_unlock(&optee->supp.ctx_mutex);
}
if (teedev == optee->supp_teedev)
optee_supp_release(&optee->supp);
}
static const struct tee_driver_ops optee_ops = {
......
......@@ -53,36 +53,24 @@ struct optee_wait_queue {
* @ctx the context of current connected supplicant.
* if !NULL the supplicant device is available for use,
* else busy
* @ctx_mutex: held while accessing @ctx
* @func: supplicant function id to call
* @ret: call return value
* @num_params: number of elements in @param
* @param: parameters for @func
* @req_posted: if true, a request has been posted to the supplicant
* @supp_next_send: if true, next step is for supplicant to send response
* @thrd_mutex: held by the thread doing a request to supplicant
* @supp_mutex: held by supplicant while operating on this struct
* @data_to_supp: supplicant is waiting on this for next request
* @data_from_supp: requesting thread is waiting on this to get the result
* @mutex: held while accessing content of this struct
* @req_id: current request id if supplicant is doing synchronous
* communication, else -1
* @reqs: queued request not yet retrieved by supplicant
* @idr: IDR holding all requests currently being processed
* by supplicant
* @reqs_c: completion used by supplicant when waiting for a
* request to be queued.
*/
struct optee_supp {
/* Serializes access to this struct */
struct mutex mutex;
struct tee_context *ctx;
/* Serializes access of ctx */
struct mutex ctx_mutex;
u32 func;
u32 ret;
size_t num_params;
struct tee_param *param;
bool req_posted;
bool supp_next_send;
/* Serializes access to this struct for requesting thread */
struct mutex thrd_mutex;
/* Serializes access to this struct for supplicant threads */
struct mutex supp_mutex;
struct completion data_to_supp;
struct completion data_from_supp;
int req_id;
struct list_head reqs;
struct idr idr;
struct completion reqs_c;
};
/**
......@@ -142,6 +130,7 @@ int optee_supp_read(struct tee_context *ctx, void __user *buf, size_t len);
int optee_supp_write(struct tee_context *ctx, void __user *buf, size_t len);
void optee_supp_init(struct optee_supp *supp);
void optee_supp_uninit(struct optee_supp *supp);
void optee_supp_release(struct optee_supp *supp);
int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
struct tee_param *param);
......
......@@ -192,10 +192,10 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
if (ret)
return ERR_PTR(-ENOMEM);
mutex_lock(&optee->supp.ctx_mutex);
mutex_lock(&optee->supp.mutex);
/* Increases count as secure world doesn't have a reference */
shm = tee_shm_get_from_id(optee->supp.ctx, param.u.value.c);
mutex_unlock(&optee->supp.ctx_mutex);
mutex_unlock(&optee->supp.mutex);
return shm;
}
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment