[PATCH v2 11/12] crypto: talitos/hash - fix SEC2 64k - 1 ahash request limitation
From: Paul Louvel
Date: Tue May 05 2026 - 14:00:00 EST
The problem described in commit 655ef638a2bc ("crypto: talitos - fix
SEC1 32k ahash request limitation") also apply for the SEC2 hardware,
but with a limitation of 64k - 1 bytes.
Split ahash_done() into SEC1 and SEC2 paths: SEC1 continues to free the
whole descriptor list at once, while SEC2 now iterates through
descriptors one by one, submitting the next only after the previous
completes, which is required since SEC2 cannot chain descriptors in
hardware.
Cc: stable@xxxxxxxxxxxxxxx
Fixes: c662b043cdca ("crypto: af_alg/hash: Support MSG_SPLICE_PAGES")
Signed-off-by: Paul Louvel <paul.louvel@xxxxxxxxxxx>
---
drivers/crypto/talitos.c | 50 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 42 insertions(+), 8 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 10181f5ee0ec..cdb6823d7038 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1833,18 +1833,51 @@ static void ahash_done(struct device *dev,
{
struct ahash_request *areq = context;
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+ bool is_sec1 = has_ftr_sec1(dev_get_drvdata(dev));
+ struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct talitos_edesc *edesc, *next;
+ bool is_last;
+
+ if (is_sec1) {
+ is_last = true;
+ ahash_free_desc_list_from(areq,
+ list_first_entry(&req_ctx->desc_list,
+ struct talitos_edesc, node));
+
+ ahash_request_complete(areq, err);
+ } else {
+ edesc = container_of(desc, struct talitos_edesc, desc);
+ is_last = edesc->last;
+ if (!is_last)
+ next = list_next_entry(edesc, node);
- if (!req_ctx->last_request && req_ctx->to_hash_later) {
+ list_del(&edesc->node);
+ common_nonsnoop_hash_unmap(dev, edesc, areq);
+ kfree(edesc);
+
+ if (err)
+ goto out;
+
+ if (!is_last) {
+ err = talitos_submit(dev, ctx->ch, &next->desc,
+ ahash_done, areq);
+ if (err != -EINPROGRESS)
+ goto out;
+ return;
+ }
+
+out:
+ if (err && !is_last)
+ ahash_free_desc_list_from(areq, next);
+ ahash_request_complete(areq, err);
+ }
+
+ if (!req_ctx->last_request && is_last && req_ctx->to_hash_later) {
/* Position any partial block for next update/final/finup */
req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
req_ctx->nbuf = req_ctx->to_hash_later;
}
-
- ahash_free_desc_list_from(areq,
- list_first_entry(&req_ctx->desc_list,
- struct talitos_edesc, node));
-
- ahash_request_complete(areq, err);
}
/*
@@ -1954,7 +1987,8 @@ static int ahash_process_req_prepare(struct ahash_request *areq,
{
struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
- size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN : SIZE_MAX;
+ size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN :
+ TALITOS2_MAX_DATA_LEN;
struct talitos_edesc *edesc;
struct scatterlist tmp[2];
size_t to_hash_this_desc;
--
2.53.0