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) ...@@ -187,12 +187,12 @@ static int optee_open(struct tee_context *ctx)
if (teedev == optee->supp_teedev) { if (teedev == optee->supp_teedev) {
bool busy = true; bool busy = true;
mutex_lock(&optee->supp.ctx_mutex); mutex_lock(&optee->supp.mutex);
if (!optee->supp.ctx) { if (!optee->supp.ctx) {
busy = false; busy = false;
optee->supp.ctx = ctx; optee->supp.ctx = ctx;
} }
mutex_unlock(&optee->supp.ctx_mutex); mutex_unlock(&optee->supp.mutex);
if (busy) { if (busy) {
kfree(ctxdata); kfree(ctxdata);
return -EBUSY; return -EBUSY;
...@@ -252,11 +252,8 @@ static void optee_release(struct tee_context *ctx) ...@@ -252,11 +252,8 @@ static void optee_release(struct tee_context *ctx)
ctx->data = NULL; ctx->data = NULL;
if (teedev == optee->supp_teedev) { if (teedev == optee->supp_teedev)
mutex_lock(&optee->supp.ctx_mutex); optee_supp_release(&optee->supp);
optee->supp.ctx = NULL;
mutex_unlock(&optee->supp.ctx_mutex);
}
} }
static const struct tee_driver_ops optee_ops = { static const struct tee_driver_ops optee_ops = {
......
...@@ -53,36 +53,24 @@ struct optee_wait_queue { ...@@ -53,36 +53,24 @@ struct optee_wait_queue {
* @ctx the context of current connected supplicant. * @ctx the context of current connected supplicant.
* if !NULL the supplicant device is available for use, * if !NULL the supplicant device is available for use,
* else busy * else busy
* @ctx_mutex: held while accessing @ctx * @mutex: held while accessing content of this struct
* @func: supplicant function id to call * @req_id: current request id if supplicant is doing synchronous
* @ret: call return value * communication, else -1
* @num_params: number of elements in @param * @reqs: queued request not yet retrieved by supplicant
* @param: parameters for @func * @idr: IDR holding all requests currently being processed
* @req_posted: if true, a request has been posted to the supplicant * by supplicant
* @supp_next_send: if true, next step is for supplicant to send response * @reqs_c: completion used by supplicant when waiting for a
* @thrd_mutex: held by the thread doing a request to supplicant * request to be queued.
* @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
*/ */
struct optee_supp { struct optee_supp {
/* Serializes access to this struct */
struct mutex mutex;
struct tee_context *ctx; struct tee_context *ctx;
/* Serializes access of ctx */
struct mutex ctx_mutex; int req_id;
struct list_head reqs;
u32 func; struct idr idr;
u32 ret; struct completion reqs_c;
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;
}; };
/** /**
...@@ -142,6 +130,7 @@ int optee_supp_read(struct tee_context *ctx, void __user *buf, size_t len); ...@@ -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); 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_init(struct optee_supp *supp);
void optee_supp_uninit(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, int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
struct tee_param *param); struct tee_param *param);
......
...@@ -192,10 +192,10 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz) ...@@ -192,10 +192,10 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
if (ret) if (ret)
return ERR_PTR(-ENOMEM); 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 */ /* Increases count as secure world doesn't have a reference */
shm = tee_shm_get_from_id(optee->supp.ctx, param.u.value.c); 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; 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