Linux cryptographic layer development
 help / color / mirror / Atom feed
* Re: [PATCH 29/29] crypto: talitos - Remove TALITOS_DESC_SIZE macro
From: Paul Louvel @ 2026-06-04 13:01 UTC (permalink / raw)
  To: Christophe Leroy (CS GROUP), Paul Louvel, Herbert Xu,
	David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <4202c304-4a4e-4b1a-8d40-d96a1ef143fb@kernel.org>

On Thu Jun 4, 2026 at 11:59 AM CEST, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 28/05/2026 à 11:08, Paul Louvel a écrit :
>> Now that struct talitos_desc no longer has the SEC1-only next_desc field
>> (it was moved into sec1_talitos_desc), TALITOS_DESC_SIZE is identical to
>> sizeof(struct talitos_desc) and no longer serves any purpose. Remove it
>> and use sizeof directly at each macro invocation.
>
> It is still there ...
>
> $ git grep TALITOS_DESC_SIZE drivers
> drivers/crypto/talitos/talitos.h:#define TALITOS_DESC_SIZE 
> sizeof(struct talitos_desc)

My bad. At least, it is no longer _used_ in the code..

Thanks.

>
>
>> 
>> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
>> ---
>>   drivers/crypto/talitos/talitos-sec1.c | 10 +++++-----
>>   drivers/crypto/talitos/talitos-sec2.c |  6 +++---
>>   2 files changed, 8 insertions(+), 8 deletions(-)
>> 
>> diff --git a/drivers/crypto/talitos/talitos-sec1.c b/drivers/crypto/talitos/talitos-sec1.c
>> index e4f482520372..504ce9e23e59 100644
>> --- a/drivers/crypto/talitos/talitos-sec1.c
>> +++ b/drivers/crypto/talitos/talitos-sec1.c
>> @@ -190,7 +190,7 @@ static void sec1_dma_map_request(struct device *dev,
>>   	while (edesc) {
>>   
>>   		dma_desc = dma_map_single(dev, &edesc->desc.sec1.hdr,
>> -					  TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>> +					  sizeof(struct talitos_desc), DMA_BIDIRECTIONAL);
>>   
>>   		if (!prev_edesc) {
>>   			request->dma_desc = dma_desc;
>> @@ -202,7 +202,7 @@ static void sec1_dma_map_request(struct device *dev,
>>   		prev_edesc->desc.sec1.next_desc = cpu_to_be32(dma_desc);
>>   
>>   		dma_sync_single_for_device(dev, prev_dma_desc,
>> -					   TALITOS_DESC_SIZE, DMA_TO_DEVICE);
>> +					   sizeof(struct talitos_desc), DMA_TO_DEVICE);
>>   
>>   next:
>>   		prev_edesc = edesc;
>> @@ -216,12 +216,12 @@ static void sec1_dma_unmap_request(struct device *dev,
>>   {
>>   	struct talitos_edesc *edesc;
>>   
>> -	dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
>> +	dma_unmap_single(dev, request->dma_desc, sizeof(struct talitos_desc),
>>   			 DMA_BIDIRECTIONAL);
>>   	edesc = container_of(request->desc, struct talitos_edesc, desc);
>>   	while (edesc->next_desc) {
>>   		dma_unmap_single(dev, be32_to_cpu(edesc->desc.sec1.next_desc),
>> -				 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>> +				 sizeof(struct talitos_desc), DMA_BIDIRECTIONAL);
>>   		edesc = edesc->next_desc;
>>   	}
>>   }
>> @@ -239,7 +239,7 @@ static __be32 sec1_get_request_hdr(struct device *dev,
>>   		edesc = edesc->next_desc;
>>   	}
>>   
>> -	dma_sync_single_for_cpu(dev, dma_desc, TALITOS_DESC_SIZE,
>> +	dma_sync_single_for_cpu(dev, dma_desc, sizeof(struct talitos_desc),
>>   				DMA_BIDIRECTIONAL);
>>   
>>   	return edesc->desc.sec1.hdr;
>> diff --git a/drivers/crypto/talitos/talitos-sec2.c b/drivers/crypto/talitos/talitos-sec2.c
>> index 52f783ddc8b6..0df3b22510c7 100644
>> --- a/drivers/crypto/talitos/talitos-sec2.c
>> +++ b/drivers/crypto/talitos/talitos-sec2.c
>> @@ -205,7 +205,7 @@ static void sec2_dma_map_request(struct device *dev,
>>   				 struct talitos_desc *desc)
>>   {
>>   	request->dma_desc =
>> -		dma_map_single(dev, desc, TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>> +		dma_map_single(dev, desc, sizeof(struct talitos_desc), DMA_BIDIRECTIONAL);
>>   }
>>   
>>   static int sec2_talitos_handle_error(struct device *dev, u32 isr, u32 isr_lo)
>> @@ -346,14 +346,14 @@ static void sec2_init_task(struct device *dev)
>>   static void sec2_dma_unmap_request(struct device *dev,
>>   				   struct talitos_request *request)
>>   {
>> -	dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
>> +	dma_unmap_single(dev, request->dma_desc, sizeof(struct talitos_desc),
>>   			 DMA_BIDIRECTIONAL);
>>   }
>>   
>>   static __be32 sec2_get_request_hdr(struct device *dev,
>>   				   struct talitos_request *request)
>>   {
>> -	dma_sync_single_for_cpu(dev, request->dma_desc, TALITOS_DESC_SIZE,
>> +	dma_sync_single_for_cpu(dev, request->dma_desc, sizeof(struct talitos_desc),
>>   				DMA_BIDIRECTIONAL);
>>   
>>   	return request->desc->sec2.hdr;
>> 




-- 
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH 27/29] crypto: talitos - Introduce per-SEC-version descriptor structures and ops
From: Paul Louvel @ 2026-06-04 13:01 UTC (permalink / raw)
  To: Christophe Leroy (CS GROUP), Paul Louvel, Herbert Xu,
	David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <a4c06e1e-e9f2-4144-a2c1-68b8a12cd24f@kernel.org>

On Thu Jun 4, 2026 at 11:57 AM CEST, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 28/05/2026 à 11:08, Paul Louvel a écrit :
>> The driver used a single shared talitos_desc with overlapping union
>> members and a SEC1-specific "hdr1" hack to handle differences between
>> SEC1 and SEC2 descriptor layouts.
>
> I'd call it a feature not a hack. We have the chance that allthough 
> different the structures are very close and can be kept common at the 
> low price of that copy from hdr to hdr1 in talitos submit.
>
>> 
>> Introduce distinct sec1_talitos_desc/sec2_talitos_desc and
>> sec1_talitos_ptr/sec2_talitos_ptr structures, nested inside a union
>> in talitos_desc/talitos_ptr.
>> Mark them packed to reflect that these structures are used directly by
>> the hardware, even if the structure is naturally aligned.
>> 
>> Abstract descriptor field access through a new talitos_desc_ops
>> structure (set_hdr, get_hdr, get_hdr_lo, get_ptr), and add get_ptr_value
>> to the existing talitos_ptr_ops.
>
> Too much abstraction and opacity kills readability and maintainability. 
> Especially here your change increases the number of places you have to 
> break instructions in two lines or more. This really kills readability.
>
> I really prefer reading
>
>    &edesc->desc.ptr[6]
>
> over
>
>    ctx->desc_ops->get_ptr(&edesc->desc, 6)
>

I was reluctant to add this set of changes because of this needed boilerplate.
I did it anyway because I like the clear separation of descriptor / pointer
layouts between the two version.
For example, in SEC2, there is no next descriptor field. With the current code,
that field is ignored but still exists in the structure. With two different
structures, this difference is immediately visible to the reader without any
further reading.
Of course, it makes no difference to the hardware.

Performance wise, it could be solved with static branching like you suggested
earlier with a small helper like talitos_get_ptr(). But it would not solve the
readability issue you mentionned.

What do you think ?

>
>
>> 
>> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
>> ---
>>   drivers/crypto/talitos/talitos-aead.c     | 76 +++++++++++++++++++------------
>>   drivers/crypto/talitos/talitos-hash.c     | 51 +++++++++++++--------
>>   drivers/crypto/talitos/talitos-sec1.c     | 61 +++++++++++++++++++------
>>   drivers/crypto/talitos/talitos-sec2.c     | 56 ++++++++++++++++++-----
>>   drivers/crypto/talitos/talitos-skcipher.c | 46 +++++++++++--------
>>   drivers/crypto/talitos/talitos.c          |  4 +-
>>   drivers/crypto/talitos/talitos.h          | 60 +++++++++++++++++-------
>>   7 files changed, 244 insertions(+), 110 deletions(-)
>> 
>> diff --git a/drivers/crypto/talitos/talitos-aead.c b/drivers/crypto/talitos/talitos-aead.c
>> index b585abdd2275..d1cec7e4dd3f 100644
>> --- a/drivers/crypto/talitos/talitos-aead.c
>> +++ b/drivers/crypto/talitos/talitos-aead.c
>> @@ -94,12 +94,15 @@ static void ipsec_esp_unmap(struct device *dev,
>>   	unsigned int ivsize = crypto_aead_ivsize(aead);
>>   	unsigned int authsize = crypto_aead_authsize(aead);
>>   	unsigned int cryptlen = areq->cryptlen - (encrypt ? 0 : authsize);
>> -	bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
>> -	struct talitos_ptr *civ_ptr = &edesc->desc.ptr[is_ipsec_esp ? 2 : 3];
>> +	bool is_ipsec_esp = ctx->desc_ops->get_hdr(&edesc->desc) &
>> +			    DESC_HDR_TYPE_IPSEC_ESP;
>> +	struct talitos_ptr *civ_ptr =
>> +		ctx->desc_ops->get_ptr(&edesc->desc, is_ipsec_esp ? 2 : 3);
>>   
>>   	if (is_ipsec_esp)
>> -		unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6],
>> -					 DMA_FROM_DEVICE);
>> +		unmap_single_talitos_ptr(
>> +			dev, ctx->desc_ops->get_ptr(&edesc->desc, 6),
>> +			DMA_FROM_DEVICE);
>>   	unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
>>   
>>   	talitos_sg_unmap(dev, edesc, areq->src, areq->dst,
>> @@ -171,6 +174,7 @@ static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
>>   					  struct talitos_desc *desc,
>>   					  void *context, int err)
>>   {
>> +	struct talitos_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(context));
>>   	struct aead_request *req = context;
>>   	struct talitos_edesc *edesc;
>>   
>> @@ -179,8 +183,8 @@ static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
>>   	ipsec_esp_unmap(dev, edesc, req, false);
>>   
>>   	/* check ICV auth status */
>> -	if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
>> -		     DESC_HDR_LO_ICCR1_PASS))
>> +	if (!err && ((ctx->desc_ops->get_hdr_lo(desc) &
>> +		      DESC_HDR_LO_ICCR1_MASK) != DESC_HDR_LO_ICCR1_PASS))
>>   		err = -EBADMSG;
>>   
>>   	kfree(edesc);
>> @@ -210,13 +214,17 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>>   	bool sync_needed = false;
>>   	struct talitos_private *priv = dev_get_drvdata(dev);
>>   	bool is_sec1 = has_ftr_sec1(priv);
>> -	bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
>> -	struct talitos_ptr *civ_ptr = &desc->ptr[is_ipsec_esp ? 2 : 3];
>> -	struct talitos_ptr *ckey_ptr = &desc->ptr[is_ipsec_esp ? 3 : 2];
>> +	bool is_ipsec_esp = ctx->desc_ops->get_hdr(desc) &
>> +			    DESC_HDR_TYPE_IPSEC_ESP;
>> +	struct talitos_ptr *civ_ptr =
>> +		ctx->desc_ops->get_ptr(desc, is_ipsec_esp ? 2 : 3);
>> +	struct talitos_ptr *ckey_ptr =
>> +		ctx->desc_ops->get_ptr(desc, is_ipsec_esp ? 3 : 2);
>>   	dma_addr_t dma_icv = edesc->dma_link_tbl + edesc->dma_len - authsize;
>>   
>>   	/* hmac key */
>> -	ctx->ptr_ops->to_talitos_ptr(&desc->ptr[0], ctx->dma_key, ctx->authkeylen);
>> +	ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 0),
>> +				     ctx->dma_key, ctx->authkeylen);
>>   
>>   	sg_count = edesc->src_nents ?: 1;
>>   	if (is_sec1 && sg_count > 1)
>> @@ -229,7 +237,8 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>>   
>>   	/* hmac data */
>>   	ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
>> -			     &desc->ptr[1], sg_count, 0, tbl_off);
>> +			     ctx->desc_ops->get_ptr(desc, 1), sg_count, 0,
>> +			     tbl_off);
>>   
>>   	if (ret > 1) {
>>   		tbl_off += ret;
>> @@ -249,12 +258,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>>   	 * extent is bytes of HMAC postpended to ciphertext,
>>   	 * typically 12 for ipsec
>>   	 */
>> -	if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
>> +	if (is_ipsec_esp &&
>> +	    (ctx->desc_ops->get_hdr(desc) & DESC_HDR_MODE1_MDEU_CICV))
>>   		elen = authsize;
>>   
>> -	ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
>> -				 sg_count, areq->assoclen, tbl_off, elen,
>> -				 false, 1);
>> +	ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc,
>> +				 ctx->desc_ops->get_ptr(desc, 4), sg_count,
>> +				 areq->assoclen, tbl_off, elen, false, 1);
>>   
>>   	if (ret > 1) {
>>   		tbl_off += ret;
>> @@ -272,8 +282,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>>   		elen = authsize;
>>   	else
>>   		elen = 0;
>> -	ret = talitos_sg_map_ext(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
>> -				 sg_count, areq->assoclen, tbl_off, elen,
>> +	ret = talitos_sg_map_ext(dev, areq->dst, cryptlen, edesc,
>> +				 ctx->desc_ops->get_ptr(desc, 5), sg_count,
>> +				 areq->assoclen, tbl_off, elen,
>>   				 is_ipsec_esp && !encrypt, 1);
>>   	tbl_off += ret;
>>   
>> @@ -286,20 +297,23 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>>   
>>   		/* icv data follows link tables */
>>   		ctx->ptr_ops->to_talitos_ptr(tbl_ptr, dma_icv, authsize);
>> -		ctx->ptr_ops->to_talitos_ptr_ext_or(&desc->ptr[5], authsize);
>> +		ctx->ptr_ops->to_talitos_ptr_ext_or(
>> +			ctx->desc_ops->get_ptr(desc, 5), authsize);
>>   		sync_needed = true;
>>   	} else if (!encrypt) {
>> -		ctx->ptr_ops->to_talitos_ptr(&desc->ptr[6], dma_icv, authsize);
>> +		ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 6),
>> +					     dma_icv, authsize);
>>   		sync_needed = true;
>>   	} else if (!is_ipsec_esp) {
>> -		talitos_sg_map(dev, areq->dst, authsize, edesc, &desc->ptr[6],
>> -			       sg_count, areq->assoclen + cryptlen, tbl_off);
>> +		talitos_sg_map(dev, areq->dst, authsize, edesc,
>> +			       ctx->desc_ops->get_ptr(desc, 6), sg_count,
>> +			       areq->assoclen + cryptlen, tbl_off);
>>   	}
>>   
>>   	/* iv out */
>>   	if (is_ipsec_esp)
>> -		map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
>> -				       DMA_FROM_DEVICE);
>> +		map_single_talitos_ptr(dev, ctx->desc_ops->get_ptr(desc, 6),
>> +				       ivsize, ctx->iv, DMA_FROM_DEVICE);
>>   
>>   	if (sync_needed)
>>   		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
>> @@ -341,7 +355,7 @@ static int aead_encrypt(struct aead_request *req)
>>   		return PTR_ERR(edesc);
>>   
>>   	/* set encrypt */
>> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
>> +	ctx->desc_ops->set_hdr(&edesc->desc, ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT);
>>   
>>   	return ipsec_esp(edesc, req, true, ipsec_esp_encrypt_done);
>>   }
>> @@ -354,21 +368,24 @@ static int aead_decrypt(struct aead_request *req)
>>   	struct talitos_private *priv = dev_get_drvdata(ctx->dev);
>>   	struct talitos_edesc *edesc;
>>   	void *icvdata;
>> +	__be32 hdr;
>>   
>>   	/* allocate extended descriptor */
>>   	edesc = aead_edesc_alloc(req, req->iv, 1, false);
>>   	if (IS_ERR(edesc))
>>   		return PTR_ERR(edesc);
>>   
>> -	if ((edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP) &&
>> +	hdr = ctx->desc_ops->get_hdr(&edesc->desc);
>> +	if ((hdr & DESC_HDR_TYPE_IPSEC_ESP) &&
>>   	    (priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
>>   	    ((!edesc->src_nents && !edesc->dst_nents) ||
>>   	     priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
>>   
>>   		/* decrypt and check the ICV */
>> -		edesc->desc.hdr = ctx->desc_hdr_template |
>> -				  DESC_HDR_DIR_INBOUND |
>> -				  DESC_HDR_MODE1_MDEU_CICV;
>> +		ctx->desc_ops->set_hdr(&edesc->desc,
>> +				       ctx->desc_hdr_template |
>> +					       DESC_HDR_DIR_INBOUND |
>> +					       DESC_HDR_MODE1_MDEU_CICV);
>>   
>>   		/* reset integrity check result bits */
>>   
>> @@ -377,7 +394,8 @@ static int aead_decrypt(struct aead_request *req)
>>   	}
>>   
>>   	/* Have to check the ICV with software */
>> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
>> +	ctx->desc_ops->set_hdr(&edesc->desc,
>> +			       ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND);
>>   
>>   	/* stash incoming ICV for later cmp with ICV generated by the h/w */
>>   	icvdata = edesc->buf + edesc->dma_len;
>> diff --git a/drivers/crypto/talitos/talitos-hash.c b/drivers/crypto/talitos/talitos-hash.c
>> index 026eebf037f5..fb4d53e2abf8 100644
>> --- a/drivers/crypto/talitos/talitos-hash.c
>> +++ b/drivers/crypto/talitos/talitos-hash.c
>> @@ -44,7 +44,8 @@ static void common_nonsnoop_hash_unmap(struct talitos_ctx *ctx,
>>   	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>>   	struct talitos_desc *desc = &edesc->desc;
>>   
>> -	unmap_single_talitos_ptr(ctx->dev, &desc->ptr[5], DMA_FROM_DEVICE);
>> +	unmap_single_talitos_ptr(ctx->dev, ctx->desc_ops->get_ptr(desc, 5),
>> +				 DMA_FROM_DEVICE);
>>   
>>   	if (edesc->last && req_ctx->last_request)
>>   		memcpy(areq->result, req_ctx->hw_context,
>> @@ -54,8 +55,9 @@ static void common_nonsnoop_hash_unmap(struct talitos_ctx *ctx,
>>   		talitos_sg_unmap(ctx->dev, edesc, edesc->src, NULL, 0, 0);
>>   
>>   	/* When using hashctx-in, must unmap it. */
>> -	if (ctx->ptr_ops->from_talitos_ptr_len(&desc->ptr[1]))
>> -		unmap_single_talitos_ptr(ctx->dev, &desc->ptr[1],
>> +	if (ctx->ptr_ops->from_talitos_ptr_len(ctx->desc_ops->get_ptr(desc, 1)))
>> +		unmap_single_talitos_ptr(ctx->dev,
>> +					 ctx->desc_ops->get_ptr(desc, 1),
>>   					 DMA_TO_DEVICE);
>>   
>>   	if (edesc->dma_len)
>> @@ -131,7 +133,9 @@ static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
>>   	};
>>   
>>   	pr_err_once("Bug in SEC1, padding ourself\n");
>> -	edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
>> +	ctx->desc_ops->set_hdr(&edesc->desc,
>> +			       ctx->desc_ops->get_hdr(&edesc->desc) &
>> +				       ~DESC_HDR_MODE0_MDEU_PAD);
>>   	map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
>>   			       (char *)padded_hash, DMA_TO_DEVICE);
>>   }
>> @@ -154,7 +158,8 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>>   
>>   	/* hash context in */
>>   	if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) {
>> -		map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
>> +		map_single_talitos_ptr_nosync(dev,
>> +					      ctx->desc_ops->get_ptr(desc, 1),
>>   					      req_ctx->hw_context_size,
>>   					      req_ctx->hw_context,
>>   					      DMA_TO_DEVICE);
>> @@ -165,8 +170,8 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>>   
>>   	/* HMAC key */
>>   	if (ctx->keylen)
>> -		ctx->ptr_ops->to_talitos_ptr(&desc->ptr[2], ctx->dma_key,
>> -					     ctx->keylen);
>> +		ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 2),
>> +					     ctx->dma_key, ctx->keylen);
>>   
>>   	sg_count = edesc->src_nents ?: 1;
>>   	if (is_sec1 && sg_count > 1)
>> @@ -177,8 +182,10 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>>   	/*
>>   	 * data in
>>   	 */
>> -	sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
>> -				  sg_count, 0, 0);
>> +	sg_count = talitos_sg_map(dev, edesc->src, length, edesc,
>> +				  ctx->desc_ops->get_ptr(desc, 3), sg_count, 0,
>> +				  0);
>> +
>>   	if (sg_count > 1)
>>   		sync_needed = true;
>>   
>> @@ -186,19 +193,22 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>>   
>>   	/* hash/HMAC out -or- hash context out */
>>   	if (edesc->last && req_ctx->last_request)
>> -		map_single_talitos_ptr(dev, &desc->ptr[5],
>> +		map_single_talitos_ptr(dev, ctx->desc_ops->get_ptr(desc, 5),
>>   				       crypto_ahash_digestsize(tfm),
>>   				       req_ctx->hw_context, DMA_FROM_DEVICE);
>>   	else
>> -		map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
>> +		map_single_talitos_ptr_nosync(dev,
>> +					      ctx->desc_ops->get_ptr(desc, 5),
>>   					      req_ctx->hw_context_size,
>>   					      req_ctx->hw_context,
>>   					      DMA_FROM_DEVICE);
>>   
>>   	/* last DWORD empty */
>>   
>> -	if (is_sec1 && ctx->ptr_ops->from_talitos_ptr_len(&desc->ptr[3]) == 0)
>> -		talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
>> +	if (is_sec1 && ctx->ptr_ops->from_talitos_ptr_len(
>> +			       ctx->desc_ops->get_ptr(desc, 3)) == 0)
>> +		talitos_handle_buggy_hash(ctx, edesc,
>> +					  ctx->desc_ops->get_ptr(desc, 3));
>>   
>>   	if (sync_needed)
>>   		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
>> @@ -229,6 +239,7 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>>   	size_t to_hash_this_desc;
>>   	struct scatterlist *src;
>>   	size_t offset = 0;
>> +	__be32 hdr;
>>   
>>   	do {
>>   		src = scatterwalk_ffwd(tmp, areq->src, offset);
>> @@ -245,19 +256,19 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>>   		}
>>   
>>   		edesc->src = scatterwalk_ffwd(edesc->bufsl, areq->src, offset);
>> -		edesc->desc.hdr = ctx->desc_hdr_template;
>> +		hdr = ctx->desc_hdr_template;
>>   		edesc->first = offset == 0;
>>   		edesc->last = nbytes - to_hash_this_desc == 0;
>>   
>>   		/* On last one, request SEC to pad; otherwise continue */
>>   		if (req_ctx->last_request && edesc->last)
>> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
>> +			hdr |= DESC_HDR_MODE0_MDEU_PAD;
>>   		else
>> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
>> +			hdr |= DESC_HDR_MODE0_MDEU_CONT;
>>   
>>   		/* request SEC to INIT hash. */
>>   		if (req_ctx->first_request && edesc->first && !req_ctx->swinit)
>> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
>> +			hdr |= DESC_HDR_MODE0_MDEU_INIT;
>>   
>>   		/*
>>   		 * When the tfm context has a keylen, it's an HMAC.
>> @@ -265,11 +276,13 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>>   		 */
>>   		if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
>>   				    (req_ctx->last_request && edesc->last)))
>> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
>> +			hdr |= DESC_HDR_MODE0_MDEU_HMAC;
>>   
>>   		/* clear the DN bit  */
>>   		if (is_sec1 && !edesc->last)
>> -			edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
>> +			hdr &= ~DESC_HDR_DONE_NOTIFY;
>> +
>> +		ctx->desc_ops->set_hdr(&edesc->desc, hdr);
>>   
>>   		common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
>>   
>> diff --git a/drivers/crypto/talitos/talitos-sec1.c b/drivers/crypto/talitos/talitos-sec1.c
>> index ef1bd19b6772..e4f482520372 100644
>> --- a/drivers/crypto/talitos/talitos-sec1.c
>> +++ b/drivers/crypto/talitos/talitos-sec1.c
>> @@ -76,20 +76,20 @@ DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
>>   static void sec1_to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
>>   				unsigned int len)
>>   {
>> -	ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
>> -	ptr->len1 = cpu_to_be16(len);
>> +	ptr->sec1.ptr = cpu_to_be32(lower_32_bits(dma_addr));
>> +	ptr->sec1.len = cpu_to_be16(len);
>>   }
>>   
>>   static void sec1_copy_talitos_ptr(struct talitos_ptr *dst_ptr,
>>   				  struct talitos_ptr *src_ptr)
>>   {
>> -	dst_ptr->ptr = src_ptr->ptr;
>> -	dst_ptr->len1 = src_ptr->len1;
>> +	dst_ptr->sec1.ptr = src_ptr->sec1.ptr;
>> +	dst_ptr->sec1.len = src_ptr->sec1.len;
>>   }
>>   
>>   static unsigned short sec1_from_talitos_ptr_len(struct talitos_ptr *ptr)
>>   {
>> -	return be16_to_cpu(ptr->len1);
>> +	return be16_to_cpu(ptr->sec1.len);
>>   }
>>   
>>   static void sec1_to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val)
>> @@ -100,6 +100,31 @@ static void sec1_to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val)
>>   {
>>   }
>>   
>> +static __be32 sec1_get_ptr_value(struct talitos_ptr *ptr)
>> +{
>> +	return ptr->sec1.ptr;
>> +}
>> +
>> +static __be32 sec1_get_hdr(struct talitos_desc *desc)
>> +{
>> +	return desc->sec1.hdr;
>> +}
>> +
>> +static __be32 sec1_get_hdr_lo(struct talitos_desc *desc)
>> +{
>> +	return 0;
>> +}
>> +
>> +static void sec1_set_hdr(struct talitos_desc *desc, __be32 val)
>> +{
>> +	desc->sec1.hdr = val;
>> +}
>> +
>> +static struct talitos_ptr *sec1_get_ptr(struct talitos_desc *desc, size_t idx)
>> +{
>> +	return (struct talitos_ptr *)&desc->sec1.ptr[idx];
>> +}
>> +
>>   static int sec1_reset_device(struct device *dev)
>>   {
>>   	struct talitos_private *priv = dev_get_drvdata(dev);
>> @@ -163,9 +188,8 @@ static void sec1_dma_map_request(struct device *dev,
>>   	struct talitos_edesc *prev_edesc = NULL;
>>   
>>   	while (edesc) {
>> -		edesc->desc.hdr1 = edesc->desc.hdr;
>>   
>> -		dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
>> +		dma_desc = dma_map_single(dev, &edesc->desc.sec1.hdr,
>>   					  TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>>   
>>   		if (!prev_edesc) {
>> @@ -175,7 +199,7 @@ static void sec1_dma_map_request(struct device *dev,
>>   
>>   		/* Chain in any previous descriptors. */
>>   
>> -		prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
>> +		prev_edesc->desc.sec1.next_desc = cpu_to_be32(dma_desc);
>>   
>>   		dma_sync_single_for_device(dev, prev_dma_desc,
>>   					   TALITOS_DESC_SIZE, DMA_TO_DEVICE);
>> @@ -196,7 +220,7 @@ static void sec1_dma_unmap_request(struct device *dev,
>>   			 DMA_BIDIRECTIONAL);
>>   	edesc = container_of(request->desc, struct talitos_edesc, desc);
>>   	while (edesc->next_desc) {
>> -		dma_unmap_single(dev, be32_to_cpu(edesc->desc.next_desc),
>> +		dma_unmap_single(dev, be32_to_cpu(edesc->desc.sec1.next_desc),
>>   				 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>>   		edesc = edesc->next_desc;
>>   	}
>> @@ -211,14 +235,14 @@ static __be32 sec1_get_request_hdr(struct device *dev,
>>   	edesc = container_of(request->desc, struct talitos_edesc, desc);
>>   	dma_desc = request->dma_desc;
>>   	while (edesc->next_desc) {
>> -		dma_desc = be32_to_cpu(edesc->desc.next_desc);
>> +		dma_desc = be32_to_cpu(edesc->desc.sec1.next_desc);
>>   		edesc = edesc->next_desc;
>>   	}
>>   
>>   	dma_sync_single_for_cpu(dev, dma_desc, TALITOS_DESC_SIZE,
>>   				DMA_BIDIRECTIONAL);
>>   
>> -	return edesc->desc.hdr1;
>> +	return edesc->desc.sec1.hdr;
>>   }
>>   
>>   static __be32 sec1_search_desc_hdr_in_request(struct talitos_request *request,
>> @@ -228,12 +252,12 @@ static __be32 sec1_search_desc_hdr_in_request(struct talitos_request *request,
>>   
>>   
>>   	if (request->dma_desc == cur_desc)
>> -		return request->desc->hdr;
>> +		return request->desc->sec1.hdr;
>>   
>>   	edesc = container_of(request->desc, struct talitos_edesc, desc);
>>   	while (edesc->next_desc) {
>> -		if (edesc->desc.next_desc == cpu_to_be32(cur_desc))
>> -			return edesc->next_desc->desc.hdr1;
>> +		if (edesc->desc.sec1.next_desc == cpu_to_be32(cur_desc))
>> +			return edesc->next_desc->desc.sec1.hdr;
>>   		edesc = edesc->next_desc;
>>   	}
>>   
>> @@ -319,6 +343,14 @@ static const struct talitos_ptr_ops sec1_ptr_ops = {
>>   	.from_talitos_ptr_len = sec1_from_talitos_ptr_len,
>>   	.to_talitos_ptr_ext_set = sec1_to_talitos_ptr_ext_set,
>>   	.to_talitos_ptr_ext_or = sec1_to_talitos_ptr_ext_or,
>> +	.get_ptr_value = sec1_get_ptr_value,
>> +};
>> +
>> +static const struct talitos_desc_ops sec1_desc_ops = {
>> +	.set_hdr = sec1_set_hdr,
>> +	.get_hdr = sec1_get_hdr,
>> +	.get_hdr_lo = sec1_get_hdr_lo,
>> +	.get_ptr = sec1_get_ptr,
>>   };
>>   
>>   static const struct talitos_ops sec1_ops = {
>> @@ -337,5 +369,6 @@ static const struct talitos_ops sec1_ops = {
>>   void talitos_register_sec1(struct talitos_private *priv)
>>   {
>>   	priv->ops = &sec1_ops;
>> +	priv->desc_ops = &sec1_desc_ops;
>>   	priv->ptr_ops = &sec1_ptr_ops;
>>   }
>> diff --git a/drivers/crypto/talitos/talitos-sec2.c b/drivers/crypto/talitos/talitos-sec2.c
>> index 14f0ca13e6e5..52f783ddc8b6 100644
>> --- a/drivers/crypto/talitos/talitos-sec2.c
>> +++ b/drivers/crypto/talitos/talitos-sec2.c
>> @@ -82,32 +82,57 @@ DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
>>   static void sec2_to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
>>   				unsigned int len)
>>   {
>> -	ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
>> -	ptr->len = cpu_to_be16(len);
>> -	ptr->eptr = upper_32_bits(dma_addr);
>> +	ptr->sec2.ptr = cpu_to_be32(lower_32_bits(dma_addr));
>> +	ptr->sec2.len = cpu_to_be16(len);
>> +	ptr->sec2.eptr = upper_32_bits(dma_addr);
>>   }
>>   
>>   static void sec2_copy_talitos_ptr(struct talitos_ptr *dst_ptr,
>>   				  struct talitos_ptr *src_ptr)
>>   {
>> -	dst_ptr->ptr = src_ptr->ptr;
>> -	dst_ptr->len = src_ptr->len;
>> -	dst_ptr->eptr = src_ptr->eptr;
>> +	dst_ptr->sec2.ptr = src_ptr->sec2.ptr;
>> +	dst_ptr->sec2.len = src_ptr->sec2.len;
>> +	dst_ptr->sec2.eptr = src_ptr->sec2.eptr;
>>   }
>>   
>>   static unsigned short sec2_from_talitos_ptr_len(struct talitos_ptr *ptr)
>>   {
>> -	return be16_to_cpu(ptr->len);
>> +	return be16_to_cpu(ptr->sec2.len);
>>   }
>>   
>>   static void sec2_to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val)
>>   {
>> -	ptr->j_extent = val;
>> +	ptr->sec2.j_extent = val;
>>   }
>>   
>>   static void sec2_to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val)
>>   {
>> -	ptr->j_extent |= val;
>> +	ptr->sec2.j_extent |= val;
>> +}
>> +
>> +static __be32 sec2_get_ptr_value(struct talitos_ptr *ptr)
>> +{
>> +	return ptr->sec2.ptr;
>> +}
>> +
>> +static __be32 sec2_get_hdr(struct talitos_desc *desc)
>> +{
>> +	return desc->sec2.hdr;
>> +}
>> +
>> +static __be32 sec2_get_hdr_lo(struct talitos_desc *desc)
>> +{
>> +	return desc->sec2.hdr_lo;
>> +}
>> +
>> +static void sec2_set_hdr(struct talitos_desc *desc, __be32 val)
>> +{
>> +	desc->sec2.hdr = val;
>> +}
>> +
>> +static struct talitos_ptr *sec2_get_ptr(struct talitos_desc *desc, size_t idx)
>> +{
>> +	return (struct talitos_ptr *)&desc->sec2.ptr[idx];
>>   }
>>   
>>   static int sec2_reset_channel(struct device *dev, int ch)
>> @@ -331,14 +356,14 @@ static __be32 sec2_get_request_hdr(struct device *dev,
>>   	dma_sync_single_for_cpu(dev, request->dma_desc, TALITOS_DESC_SIZE,
>>   				DMA_BIDIRECTIONAL);
>>   
>> -	return request->desc->hdr;
>> +	return request->desc->sec2.hdr;
>>   }
>>   
>>   static __be32 sec2_search_desc_hdr_in_request(struct talitos_request *request,
>>   					      dma_addr_t cur_desc)
>>   {
>>   	if (request->dma_desc == cur_desc)
>> -		return request->desc->hdr;
>> +		return request->desc->sec2.hdr;
>>   	return 0;
>>   }
>>   
>> @@ -348,6 +373,14 @@ static const struct talitos_ptr_ops sec2_ptr_ops = {
>>   	.from_talitos_ptr_len = sec2_from_talitos_ptr_len,
>>   	.to_talitos_ptr_ext_set = sec2_to_talitos_ptr_ext_set,
>>   	.to_talitos_ptr_ext_or = sec2_to_talitos_ptr_ext_or,
>> +	.get_ptr_value = sec2_get_ptr_value,
>> +};
>> +
>> +static const struct talitos_desc_ops sec2_desc_ops = {
>> +	.set_hdr = sec2_set_hdr,
>> +	.get_hdr = sec2_get_hdr,
>> +	.get_hdr_lo = sec2_get_hdr_lo,
>> +	.get_ptr = sec2_get_ptr,
>>   };
>>   
>>   static const struct talitos_ops sec2_ops = {
>> @@ -366,5 +399,6 @@ static const struct talitos_ops sec2_ops = {
>>   void talitos_register_sec2(struct talitos_private *priv)
>>   {
>>   	priv->ops = &sec2_ops;
>> +	priv->desc_ops = &sec2_desc_ops;
>>   	priv->ptr_ops = &sec2_ptr_ops;
>>   }
>> diff --git a/drivers/crypto/talitos/talitos-skcipher.c b/drivers/crypto/talitos/talitos-skcipher.c
>> index a96f827c7b93..58ad931ff3a4 100644
>> --- a/drivers/crypto/talitos/talitos-skcipher.c
>> +++ b/drivers/crypto/talitos/talitos-skcipher.c
>> @@ -11,17 +11,21 @@
>>   
>>   #include "talitos.h"
>>   
>> -static void common_nonsnoop_unmap(struct device *dev,
>> +static void common_nonsnoop_unmap(struct talitos_ctx *ctx,
>>   				  struct talitos_edesc *edesc,
>>   				  struct skcipher_request *areq)
>>   {
>> -	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
>> +	unmap_single_talitos_ptr(ctx->dev,
>> +				 ctx->desc_ops->get_ptr(&edesc->desc, 5),
>> +				 DMA_FROM_DEVICE);
>>   
>> -	talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen, 0);
>> -	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
>> +	talitos_sg_unmap(ctx->dev, edesc, areq->src, areq->dst, areq->cryptlen, 0);
>> +	unmap_single_talitos_ptr(ctx->dev,
>> +				 ctx->desc_ops->get_ptr(&edesc->desc, 1),
>> +				 DMA_TO_DEVICE);
>>   
>>   	if (edesc->dma_len)
>> -		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
>> +		dma_unmap_single(ctx->dev, edesc->dma_link_tbl, edesc->dma_len,
>>   				 DMA_BIDIRECTIONAL);
>>   }
>>   
>> @@ -37,7 +41,7 @@ static void skcipher_done(struct device *dev,
>>   
>>   	edesc = container_of(desc, struct talitos_edesc, desc);
>>   
>> -	common_nonsnoop_unmap(dev, edesc, areq);
>> +	common_nonsnoop_unmap(ctx, edesc, areq);
>>   	memcpy(areq->iv, ctx->iv, ivsize);
>>   
>>   	kfree(edesc);
>> @@ -61,16 +65,18 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
>>   	bool sync_needed = false;
>>   	struct talitos_private *priv = dev_get_drvdata(dev);
>>   	bool is_sec1 = has_ftr_sec1(priv);
>> -	bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU &&
>> -		      (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
>> +	bool is_ctr = (ctx->desc_ops->get_hdr(desc) & DESC_HDR_SEL0_MASK) ==
>> +			      DESC_HDR_SEL0_AESU &&
>> +		      (ctx->desc_ops->get_hdr(desc) &
>> +		       DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
>>   
>>   	/* first DWORD empty */
>>   
>>   	/* cipher iv */
>> -	ctx->ptr_ops->to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize);
>> +	ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 1), edesc->iv_dma, ivsize);
>>   
>>   	/* cipher key */
>> -	ctx->ptr_ops->to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen);
>> +	ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 2), ctx->dma_key, ctx->keylen);
>>   
>>   	sg_count = edesc->src_nents ?: 1;
>>   	if (is_sec1 && sg_count > 1)
>> @@ -83,8 +89,9 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
>>   	/*
>>   	 * cipher in
>>   	 */
>> -	sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3],
>> -				      sg_count, 0, 0, 0, false, is_ctr ? 16 : 1);
>> +	sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc,
>> +				      ctx->desc_ops->get_ptr(desc, 3), sg_count,
>> +				      0, 0, 0, false, is_ctr ? 16 : 1);
>>   	if (sg_count > 1)
>>   		sync_needed = true;
>>   
>> @@ -95,14 +102,15 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
>>   			dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
>>   	}
>>   
>> -	ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
>> -			     sg_count, 0, (edesc->src_nents + 1));
>> +	ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc,
>> +			     ctx->desc_ops->get_ptr(desc, 4), sg_count, 0,
>> +			     (edesc->src_nents + 1));
>>   	if (ret > 1)
>>   		sync_needed = true;
>>   
>>   	/* iv out */
>> -	map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
>> -			       DMA_FROM_DEVICE);
>> +	map_single_talitos_ptr(dev, ctx->desc_ops->get_ptr(desc, 5), ivsize,
>> +			       ctx->iv, DMA_FROM_DEVICE);
>>   
>>   	/* last DWORD empty */
>>   
>> @@ -112,7 +120,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
>>   
>>   	ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
>>   	if (ret != -EINPROGRESS) {
>> -		common_nonsnoop_unmap(dev, edesc, areq);
>> +		common_nonsnoop_unmap(ctx, edesc, areq);
>>   		kfree(edesc);
>>   	}
>>   	return ret;
>> @@ -191,7 +199,7 @@ static int skcipher_encrypt(struct skcipher_request *areq)
>>   		return PTR_ERR(edesc);
>>   
>>   	/* set encrypt */
>> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
>> +	ctx->desc_ops->set_hdr(&edesc->desc, ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT);
>>   
>>   	return common_nonsnoop(edesc, areq, skcipher_done);
>>   }
>> @@ -215,7 +223,7 @@ static int skcipher_decrypt(struct skcipher_request *areq)
>>   	if (IS_ERR(edesc))
>>   		return PTR_ERR(edesc);
>>   
>> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
>> +	ctx->desc_ops->set_hdr(&edesc->desc, ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND);
>>   
>>   	return common_nonsnoop(edesc, areq, skcipher_done);
>>   }
>> diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
>> index 19e63ce6cc3e..a032907e900f 100644
>> --- a/drivers/crypto/talitos/talitos.c
>> +++ b/drivers/crypto/talitos/talitos.c
>> @@ -81,7 +81,7 @@ void unmap_single_talitos_ptr(struct device *dev,
>>   {
>>   	struct talitos_private *priv = dev_get_drvdata(dev);
>>   
>> -	dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
>> +	dma_unmap_single(dev, be32_to_cpu(priv->ptr_ops->get_ptr_value(ptr)),
>>   			 priv->ptr_ops->from_talitos_ptr_len(ptr), dir);
>>   }
>>   
>> @@ -625,6 +625,8 @@ int talitos_init_common(struct talitos_ctx *ctx,
>>   
>>   	ctx->ptr_ops = priv->ptr_ops;
>>   
>> +	ctx->desc_ops = priv->desc_ops;
>> +
>>   	return 0;
>>   }
>>   
>> diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
>> index 54e33da03fd0..2107fb1ade5d 100644
>> --- a/drivers/crypto/talitos/talitos.h
>> +++ b/drivers/crypto/talitos/talitos.h
>> @@ -36,33 +36,49 @@
>>   #define TALITOS_MAX_IV_LENGTH		16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
>>   
>>   /* descriptor pointer entry */
>> +
>> +struct sec1_talitos_ptr {
>> +	__be16 res;
>> +	__be16 len;
>> +	__be32 ptr;
>> +} __packed;
>> +
>> +struct sec2_talitos_ptr {
>> +	__be16 len;
>> +	u8 j_extent;
>> +	u8 eptr;
>> +	__be32 ptr;
>> +} __packed;
>> +
>>   struct talitos_ptr {
>>   	union {
>> -		struct {		/* SEC2 format */
>> -			__be16 len;     /* length */
>> -			u8 j_extent;    /* jump to sg link table and/or extent*/
>> -			u8 eptr;        /* extended address */
>> -		};
>> -		struct {			/* SEC1 format */
>> -			__be16 res;
>> -			__be16 len1;	/* length */
>> -		};
>> +		struct sec1_talitos_ptr sec1;
>> +		struct sec2_talitos_ptr sec2;
>>   	};
>> -	__be32 ptr;     /* address */
>>   };
>>   
>> -/* descriptor */
>> +/* descriptor format */
>> +
>> +struct sec1_talitos_desc {
>> +	__be32 hdr;
>> +	struct sec1_talitos_ptr ptr[7];
>> +	__be32 next_desc;
>> +} __packed;
>> +
>> +struct sec2_talitos_desc {
>> +	__be32 hdr;
>> +	__be32 hdr_lo;
>> +	struct sec2_talitos_ptr ptr[7];
>> +} __packed;
>> +
>>   struct talitos_desc {
>> -	__be32 hdr;                     /* header high bits */
>>   	union {
>> -		__be32 hdr_lo;		/* header low bits */
>> -		__be32 hdr1;		/* header for SEC1 */
>> +		struct sec1_talitos_desc sec1;
>> +		struct sec2_talitos_desc sec2;
>>   	};
>> -	struct talitos_ptr ptr[7];      /* ptr/len pair array */
>> -	__be32 next_desc;		/* next descriptor (SEC1) */
>>   };
>>   
>> -#define TALITOS_DESC_SIZE	(sizeof(struct talitos_desc) - sizeof(__be32))
>> +#define TALITOS_DESC_SIZE	sizeof(struct talitos_desc)
>>   
>>   /*
>>    * talitos_edesc - s/w-extended descriptor
>> @@ -148,6 +164,14 @@ struct talitos_ptr_ops {
>>   	unsigned short (*from_talitos_ptr_len)(struct talitos_ptr *ptr);
>>   	void (*to_talitos_ptr_ext_set)(struct talitos_ptr *ptr, u8 val);
>>   	void (*to_talitos_ptr_ext_or)(struct talitos_ptr *ptr, u8 val);
>> +	__be32 (*get_ptr_value)(struct talitos_ptr *ptr);
>> +};
>> +
>> +struct talitos_desc_ops {
>> +	void (*set_hdr)(struct talitos_desc *desc, __be32 val);
>> +	__be32 (*get_hdr)(struct talitos_desc *desc);
>> +	__be32 (*get_hdr_lo)(struct talitos_desc *desc);
>> +	struct talitos_ptr *(*get_ptr)(struct talitos_desc *desc, size_t idx);
>>   };
>>   
>>   struct talitos_ops {
>> @@ -194,6 +218,7 @@ struct talitos_private {
>>   
>>   	const struct talitos_ops *ops;
>>   	const struct talitos_ptr_ops *ptr_ops;
>> +	const struct talitos_desc_ops *desc_ops;
>>   
>>   	/* SEC Compatibility info */
>>   	unsigned long features;
>> @@ -225,6 +250,7 @@ struct talitos_private {
>>   struct talitos_ctx {
>>   	struct device *dev;
>>   	const struct talitos_ptr_ops *ptr_ops;
>> +	const struct talitos_desc_ops *desc_ops;
>>   	int ch;
>>   	__be32 desc_hdr_template;
>>   	u8 key[TALITOS_MAX_KEY_SIZE];
>> 




-- 
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH 18/29] crypto: talitos - Split SEC1/SEC2 code into separate function variants
From: Paul Louvel @ 2026-06-04 12:46 UTC (permalink / raw)
  To: Christophe Leroy (CS GROUP), Paul Louvel, Herbert Xu,
	David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <d998ea38-8770-468f-bfdd-9bb4c34e54a7@kernel.org>

On Mon Jun 1, 2026 at 2:32 PM CEST, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 28/05/2026 à 11:08, Paul Louvel a écrit :
>> Split the functions that have SEC1/SEC2-specific behavior into
>> separate sec1_ and sec2_ function variants, removing the runtime
>> is_sec1 checks from within each function body.
>
> Regarding naming, I would prefer prefixing with talitos1_ and talitos2_ 
> to stick with the already existing naming we already have today:
> - talitos1_done_ch0
> - talitos1_done_4ch
> - talitos1_interrupt_4ch,
> - talitos2_done_ch0_2,
> - talitos2_done_ch1_3,
> - talitos2_done_ch0,
> - talitos2_done_4ch,
> - talitos2_interrupt_4ch,
> - talitos2_interrupt_ch0_2,
> - talitos2_interrupt_ch1_3,
>
> Christophe
>

Understood.

>> 
>> The callers still dispatch between the two variants using local
>> is_sec1 variables and if/else checks.
>> 
>> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
>> ---
>>   drivers/crypto/talitos/talitos.c | 524 +++++++++++++++++++++++++--------------
>>   drivers/crypto/talitos/talitos.h |  36 ++-
>>   2 files changed, 357 insertions(+), 203 deletions(-)
>> 
>> diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
>> index f38a156a0459..b6793d97735e 100644
>> --- a/drivers/crypto/talitos/talitos.c
>> +++ b/drivers/crypto/talitos/talitos.c
>> @@ -133,75 +133,124 @@ void unmap_single_talitos_ptr(struct device *dev,
>>   			 from_talitos_ptr_len(ptr, is_sec1), dir);
>>   }
>>   
>> -static int reset_channel(struct device *dev, int ch)
>> +static int sec1_reset_channel(struct device *dev, int ch)
>>   {
>>   	struct talitos_private *priv = dev_get_drvdata(dev);
>>   	unsigned int timeout = TALITOS_TIMEOUT;
>> -	bool is_sec1 = has_ftr_sec1(priv);
>>   
>> -	if (is_sec1) {
>> -		setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
>> -			  TALITOS1_CCCR_LO_RESET);
>> +	setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS1_CCCR_LO_RESET);
>>   
>> -		while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) &
>> -			TALITOS1_CCCR_LO_RESET) && --timeout)
>> -			cpu_relax();
>> -	} else {
>> -		setbits32(priv->chan[ch].reg + TALITOS_CCCR,
>> -			  TALITOS2_CCCR_RESET);
>> +	while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) &
>> +		TALITOS1_CCCR_LO_RESET) &&
>> +	       --timeout)
>> +		cpu_relax();
>>   
>> -		while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
>> -			TALITOS2_CCCR_RESET) && --timeout)
>> -			cpu_relax();
>> +	if (timeout == 0) {
>> +		dev_err(dev, "failed to reset sec1 channel %d\n", ch);
>> +		return -EIO;
>>   	}
>>   
>> +	setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
>> +		  TALITOS_CCCR_LO_NE | TALITOS_CCCR_LO_CDIE |
>> +			  TALITOS_CCCR_LO_CDWE);
>> +
>> +	return 0;
>> +}
>> +
>> +static int sec2_reset_channel(struct device *dev, int ch)
>> +{
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +	unsigned int timeout = TALITOS_TIMEOUT;
>> +
>> +	setbits32(priv->chan[ch].reg + TALITOS_CCCR, TALITOS2_CCCR_RESET);
>> +
>> +	while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
>> +		TALITOS2_CCCR_RESET) &&
>> +	       --timeout)
>> +		cpu_relax();
>> +
>>   	if (timeout == 0) {
>> -		dev_err(dev, "failed to reset channel %d\n", ch);
>> +		dev_err(dev, "failed to reset sec2 channel %d\n", ch);
>>   		return -EIO;
>>   	}
>>   
>> -	/* set 36-bit addressing, done writeback enable and done IRQ enable */
>> -	setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
>> -		  TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
>> -	/* enable chaining descriptors */
>> -	if (is_sec1)
>> -		setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
>> -			  TALITOS_CCCR_LO_NE);
>> +	setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
>> +		  TALITOS_CCCR_LO_EAE | TALITOS_CCCR_LO_CDWE |
>> +			  TALITOS_CCCR_LO_CDIE);
>>   
>> -	/* and ICCR writeback, if available */
>> +	/* ICCR writeback, if available */
>>   	if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
>>   		setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
>> -		          TALITOS_CCCR_LO_IWSE);
>> +			  TALITOS_CCCR_LO_IWSE);
>>   
>>   	return 0;
>>   }
>>   
>> -static int reset_device(struct device *dev)
>> +static int sec1_reset_device(struct device *dev)
>>   {
>>   	struct talitos_private *priv = dev_get_drvdata(dev);
>>   	unsigned int timeout = TALITOS_TIMEOUT;
>> -	bool is_sec1 = has_ftr_sec1(priv);
>> -	u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
>>   
>> -	setbits32(priv->reg + TALITOS_MCR, mcr);
>> +	setbits32(priv->reg + TALITOS_MCR, TALITOS1_MCR_SWR);
>>   
>> -	while ((in_be32(priv->reg + TALITOS_MCR) & mcr)
>> -	       && --timeout)
>> +	while ((in_be32(priv->reg + TALITOS_MCR) & TALITOS1_MCR_SWR) &&
>> +	       --timeout)
>>   		cpu_relax();
>>   
>> -	if (priv->irq[1]) {
>> -		mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
>> -		setbits32(priv->reg + TALITOS_MCR, mcr);
>> +	if (timeout == 0) {
>> +		dev_err(dev, "failed to reset sec1 device\n");
>> +		return -EIO;
>>   	}
>>   
>> +	return 0;
>> +}
>> +
>> +static int sec2_reset_device(struct device *dev)
>> +{
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +	unsigned int timeout = TALITOS_TIMEOUT;
>> +
>> +	setbits32(priv->reg + TALITOS_MCR, TALITOS2_MCR_SWR);
>> +
>> +	while ((in_be32(priv->reg + TALITOS_MCR) & TALITOS2_MCR_SWR) &&
>> +	       --timeout)
>> +		cpu_relax();
>> +
>> +	if (priv->irq[1])
>> +		setbits32(priv->reg + TALITOS_MCR,
>> +			  TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3);
>> +
>>   	if (timeout == 0) {
>> -		dev_err(dev, "failed to reset device\n");
>> +		dev_err(dev, "failed to reset sec2 device\n");
>>   		return -EIO;
>>   	}
>>   
>>   	return 0;
>>   }
>>   
>> +static void sec1_configure_device(struct device *dev)
>> +{
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +
>> +	clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
>> +	clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
>> +	/* disable parity error check in DEU (erroneous? test vect.) */
>> +	setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
>> +}
>> +
>> +static void sec2_configure_device(struct device *dev)
>> +{
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +
>> +	setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
>> +	setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
>> +
>> +	/* disable integrity check error interrupts (use writeback instead) */
>> +	if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
>> +		setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
>> +			  TALITOS_MDEUICR_LO_ICE);
>> +}
>> +
>>   /*
>>    * Reset and initialize the device
>>    */
>> @@ -217,80 +266,81 @@ static int init_device(struct device *dev)
>>   	 * are not fully cleared by writing the MCR:SWR bit,
>>   	 * set bit twice to completely reset
>>   	 */
>> -	err = reset_device(dev);
>> +	if (is_sec1)
>> +		err = sec1_reset_device(dev);
>> +	else
>> +		err = sec2_reset_device(dev);
>> +
>>   	if (err)
>>   		return err;
>>   
>> -	err = reset_device(dev);
>> +	if (is_sec1)
>> +		err = sec1_reset_device(dev);
>> +	else
>> +		err = sec2_reset_device(dev);
>>   	if (err)
>>   		return err;
>>   
>>   	/* reset channels */
>>   	for (ch = 0; ch < priv->num_channels; ch++) {
>> -		err = reset_channel(dev, ch);
>> +		if (is_sec1)
>> +			err = sec1_reset_channel(dev, ch);
>> +		else
>> +			err = sec2_reset_channel(dev, ch);
>>   		if (err)
>>   			return err;
>>   	}
>>   
>> -	/* enable channel done and error interrupts */
>> -	if (is_sec1) {
>> -		clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
>> -		clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
>> -		/* disable parity error check in DEU (erroneous? test vect.) */
>> -		setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
>> -	} else {
>> -		setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
>> -		setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
>> -	}
>> -
>> -	/* disable integrity check error interrupts (use writeback instead) */
>> -	if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
>> -		setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
>> -		          TALITOS_MDEUICR_LO_ICE);
>> +	if (is_sec1)
>> +		sec1_configure_device(dev);
>> +	else
>> +		sec2_configure_device(dev);
>>   
>>   	return 0;
>>   }
>>   
>> -static void dma_map_request(struct device *dev, struct talitos_request *request,
>> -			    struct talitos_desc *desc, bool is_sec1)
>> +static void sec1_dma_map_request(struct device *dev,
>> +				 struct talitos_request *request,
>> +				 struct talitos_desc *desc)
>>   {
>>   	struct talitos_edesc *edesc =
>>   		container_of(desc, struct talitos_edesc, desc);
>>   	dma_addr_t dma_desc, prev_dma_desc;
>>   	struct talitos_edesc *prev_edesc = NULL;
>>   
>> -	if (is_sec1) {
>> -		while (edesc) {
>> -			edesc->desc.hdr1 = edesc->desc.hdr;
>> +	while (edesc) {
>> +		edesc->desc.hdr1 = edesc->desc.hdr;
>>   
>> -			dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
>> -						  TALITOS_DESC_SIZE,
>> -						  DMA_BIDIRECTIONAL);
>> +		dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
>> +					  TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>>   
>> -			if (!prev_edesc) {
>> -				request->dma_desc = dma_desc;
>> -				goto next;
>> -			}
>> +		if (!prev_edesc) {
>> +			request->dma_desc = dma_desc;
>> +			goto next;
>> +		}
>>   
>> -			/* Chain in any previous descriptors. */
>> +		/* Chain in any previous descriptors. */
>>   
>> -			prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
>> +		prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
>>   
>> -			dma_sync_single_for_device(dev, prev_dma_desc,
>> -						   TALITOS_DESC_SIZE,
>> -						   DMA_TO_DEVICE);
>> +		dma_sync_single_for_device(dev, prev_dma_desc,
>> +					   TALITOS_DESC_SIZE, DMA_TO_DEVICE);
>>   
>>   next:
>> -			prev_edesc = edesc;
>> -			prev_dma_desc = dma_desc;
>> -			edesc = edesc->next_desc;
>> -		}
>> -	} else {
>> -		request->dma_desc = dma_map_single(dev, desc, TALITOS_DESC_SIZE,
>> -						   DMA_BIDIRECTIONAL);
>> +		prev_edesc = edesc;
>> +		prev_dma_desc = dma_desc;
>> +		edesc = edesc->next_desc;
>>   	}
>>   }
>>   
>> +static void sec2_dma_map_request(struct device *dev,
>> +				 struct talitos_request *request,
>> +				 struct talitos_desc *desc)
>> +{
>> +	request->dma_desc =
>> +		dma_map_single(dev, desc, TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>> +}
>> +
>>   /**
>>    * talitos_submit - submits a descriptor to the device for processing
>>    * @dev:	the SEC device to be used
>> @@ -327,7 +377,10 @@ int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
>>   	request = &priv->chan[ch].fifo[head];
>>   
>>   	/* map descriptor and save caller data */
>> -	dma_map_request(dev, request, desc, is_sec1);
>> +	if (is_sec1)
>> +		sec1_dma_map_request(dev, request, desc);
>> +	else
>> +		sec2_dma_map_request(dev, request, desc);
>>   	request->callback = callback;
>>   	request->context = context;
>>   
>> @@ -349,19 +402,12 @@ int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
>>   	return -EINPROGRESS;
>>   }
>>   
>> -static __be32 get_request_hdr(struct device *dev,
>> -			      struct talitos_request *request, bool is_sec1)
>> +static __be32 sec1_get_request_hdr(struct device *dev,
>> +				   struct talitos_request *request)
>>   {
>>   	struct talitos_edesc *edesc;
>>   	dma_addr_t dma_desc;
>>   
>> -	if (!is_sec1) {
>> -		dma_sync_single_for_cpu(dev, request->dma_desc,
>> -					TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>> -
>> -		return request->desc->hdr;
>> -	}
>> -
>>   	edesc = container_of(request->desc, struct talitos_edesc, desc);
>>   	dma_desc = request->dma_desc;
>>   	while (edesc->next_desc) {
>> @@ -375,27 +421,37 @@ static __be32 get_request_hdr(struct device *dev,
>>   	return edesc->desc.hdr1;
>>   }
>>   
>> -static void dma_unmap_request(struct device *dev,
>> -			      struct talitos_request *request, bool is_sec1)
>> +static __be32 sec2_get_request_hdr(struct device *dev,
>> +				   struct talitos_request *request)
>> +{
>> +	dma_sync_single_for_cpu(dev, request->dma_desc, TALITOS_DESC_SIZE,
>> +				DMA_BIDIRECTIONAL);
>> +
>> +	return request->desc->hdr;
>> +}
>> +
>> +static void sec1_dma_unmap_request(struct device *dev,
>> +				   struct talitos_request *request)
>>   {
>>   	struct talitos_edesc *edesc;
>>   
>> -	if (is_sec1) {
>> -		dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
>> -				 DMA_BIDIRECTIONAL);
>> -		edesc = container_of(request->desc, struct talitos_edesc, desc);
>> -		while (edesc->next_desc) {
>> -			dma_unmap_single(dev,
>> -					 be32_to_cpu(edesc->desc.next_desc),
>> -					 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>> -			edesc = edesc->next_desc;
>> -		}
>> -	} else {
>> -		dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
>> -				 DMA_BIDIRECTIONAL);
>> +	dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
>> +			 DMA_BIDIRECTIONAL);
>> +	edesc = container_of(request->desc, struct talitos_edesc, desc);
>> +	while (edesc->next_desc) {
>> +		dma_unmap_single(dev, be32_to_cpu(edesc->desc.next_desc),
>> +				 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>> +		edesc = edesc->next_desc;
>>   	}
>>   }
>>   
>> +static void sec2_dma_unmap_request(struct device *dev,
>> +				   struct talitos_request *request)
>> +{
>> +	dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
>> +			 DMA_BIDIRECTIONAL);
>> +}
>> +
>>   /*
>>    * process what was done, notify callback of error if not
>>    */
>> @@ -417,7 +473,10 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
>>   
>>   		/* descriptors with their done bits set don't get the error */
>>   		rmb();
>> -		hdr = get_request_hdr(dev, request, is_sec1);
>> +		if (is_sec1)
>> +			hdr = sec1_get_request_hdr(dev, request);
>> +		else
>> +			hdr = sec2_get_request_hdr(dev, request);
>>   
>>   		if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
>>   			status = 0;
>> @@ -427,7 +486,10 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
>>   			else
>>   				status = error;
>>   
>> -		dma_unmap_request(dev, request, is_sec1);
>> +		if (is_sec1)
>> +			sec1_dma_unmap_request(dev, request);
>> +		else
>> +			sec2_dma_unmap_request(dev, request);
>>   
>>   		/* copy entries so we can call callback outside lock */
>>   		saved_req.desc = request->desc;
>> @@ -516,21 +578,30 @@ DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
>>   DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
>>   DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
>>   
>> -static __be32 search_desc_hdr_in_request(struct talitos_request *request,
>> -					 dma_addr_t cur_desc, bool is_sec1)
>> +static __be32 sec1_search_desc_hdr_in_request(struct talitos_request *request,
>> +					      dma_addr_t cur_desc)
>>   {
>>   	struct talitos_edesc *edesc;
>>   
>> -	if (request->dma_desc == cur_desc) {
>> +
>> +	if (request->dma_desc == cur_desc)
>>   		return request->desc->hdr;
>> -	} else if (is_sec1) {
>> -		edesc = container_of(request->desc, struct talitos_edesc, desc);
>> -		while (edesc->next_desc) {
>> -			if (edesc->desc.next_desc == cpu_to_be32(cur_desc))
>> -				return edesc->next_desc->desc.hdr1;
>> -			edesc = edesc->next_desc;
>> -		}
>> +
>> +	edesc = container_of(request->desc, struct talitos_edesc, desc);
>> +	while (edesc->next_desc) {
>> +		if (edesc->desc.next_desc == cpu_to_be32(cur_desc))
>> +			return edesc->next_desc->desc.hdr1;
>> +		edesc = edesc->next_desc;
>>   	}
>> +
>> +	return 0;
>> +}
>> +
>> +static __be32 sec2_search_desc_hdr_in_request(struct talitos_request *request,
>> +					      dma_addr_t cur_desc)
>> +{
>> +	if (request->dma_desc == cur_desc)
>> +		return request->desc->hdr;
>>   	return 0;
>>   }
>>   
>> @@ -559,7 +630,10 @@ static __be32 current_desc_hdr(struct device *dev, int ch)
>>   	do {
>>   		request = &priv->chan[ch].fifo[iter];
>>   
>> -		hdr = search_desc_hdr_in_request(request, cur_desc, is_sec1);
>> +		if (is_sec1)
>> +			hdr = sec1_search_desc_hdr_in_request(request, cur_desc);
>> +		else
>> +			hdr = sec2_search_desc_hdr_in_request(request, cur_desc);
>>   		if (hdr)
>>   			break;
>>   
>> @@ -647,79 +721,100 @@ static void report_eu_error(struct device *dev, int ch, __be32 desc_hdr)
>>   			in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
>>   }
>>   
>> -/*
>> - * recover from error interrupts
>> - */
>> -static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
>> +static int sec1_talitos_handle_error(struct device *dev, u32 isr, u32 isr_lo)
>> +{
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +	int ch, error;
>> +	u32 v_lo;
>> +
>> +	for (ch = 0; ch < priv->num_channels; ch++) {
>> +		if (!TALITOS1_CH_HAS_ERROR(isr, ch))
>> +			continue;
>> +
>> +		v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
>> +
>> +		error = -EINVAL;
>> +
>> +		if (v_lo & TALITOS1_CCPSR_LO_TEA)
>> +			dev_err(dev, "transfer error acknowledge\n");
>> +		if (v_lo & TALITOS1_CCPSR_LO_PTRNC)
>> +			dev_err(dev, "pointer not complete error\n");
>> +		if (v_lo & TALITOS1_CCPSR_LO_PE)
>> +			dev_err(dev, "parity error\n");
>> +		if (v_lo & TALITOS1_CCPSR_LO_IDH)
>> +			dev_err(dev, "illegal descriptor header error\n");
>> +		if (v_lo & TALITOS1_CCPSR_LO_SA)
>> +			dev_err(dev, "static assignment error\n");
>> +		if (v_lo & TALITOS1_CCPSR_LO_EU)
>> +			report_eu_error(dev, ch, current_desc_hdr(dev, ch));
>> +
>> +		flush_channel(dev, ch, error, 1);
>> +		priv->ops->reset_channel(dev, ch);
>> +	}
>> +
>> +	if (isr_lo & TALITOS1_ISR_TEA_ERR)
>> +		dev_err(dev, "TEA error: ISR 0x%08x_%08x\n", isr, isr_lo);
>> +
>> +	return (isr & ~TALITOS1_ISR_4CHERR) || isr_lo;
>> +}
>> +
>> +static int sec2_talitos_handle_error(struct device *dev, u32 isr, u32 isr_lo)
>>   {
>>   	struct talitos_private *priv = dev_get_drvdata(dev);
>>   	unsigned int timeout = TALITOS_TIMEOUT;
>>   	int ch, error, reset_dev = 0;
>>   	u32 v_lo;
>> -	bool is_sec1 = has_ftr_sec1(priv);
>> -	int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */
>> +	int reset_ch = 0;
>>   
>>   	for (ch = 0; ch < priv->num_channels; ch++) {
>> -		/* skip channels without errors */
>> -		if (is_sec1) {
>> -			/* bits 29, 31, 17, 19 */
>> -			if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
>> -				continue;
>> -		} else {
>> -			if (!(isr & (1 << (ch * 2 + 1))))
>> -				continue;
>> -		}
>> +		if (!TALITOS2_CH_HAS_ERROR(isr, ch))
>> +			continue;
>>   
>>   		error = -EINVAL;
>>   
>>   		v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
>>   
>> -		if (v_lo & TALITOS_CCPSR_LO_DOF) {
>> +		if (v_lo & TALITOS2_CCPSR_LO_DOF) {
>>   			dev_err(dev, "double fetch fifo overflow error\n");
>>   			error = -EAGAIN;
>>   			reset_ch = 1;
>>   		}
>> -		if (v_lo & TALITOS_CCPSR_LO_SOF) {
>> +		if (v_lo & TALITOS2_CCPSR_LO_SOF) {
>>   			/* h/w dropped descriptor */
>>   			dev_err(dev, "single fetch fifo overflow error\n");
>>   			error = -EAGAIN;
>>   		}
>> -		if (v_lo & TALITOS_CCPSR_LO_MDTE)
>> +		if (v_lo & TALITOS2_CCPSR_LO_MDTE)
>>   			dev_err(dev, "master data transfer error\n");
>> -		if (v_lo & TALITOS_CCPSR_LO_SGDLZ)
>> -			dev_err(dev, is_sec1 ? "pointer not complete error\n"
>> -					     : "s/g data length zero error\n");
>> -		if (v_lo & TALITOS_CCPSR_LO_FPZ)
>> -			dev_err(dev, is_sec1 ? "parity error\n"
>> -					     : "fetch pointer zero error\n");
>> -		if (v_lo & TALITOS_CCPSR_LO_IDH)
>> +		if (v_lo & TALITOS2_CCPSR_LO_SGDLZ)
>> +			dev_err(dev, "s/g data length zero error\n");
>> +		if (v_lo & TALITOS2_CCPSR_LO_FPZ)
>> +			dev_err(dev, "fetch pointer zero error\n");
>> +		if (v_lo & TALITOS2_CCPSR_LO_IDH)
>>   			dev_err(dev, "illegal descriptor header error\n");
>> -		if (v_lo & TALITOS_CCPSR_LO_IEU)
>> -			dev_err(dev, is_sec1 ? "static assignment error\n"
>> -					     : "invalid exec unit error\n");
>> -		if (v_lo & TALITOS_CCPSR_LO_EU)
>> +		if (v_lo & TALITOS2_CCPSR_LO_IEU)
>> +			dev_err(dev, "invalid exec unit error\n");
>> +		if (v_lo & TALITOS2_CCPSR_LO_EU)
>>   			report_eu_error(dev, ch, current_desc_hdr(dev, ch));
>> -		if (!is_sec1) {
>> -			if (v_lo & TALITOS_CCPSR_LO_GB)
>> -				dev_err(dev, "gather boundary error\n");
>> -			if (v_lo & TALITOS_CCPSR_LO_GRL)
>> -				dev_err(dev, "gather return/length error\n");
>> -			if (v_lo & TALITOS_CCPSR_LO_SB)
>> -				dev_err(dev, "scatter boundary error\n");
>> -			if (v_lo & TALITOS_CCPSR_LO_SRL)
>> -				dev_err(dev, "scatter return/length error\n");
>> -		}
>> +		if (v_lo & TALITOS2_CCPSR_LO_GB)
>> +			dev_err(dev, "gather boundary error\n");
>> +		if (v_lo & TALITOS2_CCPSR_LO_GRL)
>> +			dev_err(dev, "gather return/length error\n");
>> +		if (v_lo & TALITOS2_CCPSR_LO_SB)
>> +			dev_err(dev, "scatter boundary error\n");
>> +		if (v_lo & TALITOS2_CCPSR_LO_SRL)
>> +			dev_err(dev, "scatter return/length error\n");
>>   
>>   		flush_channel(dev, ch, error, reset_ch);
>>   
>>   		if (reset_ch) {
>> -			reset_channel(dev, ch);
>> +			priv->ops->reset_channel(dev, ch);
>>   		} else {
>>   			setbits32(priv->chan[ch].reg + TALITOS_CCCR,
>>   				  TALITOS2_CCCR_CONT);
>>   			setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
>>   			while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
>> -			       TALITOS2_CCCR_CONT) && --timeout)
>> +				TALITOS2_CCCR_CONT) && --timeout)
>>   				cpu_relax();
>>   			if (timeout == 0) {
>>   				dev_err(dev, "failed to restart channel %d\n",
>> @@ -728,14 +823,29 @@ static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
>>   			}
>>   		}
>>   	}
>> -	if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) ||
>> -	    (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) {
>> -		if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR))
>> -			dev_err(dev, "TEA error: ISR 0x%08x_%08x\n",
>> -				isr, isr_lo);
>> -		else
>> -			dev_err(dev, "done overflow, internal time out, or "
>> -				"rngu error: ISR 0x%08x_%08x\n", isr, isr_lo);
>> +
>> +	return reset_dev || (isr & ~TALITOS2_ISR_4CHERR) || isr_lo;
>> +}
>> +
>> +/*
>> + * recover from error interrupts
>> + */
>> +static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
>> +{
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +	bool is_sec1 = has_ftr_sec1(priv);
>> +	int ch, reset_dev;
>> +
>> +	if (is_sec1)
>> +		reset_dev = sec1_talitos_handle_error(dev, isr, isr_lo);
>> +	else
>> +		reset_dev = sec2_talitos_handle_error(dev, isr, isr_lo);
>> +
>> +	if (reset_dev) {
>> +		dev_err(dev,
>> +			"done overflow, internal time out, or "
>> +			"rngu error: ISR 0x%08x_%08x\n",
>> +			isr, isr_lo);
>>   
>>   		/* purge request queues */
>>   		for (ch = 0; ch < priv->num_channels; ch++)
>> @@ -1181,25 +1291,41 @@ int talitos_register_common(struct device *dev,
>>   	return 0;
>>   }
>>   
>> -static int talitos_probe_irq(struct platform_device *ofdev)
>> +static int sec1_talitos_probe_irq(struct platform_device *ofdev)
>>   {
>>   	struct device *dev = &ofdev->dev;
>>   	struct device_node *np = ofdev->dev.of_node;
>>   	struct talitos_private *priv = dev_get_drvdata(dev);
>>   	int err;
>> -	bool is_sec1 = has_ftr_sec1(priv);
>>   
>>   	priv->irq[0] = irq_of_parse_and_map(np, 0);
>>   	if (!priv->irq[0]) {
>>   		dev_err(dev, "failed to map irq\n");
>>   		return -EINVAL;
>>   	}
>> -	if (is_sec1) {
>> -		err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
>> -				  dev_driver_string(dev), dev);
>> -		goto primary_out;
>> +	err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
>> +			  dev_driver_string(dev), dev);
>> +	if (err) {
>> +		dev_err(dev, "failed to request primary irq\n");
>> +		irq_dispose_mapping(priv->irq[0]);
>> +		priv->irq[0] = 0;
>>   	}
>>   
>> +	return err;
>> +}
>> +
>> +static int sec2_talitos_probe_irq(struct platform_device *ofdev)
>> +{
>> +	struct device *dev = &ofdev->dev;
>> +	struct device_node *np = ofdev->dev.of_node;
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +	int err;
>> +
>> +	priv->irq[0] = irq_of_parse_and_map(np, 0);
>> +	if (!priv->irq[0]) {
>> +		dev_err(dev, "failed to map irq\n");
>> +		return -EINVAL;
>> +	}
>>   	priv->irq[1] = irq_of_parse_and_map(np, 1);
>>   
>>   	/* get the primary irq line */
>> @@ -1235,6 +1361,36 @@ static int talitos_probe_irq(struct platform_device *ofdev)
>>   	return err;
>>   }
>>   
>> +static void sec1_init_task(struct device *dev)
>> +{
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +
>> +	if (priv->num_channels == 1)
>> +		tasklet_init(&priv->done_task[0], talitos1_done_ch0,
>> +			     (unsigned long)dev);
>> +	else
>> +		tasklet_init(&priv->done_task[0], talitos1_done_4ch,
>> +			     (unsigned long)dev);
>> +}
>> +
>> +static void sec2_init_task(struct device *dev)
>> +{
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +
>> +	if (priv->irq[1]) {
>> +		tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
>> +			     (unsigned long)dev);
>> +		tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
>> +			     (unsigned long)dev);
>> +	} else if (priv->num_channels == 1) {
>> +		tasklet_init(&priv->done_task[0], talitos2_done_ch0,
>> +			     (unsigned long)dev);
>> +	} else {
>> +		tasklet_init(&priv->done_task[0], talitos2_done_4ch,
>> +			     (unsigned long)dev);
>> +	}
>> +}
>> +
>>   static int talitos_probe(struct platform_device *ofdev)
>>   {
>>   	struct device *dev = &ofdev->dev;
>> @@ -1317,31 +1473,17 @@ static int talitos_probe(struct platform_device *ofdev)
>>   		stride = TALITOS2_CH_STRIDE;
>>   	}
>>   
>> -	err = talitos_probe_irq(ofdev);
>> +	if (has_ftr_sec1(priv))
>> +		err = sec1_talitos_probe_irq(ofdev);
>> +	else
>> +		err = sec2_talitos_probe_irq(ofdev);
>>   	if (err)
>>   		goto err_out;
>>   
>> -	if (has_ftr_sec1(priv)) {
>> -		if (priv->num_channels == 1)
>> -			tasklet_init(&priv->done_task[0], talitos1_done_ch0,
>> -				     (unsigned long)dev);
>> -		else
>> -			tasklet_init(&priv->done_task[0], talitos1_done_4ch,
>> -				     (unsigned long)dev);
>> -	} else {
>> -		if (priv->irq[1]) {
>> -			tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
>> -				     (unsigned long)dev);
>> -			tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
>> -				     (unsigned long)dev);
>> -		} else if (priv->num_channels == 1) {
>> -			tasklet_init(&priv->done_task[0], talitos2_done_ch0,
>> -				     (unsigned long)dev);
>> -		} else {
>> -			tasklet_init(&priv->done_task[0], talitos2_done_4ch,
>> -				     (unsigned long)dev);
>> -		}
>> -	}
>> +	if (has_ftr_sec1(priv))
>> +		sec1_init_task(dev);
>> +	else
>> +		sec2_init_task(dev);
>>   
>>   	priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
>>   
>> diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
>> index 6cf3628c52c2..904fdc9dec80 100644
>> --- a/drivers/crypto/talitos/talitos.h
>> +++ b/drivers/crypto/talitos/talitos.h
>> @@ -301,20 +301,32 @@ static inline bool has_ftr_sec1(struct talitos_private *priv)
>>   #define   TALITOS1_CCCR_LO_RESET	0x1    /* channel reset on SEC1 */
>>   
>>   /* CCPSR: channel pointer status register */
>> +
>> +/* bits 29, 31, 17, 19 */
>> +#define TALITOS1_CH_HAS_ERROR(isr, ch) \
>> +	((isr) & (1 << (29 + ((ch) & 1) * 2 - ((ch) & 2) * 6)))
>> +#define TALITOS2_CH_HAS_ERROR(isr, ch) ((isr) & (1 << ((ch) * 2 + 1)))
>> +
>>   #define TALITOS_CCPSR			0x10
>>   #define TALITOS_CCPSR_LO		0x14
>> -#define   TALITOS_CCPSR_LO_DOF		0x8000 /* double FF write oflow error */
>> -#define   TALITOS_CCPSR_LO_SOF		0x4000 /* single FF write oflow error */
>> -#define   TALITOS_CCPSR_LO_MDTE		0x2000 /* master data transfer error */
>> -#define   TALITOS_CCPSR_LO_SGDLZ	0x1000 /* s/g data len zero error */
>> -#define   TALITOS_CCPSR_LO_FPZ		0x0800 /* fetch ptr zero error */
>> -#define   TALITOS_CCPSR_LO_IDH		0x0400 /* illegal desc hdr error */
>> -#define   TALITOS_CCPSR_LO_IEU		0x0200 /* invalid EU error */
>> -#define   TALITOS_CCPSR_LO_EU		0x0100 /* EU error detected */
>> -#define   TALITOS_CCPSR_LO_GB		0x0080 /* gather boundary error */
>> -#define   TALITOS_CCPSR_LO_GRL		0x0040 /* gather return/length error */
>> -#define   TALITOS_CCPSR_LO_SB		0x0020 /* scatter boundary error */
>> -#define   TALITOS_CCPSR_LO_SRL		0x0010 /* scatter return/length error */
>> +#define   TALITOS1_CCPSR_LO_TEA		0x2000 /* transfer error acknowledge */
>> +#define   TALITOS1_CCPSR_LO_PTRNC	0x1000 /* pointer not complete error */
>> +#define   TALITOS1_CCPSR_LO_PE		0x0800 /* parity error */
>> +#define   TALITOS1_CCPSR_LO_IDH		0x0400 /* illegal desc hdr error */
>> +#define   TALITOS1_CCPSR_LO_SA		0x0200 /* static assignment error */
>> +#define   TALITOS1_CCPSR_LO_EU		0x0100 /* EU error detected */
>> +#define   TALITOS2_CCPSR_LO_DOF		0x8000 /* double FF write oflow error */
>> +#define   TALITOS2_CCPSR_LO_SOF		0x4000 /* single FF write oflow error */
>> +#define   TALITOS2_CCPSR_LO_MDTE	0x2000 /* master data transfer error */
>> +#define   TALITOS2_CCPSR_LO_SGDLZ	0x1000 /* s/g data len zero error */
>> +#define   TALITOS2_CCPSR_LO_FPZ		0x0800 /* fetch ptr zero error */
>> +#define   TALITOS2_CCPSR_LO_IDH		0x0400 /* illegal desc hdr error */
>> +#define   TALITOS2_CCPSR_LO_IEU		0x0200 /* invalid EU error */
>> +#define   TALITOS2_CCPSR_LO_EU		0x0100 /* EU error detected */
>> +#define   TALITOS2_CCPSR_LO_GB		0x0080 /* gather boundary error */
>> +#define   TALITOS2_CCPSR_LO_GRL		0x0040 /* gather return/length error */
>> +#define   TALITOS2_CCPSR_LO_SB		0x0020 /* scatter boundary error */
>> +#define   TALITOS2_CCPSR_LO_SRL		0x0010 /* scatter return/length error */
>>   
>>   /* channel fetch fifo register */
>>   #define TALITOS_FF			0x48
>> 




