mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
crypto: rockchip: fixed probabilistic crashes in multithreading
The protection range of spin lock is optimized to prevent competition conditions. Signed-off-by: Lin Jinhan <troy.lin@rock-chips.com> Change-Id: I6d3dd088fc5e5c0046df12184108b9e176ac26a7
This commit is contained in:
@@ -286,7 +286,6 @@ int rk_ahash_start(struct rk_crypto_dev *rk_dev)
|
||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||
struct rk_crypto_algt *algt = rk_ahash_get_algt(tfm);
|
||||
struct scatterlist *src_sg;
|
||||
unsigned long flags;
|
||||
unsigned int nbytes;
|
||||
int ret = 0;
|
||||
|
||||
@@ -378,14 +377,12 @@ int rk_ahash_start(struct rk_crypto_dev *rk_dev)
|
||||
ctx->hash_tmp_len, ctx->lastc_len, nbytes);
|
||||
|
||||
if (nbytes) {
|
||||
spin_lock_irqsave(&rk_dev->lock, flags);
|
||||
if (ctx->calc_cnt == 0)
|
||||
alg_ctx->ops.hw_init(rk_dev, algt->algo, algt->type);
|
||||
|
||||
/* flush all 64byte key buffer for hmac */
|
||||
alg_ctx->ops.hw_write_key(ctx->rk_dev, ctx->authkey, sizeof(ctx->authkey));
|
||||
ret = rk_ahash_set_data_start(rk_dev, rctx->flag);
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
}
|
||||
exit:
|
||||
return ret;
|
||||
|
||||
@@ -281,10 +281,12 @@ static void rk_crypto_irq_timer_handle(struct timer_list *t)
|
||||
static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id)
|
||||
{
|
||||
struct rk_crypto_dev *rk_dev = platform_get_drvdata(dev_id);
|
||||
struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev->async_req);
|
||||
struct rk_alg_ctx *alg_ctx;
|
||||
|
||||
spin_lock(&rk_dev->lock);
|
||||
|
||||
alg_ctx = rk_alg_ctx_cast(rk_dev->async_req);
|
||||
|
||||
rk_dev->stat.irq_cnt++;
|
||||
|
||||
if (alg_ctx->ops.irq_handle)
|
||||
@@ -390,23 +392,22 @@ static void rk_crypto_queue_task_cb(unsigned long data)
|
||||
struct crypto_async_request *async_req, *backlog;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&rk_dev->lock, flags);
|
||||
if (rk_dev->async_req) {
|
||||
dev_err(rk_dev->dev, "%s: Unexpected crypto paths.\n", __func__);
|
||||
return;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rk_dev->err = 0;
|
||||
spin_lock_irqsave(&rk_dev->lock, flags);
|
||||
|
||||
backlog = crypto_get_backlog(&rk_dev->queue);
|
||||
async_req = crypto_dequeue_request(&rk_dev->queue);
|
||||
|
||||
if (!async_req) {
|
||||
rk_dev->busy = false;
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
return;
|
||||
goto exit;
|
||||
}
|
||||
rk_dev->stat.dequeue_cnt++;
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
|
||||
if (backlog) {
|
||||
backlog->complete(backlog, -EINPROGRESS);
|
||||
@@ -417,15 +418,22 @@ static void rk_crypto_queue_task_cb(unsigned long data)
|
||||
rk_dev->err = rk_start_op(rk_dev);
|
||||
if (rk_dev->err)
|
||||
rk_complete_op(rk_dev, rk_dev->err);
|
||||
|
||||
exit:
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
}
|
||||
|
||||
static void rk_crypto_done_task_cb(unsigned long data)
|
||||
{
|
||||
struct rk_crypto_dev *rk_dev = (struct rk_crypto_dev *)data;
|
||||
struct rk_alg_ctx *alg_ctx;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&rk_dev->lock, flags);
|
||||
|
||||
if (!rk_dev->async_req) {
|
||||
dev_err(rk_dev->dev, "done task receive invalid async_req\n");
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -447,9 +455,12 @@ static void rk_crypto_done_task_cb(unsigned long data)
|
||||
if (rk_dev->err)
|
||||
goto exit;
|
||||
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
|
||||
return;
|
||||
exit:
|
||||
rk_complete_op(rk_dev, rk_dev->err);
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
}
|
||||
|
||||
static struct rk_crypto_algt *rk_crypto_find_algs(struct rk_crypto_dev *rk_dev,
|
||||
|
||||
@@ -331,7 +331,6 @@ int rk_ablk_start(struct rk_crypto_dev *rk_dev)
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||
struct rk_crypto_algt *algt = rk_cipher_get_algt(tfm);
|
||||
struct rk_alg_ctx *alg_ctx = rk_cipher_alg_ctx(rk_dev);
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
alg_ctx->left_bytes = req->cryptlen;
|
||||
@@ -345,10 +344,9 @@ int rk_ablk_start(struct rk_crypto_dev *rk_dev)
|
||||
|
||||
CRYPTO_TRACE("total = %u", alg_ctx->total);
|
||||
|
||||
spin_lock_irqsave(&rk_dev->lock, flags);
|
||||
alg_ctx->ops.hw_init(rk_dev, algt->algo, algt->mode);
|
||||
err = rk_set_data_start(rk_dev);
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -443,7 +441,6 @@ int rk_aead_start(struct rk_crypto_dev *rk_dev)
|
||||
struct rk_crypto_algt *algt = rk_aead_get_algt(tfm);
|
||||
struct rk_alg_ctx *alg_ctx = rk_cipher_alg_ctx(rk_dev);
|
||||
unsigned int total = 0, authsize;
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
total = req->cryptlen + req->assoclen;
|
||||
@@ -464,10 +461,9 @@ int rk_aead_start(struct rk_crypto_dev *rk_dev)
|
||||
CRYPTO_TRACE("is_enc = %d, authsize = %u, cryptlen = %u, total = %u, assoclen = %u",
|
||||
ctx->is_enc, authsize, req->cryptlen, alg_ctx->total, alg_ctx->assoclen);
|
||||
|
||||
spin_lock_irqsave(&rk_dev->lock, flags);
|
||||
alg_ctx->ops.hw_init(rk_dev, algt->algo, algt->mode);
|
||||
err = rk_set_data_start(rk_dev);
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +269,6 @@ static int rk_ablk_start(struct rk_crypto_dev *rk_dev)
|
||||
struct skcipher_request *req =
|
||||
skcipher_request_cast(rk_dev->async_req);
|
||||
struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev);
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
alg_ctx->left_bytes = req->cryptlen;
|
||||
@@ -281,10 +280,9 @@ static int rk_ablk_start(struct rk_crypto_dev *rk_dev)
|
||||
alg_ctx->req_dst = req->dst;
|
||||
alg_ctx->dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
|
||||
|
||||
spin_lock_irqsave(&rk_dev->lock, flags);
|
||||
rk_ablk_hw_init(rk_dev);
|
||||
err = rk_set_data_start(rk_dev);
|
||||
spin_unlock_irqrestore(&rk_dev->lock, flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user