@@ -1120,7 +1120,7 @@ static int ahash_digest(struct ahash_request *req)
src_nents = sg_nents_for_len(req->src, req->nbytes);
mapped_nents = dma_map_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
- if (mapped_nents == 0) {
+ if (src_nents && mapped_nents == 0) {
dev_err(jrdev, "unable to map source for DMA\n");
return -ENOMEM;
}
I still see tcrypts test failures:
caam_jr ffe301000.jr: 4000131c: DECO: desc idx 19: DECO Watchdog timer timeout error
alt: hash: update failed on test 6 for hmac-sha1-caam: ret=-1073746716
alg: hash: Test 4 failed for sha1-caam
00000000: 75 e1 d9 26 df 3b 5c 31 d7 a3 02 ca 79 26 55 0e
00000010: 31 96 8d 9f
[...]
git bisect points to this commit.
> ---
> drivers/crypto/caam/caamhash.c | 106 +++++++++++++++++++----------------------
> 1 file changed, 49 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
> index 241268d108ec..4e73d3218481 100644
> --- a/drivers/crypto/caam/caamhash.c
> +++ b/drivers/crypto/caam/caamhash.c
> @@ -789,6 +789,40 @@ static struct ahash_edesc *ahash_edesc_alloc(struct caam_hash_ctx *ctx,
> return edesc;
> }
>
> +static int ahash_edesc_add_src(struct caam_hash_ctx *ctx,
> + struct ahash_edesc *edesc,
> + struct ahash_request *req, int nents,
> + unsigned int first_sg, unsigned int first_bytes)
> +{
> + dma_addr_t src_dma;
> + u32 options;
> +
> + if (nents > 1 || first_sg) {
> + struct sec4_sg_entry *sg = edesc->sec4_sg;
> + unsigned int sgsize = sizeof(*sg) * (first_sg + nents);
> +
> + sg_to_sec4_sg_last(req->src, nents, sg + first_sg, 0);
> +
> + src_dma = dma_map_single(ctx->jrdev, sg, sgsize, DMA_TO_DEVICE);
> + if (dma_mapping_error(ctx->jrdev, src_dma)) {
> + dev_err(ctx->jrdev, "unable to map S/G table\n");
> + return -ENOMEM;
> + }
> +
> + edesc->sec4_sg_bytes = sgsize;
> + edesc->sec4_sg_dma = src_dma;
> + options = LDST_SGF;
> + } else {
> + src_dma = sg_dma_address(req->src);
> + options = 0;
> + }
> +
> + append_seq_in_ptr(edesc->hw_desc, src_dma, first_bytes + req->nbytes,
> + options);
> +
> + return 0;
> +}
[snip]
> @@ -1471,9 +1486,7 @@ static int ahash_update_first(struct ahash_request *req)
> &state->buflen_1 : &state->buflen_0;
> int to_hash;
> u32 *desc;
> - int sec4_sg_bytes, src_nents, mapped_nents;
> - dma_addr_t src_dma;
> - u32 options;
> + int src_nents, mapped_nents;
> struct ahash_edesc *edesc;
> int ret = 0;
>
> @@ -1490,11 +1503,6 @@ static int ahash_update_first(struct ahash_request *req)
> dev_err(jrdev, "unable to map source for DMA\n");
> return -ENOMEM;
> }
> - if (mapped_nents > 1)
> - sec4_sg_bytes = mapped_nents *
> - sizeof(struct sec4_sg_entry);
> - else
> - sec4_sg_bytes = 0;
>
> /*
> * allocate space for base edesc and hw desc commands,
> @@ -1511,28 +1519,14 @@ static int ahash_update_first(struct ahash_request *req)
> }
>
> edesc->src_nents = src_nents;
> - edesc->sec4_sg_bytes = sec4_sg_bytes;
> edesc->dst_dma = 0;
>
> - if (src_nents > 1) {
> - sg_to_sec4_sg_last(req->src, mapped_nents,
> - edesc->sec4_sg, 0);
> - edesc->sec4_sg_dma = dma_map_single(jrdev,
> - edesc->sec4_sg,
> - sec4_sg_bytes,
> - DMA_TO_DEVICE);
> - if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
> - dev_err(jrdev, "unable to map S/G table\n");
> - ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len,
> - DMA_TO_DEVICE);
> - kfree(edesc);
> - return -ENOMEM;
> - }
> - src_dma = edesc->sec4_sg_dma;
> - options = LDST_SGF;
> - } else {
> - src_dma = sg_dma_address(req->src);
> - options = 0;
> + ret = ahash_edesc_add_src(ctx, edesc, req, mapped_nents, 0, 0);
> + if (ret) {
> + ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len,
> + DMA_TO_DEVICE);
> + kfree(edesc);
> + return ret;
> }
>
> if (*next_buflen)
> @@ -1541,8 +1535,6 @@ static int ahash_update_first(struct ahash_request *req)
>
> desc = edesc->hw_desc;
>
> - append_seq_in_ptr(desc, src_dma, to_hash, options);
> -
The refactoring changes the logic here: instead of hashing over "to_hash" input
bytes, it will do over req->nbytes.
Current patch could be fixed as follows, but I guess it's abusing the
"first_bytes" param:
@@ -792,7 +792,7 @@ static struct ahash_edesc *ahash_edesc_alloc(struct
caam_hash_ctx *ctx,
static int ahash_edesc_add_src(struct caam_hash_ctx *ctx,
struct ahash_edesc *edesc,
struct ahash_request *req, int nents,
- unsigned int first_sg, unsigned int first_bytes)
+ unsigned int first_sg, int first_bytes)
{
dma_addr_t src_dma;