-- 
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH 14/29] crypto: talitos/aead - Convert to init/exit type-specific API
From: Paul Louvel @ 2026-06-04 12:44 UTC (permalink / raw)
  To: Christophe Leroy (CS GROUP), Paul Louvel, Herbert Xu,
	David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <5c25a511-39c7-43aa-a2e2-7690ca4d074a@kernel.org>

On Mon Jun 1, 2026 at 1:59 PM CEST, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 28/05/2026 à 11:08, Paul Louvel a écrit :
>> Since commit 6eed1e3552fc0 ("crypto: api - Mark cra_init/cra_exit as
>> deprecated"), both cra_{init,exit} are deprecated.
>> 
>> Restore the type-specific talitos_cra_exit_aead() wrapper and use
>> aead_alg->exit instead of the generic cra_exit field, matching the
>> pattern used by init.
>
> When you say "restore", do you mean it was removed at some point in the 
> past ?

No. It was probably true at some point of my the series locally (I did a lot of
rebase), I forgot to update the commit message of this patch.

Thanks for pointing this out.

>> 
>> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
>
> Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
>
>> ---
>>   drivers/crypto/talitos/talitos-aead.c | 7 ++++++-
>>   1 file changed, 6 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/crypto/talitos/talitos-aead.c b/drivers/crypto/talitos/talitos-aead.c
>> index c09ed08be2ef..38df616c9b22 100644
>> --- a/drivers/crypto/talitos/talitos-aead.c
>> +++ b/drivers/crypto/talitos/talitos-aead.c
>> @@ -400,6 +400,11 @@ static int talitos_cra_init_aead(struct crypto_aead *tfm)
>>   	return talitos_init_common(ctx, talitos_alg);
>>   }
>>   
>> +static void talitos_cra_exit_aead(struct crypto_aead *tfm)
>> +{
>> +	talitos_cra_exit(crypto_aead_tfm(tfm));
>> +}
>> +
>>   static struct talitos_alg_template aead_driver_algs[] = {
>>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
>>   		.alg.aead = {
>> @@ -950,8 +955,8 @@ int talitos_register_aead(struct device *dev)
>>   		if (has_ftr_sec1(priv))
>>   			alg->cra_alignmask = 3;
>>   
>> -		alg->cra_exit = talitos_cra_exit;
>>   		aead_alg->init = talitos_cra_init_aead;
>> +		aead_alg->exit = talitos_cra_exit_aead;
>>   		aead_alg->setkey = aead_alg->setkey ?: aead_setkey;
>>   		aead_alg->encrypt = aead_encrypt;
>>   		aead_alg->decrypt = aead_decrypt;
>> 




-- 
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH 11/29] crypto: talitos - Remove unused priority field in struct talitos_alg_template
From: Paul Louvel @ 2026-06-04 12:39 UTC (permalink / raw)
  To: Christophe Leroy (CS GROUP), Paul Louvel, Herbert Xu,
	David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <a09e9b6e-83ac-47d2-a641-a4c7ce50875c@kernel.org>

On Mon Jun 1, 2026 at 1:54 PM CEST, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 28/05/2026 à 11:08, Paul Louvel a écrit :
>> After algorithm properties are now set at definition time, the priority
>> field in struct talitos_alg_template is no longer used. Remove it.
>
> Should probably be sqashed (with the above explanation) in the previous 
> commit.

Ok.

>
>> 
>> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
>> ---
>>   drivers/crypto/talitos/talitos.h | 1 -
>>   1 file changed, 1 deletion(-)
>> 
>> diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
>> index 438be8c8f08d..6cf3628c52c2 100644
>> --- a/drivers/crypto/talitos/talitos.h
>> +++ b/drivers/crypto/talitos/talitos.h
>> @@ -203,7 +203,6 @@ struct talitos_ctx {
>>   
>>   struct talitos_alg_template {
>>   	u32 type;
>> -	u32 priority;
>>   	union {
>>   		struct skcipher_alg skcipher;
>>   		struct ahash_alg hash;
>> 




-- 
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH 10/29] crypto: talitos - Remove alg settings in talitos_register_common()
From: Paul Louvel @ 2026-06-04 12:38 UTC (permalink / raw)
  To: Christophe Leroy (CS GROUP), Paul Louvel, Herbert Xu,
	David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <d98bd2ad-fba2-49f4-97e0-1dfb559ea419@kernel.org>


On Mon Jun 1, 2026 at 1:53 PM CEST, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 28/05/2026 à 11:08, Paul Louvel a écrit :
>> Algorithm properties should be set at definition time.
>
> Can you provide more details on why it _should_ be set at definition time ?

"Should" is definetly not the right wording here. In my opinion, it would be
better if they were set a definition time.
The properties set in talitos_alg_set_common() have no reason to be set at
runtime, unlike the properties set in the algorithm registration functions that
depends on runtime checks (if the hardware supports a feature or not).

>
> Also, couldn't this change be done after the "Use macro for algorithm 
> definitions" patches in order to minimise churn ?
>

Yes.

>> 
>> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
>> ---
>>   drivers/crypto/talitos/talitos-aead.c     | 131 +++++++++++++++++++++++-------
>>   drivers/crypto/talitos/talitos-hash.c     |  72 +++++++++++++---
>>   drivers/crypto/talitos/talitos-skcipher.c |  51 ++++++++++--
>>   drivers/crypto/talitos/talitos.c          |  23 ------
>>   4 files changed, 206 insertions(+), 71 deletions(-)
>> 
>> diff --git a/drivers/crypto/talitos/talitos-aead.c b/drivers/crypto/talitos/talitos-aead.c
>> index ce6bd6133fd0..c09ed08be2ef 100644
>> --- a/drivers/crypto/talitos/talitos-aead.c
>> +++ b/drivers/crypto/talitos/talitos-aead.c
>> @@ -409,7 +409,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = SHA1_DIGEST_SIZE,
>> @@ -423,7 +427,6 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   				     DESC_HDR_MODE1_MDEU_SHA1_HMAC,
>>   	},
>>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
>> -		.priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>>   		.alg.aead = {
>>   			.base = {
>>   				.cra_name = "authenc(hmac(sha1),cbc(aes))",
>> @@ -431,7 +434,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos-hsna",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = SHA1_DIGEST_SIZE,
>> @@ -453,7 +460,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = SHA1_DIGEST_SIZE,
>> @@ -469,7 +480,6 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   				     DESC_HDR_MODE1_MDEU_SHA1_HMAC,
>>   	},
>>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
>> -		.priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>>   		.alg.aead = {
>>   			.base = {
>>   				.cra_name = "authenc(hmac(sha1),"
>> @@ -478,7 +488,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos-hsna",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = SHA1_DIGEST_SIZE,
>> @@ -501,7 +515,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = SHA224_DIGEST_SIZE,
>> @@ -515,7 +533,6 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   				     DESC_HDR_MODE1_MDEU_SHA224_HMAC,
>>   	},
>>   	{       .type = CRYPTO_ALG_TYPE_AEAD,
>> -		.priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>>   		.alg.aead = {
>>   			.base = {
>>   				.cra_name = "authenc(hmac(sha224),cbc(aes))",
>> @@ -523,7 +540,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos-hsna",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = SHA224_DIGEST_SIZE,
>> @@ -545,7 +566,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = SHA224_DIGEST_SIZE,
>> @@ -561,7 +586,6 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   				     DESC_HDR_MODE1_MDEU_SHA224_HMAC,
>>   	},
>>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
>> -		.priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>>   		.alg.aead = {
>>   			.base = {
>>   				.cra_name = "authenc(hmac(sha224),"
>> @@ -570,7 +594,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos-hsna",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = SHA224_DIGEST_SIZE,
>> @@ -593,7 +621,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = SHA256_DIGEST_SIZE,
>> @@ -607,7 +639,6 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   				     DESC_HDR_MODE1_MDEU_SHA256_HMAC,
>>   	},
>>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
>> -		.priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>>   		.alg.aead = {
>>   			.base = {
>>   				.cra_name = "authenc(hmac(sha256),cbc(aes))",
>> @@ -615,7 +646,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos-hsna",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = SHA256_DIGEST_SIZE,
>> @@ -637,7 +672,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = SHA256_DIGEST_SIZE,
>> @@ -653,7 +692,6 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   				     DESC_HDR_MODE1_MDEU_SHA256_HMAC,
>>   	},
>>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
>> -		.priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>>   		.alg.aead = {
>>   			.base = {
>>   				.cra_name = "authenc(hmac(sha256),"
>> @@ -662,7 +700,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos-hsna",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = SHA256_DIGEST_SIZE,
>> @@ -685,7 +727,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = SHA384_DIGEST_SIZE,
>> @@ -707,7 +753,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = SHA384_DIGEST_SIZE,
>> @@ -730,7 +780,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = SHA512_DIGEST_SIZE,
>> @@ -752,7 +806,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = SHA512_DIGEST_SIZE,
>> @@ -775,7 +833,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = MD5_DIGEST_SIZE,
>> @@ -789,7 +851,6 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   				     DESC_HDR_MODE1_MDEU_MD5_HMAC,
>>   	},
>>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
>> -		.priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>>   		.alg.aead = {
>>   			.base = {
>>   				.cra_name = "authenc(hmac(md5),cbc(aes))",
>> @@ -797,7 +858,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-aes-talitos-hsna",
>>   				.cra_blocksize = AES_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = AES_BLOCK_SIZE,
>>   			.maxauthsize = MD5_DIGEST_SIZE,
>> @@ -818,7 +883,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = MD5_DIGEST_SIZE,
>> @@ -834,7 +903,6 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   				     DESC_HDR_MODE1_MDEU_MD5_HMAC,
>>   	},
>>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
>> -		.priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>>   		.alg.aead = {
>>   			.base = {
>>   				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
>> @@ -842,7 +910,11 @@ static struct talitos_alg_template aead_driver_algs[] = {
>>   						   "cbc-3des-talitos-hsna",
>>   				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +				.cra_priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			},
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>>   			.maxauthsize = MD5_DIGEST_SIZE,
>> @@ -875,6 +947,9 @@ int talitos_register_aead(struct device *dev)
>>   		aead_alg = &aead_driver_algs[i].alg.aead;
>>   		alg = &aead_alg->base;
>>   
>> +		if (has_ftr_sec1(priv))
>> +			alg->cra_alignmask = 3;
>> +
>>   		alg->cra_exit = talitos_cra_exit;
>>   		aead_alg->init = talitos_cra_init_aead;
>>   		aead_alg->setkey = aead_alg->setkey ?: aead_setkey;
>> diff --git a/drivers/crypto/talitos/talitos-hash.c b/drivers/crypto/talitos/talitos-hash.c
>> index 5792e7093392..3793b6fd5b75 100644
>> --- a/drivers/crypto/talitos/talitos-hash.c
>> +++ b/drivers/crypto/talitos/talitos-hash.c
>> @@ -559,8 +559,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -578,8 +582,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -597,8 +605,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -616,8 +628,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -635,8 +651,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -654,8 +674,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -673,8 +697,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -692,8 +720,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -711,8 +743,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -730,8 +766,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -749,8 +789,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> @@ -768,8 +812,12 @@ static struct talitos_alg_template hash_driver_algs[] = {
>>   				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>>   				.cra_flags = CRYPTO_ALG_ASYNC |
>>   					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_ALG_KERN_DRIVER_ONLY |
>> +			     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>>   					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +				.cra_priority = TALITOS_CRA_PRIORITY,
>> +				.cra_ctxsize = sizeof(struct talitos_ctx),
>> +				.cra_module = THIS_MODULE,
>>   			}
>>   		},
>>   		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> diff --git a/drivers/crypto/talitos/talitos-skcipher.c b/drivers/crypto/talitos/talitos-skcipher.c
>> index 4f742930ec47..ff7b8f9344c4 100644
>> --- a/drivers/crypto/talitos/talitos-skcipher.c
>> +++ b/drivers/crypto/talitos/talitos-skcipher.c
>> @@ -239,7 +239,11 @@ static struct talitos_alg_template skcipher_driver_algs[] = {
>>   			.base.cra_driver_name = "ecb-aes-talitos",
>>   			.base.cra_blocksize = AES_BLOCK_SIZE,
>>   			.base.cra_flags = CRYPTO_ALG_ASYNC |
>> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					  CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					  CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +			.base.cra_priority = TALITOS_CRA_PRIORITY,
>> +			.base.cra_ctxsize = sizeof(struct talitos_ctx),
>> +			.base.cra_module = THIS_MODULE,
>>   			.min_keysize = AES_MIN_KEY_SIZE,
>>   			.max_keysize = AES_MAX_KEY_SIZE,
>>   			.setkey = skcipher_aes_setkey,
>> @@ -253,7 +257,11 @@ static struct talitos_alg_template skcipher_driver_algs[] = {
>>   			.base.cra_driver_name = "cbc-aes-talitos",
>>   			.base.cra_blocksize = AES_BLOCK_SIZE,
>>   			.base.cra_flags = CRYPTO_ALG_ASYNC |
>> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					  CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					  CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +			.base.cra_priority = TALITOS_CRA_PRIORITY,
>> +			.base.cra_ctxsize = sizeof(struct talitos_ctx),
>> +			.base.cra_module = THIS_MODULE,
>>   			.min_keysize = AES_MIN_KEY_SIZE,
>>   			.max_keysize = AES_MAX_KEY_SIZE,
>>   			.ivsize = AES_BLOCK_SIZE,
>> @@ -269,7 +277,11 @@ static struct talitos_alg_template skcipher_driver_algs[] = {
>>   			.base.cra_driver_name = "ctr-aes-talitos",
>>   			.base.cra_blocksize = 1,
>>   			.base.cra_flags = CRYPTO_ALG_ASYNC |
>> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					  CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					  CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +			.base.cra_priority = TALITOS_CRA_PRIORITY,
>> +			.base.cra_ctxsize = sizeof(struct talitos_ctx),
>> +			.base.cra_module = THIS_MODULE,
>>   			.min_keysize = AES_MIN_KEY_SIZE,
>>   			.max_keysize = AES_MAX_KEY_SIZE,
>>   			.ivsize = AES_BLOCK_SIZE,
>> @@ -285,7 +297,11 @@ static struct talitos_alg_template skcipher_driver_algs[] = {
>>   			.base.cra_driver_name = "ctr-aes-talitos",
>>   			.base.cra_blocksize = 1,
>>   			.base.cra_flags = CRYPTO_ALG_ASYNC |
>> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					  CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					  CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +			.base.cra_priority = TALITOS_CRA_PRIORITY,
>> +			.base.cra_ctxsize = sizeof(struct talitos_ctx),
>> +			.base.cra_module = THIS_MODULE,
>>   			.min_keysize = AES_MIN_KEY_SIZE,
>>   			.max_keysize = AES_MAX_KEY_SIZE,
>>   			.ivsize = AES_BLOCK_SIZE,
>> @@ -301,7 +317,11 @@ static struct talitos_alg_template skcipher_driver_algs[] = {
>>   			.base.cra_driver_name = "ecb-des-talitos",
>>   			.base.cra_blocksize = DES_BLOCK_SIZE,
>>   			.base.cra_flags = CRYPTO_ALG_ASYNC |
>> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					  CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					  CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +			.base.cra_priority = TALITOS_CRA_PRIORITY,
>> +			.base.cra_ctxsize = sizeof(struct talitos_ctx),
>> +			.base.cra_module = THIS_MODULE,
>>   			.min_keysize = DES_KEY_SIZE,
>>   			.max_keysize = DES_KEY_SIZE,
>>   			.setkey = skcipher_des_setkey,
>> @@ -315,7 +335,11 @@ static struct talitos_alg_template skcipher_driver_algs[] = {
>>   			.base.cra_driver_name = "cbc-des-talitos",
>>   			.base.cra_blocksize = DES_BLOCK_SIZE,
>>   			.base.cra_flags = CRYPTO_ALG_ASYNC |
>> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					  CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					  CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +			.base.cra_priority = TALITOS_CRA_PRIORITY,
>> +			.base.cra_ctxsize = sizeof(struct talitos_ctx),
>> +			.base.cra_module = THIS_MODULE,
>>   			.min_keysize = DES_KEY_SIZE,
>>   			.max_keysize = DES_KEY_SIZE,
>>   			.ivsize = DES_BLOCK_SIZE,
>> @@ -331,7 +355,11 @@ static struct talitos_alg_template skcipher_driver_algs[] = {
>>   			.base.cra_driver_name = "ecb-3des-talitos",
>>   			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   			.base.cra_flags = CRYPTO_ALG_ASYNC |
>> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					  CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					  CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +			.base.cra_priority = TALITOS_CRA_PRIORITY,
>> +			.base.cra_ctxsize = sizeof(struct talitos_ctx),
>> +			.base.cra_module = THIS_MODULE,
>>   			.min_keysize = DES3_EDE_KEY_SIZE,
>>   			.max_keysize = DES3_EDE_KEY_SIZE,
>>   			.setkey = skcipher_des3_setkey,
>> @@ -346,7 +374,11 @@ static struct talitos_alg_template skcipher_driver_algs[] = {
>>   			.base.cra_driver_name = "cbc-3des-talitos",
>>   			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
>>   			.base.cra_flags = CRYPTO_ALG_ASYNC |
>> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
>> +					  CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					  CRYPTO_ALG_KERN_DRIVER_ONLY,
>> +			.base.cra_priority = TALITOS_CRA_PRIORITY,
>> +			.base.cra_ctxsize = sizeof(struct talitos_ctx),
>> +			.base.cra_module = THIS_MODULE,
>>   			.min_keysize = DES3_EDE_KEY_SIZE,
>>   			.max_keysize = DES3_EDE_KEY_SIZE,
>>   			.ivsize = DES3_EDE_BLOCK_SIZE,
>> @@ -375,6 +407,9 @@ int talitos_register_skcipher(struct device *dev)
>>   		skcipher_alg = &skcipher_driver_algs[i].alg.skcipher;
>>   		alg = &skcipher_alg->base;
>>   
>> +		if (has_ftr_sec1(priv))
>> +			alg->cra_alignmask = 3;
>> +
>>   		alg->cra_exit = talitos_cra_exit;
>>   		skcipher_alg->init = talitos_cra_init_skcipher;
>>   		skcipher_alg->setkey = skcipher_alg->setkey ?: skcipher_setkey;
>> diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
>> index 41d7d0e570e3..f38a156a0459 100644
>> --- a/drivers/crypto/talitos/talitos.c
>> +++ b/drivers/crypto/talitos/talitos.c
>> @@ -1133,23 +1133,6 @@ static void talitos_remove(struct platform_device *ofdev)
>>   		tasklet_kill(&priv->done_task[1]);
>>   }
>>   
>> -static void talitos_alg_set_common(struct talitos_private *priv,
>> -				   struct crypto_alg *alg, u32 custom_priority,
>> -				   u32 type)
>> -{
>> -	alg->cra_module = THIS_MODULE;
>> -	if (custom_priority)
>> -		alg->cra_priority = custom_priority;
>> -	else
>> -		alg->cra_priority = TALITOS_CRA_PRIORITY;
>> -	if (has_ftr_sec1(priv) && type != CRYPTO_ALG_TYPE_AHASH)
>> -		alg->cra_alignmask = 3;
>> -	else
>> -		alg->cra_alignmask = 0;
>> -	alg->cra_ctxsize = sizeof(struct talitos_ctx);
>> -	alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
>> -}
>> -
>>   int talitos_register_common(struct device *dev,
>>   			    struct talitos_alg_template *template)
>>   {
>> @@ -1168,20 +1151,14 @@ int talitos_register_common(struct device *dev,
>>   	switch (t_alg->algt.type) {
>>   	case CRYPTO_ALG_TYPE_AHASH:
>>   		alg = &t_alg->algt.alg.hash.halg.base;
>> -		talitos_alg_set_common(priv, alg, t_alg->algt.priority,
>> -				       t_alg->algt.type);
>>   		ret = crypto_register_ahash(&t_alg->algt.alg.hash);
>>   		break;
>>   	case CRYPTO_ALG_TYPE_SKCIPHER:
>>   		alg = &t_alg->algt.alg.skcipher.base;
>> -		talitos_alg_set_common(priv, alg, t_alg->algt.priority,
>> -				       t_alg->algt.type);
>>   		ret = crypto_register_skcipher(&t_alg->algt.alg.skcipher);
>>   		break;
>>   	case CRYPTO_ALG_TYPE_AEAD:
>>   		alg = &t_alg->algt.alg.aead.base;
>> -		talitos_alg_set_common(priv, alg, t_alg->algt.priority,
>> -				       t_alg->algt.type);
>>   		ret = crypto_register_aead(&t_alg->algt.alg.aead);
>>   		break;
>>   	default:
>> 

Thanks,

Paul.




-- 
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH 07/29] crypto: talitos/hash - Move into separate file
From: Paul Louvel @ 2026-06-04 12:31 UTC (permalink / raw)
  To: Christophe Leroy (CS GROUP), Paul Louvel, Herbert Xu,
	David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <6a5ec43a-b05a-431c-9ace-2f7b58523895@kernel.org>

On Mon Jun 1, 2026 at 1:47 PM CEST, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 28/05/2026 à 11:08, Paul Louvel a écrit :
>> Move the ahash algorithm implementations from talitos.c into a dedicated
>> talitos-hash.c file.
>> 
>> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
>
> Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
>
> While at it, (maybe another patch) the problem with size 0 hash on SEC1 
> is not a driver bug but a hardware bug, it is therefore probably not 
> worth a pr_err() because there is nothing the user can do about it and 
> it is transparent as there is a workaround in the driver.

I was considering doing it differently too.
Instead of having a special case inside common_nonsnoop_hash(), handle it at the
beginning in ahash_process_req() or ahash_update() : if nbytes == 0 &&
first_request && last_request, create a scatterlist with a single entry. This
entry would be the static array with the padded bit.
It seems to me that it belongs more to the request preparation than to the
common_nonsnoop_hash() function, which is more about mapping the buffers and
preparing the descriptor.

Anyway, I agree with the call to pr_err_once().

>> ---
>>   drivers/crypto/talitos/Makefile       |   2 +-
>>   drivers/crypto/talitos/talitos-hash.c | 832 ++++++++++++++++++++++++++++++++++
>>   drivers/crypto/talitos/talitos.c      | 807 +--------------------------------
>>   drivers/crypto/talitos/talitos.h      |   4 +
>>   4 files changed, 847 insertions(+), 798 deletions(-)
>> 
>> diff --git a/drivers/crypto/talitos/Makefile b/drivers/crypto/talitos/Makefile
>> index 901ec681f010..40d37f9364ef 100644
>> --- a/drivers/crypto/talitos/Makefile
>> +++ b/drivers/crypto/talitos/Makefile
>> @@ -1,3 +1,3 @@
>>   obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
>>   
>> -talitos-y := talitos.o talitos-rng.o
>> +talitos-y := talitos.o talitos-rng.o talitos-hash.o
>> diff --git a/drivers/crypto/talitos/talitos-hash.c b/drivers/crypto/talitos/talitos-hash.c
>> new file mode 100644
>> index 000000000000..5792e7093392
>> --- /dev/null
>> +++ b/drivers/crypto/talitos/talitos-hash.c
>> @@ -0,0 +1,832 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +
>> +/*
>> + * Freescale SEC (talitos) hash implementation
>> + *
>> + * Copyright (c) 2006-2011 Freescale Semiconductor, Inc.
>> + */
>> +
>> +#include <linux/scatterlist.h>
>> +
>> +#include <crypto/hash.h>
>> +#include <crypto/internal/hash.h>
>> +#include <crypto/md5.h>
>> +#include <crypto/scatterwalk.h>
>> +#include <crypto/sha1.h>
>> +
>> +#include "talitos.h"
>> +
>> +#define HASH_MAX_BLOCK_SIZE		SHA512_BLOCK_SIZE
>> +#define TALITOS_MDEU_MAX_CONTEXT_SIZE	TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
>> +
>> +struct talitos_ahash_req_ctx {
>> +	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
>> +	unsigned int hw_context_size;
>> +	unsigned int swinit;
>> +	unsigned int first_request;
>> +	unsigned int last_request;
>> +	unsigned int to_hash_later;
>> +};
>> +
>> +struct talitos_export_state {
>> +	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
>> +	unsigned int swinit;
>> +	unsigned int first_request;
>> +	unsigned int last_request;
>> +	unsigned int to_hash_later;
>> +};
>> +
>> +static void common_nonsnoop_hash_unmap(struct device *dev,
>> +				       struct talitos_edesc *edesc,
>> +				       struct ahash_request *areq)
>> +{
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +	bool is_sec1 = has_ftr_sec1(priv);
>> +	struct talitos_desc *desc = &edesc->desc;
>> +
>> +	unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
>> +
>> +	if (edesc->last && req_ctx->last_request)
>> +		memcpy(areq->result, req_ctx->hw_context,
>> +		       crypto_ahash_digestsize(tfm));
>> +
>> +	if (edesc->src)
>> +		talitos_sg_unmap(dev, edesc, edesc->src, NULL, 0, 0);
>> +
>> +	/* When using hashctx-in, must unmap it. */
>> +	if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
>> +		unmap_single_talitos_ptr(dev, &desc->ptr[1],
>> +					 DMA_TO_DEVICE);
>> +
>> +	if (edesc->dma_len)
>> +		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
>> +				 DMA_BIDIRECTIONAL);
>> +}
>> +
>> +static void free_edesc_list_from(struct ahash_request *areq, struct talitos_edesc *edesc)
>> +{
>> +	struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
>> +	struct talitos_edesc *next;
>> +
>> +	while (edesc) {
>> +		next = edesc->next_desc;
>> +		common_nonsnoop_hash_unmap(ctx->dev, edesc, areq);
>> +		kfree(edesc);
>> +		edesc = next;
>> +	}
>> +}
>> +
>> +static void ahash_done(struct device *dev,
>> +		       struct talitos_desc *desc, void *context,
>> +		       int err)
>> +{
>> +	struct ahash_request *areq = context;
>> +	struct talitos_edesc *edesc =
>> +		 container_of(desc, struct talitos_edesc, desc);
>> +	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 *next;
>> +
>> +	if (is_sec1) {
>> +		free_edesc_list_from(areq, edesc);
>> +		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
>> +	} else {
>> +		next = edesc->next_desc;
>> +
>> +		common_nonsnoop_hash_unmap(dev, edesc, areq);
>> +		kfree(edesc);
>> +
>> +		if (err)
>> +			goto out;
>> +
>> +		if (next) {
>> +			err = talitos_submit(dev, ctx->ch, &next->desc,
>> +					     ahash_done, areq);
>> +			if (err != -EINPROGRESS)
>> +				goto out;
>> +			return;
>> +		}
>> +out:
>> +		if (err && next)
>> +			free_edesc_list_from(areq, next);
>> +		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
>> +	}
>> +}
>> +
>> +/*
>> + * SEC1 doesn't like hashing of 0 sized message, so we do the padding
>> + * ourself and submit a padded block
>> + */
>> +static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
>> +			       struct talitos_edesc *edesc,
>> +			       struct talitos_ptr *ptr)
>> +{
>> +	static u8 padded_hash[64] = {
>> +		0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> +	};
>> +
>> +	pr_err_once("Bug in SEC1, padding ourself\n");
>> +	edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
>> +	map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
>> +			       (char *)padded_hash, DMA_TO_DEVICE);
>> +}
>> +
>> +static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>> +				 struct ahash_request *areq,
>> +				 unsigned int length)
>> +{
>> +	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> +	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +	struct device *dev = ctx->dev;
>> +	struct talitos_desc *desc = &edesc->desc;
>> +	bool sync_needed = false;
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +	bool is_sec1 = has_ftr_sec1(priv);
>> +	int sg_count;
>> +
>> +	/* first DWORD empty */
>> +
>> +	/* hash context in */
>> +	if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) {
>> +		map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
>> +					      req_ctx->hw_context_size,
>> +					      req_ctx->hw_context,
>> +					      DMA_TO_DEVICE);
>> +		req_ctx->swinit = 0;
>> +	}
>> +	/* Indicate next op is not the first. */
>> +	req_ctx->first_request = 0;
>> +
>> +	/* HMAC key */
>> +	if (ctx->keylen)
>> +		to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
>> +			       is_sec1);
>> +
>> +	sg_count = edesc->src_nents ?: 1;
>> +	if (is_sec1 && sg_count > 1)
>> +		sg_copy_to_buffer(edesc->src, sg_count, edesc->buf, length);
>> +	else if (length)
>> +		sg_count = dma_map_sg(dev, edesc->src, sg_count, DMA_TO_DEVICE);
>> +
>> +	/*
>> +	 * data in
>> +	 */
>> +	sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
>> +				  sg_count, 0, 0);
>> +	if (sg_count > 1)
>> +		sync_needed = true;
>> +
>> +	/* fifth DWORD empty */
>> +
>> +	/* hash/HMAC out -or- hash context out */
>> +	if (edesc->last && req_ctx->last_request)
>> +		map_single_talitos_ptr(dev, &desc->ptr[5],
>> +				       crypto_ahash_digestsize(tfm),
>> +				       req_ctx->hw_context, DMA_FROM_DEVICE);
>> +	else
>> +		map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
>> +					      req_ctx->hw_context_size,
>> +					      req_ctx->hw_context,
>> +					      DMA_FROM_DEVICE);
>> +
>> +	/* last DWORD empty */
>> +
>> +	if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
>> +		talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
>> +
>> +	if (sync_needed)
>> +		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
>> +					   edesc->dma_len, DMA_BIDIRECTIONAL);
>> +}
>> +
>> +static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
>> +					       struct scatterlist *src,
>> +					       unsigned int nbytes)
>> +{
>> +	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> +	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> +
>> +	return talitos_edesc_alloc(ctx->dev, src, NULL, NULL, 0,
>> +				   nbytes, 0, 0, 0, areq->base.flags, false);
>> +}
>> +
>> +static struct talitos_edesc *
>> +ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>> +			  unsigned int blocksize, bool is_sec1)
>> +{
>> +	struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +	struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
>> +	size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN :
>> +				    TALITOS2_MAX_DATA_LEN;
>> +	struct scatterlist tmp[2];
>> +	size_t to_hash_this_desc;
>> +	struct scatterlist *src;
>> +	size_t offset = 0;
>> +
>> +	do {
>> +		src = scatterwalk_ffwd(tmp, areq->src, offset);
>> +
>> +		to_hash_this_desc =
>> +			min(nbytes, ALIGN_DOWN(desc_max, blocksize));
>> +
>> +		/* Allocate extended descriptor */
>> +		edesc = ahash_edesc_alloc(areq, src, to_hash_this_desc);
>> +		if (IS_ERR(edesc)) {
>> +			if (first)
>> +				free_edesc_list_from(areq, first);
>> +			return edesc;
>> +		}
>> +
>> +		edesc->src = scatterwalk_ffwd(edesc->bufsl, areq->src, offset);
>> +		edesc->desc.hdr = ctx->desc_hdr_template;
>> +		edesc->first = offset == 0;
>> +		edesc->last = nbytes - to_hash_this_desc == 0;
>> +
>> +		/* On last one, request SEC to pad; otherwise continue */
>> +		if (req_ctx->last_request && edesc->last)
>> +			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
>> +		else
>> +			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
>> +
>> +		/* request SEC to INIT hash. */
>> +		if (req_ctx->first_request && edesc->first && !req_ctx->swinit)
>> +			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
>> +
>> +		/*
>> +		 * When the tfm context has a keylen, it's an HMAC.
>> +		 * A first or last (ie. not middle) descriptor must request HMAC.
>> +		 */
>> +		if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
>> +				    (req_ctx->last_request && edesc->last)))
>> +			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
>> +
>> +		/* clear the DN bit  */
>> +		if (is_sec1 && !edesc->last)
>> +			edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
>> +
>> +		common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
>> +
>> +		offset += to_hash_this_desc;
>> +		nbytes -= to_hash_this_desc;
>> +
>> +		if (!prev_edesc)
>> +			first = edesc;
>> +		else
>> +			prev_edesc->next_desc = edesc;
>> +		prev_edesc = edesc;
>> +	} while (nbytes);
>> +
>> +	return first;
>> +}
>> +
>> +static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
>> +{
>> +	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> +	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +	struct talitos_edesc *edesc;
>> +	unsigned int blocksize =
>> +			crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
>> +	bool is_sec1 = has_ftr_sec1(dev_get_drvdata(ctx->dev));
>> +	unsigned int nbytes_to_hash;
>> +	unsigned int to_hash_later;
>> +	struct device *dev = ctx->dev;
>> +	int ret;
>> +
>> +	nbytes_to_hash = ALIGN_DOWN(nbytes, blocksize);
>> +	to_hash_later = nbytes - nbytes_to_hash;
>> +
>> +	if (req_ctx->last_request) {
>> +		nbytes_to_hash = nbytes;
>> +		to_hash_later = 0;
>> +	}
>> +
>> +	req_ctx->to_hash_later = to_hash_later;
>> +
>> +	edesc = ahash_process_req_prepare(areq, nbytes_to_hash, blocksize,
>> +					  is_sec1);
>> +	if (IS_ERR(edesc))
>> +		return PTR_ERR(edesc);
>> +
>> +	ret = talitos_submit(dev, ctx->ch, &edesc->desc, ahash_done, areq);
>> +	if (ret != -EINPROGRESS)
>> +		free_edesc_list_from(areq, edesc);
>> +
>> +	return ret;
>> +}
>> +
>> +static int ahash_init(struct ahash_request *areq)
>> +{
>> +	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> +	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> +	struct device *dev = ctx->dev;
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +	unsigned int size;
>> +	dma_addr_t dma;
>> +
>> +	/* Initialize the context */
>> +	req_ctx->first_request = 1;
>> +	req_ctx->swinit = 0; /* assume h/w init of context */
>> +	size =	(crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
>> +			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
>> +			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
>> +	req_ctx->hw_context_size = size;
>> +	req_ctx->last_request = 0;
>> +
>> +	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> +			     DMA_TO_DEVICE);
>> +	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * on h/w without explicit sha224 support, we initialize h/w context
>> + * manually with sha224 constants, and tell it to run sha256.
>> + */
>> +static int ahash_init_sha224_swinit(struct ahash_request *areq)
>> +{
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +
>> +	req_ctx->hw_context[0] = SHA224_H0;
>> +	req_ctx->hw_context[1] = SHA224_H1;
>> +	req_ctx->hw_context[2] = SHA224_H2;
>> +	req_ctx->hw_context[3] = SHA224_H3;
>> +	req_ctx->hw_context[4] = SHA224_H4;
>> +	req_ctx->hw_context[5] = SHA224_H5;
>> +	req_ctx->hw_context[6] = SHA224_H6;
>> +	req_ctx->hw_context[7] = SHA224_H7;
>> +
>> +	/* init 64-bit count */
>> +	req_ctx->hw_context[8] = 0;
>> +	req_ctx->hw_context[9] = 0;
>> +
>> +	ahash_init(areq);
>> +	req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
>> +
>> +	return 0;
>> +}
>> +
>> +static int ahash_update(struct ahash_request *areq)
>> +{
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +
>> +	req_ctx->last_request = 0;
>> +
>> +	return ahash_process_req(areq, areq->nbytes);
>> +}
>> +
>> +static int ahash_final(struct ahash_request *areq)
>> +{
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +
>> +	req_ctx->last_request = 1;
>> +
>> +	return ahash_process_req(areq, 0);
>> +}
>> +
>> +static int ahash_finup(struct ahash_request *areq)
>> +{
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +
>> +	req_ctx->last_request = 1;
>> +
>> +	return ahash_process_req(areq, areq->nbytes);
>> +}
>> +
>> +static int ahash_digest(struct ahash_request *areq)
>> +{
>> +	ahash_init(areq);
>> +	return ahash_finup(areq);
>> +}
>> +
>> +static int ahash_digest_sha224_swinit(struct ahash_request *areq)
>> +{
>> +	ahash_init_sha224_swinit(areq);
>> +	return ahash_finup(areq);
>> +}
>> +
>> +static int ahash_export(struct ahash_request *areq, void *out)
>> +{
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +	struct talitos_export_state *export = out;
>> +	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> +	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> +	struct device *dev = ctx->dev;
>> +	dma_addr_t dma;
>> +
>> +	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> +			     DMA_FROM_DEVICE);
>> +	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
>> +
>> +	memcpy(export->hw_context, req_ctx->hw_context,
>> +	       req_ctx->hw_context_size);
>> +	export->swinit = req_ctx->swinit;
>> +	export->first_request = req_ctx->first_request;
>> +	export->last_request = req_ctx->last_request;
>> +	export->to_hash_later = req_ctx->to_hash_later;
>> +
>> +	return 0;
>> +}
>> +
>> +static int ahash_import(struct ahash_request *areq, const void *in)
>> +{
>> +	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> +	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> +	struct device *dev = ctx->dev;
>> +	const struct talitos_export_state *export = in;
>> +	unsigned int size;
>> +	dma_addr_t dma;
>> +
>> +	memset(req_ctx, 0, sizeof(*req_ctx));
>> +	size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
>> +			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
>> +			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
>> +	req_ctx->hw_context_size = size;
>> +	memcpy(req_ctx->hw_context, export->hw_context, size);
>> +	req_ctx->swinit = export->swinit;
>> +	req_ctx->first_request = export->first_request;
>> +	req_ctx->last_request = export->last_request;
>> +	req_ctx->to_hash_later = export->to_hash_later;
>> +
>> +	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> +			     DMA_TO_DEVICE);
>> +	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
>> +
>> +	return 0;
>> +}
>> +
>> +static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
>> +		   u8 *hash)
>> +{
>> +	struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
>> +
>> +	struct scatterlist sg[1];
>> +	struct ahash_request *req;
>> +	struct crypto_wait wait;
>> +	int ret;
>> +
>> +	crypto_init_wait(&wait);
>> +
>> +	req = ahash_request_alloc(tfm, GFP_KERNEL);
>> +	if (!req)
>> +		return -ENOMEM;
>> +
>> +	/* Keep tfm keylen == 0 during hash of the long key */
>> +	ctx->keylen = 0;
>> +	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
>> +				   crypto_req_done, &wait);
>> +
>> +	sg_init_one(&sg[0], key, keylen);
>> +
>> +	ahash_request_set_crypt(req, sg, hash, keylen);
>> +	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
>> +
>> +	ahash_request_free(req);
>> +
>> +	return ret;
>> +}
>> +
>> +static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
>> +			unsigned int keylen)
>> +{
>> +	struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
>> +	struct device *dev = ctx->dev;
>> +	unsigned int blocksize =
>> +			crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
>> +	unsigned int digestsize = crypto_ahash_digestsize(tfm);
>> +	unsigned int keysize = keylen;
>> +	u8 hash[SHA512_DIGEST_SIZE];
>> +	int ret;
>> +
>> +	if (keylen <= blocksize)
>> +		memcpy(ctx->key, key, keysize);
>> +	else {
>> +		/* Must get the hash of the long key */
>> +		ret = keyhash(tfm, key, keylen, hash);
>> +
>> +		if (ret)
>> +			return -EINVAL;
>> +
>> +		keysize = digestsize;
>> +		memcpy(ctx->key, hash, digestsize);
>> +	}
>> +
>> +	if (ctx->keylen)
>> +		dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
>> +
>> +	ctx->keylen = keysize;
>> +	ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
>> +
>> +	return 0;
>> +}
>> +
>> +static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
>> +{
>> +	struct crypto_alg *alg = tfm->__crt_alg;
>> +	struct talitos_crypto_alg *talitos_alg;
>> +	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
>> +
>> +	talitos_alg = container_of(__crypto_ahash_alg(alg),
>> +				   struct talitos_crypto_alg,
>> +				   algt.alg.hash);
>> +
>> +	ctx->keylen = 0;
>> +				 sizeof(struct talitos_ahash_req_ctx));
>> +
>> +	return talitos_init_common(ctx, talitos_alg);
>> +}
>> +
>> +static struct talitos_alg_template hash_driver_algs[] = {
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = MD5_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "md5",
>> +				.cra_driver_name = "md5-talitos",
>> +				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUA |
>> +				     DESC_HDR_MODE0_MDEU_MD5,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA1_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "sha1",
>> +				.cra_driver_name = "sha1-talitos",
>> +				.cra_blocksize = SHA1_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUA |
>> +				     DESC_HDR_MODE0_MDEU_SHA1,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA224_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "sha224",
>> +				.cra_driver_name = "sha224-talitos",
>> +				.cra_blocksize = SHA224_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUA |
>> +				     DESC_HDR_MODE0_MDEU_SHA224,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA256_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "sha256",
>> +				.cra_driver_name = "sha256-talitos",
>> +				.cra_blocksize = SHA256_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUA |
>> +				     DESC_HDR_MODE0_MDEU_SHA256,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA384_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "sha384",
>> +				.cra_driver_name = "sha384-talitos",
>> +				.cra_blocksize = SHA384_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUB |
>> +				     DESC_HDR_MODE0_MDEUB_SHA384,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA512_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "sha512",
>> +				.cra_driver_name = "sha512-talitos",
>> +				.cra_blocksize = SHA512_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUB |
>> +				     DESC_HDR_MODE0_MDEUB_SHA512,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = MD5_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "hmac(md5)",
>> +				.cra_driver_name = "hmac-md5-talitos",
>> +				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUA |
>> +				     DESC_HDR_MODE0_MDEU_MD5,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA1_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "hmac(sha1)",
>> +				.cra_driver_name = "hmac-sha1-talitos",
>> +				.cra_blocksize = SHA1_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUA |
>> +				     DESC_HDR_MODE0_MDEU_SHA1,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA224_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "hmac(sha224)",
>> +				.cra_driver_name = "hmac-sha224-talitos",
>> +				.cra_blocksize = SHA224_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUA |
>> +				     DESC_HDR_MODE0_MDEU_SHA224,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA256_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "hmac(sha256)",
>> +				.cra_driver_name = "hmac-sha256-talitos",
>> +				.cra_blocksize = SHA256_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUA |
>> +				     DESC_HDR_MODE0_MDEU_SHA256,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA384_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "hmac(sha384)",
>> +				.cra_driver_name = "hmac-sha384-talitos",
>> +				.cra_blocksize = SHA384_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUB |
>> +				     DESC_HDR_MODE0_MDEUB_SHA384,
>> +	},
>> +	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> +		.alg.hash = {
>> +			.halg.digestsize = SHA512_DIGEST_SIZE,
>> +			.halg.statesize = sizeof(struct talitos_export_state),
>> +			.halg.base = {
>> +				.cra_name = "hmac(sha512)",
>> +				.cra_driver_name = "hmac-sha512-talitos",
>> +				.cra_blocksize = SHA512_BLOCK_SIZE,
>> +				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> +				.cra_flags = CRYPTO_ALG_ASYNC |
>> +					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> +					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> +					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> +			}
>> +		},
>> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				     DESC_HDR_SEL0_MDEUB |
>> +				     DESC_HDR_MODE0_MDEUB_SHA512,
>> +	}
>> +};
>> +
>> +int talitos_register_hash(struct device *dev)
>> +{
>> +	struct talitos_private *priv = dev_get_drvdata(dev);
>> +	struct ahash_alg *ahash_alg;
>> +	struct crypto_alg *alg;
>> +	size_t i;
>> +	int ret;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(hash_driver_algs); i++) {
>> +		if (!talitos_hw_supports(dev,
>> +					 hash_driver_algs[i].desc_hdr_template))
>> +			continue;
>> +
>> +		ahash_alg = &hash_driver_algs[i].alg.hash;
>> +		alg = &ahash_alg->halg.base;
>> +
>> +		alg->cra_init = talitos_cra_init_ahash;
>> +		alg->cra_exit = talitos_cra_exit;
>> +		ahash_alg->init = ahash_init;
>> +		ahash_alg->update = ahash_update;
>> +		ahash_alg->final = ahash_final;
>> +		ahash_alg->finup = ahash_finup;
>> +		ahash_alg->digest = ahash_digest;
>> +		if (!strncmp(alg->cra_name, "hmac", 4))
>> +			ahash_alg->setkey = ahash_setkey;
>> +		ahash_alg->import = ahash_import;
>> +		ahash_alg->export = ahash_export;
>> +
>> +		if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
>> +		    !strncmp(alg->cra_name, "hmac", 4)) {
>> +			/* not supported */
>> +			continue;
>> +		}
>> +
>> +		if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
>> +		    (!strcmp(alg->cra_name, "sha224") ||
>> +		     !strcmp(alg->cra_name, "hmac(sha224)"))) {
>> +			ahash_alg->init = ahash_init_sha224_swinit;
>> +			ahash_alg->digest = ahash_digest_sha224_swinit;
>> +			hash_driver_algs[i].desc_hdr_template =
>> +				DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> +				DESC_HDR_SEL0_MDEUA |
>> +				DESC_HDR_MODE0_MDEU_SHA256;
>> +		}
>> +
>> +		ret = talitos_register_common(dev, &hash_driver_algs[i]);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
>> index 869739dcc4d7..b8bcb970d7d5 100644
>> --- a/drivers/crypto/talitos/talitos.c
>> +++ b/drivers/crypto/talitos/talitos.c
>> @@ -831,26 +831,6 @@ DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
>>    */
>>   #define TALITOS_CRA_PRIORITY_AEAD_HSNA	(TALITOS_CRA_PRIORITY - 1)
>>   
>> -#define HASH_MAX_BLOCK_SIZE		SHA512_BLOCK_SIZE
>> -#define TALITOS_MDEU_MAX_CONTEXT_SIZE	TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
>> -
>> -struct talitos_ahash_req_ctx {
>> -	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
>> -	unsigned int hw_context_size;
>> -	unsigned int swinit;
>> -	unsigned int first_request;
>> -	unsigned int last_request;
>> -	unsigned int to_hash_later;
>> -};
>> -
>> -struct talitos_export_state {
>> -	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
>> -	unsigned int swinit;
>> -	unsigned int first_request;
>> -	unsigned int last_request;
>> -	unsigned int to_hash_later;
>> -};
>> -
>>   static int aead_setkey(struct crypto_aead *authenc,
>>   		       const u8 *key, unsigned int keylen)
>>   {
>> @@ -1659,501 +1639,6 @@ static int skcipher_decrypt(struct skcipher_request *areq)
>>   	return common_nonsnoop(edesc, areq, skcipher_done);
>>   }
>>   
>> -static void common_nonsnoop_hash_unmap(struct device *dev,
>> -				       struct talitos_edesc *edesc,
>> -				       struct ahash_request *areq)
>> -{
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> -	struct talitos_private *priv = dev_get_drvdata(dev);
>> -	bool is_sec1 = has_ftr_sec1(priv);
>> -	struct talitos_desc *desc = &edesc->desc;
>> -
>> -	unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
>> -
>> -	if (edesc->last && req_ctx->last_request)
>> -		memcpy(areq->result, req_ctx->hw_context,
>> -		       crypto_ahash_digestsize(tfm));
>> -
>> -	if (edesc->src)
>> -		talitos_sg_unmap(dev, edesc, edesc->src, NULL, 0, 0);
>> -
>> -	/* When using hashctx-in, must unmap it. */
>> -	if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
>> -		unmap_single_talitos_ptr(dev, &desc->ptr[1],
>> -					 DMA_TO_DEVICE);
>> -
>> -	if (edesc->dma_len)
>> -		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
>> -				 DMA_BIDIRECTIONAL);
>> -}
>> -
>> -static void free_edesc_list_from(struct ahash_request *areq, struct talitos_edesc *edesc)
>> -{
>> -	struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
>> -	struct talitos_edesc *next;
>> -
>> -	while (edesc) {
>> -		next = edesc->next_desc;
>> -		common_nonsnoop_hash_unmap(ctx->dev, edesc, areq);
>> -		kfree(edesc);
>> -		edesc = next;
>> -	}
>> -}
>> -
>> -static void ahash_done(struct device *dev,
>> -		       struct talitos_desc *desc, void *context,
>> -		       int err)
>> -{
>> -	struct ahash_request *areq = context;
>> -	struct talitos_edesc *edesc =
>> -		 container_of(desc, struct talitos_edesc, desc);
>> -	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 *next;
>> -
>> -	if (is_sec1) {
>> -		free_edesc_list_from(areq, edesc);
>> -		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
>> -	} else {
>> -		next = edesc->next_desc;
>> -
>> -		common_nonsnoop_hash_unmap(dev, edesc, areq);
>> -		kfree(edesc);
>> -
>> -		if (err)
>> -			goto out;
>> -
>> -		if (next) {
>> -			err = talitos_submit(dev, ctx->ch, &next->desc,
>> -					     ahash_done, areq);
>> -			if (err != -EINPROGRESS)
>> -				goto out;
>> -			return;
>> -		}
>> -out:
>> -		if (err && next)
>> -			free_edesc_list_from(areq, next);
>> -		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
>> -	}
>> -}
>> -
>> -/*
>> - * SEC1 doesn't like hashing of 0 sized message, so we do the padding
>> - * ourself and submit a padded block
>> - */
>> -static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
>> -			       struct talitos_edesc *edesc,
>> -			       struct talitos_ptr *ptr)
>> -{
>> -	static u8 padded_hash[64] = {
>> -		0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> -		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> -		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> -		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> -	};
>> -
>> -	pr_err_once("Bug in SEC1, padding ourself\n");
>> -	edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
>> -	map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
>> -			       (char *)padded_hash, DMA_TO_DEVICE);
>> -}
>> -
>> -static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>> -				 struct ahash_request *areq,
>> -				 unsigned int length)
>> -{
>> -	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> -	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -	struct device *dev = ctx->dev;
>> -	struct talitos_desc *desc = &edesc->desc;
>> -	bool sync_needed = false;
>> -	struct talitos_private *priv = dev_get_drvdata(dev);
>> -	bool is_sec1 = has_ftr_sec1(priv);
>> -	int sg_count;
>> -
>> -	/* first DWORD empty */
>> -
>> -	/* hash context in */
>> -	if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) {
>> -		map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
>> -					      req_ctx->hw_context_size,
>> -					      req_ctx->hw_context,
>> -					      DMA_TO_DEVICE);
>> -		req_ctx->swinit = 0;
>> -	}
>> -	/* Indicate next op is not the first. */
>> -	req_ctx->first_request = 0;
>> -
>> -	/* HMAC key */
>> -	if (ctx->keylen)
>> -		to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
>> -			       is_sec1);
>> -
>> -	sg_count = edesc->src_nents ?: 1;
>> -	if (is_sec1 && sg_count > 1)
>> -		sg_copy_to_buffer(edesc->src, sg_count, edesc->buf, length);
>> -	else if (length)
>> -		sg_count = dma_map_sg(dev, edesc->src, sg_count, DMA_TO_DEVICE);
>> -
>> -	/*
>> -	 * data in
>> -	 */
>> -	sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
>> -				  sg_count, 0, 0);
>> -	if (sg_count > 1)
>> -		sync_needed = true;
>> -
>> -	/* fifth DWORD empty */
>> -
>> -	/* hash/HMAC out -or- hash context out */
>> -	if (edesc->last && req_ctx->last_request)
>> -		map_single_talitos_ptr(dev, &desc->ptr[5],
>> -				       crypto_ahash_digestsize(tfm),
>> -				       req_ctx->hw_context, DMA_FROM_DEVICE);
>> -	else
>> -		map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
>> -					      req_ctx->hw_context_size,
>> -					      req_ctx->hw_context,
>> -					      DMA_FROM_DEVICE);
>> -
>> -	/* last DWORD empty */
>> -
>> -	if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
>> -		talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
>> -
>> -	if (sync_needed)
>> -		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
>> -					   edesc->dma_len, DMA_BIDIRECTIONAL);
>> -}
>> -
>> -static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
>> -					       struct scatterlist *src,
>> -					       unsigned int nbytes)
>> -{
>> -	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> -	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> -
>> -	return talitos_edesc_alloc(ctx->dev, src, NULL, NULL, 0,
>> -				   nbytes, 0, 0, 0, areq->base.flags, false);
>> -}
>> -
>> -static struct talitos_edesc *
>> -ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>> -			  unsigned int blocksize, bool is_sec1)
>> -{
>> -	struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -	struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
>> -	size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN :
>> -				    TALITOS2_MAX_DATA_LEN;
>> -	struct scatterlist tmp[2];
>> -	size_t to_hash_this_desc;
>> -	struct scatterlist *src;
>> -	size_t offset = 0;
>> -
>> -	do {
>> -		src = scatterwalk_ffwd(tmp, areq->src, offset);
>> -
>> -		to_hash_this_desc =
>> -			min(nbytes, ALIGN_DOWN(desc_max, blocksize));
>> -
>> -		/* Allocate extended descriptor */
>> -		edesc = ahash_edesc_alloc(areq, src, to_hash_this_desc);
>> -		if (IS_ERR(edesc)) {
>> -			if (first)
>> -				free_edesc_list_from(areq, first);
>> -			return edesc;
>> -		}
>> -
>> -		edesc->src = scatterwalk_ffwd(edesc->bufsl, areq->src, offset);
>> -		edesc->desc.hdr = ctx->desc_hdr_template;
>> -		edesc->first = offset == 0;
>> -		edesc->last = nbytes - to_hash_this_desc == 0;
>> -
>> -		/* On last one, request SEC to pad; otherwise continue */
>> -		if (req_ctx->last_request && edesc->last)
>> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
>> -		else
>> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
>> -
>> -		/* request SEC to INIT hash. */
>> -		if (req_ctx->first_request && edesc->first && !req_ctx->swinit)
>> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
>> -
>> -		/*
>> -		 * When the tfm context has a keylen, it's an HMAC.
>> -		 * A first or last (ie. not middle) descriptor must request HMAC.
>> -		 */
>> -		if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
>> -				    (req_ctx->last_request && edesc->last)))
>> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
>> -
>> -		/* clear the DN bit  */
>> -		if (is_sec1 && !edesc->last)
>> -			edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
>> -
>> -		common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
>> -
>> -		offset += to_hash_this_desc;
>> -		nbytes -= to_hash_this_desc;
>> -
>> -		if (!prev_edesc)
>> -			first = edesc;
>> -		else
>> -			prev_edesc->next_desc = edesc;
>> -		prev_edesc = edesc;
>> -	} while (nbytes);
>> -
>> -	return first;
>> -}
>> -
>> -static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
>> -{
>> -	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> -	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -	struct talitos_edesc *edesc;
>> -	unsigned int blocksize =
>> -			crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
>> -	bool is_sec1 = has_ftr_sec1(dev_get_drvdata(ctx->dev));
>> -	unsigned int nbytes_to_hash;
>> -	unsigned int to_hash_later;
>> -	struct device *dev = ctx->dev;
>> -	int ret;
>> -
>> -	nbytes_to_hash = ALIGN_DOWN(nbytes, blocksize);
>> -	to_hash_later = nbytes - nbytes_to_hash;
>> -
>> -	if (req_ctx->last_request) {
>> -		nbytes_to_hash = nbytes;
>> -		to_hash_later = 0;
>> -	}
>> -
>> -	req_ctx->to_hash_later = to_hash_later;
>> -
>> -	edesc = ahash_process_req_prepare(areq, nbytes_to_hash, blocksize,
>> -					  is_sec1);
>> -	if (IS_ERR(edesc))
>> -		return PTR_ERR(edesc);
>> -
>> -	ret = talitos_submit(dev, ctx->ch, &edesc->desc, ahash_done, areq);
>> -	if (ret != -EINPROGRESS)
>> -		free_edesc_list_from(areq, edesc);
>> -
>> -	return ret;
>> -}
>> -
>> -static int ahash_init(struct ahash_request *areq)
>> -{
>> -	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> -	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> -	struct device *dev = ctx->dev;
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -	unsigned int size;
>> -	dma_addr_t dma;
>> -
>> -	/* Initialize the context */
>> -	req_ctx->first_request = 1;
>> -	req_ctx->swinit = 0; /* assume h/w init of context */
>> -	size =	(crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
>> -			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
>> -			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
>> -	req_ctx->hw_context_size = size;
>> -	req_ctx->last_request = 0;
>> -
>> -	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> -			     DMA_TO_DEVICE);
>> -	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
>> -
>> -	return 0;
>> -}
>> -
>> -/*
>> - * on h/w without explicit sha224 support, we initialize h/w context
>> - * manually with sha224 constants, and tell it to run sha256.
>> - */
>> -static int ahash_init_sha224_swinit(struct ahash_request *areq)
>> -{
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -
>> -	req_ctx->hw_context[0] = SHA224_H0;
>> -	req_ctx->hw_context[1] = SHA224_H1;
>> -	req_ctx->hw_context[2] = SHA224_H2;
>> -	req_ctx->hw_context[3] = SHA224_H3;
>> -	req_ctx->hw_context[4] = SHA224_H4;
>> -	req_ctx->hw_context[5] = SHA224_H5;
>> -	req_ctx->hw_context[6] = SHA224_H6;
>> -	req_ctx->hw_context[7] = SHA224_H7;
>> -
>> -	/* init 64-bit count */
>> -	req_ctx->hw_context[8] = 0;
>> -	req_ctx->hw_context[9] = 0;
>> -
>> -	ahash_init(areq);
>> -	req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
>> -
>> -	return 0;
>> -}
>> -
>> -static int ahash_update(struct ahash_request *areq)
>> -{
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -
>> -	req_ctx->last_request = 0;
>> -
>> -	return ahash_process_req(areq, areq->nbytes);
>> -}
>> -
>> -static int ahash_final(struct ahash_request *areq)
>> -{
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -
>> -	req_ctx->last_request = 1;
>> -
>> -	return ahash_process_req(areq, 0);
>> -}
>> -
>> -static int ahash_finup(struct ahash_request *areq)
>> -{
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -
>> -	req_ctx->last_request = 1;
>> -
>> -	return ahash_process_req(areq, areq->nbytes);
>> -}
>> -
>> -static int ahash_digest(struct ahash_request *areq)
>> -{
>> -	ahash_init(areq);
>> -	return ahash_finup(areq);
>> -}
>> -
>> -static int ahash_digest_sha224_swinit(struct ahash_request *areq)
>> -{
>> -	ahash_init_sha224_swinit(areq);
>> -	return ahash_finup(areq);
>> -}
>> -
>> -static int ahash_export(struct ahash_request *areq, void *out)
>> -{
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -	struct talitos_export_state *export = out;
>> -	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> -	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> -	struct device *dev = ctx->dev;
>> -	dma_addr_t dma;
>> -
>> -	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> -			     DMA_FROM_DEVICE);
>> -	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
>> -
>> -	memcpy(export->hw_context, req_ctx->hw_context,
>> -	       req_ctx->hw_context_size);
>> -	export->swinit = req_ctx->swinit;
>> -	export->first_request = req_ctx->first_request;
>> -	export->last_request = req_ctx->last_request;
>> -	export->to_hash_later = req_ctx->to_hash_later;
>> -
>> -	return 0;
>> -}
>> -
>> -static int ahash_import(struct ahash_request *areq, const void *in)
>> -{
>> -	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> -	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> -	struct device *dev = ctx->dev;
>> -	const struct talitos_export_state *export = in;
>> -	unsigned int size;
>> -	dma_addr_t dma;
>> -
>> -	memset(req_ctx, 0, sizeof(*req_ctx));
>> -	size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
>> -			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
>> -			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
>> -	req_ctx->hw_context_size = size;
>> -	memcpy(req_ctx->hw_context, export->hw_context, size);
>> -	req_ctx->swinit = export->swinit;
>> -	req_ctx->first_request = export->first_request;
>> -	req_ctx->last_request = export->last_request;
>> -	req_ctx->to_hash_later = export->to_hash_later;
>> -
>> -	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> -			     DMA_TO_DEVICE);
>> -	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
>> -
>> -	return 0;
>> -}
>> -
>> -static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
>> -		   u8 *hash)
>> -{
>> -	struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
>> -
>> -	struct scatterlist sg[1];
>> -	struct ahash_request *req;
>> -	struct crypto_wait wait;
>> -	int ret;
>> -
>> -	crypto_init_wait(&wait);
>> -
>> -	req = ahash_request_alloc(tfm, GFP_KERNEL);
>> -	if (!req)
>> -		return -ENOMEM;
>> -
>> -	/* Keep tfm keylen == 0 during hash of the long key */
>> -	ctx->keylen = 0;
>> -	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
>> -				   crypto_req_done, &wait);
>> -
>> -	sg_init_one(&sg[0], key, keylen);
>> -
>> -	ahash_request_set_crypt(req, sg, hash, keylen);
>> -	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
>> -
>> -	ahash_request_free(req);
>> -
>> -	return ret;
>> -}
>> -
>> -static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
>> -			unsigned int keylen)
>> -{
>> -	struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
>> -	struct device *dev = ctx->dev;
>> -	unsigned int blocksize =
>> -			crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
>> -	unsigned int digestsize = crypto_ahash_digestsize(tfm);
>> -	unsigned int keysize = keylen;
>> -	u8 hash[SHA512_DIGEST_SIZE];
>> -	int ret;
>> -
>> -	if (keylen <= blocksize)
>> -		memcpy(ctx->key, key, keysize);
>> -	else {
>> -		/* Must get the hash of the long key */
>> -		ret = keyhash(tfm, key, keylen, hash);
>> -
>> -		if (ret)
>> -			return -EINVAL;
>> -
>> -		keysize = digestsize;
>> -		memcpy(ctx->key, hash, digestsize);
>> -	}
>> -
>> -	if (ctx->keylen)
>> -		dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
>> -
>> -	ctx->keylen = keysize;
>> -	ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
>> -
>> -	return 0;
>> -}
>> -
>>   static struct talitos_alg_template driver_algs[] = {
>>   	/* AEAD algorithms.  These use a single-pass ipsec_esp descriptor */
>>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
>> @@ -2737,235 +2222,6 @@ static struct talitos_alg_template driver_algs[] = {
>>   		                     DESC_HDR_MODE0_DEU_CBC |
>>   		                     DESC_HDR_MODE0_DEU_3DES,
>>   	},
>> -	/* AHASH algorithms. */
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = MD5_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "md5",
>> -				.cra_driver_name = "md5-talitos",
>> -				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUA |
>> -				     DESC_HDR_MODE0_MDEU_MD5,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA1_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "sha1",
>> -				.cra_driver_name = "sha1-talitos",
>> -				.cra_blocksize = SHA1_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUA |
>> -				     DESC_HDR_MODE0_MDEU_SHA1,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA224_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "sha224",
>> -				.cra_driver_name = "sha224-talitos",
>> -				.cra_blocksize = SHA224_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUA |
>> -				     DESC_HDR_MODE0_MDEU_SHA224,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA256_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "sha256",
>> -				.cra_driver_name = "sha256-talitos",
>> -				.cra_blocksize = SHA256_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUA |
>> -				     DESC_HDR_MODE0_MDEU_SHA256,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA384_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "sha384",
>> -				.cra_driver_name = "sha384-talitos",
>> -				.cra_blocksize = SHA384_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUB |
>> -				     DESC_HDR_MODE0_MDEUB_SHA384,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA512_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "sha512",
>> -				.cra_driver_name = "sha512-talitos",
>> -				.cra_blocksize = SHA512_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUB |
>> -				     DESC_HDR_MODE0_MDEUB_SHA512,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = MD5_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "hmac(md5)",
>> -				.cra_driver_name = "hmac-md5-talitos",
>> -				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUA |
>> -				     DESC_HDR_MODE0_MDEU_MD5,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA1_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "hmac(sha1)",
>> -				.cra_driver_name = "hmac-sha1-talitos",
>> -				.cra_blocksize = SHA1_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUA |
>> -				     DESC_HDR_MODE0_MDEU_SHA1,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA224_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "hmac(sha224)",
>> -				.cra_driver_name = "hmac-sha224-talitos",
>> -				.cra_blocksize = SHA224_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUA |
>> -				     DESC_HDR_MODE0_MDEU_SHA224,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA256_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "hmac(sha256)",
>> -				.cra_driver_name = "hmac-sha256-talitos",
>> -				.cra_blocksize = SHA256_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUA |
>> -				     DESC_HDR_MODE0_MDEU_SHA256,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA384_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "hmac(sha384)",
>> -				.cra_driver_name = "hmac-sha384-talitos",
>> -				.cra_blocksize = SHA384_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUB |
>> -				     DESC_HDR_MODE0_MDEUB_SHA384,
>> -	},
>> -	{	.type = CRYPTO_ALG_TYPE_AHASH,
>> -		.alg.hash = {
>> -			.halg.digestsize = SHA512_DIGEST_SIZE,
>> -			.halg.statesize = sizeof(struct talitos_export_state),
>> -			.halg.base = {
>> -				.cra_name = "hmac(sha512)",
>> -				.cra_driver_name = "hmac-sha512-talitos",
>> -				.cra_blocksize = SHA512_BLOCK_SIZE,
>> -				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> -				.cra_flags = CRYPTO_ALG_ASYNC |
>> -					     CRYPTO_ALG_ALLOCATES_MEMORY |
>> -					     CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> -					     CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> -			}
>> -		},
>> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -				     DESC_HDR_SEL0_MDEUB |
>> -				     DESC_HDR_MODE0_MDEUB_SHA512,
>> -	}
>>   };
>>   
>>   int talitos_init_common(struct talitos_ctx *ctx,
>> @@ -3014,22 +2270,6 @@ static int talitos_cra_init_skcipher(struct crypto_skcipher *tfm)
>>   	return talitos_init_common(ctx, talitos_alg);
>>   }
>>   
>> -static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
>> -{
>> -	struct crypto_alg *alg = tfm->__crt_alg;
>> -	struct talitos_crypto_alg *talitos_alg;
>> -	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
>> -
>> -	talitos_alg = container_of(__crypto_ahash_alg(alg),
>> -				   struct talitos_crypto_alg,
>> -				   algt.alg.hash);
>> -
>> -	ctx->keylen = 0;
>> -				 sizeof(struct talitos_ahash_req_ctx));
>> -
>> -	return talitos_init_common(ctx, talitos_alg);
>> -}
>> -
>>   void talitos_cra_exit(struct crypto_tfm *tfm)
>>   {
>>   	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
>> @@ -3128,6 +2368,12 @@ int talitos_register_common(struct device *dev,
>>   	t_alg->algt = *template;
>>   
>>   	switch (t_alg->algt.type) {
>> +	case CRYPTO_ALG_TYPE_AHASH:
>> +		alg = &t_alg->algt.alg.hash.halg.base;
>> +		talitos_alg_set_common(priv, alg, t_alg->algt.priority,
>> +				       t_alg->algt.type);
>> +		ret = crypto_register_ahash(&t_alg->algt.alg.hash);
>> +		break;
>>   	default:
>>   		dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
>>   		devm_kfree(dev, t_alg);
>> @@ -3193,37 +2439,6 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
>>   			return ERR_PTR(-ENOTSUPP);
>>   		}
>>   		break;
>> -	case CRYPTO_ALG_TYPE_AHASH:
>> -		alg = &t_alg->algt.alg.hash.halg.base;
>> -		alg->cra_init = talitos_cra_init_ahash;
>> -		alg->cra_exit = talitos_cra_exit;
>> -		t_alg->algt.alg.hash.init = ahash_init;
>> -		t_alg->algt.alg.hash.update = ahash_update;
>> -		t_alg->algt.alg.hash.final = ahash_final;
>> -		t_alg->algt.alg.hash.finup = ahash_finup;
>> -		t_alg->algt.alg.hash.digest = ahash_digest;
>> -		if (!strncmp(alg->cra_name, "hmac", 4))
>> -			t_alg->algt.alg.hash.setkey = ahash_setkey;
>> -		t_alg->algt.alg.hash.import = ahash_import;
>> -		t_alg->algt.alg.hash.export = ahash_export;
>> -
>> -		if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
>> -		    !strncmp(alg->cra_name, "hmac", 4)) {
>> -			devm_kfree(dev, t_alg);
>> -			return ERR_PTR(-ENOTSUPP);
>> -		}
>> -		if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
>> -		    (!strcmp(alg->cra_name, "sha224") ||
>> -		     !strcmp(alg->cra_name, "hmac(sha224)"))) {
>> -			t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
>> -			t_alg->algt.alg.hash.digest =
>> -				ahash_digest_sha224_swinit;
>> -			t_alg->algt.desc_hdr_template =
>> -					DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> -					DESC_HDR_SEL0_MDEUA |
>> -					DESC_HDR_MODE0_MDEU_SHA256;
>> -		}
>> -		break;
>>   	default:
>>   		dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
>>   		devm_kfree(dev, t_alg);
>> @@ -3452,6 +2667,10 @@ static int talitos_probe(struct platform_device *ofdev)
>>   			dev_info(dev, "hwrng\n");
>>   	}
>>   
>> +	err = talitos_register_hash(dev);
>> +	if (err)
>> +		goto err_out;
>> +
>>   	/* register crypto algorithms the device supports */
>>   	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
>>   		if (talitos_hw_supports(dev,
>> @@ -3479,12 +2698,6 @@ static int talitos_probe(struct platform_device *ofdev)
>>   					&t_alg->algt.alg.aead);
>>   				alg = &t_alg->algt.alg.aead.base;
>>   				break;
>> -
>> -			case CRYPTO_ALG_TYPE_AHASH:
>> -				err = crypto_register_ahash(
>> -						&t_alg->algt.alg.hash);
>> -				alg = &t_alg->algt.alg.hash.halg.base;
>> -				break;
>>   			}
>>   			if (err) {
>>   				dev_err(dev, "%s alg registration failed\n",
>> diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
>> index afed9947f4c0..e703c18cb81f 100644
>> --- a/drivers/crypto/talitos/talitos.h
>> +++ b/drivers/crypto/talitos/talitos.h
>> @@ -530,3 +530,7 @@ int talitos_register_common(struct device *dev,
>>   
>>   int talitos_register_rng(struct device *dev);
>>   void talitos_unregister_rng(struct device *dev);
>> +
>> +/* Hash */
>> +
>> +int talitos_register_hash(struct device *dev);


Thanks,

Paul.




-- 
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH v19 00/14] crypto/dmaengine: qce: introduce BAM locking and use DMA for register I/O
From: Bartosz Golaszewski @ 2026-06-04 11:50 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Bartosz Golaszewski, Jonathan Corbet, Thara Gopinath, Herbert Xu,
	David S. Miller, Udit Tiwari, Md Sadre Alam, Dmitry Baryshkov,
	Manivannan Sadhasivam, Bjorn Andersson, Peter Ujfalusi,
	Michal Simek, Frank Li, Andy Gross, Neil Armstrong, dmaengine,
	linux-doc, linux-kernel, linux-arm-msm, linux-crypto,
	linux-arm-kernel, brgl, Bartosz Golaszewski, Dmitry Baryshkov,
	Konrad Dybcio, Stephan Gerhold
In-Reply-To: <aiFScCW_NEY3CsEf@vaman>

On Thu, 4 Jun 2026 12:24:48 +0200, Vinod Koul <vkoul@kernel.org> said:
> On 02-06-26, 18:38, Stephan Gerhold wrote:
>> On Tue, May 26, 2026 at 03:10:48PM +0200, Bartosz Golaszewski wrote:
>> > I feel like I fell into the trap of trying to address pre-existing
>> > issues reported by sashiko and in the process provoking more reports so
>> > let this be the last iteration where I do this. Vinod can we get this
>> > queued for v7.2 now and iron out any previously existing problems in
>> > tree?
>>
>> Thanks a lot for working on fixing all these issues!
>>
>> I agree there is no point addressing all the "pre-existing issues"
>> pointed out by Sashiko, but have you looked through the other comments
>> for new issues pointed out for your patches?
>
> I hope Bart and Qualcomm can fix these driver issues as well
>>
>> Out of curiosity, I was looking a bit at the comments for [PATCH v19
>> 06/14] dmaengine: qcom: bam_dma: add support for BAM locking [1]. There
>> are 8 open comments there (Critical: 1, High: 6 and Medium: 1). From a
>> quick look I would say most of these could be valid. The critical one
>> about the usage of dma_cookie_assign() sounds a bit concerning to me, if
>> it is true we would be basically breaking parts of the dmaengine API for
>> consumers by inserting the lock descriptor in front of everything else.
>
> Yes this seems to be a valid one. Attaching another descriptor for lock
> does not sound right to me, as in this case causes descriptor to be
> marked 'done' prematurely.
>

Yes, I have a fix for this queued.

> Honestly, I am not quite happy with the way lock is being handled here.
> I would hope we can have some better suggestions. Adding a descriptor
> for lock does not look right to me. We are adding odd hardware/firmware
> behaviour on engine apis.
>
> I had earlier suggested to lock always or lock only for hw/sw versions
> supported inside the driver, that might be simplist solution without the
> complexity added here
>

I'm not sure what you mean here. Several iterations ago it was deferred to
consumer drivers. Mani objected and Bjorn and you agreed. I reworked it to move
the locking logic into the DMA driver as requested.

Bart

^ permalink raw reply

* Re: [PATCH] rhashtable: Use irq work for shrinking
From: Mykyta Yatsenko @ 2026-06-04 10:47 UTC (permalink / raw)
  To: Herbert Xu
  Cc: bot+bpf-ci, bpf, ast, andrii, daniel, kafai, kernel-team, eddyz87,
	memxor, yatsenko, martin.lau, yonghong.song, clm, ihor.solodrai,
	Tejun Heo, Linux Crypto Mailing List
In-Reply-To: <aiDgUPXZUi-jnTdo@gondor.apana.org.au>


On 6/4/26 3:17 AM, Herbert Xu wrote:
> On Wed, Jun 03, 2026 at 02:08:25PM +0100, Mykyta Yatsenko wrote:
>>
>> For v7 I'm dropping automatic_shrinking, because it adds a risk of
>> calling schedule_work() on element deletion path (__rhashtable_remove_fast_one())
>> when hashtable size drops below 30% of the capacity.
> 
> Now that expansion uses irq work I think shrinking should switch
> to that as well.
> 

Makes sense, thanks, I'll include your patch below in this series then.

> ---8<---
> Use irq work for automatic shrinking so that this may be called
> in NMI context.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> 
> diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
> index ef5230cece36..0693bce6f890 100644
> --- a/include/linux/rhashtable.h
> +++ b/include/linux/rhashtable.h
> @@ -1117,7 +1117,7 @@ static __always_inline int __rhashtable_remove_fast_one(
>  		atomic_dec(&ht->nelems);
>  		if (unlikely(ht->p.automatic_shrinking &&
>  			     rht_shrink_below_30(ht, tbl)))
> -			schedule_work(&ht->run_work);
> +			irq_work_queue(&ht->run_irq_work);
>  		err = 0;
>  	}
>  
> Cheers,


^ permalink raw reply

* [PATCH] crypto: tegra: fix refcount leak in tegra_se_host1x_submit()
From: Wentao Liang @ 2026-06-04 10:27 UTC (permalink / raw)
  To: akhilrajeev, herbert, davem, thierry.reding, jonathanh
  Cc: linux-crypto, linux-tegra, linux-kernel, Wentao Liang, stable

The timeout error path in tegra_se_host1x_submit() returns without
calling host1x_job_put(), while all other paths (success, submit
error, pin error) properly release the job reference through the
job_put label.  Since host1x_job_alloc() initializes the reference
count and host1x_job_put() is required to drop it, omitting it on
timeout causes a permanent refcount leak.

Fix this by redirecting the timeout return to the existing job_put
label, ensuring the job reference and any associated syncpt
references are consistently released.

Cc: stable@vger.kernel.org
Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
 drivers/crypto/tegra/tegra-se-main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/tegra/tegra-se-main.c b/drivers/crypto/tegra/tegra-se-main.c
index eb71113ed146..e8d8c3a23d7a 100644
--- a/drivers/crypto/tegra/tegra-se-main.c
+++ b/drivers/crypto/tegra/tegra-se-main.c
@@ -180,7 +180,7 @@ int tegra_se_host1x_submit(struct tegra_se *se, struct tegra_se_cmdbuf *cmdbuf,
 				 MAX_SCHEDULE_TIMEOUT, NULL);
 	if (ret) {
 		dev_err(se->dev, "host1x job timed out\n");
-		return ret;
+		goto job_put;
 	}
 
 	host1x_job_put(job);
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v19 00/14] crypto/dmaengine: qce: introduce BAM locking and use DMA for register I/O
From: Vinod Koul @ 2026-06-04 10:24 UTC (permalink / raw)
  To: Stephan Gerhold
  Cc: Bartosz Golaszewski, Jonathan Corbet, Thara Gopinath, Herbert Xu,
	David S. Miller, Udit Tiwari, Md Sadre Alam, Dmitry Baryshkov,
	Manivannan Sadhasivam, Bjorn Andersson, Peter Ujfalusi,
	Michal Simek, Frank Li, Andy Gross, Neil Armstrong, dmaengine,
	linux-doc, linux-kernel, linux-arm-msm, linux-crypto,
	linux-arm-kernel, brgl, Bartosz Golaszewski, Dmitry Baryshkov,
	Konrad Dybcio
In-Reply-To: <ah8G_ajPS1KhgPP_@linaro.org>

On 02-06-26, 18:38, Stephan Gerhold wrote:
> On Tue, May 26, 2026 at 03:10:48PM +0200, Bartosz Golaszewski wrote:
> > I feel like I fell into the trap of trying to address pre-existing
> > issues reported by sashiko and in the process provoking more reports so
> > let this be the last iteration where I do this. Vinod can we get this
> > queued for v7.2 now and iron out any previously existing problems in
> > tree?
> 
> Thanks a lot for working on fixing all these issues!
> 
> I agree there is no point addressing all the "pre-existing issues"
> pointed out by Sashiko, but have you looked through the other comments
> for new issues pointed out for your patches?

I hope Bart and Qualcomm can fix these driver issues as well
> 
> Out of curiosity, I was looking a bit at the comments for [PATCH v19
> 06/14] dmaengine: qcom: bam_dma: add support for BAM locking [1]. There
> are 8 open comments there (Critical: 1, High: 6 and Medium: 1). From a
> quick look I would say most of these could be valid. The critical one
> about the usage of dma_cookie_assign() sounds a bit concerning to me, if
> it is true we would be basically breaking parts of the dmaengine API for
> consumers by inserting the lock descriptor in front of everything else.

Yes this seems to be a valid one. Attaching another descriptor for lock
does not sound right to me, as in this case causes descriptor to be
marked 'done' prematurely.

Honestly, I am not quite happy with the way lock is being handled here.
I would hope we can have some better suggestions. Adding a descriptor
for lock does not look right to me. We are adding odd hardware/firmware
behaviour on engine apis.

I had earlier suggested to lock always or lock only for hw/sw versions
supported inside the driver, that might be simplist solution without the
complexity added here

-- 
~Vinod

^ permalink raw reply

* [PATCH] crypto: chelsio: fix refcount leaks in ahash request functions
From: Wentao Liang @ 2026-06-04 10:13 UTC (permalink / raw)
  To: ayush.sawal, herbert, davem
  Cc: linux-crypto, linux-kernel, Wentao Liang, stable

When chcr_send_wr() fails in chcr_ahash_finup(), chcr_ahash_final(),
chcr_ahash_update(), or chcr_ahash_digest(), the function still returns
-EINPROGRESS to the crypto layer, claiming the request has been
submitted.  No completion callback will be triggered because the work
request was not actually handed over to the hardware, so the
dev->inflight refcount that was incremented by chcr_inc_wrcount() is
never decremented.  This permanently prevents device detach and leads
to a resource leak.

Check the return value of chcr_send_wr() and jump to the error unmap
path on failure so that the refcount is properly undone before
returning an error.

Cc: stable@vger.kernel.org
Fixes: 324429d74127 ("chcr: Support for Chelsio's Crypto Hardware")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
 drivers/crypto/chelsio/chcr_algo.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c
index 14a708defcd4..142eccaf82fe 100644
--- a/drivers/crypto/chelsio/chcr_algo.c
+++ b/drivers/crypto/chelsio/chcr_algo.c
@@ -1877,7 +1877,10 @@ static int chcr_ahash_finup(struct ahash_request *req)
 	req_ctx->hctx_wr.processed += params.sg_len;
 	skb->dev = u_ctx->lldi.ports[0];
 	set_wr_txq(skb, CPL_PRIORITY_DATA, req_ctx->txqidx);
-	chcr_send_wr(skb);
+	if (chcr_send_wr(skb)) {
+		error = -EIO;
+		goto unmap;
+	}
 	return -EINPROGRESS;
 unmap:
 	chcr_hash_dma_unmap(&u_ctx->lldi.pdev->dev, req);
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH 29/29] crypto: talitos - Remove TALITOS_DESC_SIZE macro
From: Christophe Leroy (CS GROUP) @ 2026-06-04  9:59 UTC (permalink / raw)
  To: Paul Louvel, Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <20260528-7-1-rc1_talitos_cleanup-v1-29-cb1ad6cdea49@bootlin.com>



