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:
Lin Jinhan
2023-05-23 09:33:21 +08:00
committed by Tao Huang
parent bfc49df515
commit 5ff1d49a54
4 changed files with 20 additions and 18 deletions

View File

@@ -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;

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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;
}