Le 28/05/2026 à 11:08, Paul Louvel a écrit :
> Now that struct talitos_desc no longer has the SEC1-only next_desc field
> (it was moved into sec1_talitos_desc), TALITOS_DESC_SIZE is identical to
> sizeof(struct talitos_desc) and no longer serves any purpose. Remove it
> and use sizeof directly at each macro invocation.

It is still there ...

$ git grep TALITOS_DESC_SIZE drivers
drivers/crypto/talitos/talitos.h:#define TALITOS_DESC_SIZE 
sizeof(struct talitos_desc)


> 
> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
> ---
>   drivers/crypto/talitos/talitos-sec1.c | 10 +++++-----
>   drivers/crypto/talitos/talitos-sec2.c |  6 +++---
>   2 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/crypto/talitos/talitos-sec1.c b/drivers/crypto/talitos/talitos-sec1.c
> index e4f482520372..504ce9e23e59 100644
> --- a/drivers/crypto/talitos/talitos-sec1.c
> +++ b/drivers/crypto/talitos/talitos-sec1.c
> @@ -190,7 +190,7 @@ static void sec1_dma_map_request(struct device *dev,
>   	while (edesc) {
>   
>   		dma_desc = dma_map_single(dev, &edesc->desc.sec1.hdr,
> -					  TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
> +					  sizeof(struct talitos_desc), DMA_BIDIRECTIONAL);
>   
>   		if (!prev_edesc) {
>   			request->dma_desc = dma_desc;
> @@ -202,7 +202,7 @@ static void sec1_dma_map_request(struct device *dev,
>   		prev_edesc->desc.sec1.next_desc = cpu_to_be32(dma_desc);
>   
>   		dma_sync_single_for_device(dev, prev_dma_desc,
> -					   TALITOS_DESC_SIZE, DMA_TO_DEVICE);
> +					   sizeof(struct talitos_desc), DMA_TO_DEVICE);
>   
>   next:
>   		prev_edesc = edesc;
> @@ -216,12 +216,12 @@ static void sec1_dma_unmap_request(struct device *dev,
>   {
>   	struct talitos_edesc *edesc;
>   
> -	dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
> +	dma_unmap_single(dev, request->dma_desc, sizeof(struct talitos_desc),
>   			 DMA_BIDIRECTIONAL);
>   	edesc = container_of(request->desc, struct talitos_edesc, desc);
>   	while (edesc->next_desc) {
>   		dma_unmap_single(dev, be32_to_cpu(edesc->desc.sec1.next_desc),
> -				 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
> +				 sizeof(struct talitos_desc), DMA_BIDIRECTIONAL);
>   		edesc = edesc->next_desc;
>   	}
>   }
> @@ -239,7 +239,7 @@ static __be32 sec1_get_request_hdr(struct device *dev,
>   		edesc = edesc->next_desc;
>   	}
>   
> -	dma_sync_single_for_cpu(dev, dma_desc, TALITOS_DESC_SIZE,
> +	dma_sync_single_for_cpu(dev, dma_desc, sizeof(struct talitos_desc),
>   				DMA_BIDIRECTIONAL);
>   
>   	return edesc->desc.sec1.hdr;
> diff --git a/drivers/crypto/talitos/talitos-sec2.c b/drivers/crypto/talitos/talitos-sec2.c
> index 52f783ddc8b6..0df3b22510c7 100644
> --- a/drivers/crypto/talitos/talitos-sec2.c
> +++ b/drivers/crypto/talitos/talitos-sec2.c
> @@ -205,7 +205,7 @@ static void sec2_dma_map_request(struct device *dev,
>   				 struct talitos_desc *desc)
>   {
>   	request->dma_desc =
> -		dma_map_single(dev, desc, TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
> +		dma_map_single(dev, desc, sizeof(struct talitos_desc), DMA_BIDIRECTIONAL);
>   }
>   
>   static int sec2_talitos_handle_error(struct device *dev, u32 isr, u32 isr_lo)
> @@ -346,14 +346,14 @@ static void sec2_init_task(struct device *dev)
>   static void sec2_dma_unmap_request(struct device *dev,
>   				   struct talitos_request *request)
>   {
> -	dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
> +	dma_unmap_single(dev, request->dma_desc, sizeof(struct talitos_desc),
>   			 DMA_BIDIRECTIONAL);
>   }
>   
>   static __be32 sec2_get_request_hdr(struct device *dev,
>   				   struct talitos_request *request)
>   {
> -	dma_sync_single_for_cpu(dev, request->dma_desc, TALITOS_DESC_SIZE,
> +	dma_sync_single_for_cpu(dev, request->dma_desc, sizeof(struct talitos_desc),
>   				DMA_BIDIRECTIONAL);
>   
>   	return request->desc->sec2.hdr;
> 


^ permalink raw reply

* Re: [PATCH 27/29] crypto: talitos - Introduce per-SEC-version descriptor structures and ops
From: Christophe Leroy (CS GROUP) @ 2026-06-04  9:57 UTC (permalink / raw)
  To: Paul Louvel, Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <20260528-7-1-rc1_talitos_cleanup-v1-27-cb1ad6cdea49@bootlin.com>



Le 28/05/2026 à 11:08, Paul Louvel a écrit :
> The driver used a single shared talitos_desc with overlapping union
> members and a SEC1-specific "hdr1" hack to handle differences between
> SEC1 and SEC2 descriptor layouts.

I'd call it a feature not a hack. We have the chance that allthough 
different the structures are very close and can be kept common at the 
low price of that copy from hdr to hdr1 in talitos submit.

> 
> Introduce distinct sec1_talitos_desc/sec2_talitos_desc and
> sec1_talitos_ptr/sec2_talitos_ptr structures, nested inside a union
> in talitos_desc/talitos_ptr.
> Mark them packed to reflect that these structures are used directly by
> the hardware, even if the structure is naturally aligned.
> 
> Abstract descriptor field access through a new talitos_desc_ops
> structure (set_hdr, get_hdr, get_hdr_lo, get_ptr), and add get_ptr_value
> to the existing talitos_ptr_ops.

Too much abstraction and opacity kills readability and maintainability. 
Especially here your change increases the number of places you have to 
break instructions in two lines or more. This really kills readability.

I really prefer reading

   &edesc->desc.ptr[6]

over

   ctx->desc_ops->get_ptr(&edesc->desc, 6)



> 
> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
> ---
>   drivers/crypto/talitos/talitos-aead.c     | 76 +++++++++++++++++++------------
>   drivers/crypto/talitos/talitos-hash.c     | 51 +++++++++++++--------
>   drivers/crypto/talitos/talitos-sec1.c     | 61 +++++++++++++++++++------
>   drivers/crypto/talitos/talitos-sec2.c     | 56 ++++++++++++++++++-----
>   drivers/crypto/talitos/talitos-skcipher.c | 46 +++++++++++--------
>   drivers/crypto/talitos/talitos.c          |  4 +-
>   drivers/crypto/talitos/talitos.h          | 60 +++++++++++++++++-------
>   7 files changed, 244 insertions(+), 110 deletions(-)
> 
> diff --git a/drivers/crypto/talitos/talitos-aead.c b/drivers/crypto/talitos/talitos-aead.c
> index b585abdd2275..d1cec7e4dd3f 100644
> --- a/drivers/crypto/talitos/talitos-aead.c
> +++ b/drivers/crypto/talitos/talitos-aead.c
> @@ -94,12 +94,15 @@ static void ipsec_esp_unmap(struct device *dev,
>   	unsigned int ivsize = crypto_aead_ivsize(aead);
>   	unsigned int authsize = crypto_aead_authsize(aead);
>   	unsigned int cryptlen = areq->cryptlen - (encrypt ? 0 : authsize);
> -	bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
> -	struct talitos_ptr *civ_ptr = &edesc->desc.ptr[is_ipsec_esp ? 2 : 3];
> +	bool is_ipsec_esp = ctx->desc_ops->get_hdr(&edesc->desc) &
> +			    DESC_HDR_TYPE_IPSEC_ESP;
> +	struct talitos_ptr *civ_ptr =
> +		ctx->desc_ops->get_ptr(&edesc->desc, is_ipsec_esp ? 2 : 3);
>   
>   	if (is_ipsec_esp)
> -		unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6],
> -					 DMA_FROM_DEVICE);
> +		unmap_single_talitos_ptr(
> +			dev, ctx->desc_ops->get_ptr(&edesc->desc, 6),
> +			DMA_FROM_DEVICE);
>   	unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
>   
>   	talitos_sg_unmap(dev, edesc, areq->src, areq->dst,
> @@ -171,6 +174,7 @@ static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
>   					  struct talitos_desc *desc,
>   					  void *context, int err)
>   {
> +	struct talitos_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(context));
>   	struct aead_request *req = context;
>   	struct talitos_edesc *edesc;
>   
> @@ -179,8 +183,8 @@ static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
>   	ipsec_esp_unmap(dev, edesc, req, false);
>   
>   	/* check ICV auth status */
> -	if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
> -		     DESC_HDR_LO_ICCR1_PASS))
> +	if (!err && ((ctx->desc_ops->get_hdr_lo(desc) &
> +		      DESC_HDR_LO_ICCR1_MASK) != DESC_HDR_LO_ICCR1_PASS))
>   		err = -EBADMSG;
>   
>   	kfree(edesc);
> @@ -210,13 +214,17 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>   	bool sync_needed = false;
>   	struct talitos_private *priv = dev_get_drvdata(dev);
>   	bool is_sec1 = has_ftr_sec1(priv);
> -	bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
> -	struct talitos_ptr *civ_ptr = &desc->ptr[is_ipsec_esp ? 2 : 3];
> -	struct talitos_ptr *ckey_ptr = &desc->ptr[is_ipsec_esp ? 3 : 2];
> +	bool is_ipsec_esp = ctx->desc_ops->get_hdr(desc) &
> +			    DESC_HDR_TYPE_IPSEC_ESP;
> +	struct talitos_ptr *civ_ptr =
> +		ctx->desc_ops->get_ptr(desc, is_ipsec_esp ? 2 : 3);
> +	struct talitos_ptr *ckey_ptr =
> +		ctx->desc_ops->get_ptr(desc, is_ipsec_esp ? 3 : 2);
>   	dma_addr_t dma_icv = edesc->dma_link_tbl + edesc->dma_len - authsize;
>   
>   	/* hmac key */
> -	ctx->ptr_ops->to_talitos_ptr(&desc->ptr[0], ctx->dma_key, ctx->authkeylen);
> +	ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 0),
> +				     ctx->dma_key, ctx->authkeylen);
>   
>   	sg_count = edesc->src_nents ?: 1;
>   	if (is_sec1 && sg_count > 1)
> @@ -229,7 +237,8 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>   
>   	/* hmac data */
>   	ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
> -			     &desc->ptr[1], sg_count, 0, tbl_off);
> +			     ctx->desc_ops->get_ptr(desc, 1), sg_count, 0,
> +			     tbl_off);
>   
>   	if (ret > 1) {
>   		tbl_off += ret;
> @@ -249,12 +258,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>   	 * extent is bytes of HMAC postpended to ciphertext,
>   	 * typically 12 for ipsec
>   	 */
> -	if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
> +	if (is_ipsec_esp &&
> +	    (ctx->desc_ops->get_hdr(desc) & DESC_HDR_MODE1_MDEU_CICV))
>   		elen = authsize;
>   
> -	ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
> -				 sg_count, areq->assoclen, tbl_off, elen,
> -				 false, 1);
> +	ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc,
> +				 ctx->desc_ops->get_ptr(desc, 4), sg_count,
> +				 areq->assoclen, tbl_off, elen, false, 1);
>   
>   	if (ret > 1) {
>   		tbl_off += ret;
> @@ -272,8 +282,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>   		elen = authsize;
>   	else
>   		elen = 0;
> -	ret = talitos_sg_map_ext(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
> -				 sg_count, areq->assoclen, tbl_off, elen,
> +	ret = talitos_sg_map_ext(dev, areq->dst, cryptlen, edesc,
> +				 ctx->desc_ops->get_ptr(desc, 5), sg_count,
> +				 areq->assoclen, tbl_off, elen,
>   				 is_ipsec_esp && !encrypt, 1);
>   	tbl_off += ret;
>   
> @@ -286,20 +297,23 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
>   
>   		/* icv data follows link tables */
>   		ctx->ptr_ops->to_talitos_ptr(tbl_ptr, dma_icv, authsize);
> -		ctx->ptr_ops->to_talitos_ptr_ext_or(&desc->ptr[5], authsize);
> +		ctx->ptr_ops->to_talitos_ptr_ext_or(
> +			ctx->desc_ops->get_ptr(desc, 5), authsize);
>   		sync_needed = true;
>   	} else if (!encrypt) {
> -		ctx->ptr_ops->to_talitos_ptr(&desc->ptr[6], dma_icv, authsize);
> +		ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 6),
> +					     dma_icv, authsize);
>   		sync_needed = true;
>   	} else if (!is_ipsec_esp) {
> -		talitos_sg_map(dev, areq->dst, authsize, edesc, &desc->ptr[6],
> -			       sg_count, areq->assoclen + cryptlen, tbl_off);
> +		talitos_sg_map(dev, areq->dst, authsize, edesc,
> +			       ctx->desc_ops->get_ptr(desc, 6), sg_count,
> +			       areq->assoclen + cryptlen, tbl_off);
>   	}
>   
>   	/* iv out */
>   	if (is_ipsec_esp)
> -		map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
> -				       DMA_FROM_DEVICE);
> +		map_single_talitos_ptr(dev, ctx->desc_ops->get_ptr(desc, 6),
> +				       ivsize, ctx->iv, DMA_FROM_DEVICE);
>   
>   	if (sync_needed)
>   		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
> @@ -341,7 +355,7 @@ static int aead_encrypt(struct aead_request *req)
>   		return PTR_ERR(edesc);
>   
>   	/* set encrypt */
> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
> +	ctx->desc_ops->set_hdr(&edesc->desc, ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT);
>   
>   	return ipsec_esp(edesc, req, true, ipsec_esp_encrypt_done);
>   }
> @@ -354,21 +368,24 @@ static int aead_decrypt(struct aead_request *req)
>   	struct talitos_private *priv = dev_get_drvdata(ctx->dev);
>   	struct talitos_edesc *edesc;
>   	void *icvdata;
> +	__be32 hdr;
>   
>   	/* allocate extended descriptor */
>   	edesc = aead_edesc_alloc(req, req->iv, 1, false);
>   	if (IS_ERR(edesc))
>   		return PTR_ERR(edesc);
>   
> -	if ((edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP) &&
> +	hdr = ctx->desc_ops->get_hdr(&edesc->desc);
> +	if ((hdr & DESC_HDR_TYPE_IPSEC_ESP) &&
>   	    (priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
>   	    ((!edesc->src_nents && !edesc->dst_nents) ||
>   	     priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
>   
>   		/* decrypt and check the ICV */
> -		edesc->desc.hdr = ctx->desc_hdr_template |
> -				  DESC_HDR_DIR_INBOUND |
> -				  DESC_HDR_MODE1_MDEU_CICV;
> +		ctx->desc_ops->set_hdr(&edesc->desc,
> +				       ctx->desc_hdr_template |
> +					       DESC_HDR_DIR_INBOUND |
> +					       DESC_HDR_MODE1_MDEU_CICV);
>   
>   		/* reset integrity check result bits */
>   
> @@ -377,7 +394,8 @@ static int aead_decrypt(struct aead_request *req)
>   	}
>   
>   	/* Have to check the ICV with software */
> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
> +	ctx->desc_ops->set_hdr(&edesc->desc,
> +			       ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND);
>   
>   	/* stash incoming ICV for later cmp with ICV generated by the h/w */
>   	icvdata = edesc->buf + edesc->dma_len;
> diff --git a/drivers/crypto/talitos/talitos-hash.c b/drivers/crypto/talitos/talitos-hash.c
> index 026eebf037f5..fb4d53e2abf8 100644
> --- a/drivers/crypto/talitos/talitos-hash.c
> +++ b/drivers/crypto/talitos/talitos-hash.c
> @@ -44,7 +44,8 @@ static void common_nonsnoop_hash_unmap(struct talitos_ctx *ctx,
>   	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>   	struct talitos_desc *desc = &edesc->desc;
>   
> -	unmap_single_talitos_ptr(ctx->dev, &desc->ptr[5], DMA_FROM_DEVICE);
> +	unmap_single_talitos_ptr(ctx->dev, ctx->desc_ops->get_ptr(desc, 5),
> +				 DMA_FROM_DEVICE);
>   
>   	if (edesc->last && req_ctx->last_request)
>   		memcpy(areq->result, req_ctx->hw_context,
> @@ -54,8 +55,9 @@ static void common_nonsnoop_hash_unmap(struct talitos_ctx *ctx,
>   		talitos_sg_unmap(ctx->dev, edesc, edesc->src, NULL, 0, 0);
>   
>   	/* When using hashctx-in, must unmap it. */
> -	if (ctx->ptr_ops->from_talitos_ptr_len(&desc->ptr[1]))
> -		unmap_single_talitos_ptr(ctx->dev, &desc->ptr[1],
> +	if (ctx->ptr_ops->from_talitos_ptr_len(ctx->desc_ops->get_ptr(desc, 1)))
> +		unmap_single_talitos_ptr(ctx->dev,
> +					 ctx->desc_ops->get_ptr(desc, 1),
>   					 DMA_TO_DEVICE);
>   
>   	if (edesc->dma_len)
> @@ -131,7 +133,9 @@ static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
>   	};
>   
>   	pr_err_once("Bug in SEC1, padding ourself\n");
> -	edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
> +	ctx->desc_ops->set_hdr(&edesc->desc,
> +			       ctx->desc_ops->get_hdr(&edesc->desc) &
> +				       ~DESC_HDR_MODE0_MDEU_PAD);
>   	map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
>   			       (char *)padded_hash, DMA_TO_DEVICE);
>   }
> @@ -154,7 +158,8 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>   
>   	/* hash context in */
>   	if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) {
> -		map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
> +		map_single_talitos_ptr_nosync(dev,
> +					      ctx->desc_ops->get_ptr(desc, 1),
>   					      req_ctx->hw_context_size,
>   					      req_ctx->hw_context,
>   					      DMA_TO_DEVICE);
> @@ -165,8 +170,8 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>   
>   	/* HMAC key */
>   	if (ctx->keylen)
> -		ctx->ptr_ops->to_talitos_ptr(&desc->ptr[2], ctx->dma_key,
> -					     ctx->keylen);
> +		ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 2),
> +					     ctx->dma_key, ctx->keylen);
>   
>   	sg_count = edesc->src_nents ?: 1;
>   	if (is_sec1 && sg_count > 1)
> @@ -177,8 +182,10 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>   	/*
>   	 * data in
>   	 */
> -	sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
> -				  sg_count, 0, 0);
> +	sg_count = talitos_sg_map(dev, edesc->src, length, edesc,
> +				  ctx->desc_ops->get_ptr(desc, 3), sg_count, 0,
> +				  0);
> +
>   	if (sg_count > 1)
>   		sync_needed = true;
>   
> @@ -186,19 +193,22 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>   
>   	/* hash/HMAC out -or- hash context out */
>   	if (edesc->last && req_ctx->last_request)
> -		map_single_talitos_ptr(dev, &desc->ptr[5],
> +		map_single_talitos_ptr(dev, ctx->desc_ops->get_ptr(desc, 5),
>   				       crypto_ahash_digestsize(tfm),
>   				       req_ctx->hw_context, DMA_FROM_DEVICE);
>   	else
> -		map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
> +		map_single_talitos_ptr_nosync(dev,
> +					      ctx->desc_ops->get_ptr(desc, 5),
>   					      req_ctx->hw_context_size,
>   					      req_ctx->hw_context,
>   					      DMA_FROM_DEVICE);
>   
>   	/* last DWORD empty */
>   
> -	if (is_sec1 && ctx->ptr_ops->from_talitos_ptr_len(&desc->ptr[3]) == 0)
> -		talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
> +	if (is_sec1 && ctx->ptr_ops->from_talitos_ptr_len(
> +			       ctx->desc_ops->get_ptr(desc, 3)) == 0)
> +		talitos_handle_buggy_hash(ctx, edesc,
> +					  ctx->desc_ops->get_ptr(desc, 3));
>   
>   	if (sync_needed)
>   		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
> @@ -229,6 +239,7 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>   	size_t to_hash_this_desc;
>   	struct scatterlist *src;
>   	size_t offset = 0;
> +	__be32 hdr;
>   
>   	do {
>   		src = scatterwalk_ffwd(tmp, areq->src, offset);
> @@ -245,19 +256,19 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>   		}
>   
>   		edesc->src = scatterwalk_ffwd(edesc->bufsl, areq->src, offset);
> -		edesc->desc.hdr = ctx->desc_hdr_template;
> +		hdr = ctx->desc_hdr_template;
>   		edesc->first = offset == 0;
>   		edesc->last = nbytes - to_hash_this_desc == 0;
>   
>   		/* On last one, request SEC to pad; otherwise continue */
>   		if (req_ctx->last_request && edesc->last)
> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
> +			hdr |= DESC_HDR_MODE0_MDEU_PAD;
>   		else
> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
> +			hdr |= DESC_HDR_MODE0_MDEU_CONT;
>   
>   		/* request SEC to INIT hash. */
>   		if (req_ctx->first_request && edesc->first && !req_ctx->swinit)
> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
> +			hdr |= DESC_HDR_MODE0_MDEU_INIT;
>   
>   		/*
>   		 * When the tfm context has a keylen, it's an HMAC.
> @@ -265,11 +276,13 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>   		 */
>   		if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
>   				    (req_ctx->last_request && edesc->last)))
> -			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
> +			hdr |= DESC_HDR_MODE0_MDEU_HMAC;
>   
>   		/* clear the DN bit  */
>   		if (is_sec1 && !edesc->last)
> -			edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
> +			hdr &= ~DESC_HDR_DONE_NOTIFY;
> +
> +		ctx->desc_ops->set_hdr(&edesc->desc, hdr);
>   
>   		common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
>   
> diff --git a/drivers/crypto/talitos/talitos-sec1.c b/drivers/crypto/talitos/talitos-sec1.c
> index ef1bd19b6772..e4f482520372 100644
> --- a/drivers/crypto/talitos/talitos-sec1.c
> +++ b/drivers/crypto/talitos/talitos-sec1.c
> @@ -76,20 +76,20 @@ DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
>   static void sec1_to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
>   				unsigned int len)
>   {
> -	ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
> -	ptr->len1 = cpu_to_be16(len);
> +	ptr->sec1.ptr = cpu_to_be32(lower_32_bits(dma_addr));
> +	ptr->sec1.len = cpu_to_be16(len);
>   }
>   
>   static void sec1_copy_talitos_ptr(struct talitos_ptr *dst_ptr,
>   				  struct talitos_ptr *src_ptr)
>   {
> -	dst_ptr->ptr = src_ptr->ptr;
> -	dst_ptr->len1 = src_ptr->len1;
> +	dst_ptr->sec1.ptr = src_ptr->sec1.ptr;
> +	dst_ptr->sec1.len = src_ptr->sec1.len;
>   }
>   
>   static unsigned short sec1_from_talitos_ptr_len(struct talitos_ptr *ptr)
>   {
> -	return be16_to_cpu(ptr->len1);
> +	return be16_to_cpu(ptr->sec1.len);
>   }
>   
>   static void sec1_to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val)
> @@ -100,6 +100,31 @@ static void sec1_to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val)
>   {
>   }
>   
> +static __be32 sec1_get_ptr_value(struct talitos_ptr *ptr)
> +{
> +	return ptr->sec1.ptr;
> +}
> +
> +static __be32 sec1_get_hdr(struct talitos_desc *desc)
> +{
> +	return desc->sec1.hdr;
> +}
> +
> +static __be32 sec1_get_hdr_lo(struct talitos_desc *desc)
> +{
> +	return 0;
> +}
> +
> +static void sec1_set_hdr(struct talitos_desc *desc, __be32 val)
> +{
> +	desc->sec1.hdr = val;
> +}
> +
> +static struct talitos_ptr *sec1_get_ptr(struct talitos_desc *desc, size_t idx)
> +{
> +	return (struct talitos_ptr *)&desc->sec1.ptr[idx];
> +}
> +
>   static int sec1_reset_device(struct device *dev)
>   {
>   	struct talitos_private *priv = dev_get_drvdata(dev);
> @@ -163,9 +188,8 @@ static void sec1_dma_map_request(struct device *dev,
>   	struct talitos_edesc *prev_edesc = NULL;
>   
>   	while (edesc) {
> -		edesc->desc.hdr1 = edesc->desc.hdr;
>   
> -		dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
> +		dma_desc = dma_map_single(dev, &edesc->desc.sec1.hdr,
>   					  TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>   
>   		if (!prev_edesc) {
> @@ -175,7 +199,7 @@ static void sec1_dma_map_request(struct device *dev,
>   
>   		/* Chain in any previous descriptors. */
>   
> -		prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
> +		prev_edesc->desc.sec1.next_desc = cpu_to_be32(dma_desc);
>   
>   		dma_sync_single_for_device(dev, prev_dma_desc,
>   					   TALITOS_DESC_SIZE, DMA_TO_DEVICE);
> @@ -196,7 +220,7 @@ static void sec1_dma_unmap_request(struct device *dev,
>   			 DMA_BIDIRECTIONAL);
>   	edesc = container_of(request->desc, struct talitos_edesc, desc);
>   	while (edesc->next_desc) {
> -		dma_unmap_single(dev, be32_to_cpu(edesc->desc.next_desc),
> +		dma_unmap_single(dev, be32_to_cpu(edesc->desc.sec1.next_desc),
>   				 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
>   		edesc = edesc->next_desc;
>   	}
> @@ -211,14 +235,14 @@ static __be32 sec1_get_request_hdr(struct device *dev,
>   	edesc = container_of(request->desc, struct talitos_edesc, desc);
>   	dma_desc = request->dma_desc;
>   	while (edesc->next_desc) {
> -		dma_desc = be32_to_cpu(edesc->desc.next_desc);
> +		dma_desc = be32_to_cpu(edesc->desc.sec1.next_desc);
>   		edesc = edesc->next_desc;
>   	}
>   
>   	dma_sync_single_for_cpu(dev, dma_desc, TALITOS_DESC_SIZE,
>   				DMA_BIDIRECTIONAL);
>   
> -	return edesc->desc.hdr1;
> +	return edesc->desc.sec1.hdr;
>   }
>   
>   static __be32 sec1_search_desc_hdr_in_request(struct talitos_request *request,
> @@ -228,12 +252,12 @@ static __be32 sec1_search_desc_hdr_in_request(struct talitos_request *request,
>   
>   
>   	if (request->dma_desc == cur_desc)
> -		return request->desc->hdr;
> +		return request->desc->sec1.hdr;
>   
>   	edesc = container_of(request->desc, struct talitos_edesc, desc);
>   	while (edesc->next_desc) {
> -		if (edesc->desc.next_desc == cpu_to_be32(cur_desc))
> -			return edesc->next_desc->desc.hdr1;
> +		if (edesc->desc.sec1.next_desc == cpu_to_be32(cur_desc))
> +			return edesc->next_desc->desc.sec1.hdr;
>   		edesc = edesc->next_desc;
>   	}
>   
> @@ -319,6 +343,14 @@ static const struct talitos_ptr_ops sec1_ptr_ops = {
>   	.from_talitos_ptr_len = sec1_from_talitos_ptr_len,
>   	.to_talitos_ptr_ext_set = sec1_to_talitos_ptr_ext_set,
>   	.to_talitos_ptr_ext_or = sec1_to_talitos_ptr_ext_or,
> +	.get_ptr_value = sec1_get_ptr_value,
> +};
> +
> +static const struct talitos_desc_ops sec1_desc_ops = {
> +	.set_hdr = sec1_set_hdr,
> +	.get_hdr = sec1_get_hdr,
> +	.get_hdr_lo = sec1_get_hdr_lo,
> +	.get_ptr = sec1_get_ptr,
>   };
>   
>   static const struct talitos_ops sec1_ops = {
> @@ -337,5 +369,6 @@ static const struct talitos_ops sec1_ops = {
>   void talitos_register_sec1(struct talitos_private *priv)
>   {
>   	priv->ops = &sec1_ops;
> +	priv->desc_ops = &sec1_desc_ops;
>   	priv->ptr_ops = &sec1_ptr_ops;
>   }
> diff --git a/drivers/crypto/talitos/talitos-sec2.c b/drivers/crypto/talitos/talitos-sec2.c
> index 14f0ca13e6e5..52f783ddc8b6 100644
> --- a/drivers/crypto/talitos/talitos-sec2.c
> +++ b/drivers/crypto/talitos/talitos-sec2.c
> @@ -82,32 +82,57 @@ DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
>   static void sec2_to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
>   				unsigned int len)
>   {
> -	ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
> -	ptr->len = cpu_to_be16(len);
> -	ptr->eptr = upper_32_bits(dma_addr);
> +	ptr->sec2.ptr = cpu_to_be32(lower_32_bits(dma_addr));
> +	ptr->sec2.len = cpu_to_be16(len);
> +	ptr->sec2.eptr = upper_32_bits(dma_addr);
>   }
>   
>   static void sec2_copy_talitos_ptr(struct talitos_ptr *dst_ptr,
>   				  struct talitos_ptr *src_ptr)
>   {
> -	dst_ptr->ptr = src_ptr->ptr;
> -	dst_ptr->len = src_ptr->len;
> -	dst_ptr->eptr = src_ptr->eptr;
> +	dst_ptr->sec2.ptr = src_ptr->sec2.ptr;
> +	dst_ptr->sec2.len = src_ptr->sec2.len;
> +	dst_ptr->sec2.eptr = src_ptr->sec2.eptr;
>   }
>   
>   static unsigned short sec2_from_talitos_ptr_len(struct talitos_ptr *ptr)
>   {
> -	return be16_to_cpu(ptr->len);
> +	return be16_to_cpu(ptr->sec2.len);
>   }
>   
>   static void sec2_to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val)
>   {
> -	ptr->j_extent = val;
> +	ptr->sec2.j_extent = val;
>   }
>   
>   static void sec2_to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val)
>   {
> -	ptr->j_extent |= val;
> +	ptr->sec2.j_extent |= val;
> +}
> +
> +static __be32 sec2_get_ptr_value(struct talitos_ptr *ptr)
> +{
> +	return ptr->sec2.ptr;
> +}
> +
> +static __be32 sec2_get_hdr(struct talitos_desc *desc)
> +{
> +	return desc->sec2.hdr;
> +}
> +
> +static __be32 sec2_get_hdr_lo(struct talitos_desc *desc)
> +{
> +	return desc->sec2.hdr_lo;
> +}
> +
> +static void sec2_set_hdr(struct talitos_desc *desc, __be32 val)
> +{
> +	desc->sec2.hdr = val;
> +}
> +
> +static struct talitos_ptr *sec2_get_ptr(struct talitos_desc *desc, size_t idx)
> +{
> +	return (struct talitos_ptr *)&desc->sec2.ptr[idx];
>   }
>   
>   static int sec2_reset_channel(struct device *dev, int ch)
> @@ -331,14 +356,14 @@ static __be32 sec2_get_request_hdr(struct device *dev,
>   	dma_sync_single_for_cpu(dev, request->dma_desc, TALITOS_DESC_SIZE,
>   				DMA_BIDIRECTIONAL);
>   
> -	return request->desc->hdr;
> +	return request->desc->sec2.hdr;
>   }
>   
>   static __be32 sec2_search_desc_hdr_in_request(struct talitos_request *request,
>   					      dma_addr_t cur_desc)
>   {
>   	if (request->dma_desc == cur_desc)
> -		return request->desc->hdr;
> +		return request->desc->sec2.hdr;
>   	return 0;
>   }
>   
> @@ -348,6 +373,14 @@ static const struct talitos_ptr_ops sec2_ptr_ops = {
>   	.from_talitos_ptr_len = sec2_from_talitos_ptr_len,
>   	.to_talitos_ptr_ext_set = sec2_to_talitos_ptr_ext_set,
>   	.to_talitos_ptr_ext_or = sec2_to_talitos_ptr_ext_or,
> +	.get_ptr_value = sec2_get_ptr_value,
> +};
> +
> +static const struct talitos_desc_ops sec2_desc_ops = {
> +	.set_hdr = sec2_set_hdr,
> +	.get_hdr = sec2_get_hdr,
> +	.get_hdr_lo = sec2_get_hdr_lo,
> +	.get_ptr = sec2_get_ptr,
>   };
>   
>   static const struct talitos_ops sec2_ops = {
> @@ -366,5 +399,6 @@ static const struct talitos_ops sec2_ops = {
>   void talitos_register_sec2(struct talitos_private *priv)
>   {
>   	priv->ops = &sec2_ops;
> +	priv->desc_ops = &sec2_desc_ops;
>   	priv->ptr_ops = &sec2_ptr_ops;
>   }
> diff --git a/drivers/crypto/talitos/talitos-skcipher.c b/drivers/crypto/talitos/talitos-skcipher.c
> index a96f827c7b93..58ad931ff3a4 100644
> --- a/drivers/crypto/talitos/talitos-skcipher.c
> +++ b/drivers/crypto/talitos/talitos-skcipher.c
> @@ -11,17 +11,21 @@
>   
>   #include "talitos.h"
>   
> -static void common_nonsnoop_unmap(struct device *dev,
> +static void common_nonsnoop_unmap(struct talitos_ctx *ctx,
>   				  struct talitos_edesc *edesc,
>   				  struct skcipher_request *areq)
>   {
> -	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
> +	unmap_single_talitos_ptr(ctx->dev,
> +				 ctx->desc_ops->get_ptr(&edesc->desc, 5),
> +				 DMA_FROM_DEVICE);
>   
> -	talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen, 0);
> -	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
> +	talitos_sg_unmap(ctx->dev, edesc, areq->src, areq->dst, areq->cryptlen, 0);
> +	unmap_single_talitos_ptr(ctx->dev,
> +				 ctx->desc_ops->get_ptr(&edesc->desc, 1),
> +				 DMA_TO_DEVICE);
>   
>   	if (edesc->dma_len)
> -		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
> +		dma_unmap_single(ctx->dev, edesc->dma_link_tbl, edesc->dma_len,
>   				 DMA_BIDIRECTIONAL);
>   }
>   
> @@ -37,7 +41,7 @@ static void skcipher_done(struct device *dev,
>   
>   	edesc = container_of(desc, struct talitos_edesc, desc);
>   
> -	common_nonsnoop_unmap(dev, edesc, areq);
> +	common_nonsnoop_unmap(ctx, edesc, areq);
>   	memcpy(areq->iv, ctx->iv, ivsize);
>   
>   	kfree(edesc);
> @@ -61,16 +65,18 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
>   	bool sync_needed = false;
>   	struct talitos_private *priv = dev_get_drvdata(dev);
>   	bool is_sec1 = has_ftr_sec1(priv);
> -	bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU &&
> -		      (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
> +	bool is_ctr = (ctx->desc_ops->get_hdr(desc) & DESC_HDR_SEL0_MASK) ==
> +			      DESC_HDR_SEL0_AESU &&
> +		      (ctx->desc_ops->get_hdr(desc) &
> +		       DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
>   
>   	/* first DWORD empty */
>   
>   	/* cipher iv */
> -	ctx->ptr_ops->to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize);
> +	ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 1), edesc->iv_dma, ivsize);
>   
>   	/* cipher key */
> -	ctx->ptr_ops->to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen);
> +	ctx->ptr_ops->to_talitos_ptr(ctx->desc_ops->get_ptr(desc, 2), ctx->dma_key, ctx->keylen);
>   
>   	sg_count = edesc->src_nents ?: 1;
>   	if (is_sec1 && sg_count > 1)
> @@ -83,8 +89,9 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
>   	/*
>   	 * cipher in
>   	 */
> -	sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3],
> -				      sg_count, 0, 0, 0, false, is_ctr ? 16 : 1);
> +	sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc,
> +				      ctx->desc_ops->get_ptr(desc, 3), sg_count,
> +				      0, 0, 0, false, is_ctr ? 16 : 1);
>   	if (sg_count > 1)
>   		sync_needed = true;
>   
> @@ -95,14 +102,15 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
>   			dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
>   	}
>   
> -	ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
> -			     sg_count, 0, (edesc->src_nents + 1));
> +	ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc,
> +			     ctx->desc_ops->get_ptr(desc, 4), sg_count, 0,
> +			     (edesc->src_nents + 1));
>   	if (ret > 1)
>   		sync_needed = true;
>   
>   	/* iv out */
> -	map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
> -			       DMA_FROM_DEVICE);
> +	map_single_talitos_ptr(dev, ctx->desc_ops->get_ptr(desc, 5), ivsize,
> +			       ctx->iv, DMA_FROM_DEVICE);
>   
>   	/* last DWORD empty */
>   
> @@ -112,7 +120,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
>   
>   	ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
>   	if (ret != -EINPROGRESS) {
> -		common_nonsnoop_unmap(dev, edesc, areq);
> +		common_nonsnoop_unmap(ctx, edesc, areq);
>   		kfree(edesc);
>   	}
>   	return ret;
> @@ -191,7 +199,7 @@ static int skcipher_encrypt(struct skcipher_request *areq)
>   		return PTR_ERR(edesc);
>   
>   	/* set encrypt */
> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
> +	ctx->desc_ops->set_hdr(&edesc->desc, ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT);
>   
>   	return common_nonsnoop(edesc, areq, skcipher_done);
>   }
> @@ -215,7 +223,7 @@ static int skcipher_decrypt(struct skcipher_request *areq)
>   	if (IS_ERR(edesc))
>   		return PTR_ERR(edesc);
>   
> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
> +	ctx->desc_ops->set_hdr(&edesc->desc, ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND);
>   
>   	return common_nonsnoop(edesc, areq, skcipher_done);
>   }
> diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
> index 19e63ce6cc3e..a032907e900f 100644
> --- a/drivers/crypto/talitos/talitos.c
> +++ b/drivers/crypto/talitos/talitos.c
> @@ -81,7 +81,7 @@ void unmap_single_talitos_ptr(struct device *dev,
>   {
>   	struct talitos_private *priv = dev_get_drvdata(dev);
>   
> -	dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
> +	dma_unmap_single(dev, be32_to_cpu(priv->ptr_ops->get_ptr_value(ptr)),
>   			 priv->ptr_ops->from_talitos_ptr_len(ptr), dir);
>   }
>   
> @@ -625,6 +625,8 @@ int talitos_init_common(struct talitos_ctx *ctx,
>   
>   	ctx->ptr_ops = priv->ptr_ops;
>   
> +	ctx->desc_ops = priv->desc_ops;
> +
>   	return 0;
>   }
>   
> diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
> index 54e33da03fd0..2107fb1ade5d 100644
> --- a/drivers/crypto/talitos/talitos.h
> +++ b/drivers/crypto/talitos/talitos.h
> @@ -36,33 +36,49 @@
>   #define TALITOS_MAX_IV_LENGTH		16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
>   
>   /* descriptor pointer entry */
> +
> +struct sec1_talitos_ptr {
> +	__be16 res;
> +	__be16 len;
> +	__be32 ptr;
> +} __packed;
> +
> +struct sec2_talitos_ptr {
> +	__be16 len;
> +	u8 j_extent;
> +	u8 eptr;
> +	__be32 ptr;
> +} __packed;
> +
>   struct talitos_ptr {
>   	union {
> -		struct {		/* SEC2 format */
> -			__be16 len;     /* length */
> -			u8 j_extent;    /* jump to sg link table and/or extent*/
> -			u8 eptr;        /* extended address */
> -		};
> -		struct {			/* SEC1 format */
> -			__be16 res;
> -			__be16 len1;	/* length */
> -		};
> +		struct sec1_talitos_ptr sec1;
> +		struct sec2_talitos_ptr sec2;
>   	};
> -	__be32 ptr;     /* address */
>   };
>   
> -/* descriptor */
> +/* descriptor format */
> +
> +struct sec1_talitos_desc {
> +	__be32 hdr;
> +	struct sec1_talitos_ptr ptr[7];
> +	__be32 next_desc;
> +} __packed;
> +
> +struct sec2_talitos_desc {
> +	__be32 hdr;
> +	__be32 hdr_lo;
> +	struct sec2_talitos_ptr ptr[7];
> +} __packed;
> +
>   struct talitos_desc {
> -	__be32 hdr;                     /* header high bits */
>   	union {
> -		__be32 hdr_lo;		/* header low bits */
> -		__be32 hdr1;		/* header for SEC1 */
> +		struct sec1_talitos_desc sec1;
> +		struct sec2_talitos_desc sec2;
>   	};
> -	struct talitos_ptr ptr[7];      /* ptr/len pair array */
> -	__be32 next_desc;		/* next descriptor (SEC1) */
>   };
>   
> -#define TALITOS_DESC_SIZE	(sizeof(struct talitos_desc) - sizeof(__be32))
> +#define TALITOS_DESC_SIZE	sizeof(struct talitos_desc)
>   
>   /*
>    * talitos_edesc - s/w-extended descriptor
> @@ -148,6 +164,14 @@ struct talitos_ptr_ops {
>   	unsigned short (*from_talitos_ptr_len)(struct talitos_ptr *ptr);
>   	void (*to_talitos_ptr_ext_set)(struct talitos_ptr *ptr, u8 val);
>   	void (*to_talitos_ptr_ext_or)(struct talitos_ptr *ptr, u8 val);
> +	__be32 (*get_ptr_value)(struct talitos_ptr *ptr);
> +};
> +
> +struct talitos_desc_ops {
> +	void (*set_hdr)(struct talitos_desc *desc, __be32 val);
> +	__be32 (*get_hdr)(struct talitos_desc *desc);
> +	__be32 (*get_hdr_lo)(struct talitos_desc *desc);
> +	struct talitos_ptr *(*get_ptr)(struct talitos_desc *desc, size_t idx);
>   };
>   
>   struct talitos_ops {
> @@ -194,6 +218,7 @@ struct talitos_private {
>   
>   	const struct talitos_ops *ops;
>   	const struct talitos_ptr_ops *ptr_ops;
> +	const struct talitos_desc_ops *desc_ops;
>   
>   	/* SEC Compatibility info */
>   	unsigned long features;
> @@ -225,6 +250,7 @@ struct talitos_private {
>   struct talitos_ctx {
>   	struct device *dev;
>   	const struct talitos_ptr_ops *ptr_ops;
> +	const struct talitos_desc_ops *desc_ops;
>   	int ch;
>   	__be32 desc_hdr_template;
>   	u8 key[TALITOS_MAX_KEY_SIZE];
> 


^ permalink raw reply

* Re: [PATCH 24/29] crypto: talitos - Introduce per-SEC-version pointer helper ops
From: Christophe Leroy (CS GROUP) @ 2026-06-04  9:48 UTC (permalink / raw)
  To: Paul Louvel, Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <20260528-7-1-rc1_talitos_cleanup-v1-24-cb1ad6cdea49@bootlin.com>



Le 28/05/2026 à 11:08, Paul Louvel a écrit :
> Introduce struct talitos_ptr_ops to abstract SEC1/SEC2 differences
> in pointer handling behind per-SEC-version ops.  Add ptr_ops to
> struct talitos_private and struct talitos_ctx, and register the
> appropriate SEC1 or SEC2 implementation at probe time.

Those helpers are so small they deserve being inlined not called 
indirectly. You should reconsider them using the is_sec1() helper I 
proposed on patch 20.

00000000 <sec1_to_talitos_ptr>:
    0:	90 83 00 04 	stw     r4,4(r3)
    4:	b0 a3 00 02 	sth     r5,2(r3)
    8:	4e 80 00 20 	blr

0000000c <sec1_copy_talitos_ptr>:
    c:	81 24 00 04 	lwz     r9,4(r4)
   10:	91 23 00 04 	stw     r9,4(r3)
   14:	a1 24 00 02 	lhz     r9,2(r4)
   18:	b1 23 00 02 	sth     r9,2(r3)
   1c:	4e 80 00 20 	blr

00000020 <sec1_from_talitos_ptr_len>:
   20:	a0 63 00 02 	lhz     r3,2(r3)
   24:	4e 80 00 20 	blr

00000028 <sec1_to_talitos_ptr_ext_set>:
   28:	4e 80 00 20 	blr

0000002c <sec1_get_ptr_value>:
   2c:	80 63 00 04 	lwz     r3,4(r3)
   30:	4e 80 00 20 	blr

00000034 <sec1_get_hdr>:
   34:	80 63 00 00 	lwz     r3,0(r3)
   38:	4e 80 00 20 	blr

0000003c <sec1_get_hdr_lo>:
   3c:	38 60 00 00 	li      r3,0
   40:	4e 80 00 20 	blr

00000044 <sec1_set_hdr>:
   44:	90 83 00 00 	stw     r4,0(r3)
   48:	4e 80 00 20 	blr

0000004c <sec1_get_ptr>:
   4c:	54 84 18 38 	slwi    r4,r4,3
   50:	38 84 00 04 	addi    r4,r4,4
   54:	7c 63 22 14 	add     r3,r3,r4
   58:	4e 80 00 20 	blr

00000be8 <sec1_to_talitos_ptr_ext_or>:
  be8:	4e 80 00 20 	blr


> 
> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
> ---
>   drivers/crypto/talitos/talitos-sec1.c | 36 +++++++++++++++++++++++++++++++
>   drivers/crypto/talitos/talitos-sec2.c | 40 +++++++++++++++++++++++++++++++++++
>   drivers/crypto/talitos/talitos.c      |  2 ++
>   drivers/crypto/talitos/talitos.h      | 12 +++++++++++
>   4 files changed, 90 insertions(+)
> 
> diff --git a/drivers/crypto/talitos/talitos-sec1.c b/drivers/crypto/talitos/talitos-sec1.c
> index 695d531aa7f4..ef1bd19b6772 100644
> --- a/drivers/crypto/talitos/talitos-sec1.c
> +++ b/drivers/crypto/talitos/talitos-sec1.c
> @@ -73,6 +73,33 @@ static irqreturn_t talitos1_interrupt_##name(int irq, void *data)	       \
>   
>   DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
>   
> +static void sec1_to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
> +				unsigned int len)
> +{
> +	ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
> +	ptr->len1 = cpu_to_be16(len);
> +}
> +
> +static void sec1_copy_talitos_ptr(struct talitos_ptr *dst_ptr,
> +				  struct talitos_ptr *src_ptr)
> +{
> +	dst_ptr->ptr = src_ptr->ptr;
> +	dst_ptr->len1 = src_ptr->len1;
> +}
> +
> +static unsigned short sec1_from_talitos_ptr_len(struct talitos_ptr *ptr)
> +{
> +	return be16_to_cpu(ptr->len1);
> +}
> +
> +static void sec1_to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val)
> +{
> +}
> +
> +static void sec1_to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val)
> +{
> +}
> +
>   static int sec1_reset_device(struct device *dev)
>   {
>   	struct talitos_private *priv = dev_get_drvdata(dev);
> @@ -286,6 +313,14 @@ static void sec1_init_task(struct device *dev)
>   			     (unsigned long)dev);
>   }
>   
> +static const struct talitos_ptr_ops sec1_ptr_ops = {
> +	.to_talitos_ptr = sec1_to_talitos_ptr,
> +	.copy_talitos_ptr = sec1_copy_talitos_ptr,
> +	.from_talitos_ptr_len = sec1_from_talitos_ptr_len,
> +	.to_talitos_ptr_ext_set = sec1_to_talitos_ptr_ext_set,
> +	.to_talitos_ptr_ext_or = sec1_to_talitos_ptr_ext_or,
> +};
> +
>   static const struct talitos_ops sec1_ops = {
>   	.probe_irq = sec1_talitos_probe_irq,
>   	.init_task = sec1_init_task,
> @@ -302,4 +337,5 @@ static const struct talitos_ops sec1_ops = {
>   void talitos_register_sec1(struct talitos_private *priv)
>   {
>   	priv->ops = &sec1_ops;
> +	priv->ptr_ops = &sec1_ptr_ops;
>   }
> diff --git a/drivers/crypto/talitos/talitos-sec2.c b/drivers/crypto/talitos/talitos-sec2.c
> index 962e7cd43631..14f0ca13e6e5 100644
> --- a/drivers/crypto/talitos/talitos-sec2.c
> +++ b/drivers/crypto/talitos/talitos-sec2.c
> @@ -79,6 +79,37 @@ DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
>   DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
>   DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
>   
> +static void sec2_to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
> +				unsigned int len)
> +{
> +	ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
> +	ptr->len = cpu_to_be16(len);
> +	ptr->eptr = upper_32_bits(dma_addr);
> +}
> +
> +static void sec2_copy_talitos_ptr(struct talitos_ptr *dst_ptr,
> +				  struct talitos_ptr *src_ptr)
> +{
> +	dst_ptr->ptr = src_ptr->ptr;
> +	dst_ptr->len = src_ptr->len;
> +	dst_ptr->eptr = src_ptr->eptr;
> +}
> +
> +static unsigned short sec2_from_talitos_ptr_len(struct talitos_ptr *ptr)
> +{
> +	return be16_to_cpu(ptr->len);
> +}
> +
> +static void sec2_to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val)
> +{
> +	ptr->j_extent = val;
> +}
> +
> +static void sec2_to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val)
> +{
> +	ptr->j_extent |= val;
> +}
> +
>   static int sec2_reset_channel(struct device *dev, int ch)
>   {
>   	struct talitos_private *priv = dev_get_drvdata(dev);
> @@ -311,6 +342,14 @@ static __be32 sec2_search_desc_hdr_in_request(struct talitos_request *request,
>   	return 0;
>   }
>   
> +static const struct talitos_ptr_ops sec2_ptr_ops = {
> +	.to_talitos_ptr = sec2_to_talitos_ptr,
> +	.copy_talitos_ptr = sec2_copy_talitos_ptr,
> +	.from_talitos_ptr_len = sec2_from_talitos_ptr_len,
> +	.to_talitos_ptr_ext_set = sec2_to_talitos_ptr_ext_set,
> +	.to_talitos_ptr_ext_or = sec2_to_talitos_ptr_ext_or,
> +};
> +
>   static const struct talitos_ops sec2_ops = {
>   	.probe_irq = sec2_talitos_probe_irq,
>   	.init_task = sec2_init_task,
> @@ -327,4 +366,5 @@ static const struct talitos_ops sec2_ops = {
>   void talitos_register_sec2(struct talitos_private *priv)
>   {
>   	priv->ops = &sec2_ops;
> +	priv->ptr_ops = &sec2_ptr_ops;
>   }
> diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
> index 152618998819..0e4bd130ac6d 100644
> --- a/drivers/crypto/talitos/talitos.c
> +++ b/drivers/crypto/talitos/talitos.c
> @@ -668,6 +668,8 @@ int talitos_init_common(struct talitos_ctx *ctx,
>   	/* select done notification */
>   	ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
>   
> +	ctx->ptr_ops = priv->ptr_ops;
> +
>   	return 0;
>   }
>   
> diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
> index ae0bdb2ea78e..09d4e8fb0e62 100644
> --- a/drivers/crypto/talitos/talitos.h
> +++ b/drivers/crypto/talitos/talitos.h
> @@ -140,6 +140,16 @@ struct talitos_channel {
>   	int tail;
>   };
>   
> +struct talitos_ptr_ops {
> +	void (*to_talitos_ptr)(struct talitos_ptr *ptr, dma_addr_t addr,
> +			       unsigned int len);
> +	void (*copy_talitos_ptr)(struct talitos_ptr *dst_ptr,
> +				 struct talitos_ptr *src_ptr);
> +	unsigned short (*from_talitos_ptr_len)(struct talitos_ptr *ptr);
> +	void (*to_talitos_ptr_ext_set)(struct talitos_ptr *ptr, u8 val);
> +	void (*to_talitos_ptr_ext_or)(struct talitos_ptr *ptr, u8 val);
> +};
> +
>   struct talitos_ops {
>   	int (*probe_irq)(struct platform_device *ofdev);
>   	void (*init_task)(struct device *dev);
> @@ -183,6 +193,7 @@ struct talitos_private {
>   	unsigned int desc_types;
>   
>   	const struct talitos_ops *ops;
> +	const struct talitos_ptr_ops *ptr_ops;
>   
>   	/* SEC Compatibility info */
>   	unsigned long features;
> @@ -213,6 +224,7 @@ struct talitos_private {
>   
>   struct talitos_ctx {
>   	struct device *dev;
> +	const struct talitos_ptr_ops *ptr_ops;
>   	int ch;
>   	__be32 desc_hdr_template;
>   	u8 key[TALITOS_MAX_KEY_SIZE];
> 


^ permalink raw reply

* Re: [PATCH 20/29] crypto: talitos - Replace SEC1/SEC2 conditionals with ops dispatch
From: Christophe Leroy (CS GROUP) @ 2026-06-04  9:37 UTC (permalink / raw)
  To: Paul Louvel, Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, linux-crypto, linux-kernel
In-Reply-To: <20260528-7-1-rc1_talitos_cleanup-v1-20-cb1ad6cdea49@bootlin.com>



Le 28/05/2026 à 11:08, Paul Louvel a écrit :
> Replace the if/else is_sec1 dispatches in callers with indirect calls
> through priv->ops. Add static const sec1_ops and sec2_ops structs
> populated with the SEC1 and SEC2 function variants, and set priv->ops
> at probe time based on the detected hardware.

Why is that needed ?

I understand your objective at the end is to get rid of that is_sec1 
boolean that is carried over the entire call chain but using ops for 
that seems overkill.

What about changing it to a helper using static branches, something like 
(untested) :

#if defined(CONFIG_CRYPTO_DEV_TALITOS1) && 
defined(CONFIG_CRYPTO_DEV_TALITOS2)
DECLARE_STATIC_KEY_FALSE(talitos_is_sec1);
static __always_inline bool is_sec1(void)
{
	return static_branch_unlikely(&talitos_is_sec1);
}

static inline void talitos_init_branch(bool is_sec1)
{
	if (is_sec1)
		static_branch_enable(&talitos_is_sec1);
}
#else
static __always_inline bool is_sec1(void)
{
	return IS_ENABLED(CONFIG_CRYPTO_DEV_TALITOS1);
}

static inline void talitos_init_branch(bool is_sec1)
{
	BUILD_BUG_ON(is_sec1 && !IS_ENABLED(CONFIG_CRYPTO_DEV_TALITOS1));
}
#endif

> 
> 
> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
> ---
>   drivers/crypto/talitos/talitos.c | 88 +++++++++++++++++++---------------------
>   1 file changed, 41 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
> index b6793d97735e..c4a311a8e7fd 100644
> --- a/drivers/crypto/talitos/talitos.c
> +++ b/drivers/crypto/talitos/talitos.c
> @@ -258,7 +258,6 @@ static int init_device(struct device *dev)
>   {
>   	struct talitos_private *priv = dev_get_drvdata(dev);
>   	int ch, err;
> -	bool is_sec1 = has_ftr_sec1(priv);
>   
>   	/*
>   	 * Master reset
> @@ -266,35 +265,23 @@ static int init_device(struct device *dev)
>   	 * are not fully cleared by writing the MCR:SWR bit,
>   	 * set bit twice to completely reset
>   	 */
> -	if (is_sec1)
> -		err = sec1_reset_device(dev);
> -	else
> -		err = sec2_reset_device(dev);
> +	err = priv->ops->reset_device(dev);
>   
>   	if (err)
>   		return err;
>   
> -	if (is_sec1)
> -		err = sec1_reset_device(dev);
> -	else
> -		err = sec2_reset_device(dev);
> +	err = priv->ops->reset_device(dev);
>   	if (err)
>   		return err;
>   
>   	/* reset channels */
>   	for (ch = 0; ch < priv->num_channels; ch++) {
> -		if (is_sec1)
> -			err = sec1_reset_channel(dev, ch);
> -		else
> -			err = sec2_reset_channel(dev, ch);
> +		err = priv->ops->reset_channel(dev, ch);
>   		if (err)
>   			return err;
>   	}
>   
> -	if (is_sec1)
> -		sec1_configure_device(dev);
> -	else
> -		sec2_configure_device(dev);
> +	priv->ops->configure_device(dev);
>   
>   	return 0;
>   }
> @@ -363,7 +350,6 @@ int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
>   	struct talitos_request *request;
>   	unsigned long flags;
>   	int head;
> -	bool is_sec1 = has_ftr_sec1(priv);
>   
>   	spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
>   
> @@ -377,10 +363,8 @@ int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
>   	request = &priv->chan[ch].fifo[head];
>   
>   	/* map descriptor and save caller data */
> -	if (is_sec1)
> -		sec1_dma_map_request(dev, request, desc);
> -	else
> -		sec2_dma_map_request(dev, request, desc);
> +	priv->ops->dma_map_request(dev, request, desc);
> +
>   	request->callback = callback;
>   	request->context = context;
>   
> @@ -461,7 +445,6 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
>   	struct talitos_request *request, saved_req;
>   	unsigned long flags;
>   	int tail, status;
> -	bool is_sec1 = has_ftr_sec1(priv);
>   
>   	spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
>   
> @@ -473,10 +456,7 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
>   
>   		/* descriptors with their done bits set don't get the error */
>   		rmb();
> -		if (is_sec1)
> -			hdr = sec1_get_request_hdr(dev, request);
> -		else
> -			hdr = sec2_get_request_hdr(dev, request);
> +		hdr = priv->ops->get_request_hdr(dev, request);
>   
>   		if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
>   			status = 0;
> @@ -486,10 +466,7 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
>   			else
>   				status = error;
>   
> -		if (is_sec1)
> -			sec1_dma_unmap_request(dev, request);
> -		else
> -			sec2_dma_unmap_request(dev, request);
> +		priv->ops->dma_unmap_request(dev, request);
>   
>   		/* copy entries so we can call callback outside lock */
>   		saved_req.desc = request->desc;
> @@ -611,7 +588,6 @@ static __be32 sec2_search_desc_hdr_in_request(struct talitos_request *request,
>   static __be32 current_desc_hdr(struct device *dev, int ch)
>   {
>   	struct talitos_private *priv = dev_get_drvdata(dev);
> -	bool is_sec1 = has_ftr_sec1(priv);
>   	struct talitos_request *request;
>   	int tail, iter;
>   	dma_addr_t cur_desc;
> @@ -630,10 +606,7 @@ static __be32 current_desc_hdr(struct device *dev, int ch)
>   	do {
>   		request = &priv->chan[ch].fifo[iter];
>   
> -		if (is_sec1)
> -			hdr = sec1_search_desc_hdr_in_request(request, cur_desc);
> -		else
> -			hdr = sec2_search_desc_hdr_in_request(request, cur_desc);
> +		hdr = priv->ops->search_desc_hdr_in_request(request, cur_desc);
>   		if (hdr)
>   			break;
>   
> @@ -833,13 +806,9 @@ static int sec2_talitos_handle_error(struct device *dev, u32 isr, u32 isr_lo)
>   static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
>   {
>   	struct talitos_private *priv = dev_get_drvdata(dev);
> -	bool is_sec1 = has_ftr_sec1(priv);
>   	int ch, reset_dev;
>   
> -	if (is_sec1)
> -		reset_dev = sec1_talitos_handle_error(dev, isr, isr_lo);
> -	else
> -		reset_dev = sec2_talitos_handle_error(dev, isr, isr_lo);
> +	reset_dev = priv->ops->handle_error(dev, isr, isr_lo);
>   
>   	if (reset_dev) {
>   		dev_err(dev,
> @@ -1391,6 +1360,32 @@ static void sec2_init_task(struct device *dev)
>   	}
>   }
>   
> +static const struct talitos_ops sec1_ops = {
> +	.probe_irq = sec1_talitos_probe_irq,
> +	.init_task = sec1_init_task,
> +	.reset_device = sec1_reset_device,
> +	.reset_channel = sec1_reset_channel,
> +	.configure_device = sec1_configure_device,
> +	.dma_map_request = sec1_dma_map_request,
> +	.dma_unmap_request = sec1_dma_unmap_request,
> +	.get_request_hdr = sec1_get_request_hdr,
> +	.search_desc_hdr_in_request = sec1_search_desc_hdr_in_request,
> +	.handle_error = sec1_talitos_handle_error,
> +};
> +
> +static const struct talitos_ops sec2_ops = {
> +	.probe_irq = sec2_talitos_probe_irq,
> +	.init_task = sec2_init_task,
> +	.reset_device = sec2_reset_device,
> +	.reset_channel = sec2_reset_channel,
> +	.configure_device = sec2_configure_device,
> +	.dma_map_request = sec2_dma_map_request,
> +	.dma_unmap_request = sec2_dma_unmap_request,
> +	.get_request_hdr = sec2_get_request_hdr,
> +	.search_desc_hdr_in_request = sec2_search_desc_hdr_in_request,
> +	.handle_error = sec2_talitos_handle_error,
> +};
> +
>   static int talitos_probe(struct platform_device *ofdev)
>   {
>   	struct device *dev = &ofdev->dev;
> @@ -1474,16 +1469,15 @@ static int talitos_probe(struct platform_device *ofdev)
>   	}
>   
>   	if (has_ftr_sec1(priv))
> -		err = sec1_talitos_probe_irq(ofdev);
> +		priv->ops = &sec1_ops;
>   	else
> -		err = sec2_talitos_probe_irq(ofdev);
> +		priv->ops = &sec2_ops;
> +
> +	err = priv->ops->probe_irq(ofdev);
>   	if (err)
>   		goto err_out;
>   
> -	if (has_ftr_sec1(priv))
> -		sec1_init_task(dev);
> -	else
> -		sec2_init_task(dev);
> +	priv->ops->init_task(dev);
>   
>   	priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
>   
> 


^ permalink raw reply

* Re: [PATCH 1/1] crypto: atmel-ecc - fix use after free situation
From: Lothar Rubusch @ 2026-06-04  7:56 UTC (permalink / raw)
  To: Thorsten Blum
  Cc: herbert, davem, nicolas.ferre, alexandre.belloni, claudiu.beznea,
	tudor.ambarus, krzk+dt, linux-crypto, linux-arm-kernel,
	linux-kernel
In-Reply-To: <ah381bcuVfN8PQr0@linux.dev>

Hi Thorsten, thanks for the feedback. Pls, find my comment down below.

On Mon, Jun 1, 2026 at 11:42 PM Thorsten Blum <thorsten.blum@linux.dev> wrote:
>
> On Fri, May 29, 2026 at 09:27:03AM +0000, Lothar Rubusch wrote:
> > Fixes a possible race condition, when having multiple of such devices
> > attached (identified by sashiko feedback).
> >
> > The Scenario:
> >     Thread A (Device 1 Probe): Successfully adds i2c_priv to the global
> >              list (Line 324). The lock is released.
> >     Thread B (An active crypto request): Concurrently calls
> >               atmel_ecc_i2c_client_alloc(). It scans the global list, sees
> >               Device 1, and assigns a crypto job to it.
> >     Thread A: Moves to line 332. crypto_register_kpp() fails (e.g., out of
> >               memory or name clash).
> >     Thread A: Enters the error path. It removes Device 1 from the list and
> >               frees the i2c_priv memory.
> >     Thread B: Is still actively trying to talk to the I2C hardware using
> >               the i2c_priv pointer it grabbed in Step 2. The memory is now
> >               gone. Result: Kernel crash (Use-After-Free).
> >
> > Fixes: 11105693fa05 ("crypto: atmel-ecc - introduce Microchip / Atmel ECC driver")
> > Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
> > ---
> >  drivers/crypto/atmel-ecc.c | 10 ++++++++++
> >  drivers/crypto/atmel-i2c.h |  2 ++
> >  2 files changed, 12 insertions(+)
> >
> > diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c
> > index 0ca02995a1de..d391fe1462f6 100644
> > --- a/drivers/crypto/atmel-ecc.c
> > +++ b/drivers/crypto/atmel-ecc.c
> > @@ -218,6 +218,8 @@ static struct i2c_client *atmel_ecc_i2c_client_alloc(void)
> >
> >       list_for_each_entry(i2c_priv, &driver_data.i2c_client_list,
> >                           i2c_client_list_node) {
> > +             if (!i2c_priv->ready)
> > +                     continue;
> >               tfm_cnt = atomic_read(&i2c_priv->tfm_count);
> >               if (tfm_cnt < min_tfm_cnt) {
> >                       min_tfm_cnt = tfm_cnt;
> > @@ -322,20 +324,24 @@ static int atmel_ecc_probe(struct i2c_client *client)
> >               return ret;
> >
> >       i2c_priv = i2c_get_clientdata(client);
> > +     i2c_priv->ready = false;
> >
> >       spin_lock(&driver_data.i2c_list_lock);
> >       list_add_tail(&i2c_priv->i2c_client_list_node,
> >                     &driver_data.i2c_client_list);
> > +     i2c_priv->ready = true;
> >       spin_unlock(&driver_data.i2c_list_lock);
> >
> >       ret = crypto_register_kpp(&atmel_ecdh_nist_p256);
> >       if (ret) {
> >               spin_lock(&driver_data.i2c_list_lock);
> > +             i2c_priv->ready = false;
> >               list_del(&i2c_priv->i2c_client_list_node);
> >               spin_unlock(&driver_data.i2c_list_lock);
> >
> >               dev_err(&client->dev, "%s alg registration failed\n",
> >                       atmel_ecdh_nist_p256.base.cra_driver_name);
> > +             return ret;
> >       } else {
> >               dev_info(&client->dev, "atmel ecc algorithms registered in /proc/crypto\n");
> >       }
> > @@ -347,6 +353,10 @@ static void atmel_ecc_remove(struct i2c_client *client)
> >  {
> >       struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);
> >
> > +     spin_lock(&driver_data.i2c_list_lock);
> > +     i2c_priv->ready = false;
> > +     spin_unlock(&driver_data.i2c_list_lock);
> > +
> >       /* Return EBUSY if i2c client already allocated. */
> >       if (atomic_read(&i2c_priv->tfm_count)) {
> >               /*
> > diff --git a/drivers/crypto/atmel-i2c.h b/drivers/crypto/atmel-i2c.h
> > index 72f04c15682f..e3b12030f9c4 100644
> > --- a/drivers/crypto/atmel-i2c.h
> > +++ b/drivers/crypto/atmel-i2c.h
> > @@ -129,6 +129,7 @@ struct atmel_ecc_driver_data {
> >   * @wake_token_sz       : size in bytes of the wake_token
> >   * @tfm_count           : number of active crypto transformations on i2c client
> >   * @hwrng               : hold the hardware generated rng
> > + * @ready               : hw client is ready to use
> >   *
> >   * Reads and writes from/to the i2c client are sequential. The first byte
> >   * transmitted to the device is treated as the byte size. Any attempt to send
> > @@ -145,6 +146,7 @@ struct atmel_i2c_client_priv {
> >       size_t wake_token_sz;
> >       atomic_t tfm_count ____cacheline_aligned;
> >       struct hwrng hwrng;
> > +     bool ready;
> >  };
>
> I don't think the ready flag fixes the race. A concurrent tfm can still
> bind to the shared I2C client after atmel_ecc_probe() adds it to the
> global list and marks it as ready, but before crypto_register_kpp()
> fails.

Argh... I see your point. The "ready" now is transparent to the
i2c_client_list usage and serves for nothing, that's nonsense. Going
some overengineering-steps back, my original idea (to satisfy a
sashiko complaint), in my own words:

Thread A:
1. probe()
  V
2. probe(): add i2c_priv to i2c_client_list <-------------- Thread B requests
  V
3. probe(): registers kpp
  V
4. probe(): say, register kpp fails
  V
5. probe(): remove i2c_priv from i2c_client_list <-----

Thread B:
Now if a crypto request/TFM comes in (thread B) and requests a client
from the i2c_client_list.
(Note, this is a case where the device must be, say, the second such
device so that kpp is already registered for any atmel driver).

If this happens before step 2 or after step 5, it's fine. This
instance is still not on the list. If it happens at step 2 through
step 4 this is problematic. A i2c_priv could be returned which is
actually (still) not ready. In the meanwhile i2c_priv will be removed,
but the TFM continues refering to this instance.

Question:
- Do you see the issue here, too? Or, is my understanding wrong? Can
this be problematic / lead to UAF?

- If true, my first idea was to set a "ready" state initially to
false, after kpp registered successfully, set it to true. The flag is
checked then, as in this patch. Then I probably messed it up. So,
could this approach solve the situation?

If you not answer I'll present this in the next days.

Best,
L

>
> Thanks,
> Thorsten

^ permalink raw reply

* Re: [PATCH 10/12] crypto: atmel - update workqueue flags and add flush on exit
From: Lothar Rubusch @ 2026-06-04  7:22 UTC (permalink / raw)
  To: Marco Crivellari
  Cc: alexandre.belloni, claudiu.beznea, davem, herbert,
	linux-arm-kernel, linux-crypto, linux-kernel, nicolas.ferre,
	thorsten.blum
In-Reply-To: <20260601090329.52616-1-marco.crivellari@suse.com>

Hi Marco,

On Mon, Jun 1, 2026 at 11:03 AM Marco Crivellari
<marco.crivellari@suse.com> wrote:
>
> Hi,
>
> > Update workqueue initialization to use WQ_MEM_RECLAIM instead of
> > WQ_PERCPU
>
> Not sure if you're working on this series right now, but this must keep
> the WQ_PERCPU flag. WQ_PERCPU has been added to mark explicitly mark
> workqueue that are per-CPU (it is the complement of WQ_UNBOUND).
>
Yes. I plan on splitting up the material presented in this series.

This particular patch was one of the things I was a unsure, if this
actually could be done.
Therefore it was already separted out. I highly appreciate your
feedback. I will drop this
change and leave WQ_PERCPU until I get there.

>
> Thanks!
>

^ permalink raw reply

* Re: [PATCH 3/4] crypto: qcom-rng - Remove crypto_rng interface
From: Eric Biggers @ 2026-06-04  5:42 UTC (permalink / raw)
  To: Neeraj Soni
  Cc: linux-crypto, linux-kernel, Om Prakash Singh, Bjorn Andersson,
	Neil Armstrong, linux-arm-msm, Olivia Mackall, stable
In-Reply-To: <021127c9-baff-816d-e053-897a7d4043d8@oss.qualcomm.com>

On Thu, Jun 04, 2026 at 10:20:38AM +0530, Neeraj Soni wrote:
> On 5/30/2026 7:33 AM, Eric Biggers wrote:
> > qcom-rng.c exposes the same hardware through two completely separate
> > interfaces, crypto_rng and hwrng.  However, the implementation of this
> > is buggy because it permits generation operations from these interfaces
> > to run concurrently with each other, accessing the same registers.  That
> > is, qcom_rng_generate() synchronizes with itself but not with
> > qcom_hwrng_read().  This results in potential repetition of output from
> > the RNG, output of non-random values, etc.
> > 
> > Fortunately, there's actually no point in hardware RNG drivers
> > implementing the crypto_rng interface.  It's not actually used by
> > anything besides the "rng" algorithm type of AF_ALG, which in turn is
> > not actually used in practice.  Other crypto_rng hardware drivers are
> 
> How it was established that there are no active users/clints for qcom-rng
> using crypto_rng interface? If there is no concrete way to do then this
> patch breaks backward compatibility.

The only in-kernel user of crypto_rng uses it to access
"drbg_nopr_hmac_sha512" on "FIPS-enabled" systems.  So, the only
possibility for a user of "qcom-rng" would be userspace via AF_ALG.  But
I've never heard of that being done.  It would be a really odd and
pointless thing to do when the much easier to use UAPIs /dev/random and
/dev/hwrng already exist.  And broken too, as I pointed out.

AF_ALG as a whole is rarely used and is a mistake.  It exposes a massive
amount of unused and broken functionality to userspace, including every
single implementation of every single crypto algorithm by name, which
never should have been done in the way it was.  We don't have much
choice but to continue removing algorithms/drivers from it to keep Linux
maintainable, as has already been happening successfully for many years.

The AF_ALG hardware RNG support is especially pointless, given the
redundancy with /dev/random and /dev/hwrng.  As far as I can tell the
main purpose of it is just to confuse RNG driver authors into thinking
that they are making Linux utilize their RNG.

Keep in mind that for AF_ALG there's also a compatibility trick
available to be implemented if it ever needs to: the kernel could
automatically remap requests for a particular driver name, like
"qcom-rng", to a different one like "drbg_nopr_hmac_sha512".

However, it's never actually been necessary to use that trick in *any*
of the times that crypto drivers have been removed or renamed.  No one
has ever cared.  There's some AF_ALG functionality we know that a few
programs use, but this isn't part of that.

So I think we can be quite confident in proceeding with this patch even
without proactively putting in the name remapping.

- Eric

^ permalink raw reply

* Re: [PATCH 3/4] crypto: qcom-rng - Remove crypto_rng interface
From: Neeraj Soni @ 2026-06-04  4:50 UTC (permalink / raw)
  To: Eric Biggers, linux-crypto
  Cc: linux-kernel, Om Prakash Singh, Bjorn Andersson, Neil Armstrong,
	linux-arm-msm, Olivia Mackall, stable
In-Reply-To: <20260530020332.143058-4-ebiggers@kernel.org>



On 5/30/2026 7:33 AM, Eric Biggers wrote:
> qcom-rng.c exposes the same hardware through two completely separate
> interfaces, crypto_rng and hwrng.  However, the implementation of this
> is buggy because it permits generation operations from these interfaces
> to run concurrently with each other, accessing the same registers.  That
> is, qcom_rng_generate() synchronizes with itself but not with
> qcom_hwrng_read().  This results in potential repetition of output from
> the RNG, output of non-random values, etc.
> 
> Fortunately, there's actually no point in hardware RNG drivers
> implementing the crypto_rng interface.  It's not actually used by
> anything besides the "rng" algorithm type of AF_ALG, which in turn is
> not actually used in practice.  Other crypto_rng hardware drivers are

How it was established that there are no active users/clints for qcom-rng
using crypto_rng interface? If there is no concrete way to do then this
patch breaks backward compatibility.

> likewise being phased out, leaving just the hwrng support.
> 
> Thus, remove it to simplify the code and avoid conflict (and confusion)
> with the hwrng interface which is the one that actually matters.
> 
> Note that while this means the driver stops supporting "qcom,prng" and
> "qcom,prng-ee", it didn't do anything useful on SoCs with those anyway.
> 
> Fixes: f29cd5bb64c2 ("crypto: qcom-rng - Add hw_random interface support")
> Cc: stable@vger.kernel.org
> Signed-off-by: Eric Biggers <ebiggers@kernel.org>
> ---
>  drivers/crypto/Kconfig    |   1 -
>  drivers/crypto/qcom-rng.c | 175 ++------------------------------------
>  2 files changed, 9 insertions(+), 167 deletions(-)
> 
> diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
> index 3449b3c9c6ad..a12cd677467b 100644
> --- a/drivers/crypto/Kconfig
> +++ b/drivers/crypto/Kconfig
> @@ -658,11 +658,10 @@ config CRYPTO_DEV_QCE_SW_MAX_LEN
>  
>  config CRYPTO_DEV_QCOM_RNG
>  	tristate "Qualcomm Random Number Generator Driver"
>  	depends on ARCH_QCOM || COMPILE_TEST
>  	depends on HW_RANDOM
> -	select CRYPTO_RNG
>  	help
>  	  This driver provides support for the Random Number
>  	  Generator hardware found on Qualcomm SoCs.
>  
>  	  To compile this driver as a module, choose M here. The
> diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c
> index b7f3b9695dac..48b605687b28 100644
> --- a/drivers/crypto/qcom-rng.c
> +++ b/drivers/crypto/qcom-rng.c
> @@ -1,14 +1,11 @@
>  // SPDX-License-Identifier: GPL-2.0
>  // Copyright (c) 2017-18 Linaro Limited
>  //
>  // Based on msm-rng.c and downstream driver
>  
> -#include <crypto/internal/rng.h>
> -#include <linux/acpi.h>
>  #include <linux/clk.h>
> -#include <linux/crypto.h>
>  #include <linux/hw_random.h>
>  #include <linux/io.h>
>  #include <linux/iopoll.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> @@ -30,28 +27,15 @@
>  #define WORD_SZ			4
>  
>  #define QCOM_TRNG_QUALITY	1024
>  
>  struct qcom_rng {
> -	struct mutex lock;
>  	void __iomem *base;
>  	struct clk *clk;
>  	struct hwrng hwrng;
> -	struct qcom_rng_match_data *match_data;
>  };
>  
> -struct qcom_rng_ctx {
> -	struct qcom_rng *rng;
> -};
> -
> -struct qcom_rng_match_data {
> -	bool skip_init;
> -	bool hwrng_support;
> -};
> -
> -static struct qcom_rng *qcom_rng_dev;
> -
>  static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
>  {
>  	unsigned int currsize = 0;
>  	u32 val;
>  	int ret;
> @@ -77,41 +61,10 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
>  	} while (currsize < max);
>  
>  	return currsize;
>  }
>  
> -static int qcom_rng_generate(struct crypto_rng *tfm,
> -			     const u8 *src, unsigned int slen,
> -			     u8 *dstn, unsigned int dlen)
> -{
> -	struct qcom_rng_ctx *ctx = crypto_rng_ctx(tfm);
> -	struct qcom_rng *rng = ctx->rng;
> -	int ret;
> -
> -	ret = clk_prepare_enable(rng->clk);
> -	if (ret)
> -		return ret;
> -
> -	mutex_lock(&rng->lock);
> -
> -	ret = qcom_rng_read(rng, dstn, dlen);
> -
> -	mutex_unlock(&rng->lock);
> -	clk_disable_unprepare(rng->clk);
> -
> -	if (ret >= 0)
> -		ret = 0;
> -
> -	return ret;
> -}
> -
> -static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed,
> -			 unsigned int slen)
> -{
> -	return 0;
> -}
> -
>  static int qcom_hwrng_init(struct hwrng *hwrng)
>  {
>  	struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);
>  
>  	return clk_prepare_enable(qrng->clk);
> @@ -129,159 +82,49 @@ static void qcom_hwrng_cleanup(struct hwrng *hwrng)
>  	struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);
>  
>  	clk_disable_unprepare(qrng->clk);
>  }
>  
> -static int qcom_rng_enable(struct qcom_rng *rng)
> -{
> -	u32 val;
> -	int ret;
> -
> -	ret = clk_prepare_enable(rng->clk);
> -	if (ret)
> -		return ret;
> -
> -	/* Enable PRNG only if it is not already enabled */
> -	val = readl_relaxed(rng->base + PRNG_CONFIG);
> -	if (val & PRNG_CONFIG_HW_ENABLE)
> -		goto already_enabled;
> -
> -	val = readl_relaxed(rng->base + PRNG_LFSR_CFG);
> -	val &= ~PRNG_LFSR_CFG_MASK;
> -	val |= PRNG_LFSR_CFG_CLOCKS;
> -	writel(val, rng->base + PRNG_LFSR_CFG);
> -
> -	val = readl_relaxed(rng->base + PRNG_CONFIG);
> -	val |= PRNG_CONFIG_HW_ENABLE;
> -	writel(val, rng->base + PRNG_CONFIG);
> -
> -already_enabled:
> -	clk_disable_unprepare(rng->clk);
> -
> -	return 0;
> -}
> -
> -static int qcom_rng_init(struct crypto_tfm *tfm)
> -{
> -	struct qcom_rng_ctx *ctx = crypto_tfm_ctx(tfm);
> -
> -	ctx->rng = qcom_rng_dev;
> -
> -	if (!ctx->rng->match_data->skip_init)
> -		return qcom_rng_enable(ctx->rng);
> -
> -	return 0;
> -}
> -
> -static struct rng_alg qcom_rng_alg = {
> -	.generate	= qcom_rng_generate,
> -	.seed		= qcom_rng_seed,
> -	.seedsize	= 0,
> -	.base		= {
> -		.cra_name		= "stdrng",
> -		.cra_driver_name	= "qcom-rng",
> -		.cra_flags		= CRYPTO_ALG_TYPE_RNG,
> -		.cra_priority		= 300,
> -		.cra_ctxsize		= sizeof(struct qcom_rng_ctx),
> -		.cra_module		= THIS_MODULE,
> -		.cra_init		= qcom_rng_init,
> -	}
> -};
> -
>  static int qcom_rng_probe(struct platform_device *pdev)
>  {
>  	struct qcom_rng *rng;
>  	int ret;
>  
>  	rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
>  	if (!rng)
>  		return -ENOMEM;
>  
> -	platform_set_drvdata(pdev, rng);
> -	mutex_init(&rng->lock);
> -
>  	rng->base = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(rng->base))
>  		return PTR_ERR(rng->base);
>  
>  	rng->clk = devm_clk_get_optional(&pdev->dev, "core");
>  	if (IS_ERR(rng->clk))
>  		return PTR_ERR(rng->clk);
>  
> -	rng->match_data = (struct qcom_rng_match_data *)device_get_match_data(&pdev->dev);
> -
> -	qcom_rng_dev = rng;
> -	ret = crypto_register_rng(&qcom_rng_alg);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Register crypto rng failed: %d\n", ret);
> -		qcom_rng_dev = NULL;
> -		return ret;
> -	}
> -
> -	if (rng->match_data->hwrng_support) {
> -		rng->hwrng.name = "qcom_hwrng";
> -		rng->hwrng.init = qcom_hwrng_init;
> -		rng->hwrng.read = qcom_hwrng_read;
> -		rng->hwrng.cleanup = qcom_hwrng_cleanup;
> -		rng->hwrng.quality = QCOM_TRNG_QUALITY;
> -		ret = devm_hwrng_register(&pdev->dev, &rng->hwrng);
> -		if (ret) {
> -			dev_err(&pdev->dev, "Register hwrng failed: %d\n", ret);
> -			qcom_rng_dev = NULL;
> -			goto fail;
> -		}
> -	}
> -
> -	return ret;
> -fail:
> -	crypto_unregister_rng(&qcom_rng_alg);
> +	rng->hwrng.name = "qcom_hwrng";
> +	rng->hwrng.init = qcom_hwrng_init;
> +	rng->hwrng.read = qcom_hwrng_read;
> +	rng->hwrng.cleanup = qcom_hwrng_cleanup;
> +	rng->hwrng.quality = QCOM_TRNG_QUALITY;
> +	ret = devm_hwrng_register(&pdev->dev, &rng->hwrng);
> +	if (ret)
> +		dev_err(&pdev->dev, "Register hwrng failed: %d\n", ret);
>  	return ret;
>  }
>  
> -static void qcom_rng_remove(struct platform_device *pdev)
> -{
> -	crypto_unregister_rng(&qcom_rng_alg);
> -
> -	qcom_rng_dev = NULL;
> -}
> -
> -static struct qcom_rng_match_data qcom_prng_match_data = {
> -	.skip_init = false,
> -	.hwrng_support = false,
> -};
> -
> -static struct qcom_rng_match_data qcom_prng_ee_match_data = {
> -	.skip_init = true,
> -	.hwrng_support = false,
> -};
> -
> -static struct qcom_rng_match_data qcom_trng_match_data = {
> -	.skip_init = true,
> -	.hwrng_support = true,
> -};
> -
> -static const struct acpi_device_id __maybe_unused qcom_rng_acpi_match[] = {
> -	{ .id = "QCOM8160", .driver_data = (kernel_ulong_t)&qcom_prng_ee_match_data },
> -	{}
> -};
> -MODULE_DEVICE_TABLE(acpi, qcom_rng_acpi_match);
> -
>  static const struct of_device_id __maybe_unused qcom_rng_of_match[] = {
> -	{ .compatible = "qcom,prng", .data = &qcom_prng_match_data },
> -	{ .compatible = "qcom,prng-ee", .data = &qcom_prng_ee_match_data },
> -	{ .compatible = "qcom,trng", .data = &qcom_trng_match_data },
> +	{ .compatible = "qcom,trng" },
>  	{}
>  };
>  MODULE_DEVICE_TABLE(of, qcom_rng_of_match);
>  
>  static struct platform_driver qcom_rng_driver = {
>  	.probe = qcom_rng_probe,
> -	.remove =  qcom_rng_remove,
>  	.driver = {
>  		.name = KBUILD_MODNAME,
>  		.of_match_table = qcom_rng_of_match,
> -		.acpi_match_table = ACPI_PTR(qcom_rng_acpi_match),
>  	}
>  };
>  module_platform_driver(qcom_rng_driver);
>  
>  MODULE_ALIAS("platform:" KBUILD_MODNAME);
> 

Regards,
Neeraj

^ permalink raw reply

* Re: [PATCH] crypto: talitos: replace in_be32/out_be32 with ioread32be/iowrite32be
From: Simon Richter @ 2026-06-04  4:26 UTC (permalink / raw)
  To: Rosen Penev, linux-crypto; +Cc: Herbert Xu, David S. Miller, open list
In-Reply-To: <20260603193300.7695-1-rosenp@gmail.com>

Hi,

On 6/4/26 4:33 AM, Rosen Penev wrote:

> Convert ppc4xx-specific in_be32/out_be32 and the setbits32/clrbits32
> macros to the portable ioread32be/iowrite32be helpers.

It doesn't do that. The setbits32/clrbits32 macros are unchanged.

If they had been adapted, there would have been no need to inline the 
macro definition before substituting the IO accessors.

This inlining makes the code harder to read, because it consists of 
nested function calls (which have very specific and annoying indentation 
requirements that you're not following), and also duplicates the address 
calculation.

> Add COMPILE_TEST for extra compile coverage.

> Assisted-by: opencode:big-pickle

I suspect these two lines are related in a horrible way, and this code 
has only been compile-tested on the wrong architecture as part of the 
feedback loop. COMPILE_TEST is not necessary for compile-testing with a 
cross compiler and an appropriate defconfig for the target platform.

> -		setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
> -			  TALITOS1_CCCR_LO_RESET);
> +		iowrite32be(ioread32be(priv->chan[ch].reg + TALITOS_CCCR_LO) |
> +				    (TALITOS1_CCCR_LO_RESET),
> +			    priv->chan[ch].reg + TALITOS_CCCR_LO);

Wrong formatting, and either the parentheses around 
TALITOS1_CCCR_LO_RESET are unnecessary here, or

> -		while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) &
> -			TALITOS1_CCCR_LO_RESET) && --timeout)
> +		while ((ioread32be(priv->chan[ch].reg + TALITOS_CCCR_LO) &
> +			TALITOS1_CCCR_LO_RESET) &&
> +		       --timeout)

also needs them. The former is correct (macro definitions need to 
include parentheses if using them inside a calculation would give you 
unexpected operator precedence.

>   	/* set 36-bit addressing, done writeback enable and done IRQ enable */
> -	setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
> -		  TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
> +	iowrite32be(ioread32be(priv->chan[ch].reg + TALITOS_CCCR_LO) |
> +			    (TALITOS_CCCR_LO_EAE | TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE),
> +		    priv->chan[ch].reg + TALITOS_CCCR_LO);

These parentheses are likewise unnecessary. It's a big OR, no need to 
group them.

\> +#define DEF_TALITOS1_DONE(name, ch_done_mask) 
                          \
> +	static void talitos1_done_##name(unsigned long data)                                  \

Inconsistent backslashes, and does not improve the horribleness that was 
there before, only makes it longer and harder to read.

>   	if (!desc_hdr)
> -		desc_hdr = cpu_to_be32(in_be32(priv->chan[ch].reg + TALITOS_DESCBUF));
> +		desc_hdr = cpu_to_be32(ioread32be(priv->chan[ch].reg + TALITOS_DESCBUF));

Likewise, this is bad and unreadable in the current state, and this 
patch does nothing to improve that.

> -		dev_err(dev, "AFEUISR 0x%08x_%08x\n",
> -			in_be32(priv->reg_afeu + TALITOS_EUISR),
> -			in_be32(priv->reg_afeu + TALITOS_EUISR_LO));
> +		dev_err(dev, "AFEUISR 0x%08x_%08x\n", ioread32be(priv->reg_afeu + TALITOS_EUISR),
> +			ioread32be(priv->reg_afeu + TALITOS_EUISR_LO));

You can probably see how the formatting is worse than before.

I'm not going to bother checking if this introduces any bugs, as I have 
the strong suspicion that I would be the first person reading this code.

    Simon

^ permalink raw reply

* [PATCH] crypto: rng - Free default RNG on module exit
From: Herbert Xu @ 2026-06-04  4:30 UTC (permalink / raw)
  To: Linux Crypto Mailing List

When the rng module is removed the default RNG will be leaked.
Call crypto_del_default_rng to free it if possible.

Fixes: 7cecadb7cca8 ("crypto: rng - Do not free default RNG when it becomes unused")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/crypto/rng.c b/crypto/rng.c
index eec786c45bdd..828b0d807473 100644
--- a/crypto/rng.c
+++ b/crypto/rng.c
@@ -230,5 +230,16 @@ void crypto_unregister_rngs(struct rng_alg *algs, int count)
 }
 EXPORT_SYMBOL_GPL(crypto_unregister_rngs);
 
+static void __exit rng_exit(void)
+{
+	int err;
+
+	err = crypto_del_default_rng();
+	if (err)
+		pr_err("Failed delete default RNG: %d\n", err);
+}
+
+module_exit(rng_exit);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Random Number Generator");
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply related

* Re: [PATCH 0/2] HiSilicon TRNG fix and simplification
From: liulongfang @ 2026-06-04  3:32 UTC (permalink / raw)
  To: Eric Biggers, linux-crypto, Herbert Xu
  Cc: Olivia Mackall, Weili Qian, Wei Xu, linux-arm-kernel,
	linux-kernel
In-Reply-To: <20260530202624.20768-1-ebiggers@kernel.org>

On 2026/5/31 4:26, Eric Biggers wrote:
> This series fixes and greatly simplifies the HiSilicon TRNG driver by
> removing the gratuitous crypto_rng interface, leaving just hwrng which
> is the one that actually matters.
> 
> Note that this mirrors similar changes in other drivers such as qcom-rng
> (https://lore.kernel.org/r/20260530020332.143058-1-ebiggers@kernel.org)
> 
> Eric Biggers (2):
>   crypto: hisi-trng - Remove crypto_rng interface
>   hwrng: hisi-trng - Move hisi-trng into drivers/char/hw_random/
> 
>  MAINTAINERS                            |   2 +-
>  arch/arm64/configs/defconfig           |   2 +-
>  drivers/char/hw_random/Kconfig         |  10 +
>  drivers/char/hw_random/Makefile        |   1 +
>  drivers/char/hw_random/hisi-trng-v2.c  |  98 +++++++
>  drivers/crypto/hisilicon/Kconfig       |   8 -
>  drivers/crypto/hisilicon/Makefile      |   1 -
>  drivers/crypto/hisilicon/trng/Makefile |   2 -
>  drivers/crypto/hisilicon/trng/trng.c   | 390 -------------------------
>  9 files changed, 111 insertions(+), 403 deletions(-)
>  create mode 100644 drivers/char/hw_random/hisi-trng-v2.c
>  delete mode 100644 drivers/crypto/hisilicon/trng/Makefile
>  delete mode 100644 drivers/crypto/hisilicon/trng/trng.c
> 
> 
> base-commit: 5624ea54f3ba5c83d2e5503411a31a8be0278c1e
> prerequisite-patch-id: 07e982b663ac3f8312ca524f6b91b5b38661df5e
> prerequisite-patch-id: 72064361a8f36e015ab0b7e1fa4d364b40d90506
> prerequisite-patch-id: 8978b8e0db7f47935e5f6f0aff14a97f55d3073c
> prerequisite-patch-id: 6aa0e3e93a008279d71e535a3d0cf48643f55e19
>

Acked-by: Longfang Liu <liulongfang@huawei.com>

Thanks.

^ permalink raw reply

* [PATCH] rhashtable: Add workqueue/irq_work header inclusions
From: Herbert Xu @ 2026-06-04  2:21 UTC (permalink / raw)
  To: Linux Crypto Mailing List

Add inclusions for irq_work.h and workqueue.h to rhashtable.c rather
than relying on indirect inclusions from elsewhere.

Remove workqueue.h from rhashtable.h now that it uses IRQ work only.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index ef5230cece36..b01d53c37a68 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -23,7 +23,6 @@
 #include <linux/irq_work.h>
 #include <linux/jhash.h>
 #include <linux/list_nulls.h>
-#include <linux/workqueue.h>
 #include <linux/rculist.h>
 #include <linux/bit_spinlock.h>
 
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 04b3a808fca9..57751ee19faa 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -14,6 +14,7 @@
 #include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/irq_work.h>
 #include <linux/log2.h>
 #include <linux/sched.h>
 #include <linux/rculist.h>
@@ -25,6 +26,7 @@
 #include <linux/rhashtable.h>
 #include <linux/err.h>
 #include <linux/export.h>
+#include <linux/workqueue.h>
 
 #define HASH_DEFAULT_SIZE	64UL
 #define HASH_MIN_SIZE		4U
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply related

* [PATCH] rhashtable: Use irq work for shrinking
From: Herbert Xu @ 2026-06-04  2:17 UTC (permalink / raw)
  To: Mykyta Yatsenko
  Cc: bot+bpf-ci, bpf, ast, andrii, daniel, kafai, kernel-team, eddyz87,
	memxor, yatsenko, martin.lau, yonghong.song, clm, ihor.solodrai,
	Tejun Heo, Linux Crypto Mailing List
In-Reply-To: <3960ffc3-78f3-46da-baaf-ce72b6495698@gmail.com>

On Wed, Jun 03, 2026 at 02:08:25PM +0100, Mykyta Yatsenko wrote:
>
> For v7 I'm dropping automatic_shrinking, because it adds a risk of
> calling schedule_work() on element deletion path (__rhashtable_remove_fast_one())
> when hashtable size drops below 30% of the capacity.

Now that expansion uses irq work I think shrinking should switch
to that as well.

---8<---
Use irq work for automatic shrinking so that this may be called
in NMI context.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index ef5230cece36..0693bce6f890 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -1117,7 +1117,7 @@ static __always_inline int __rhashtable_remove_fast_one(
 		atomic_dec(&ht->nelems);
 		if (unlikely(ht->p.automatic_shrinking &&
 			     rht_shrink_below_30(ht, tbl)))
-			schedule_work(&ht->run_work);
+			irq_work_queue(&ht->run_irq_work);
 		err = 0;
 	}
 
Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox