@@ -2590,11 +2590,22 @@ int chcr_aead_dma_map(struct device *dev,
25902590 struct chcr_aead_reqctx * reqctx = aead_request_ctx (req );
25912591 struct crypto_aead * tfm = crypto_aead_reqtfm (req );
25922592 unsigned int authsize = crypto_aead_authsize (tfm );
2593- int dst_size ;
2593+ int src_len , dst_len ;
25942594
2595- dst_size = req -> assoclen + req -> cryptlen + (op_type ?
2596- 0 : authsize );
2597- if (!req -> cryptlen || !dst_size )
2595+ /* calculate and handle src and dst sg length separately
2596+ * for inplace and out-of place operations
2597+ */
2598+ if (req -> src == req -> dst ) {
2599+ src_len = req -> assoclen + req -> cryptlen + (op_type ?
2600+ 0 : authsize );
2601+ dst_len = src_len ;
2602+ } else {
2603+ src_len = req -> assoclen + req -> cryptlen ;
2604+ dst_len = req -> assoclen + req -> cryptlen + (op_type ?
2605+ - authsize : authsize );
2606+ }
2607+
2608+ if (!req -> cryptlen || !src_len || !dst_len )
25982609 return 0 ;
25992610 reqctx -> iv_dma = dma_map_single (dev , reqctx -> iv , (IV + reqctx -> b0_len ),
26002611 DMA_BIDIRECTIONAL );
@@ -2606,20 +2617,23 @@ int chcr_aead_dma_map(struct device *dev,
26062617 reqctx -> b0_dma = 0 ;
26072618 if (req -> src == req -> dst ) {
26082619 error = dma_map_sg (dev , req -> src ,
2609- sg_nents_for_len (req -> src , dst_size ),
2620+ sg_nents_for_len (req -> src , src_len ),
26102621 DMA_BIDIRECTIONAL );
26112622 if (!error )
26122623 goto err ;
26132624 } else {
2614- error = dma_map_sg (dev , req -> src , sg_nents (req -> src ),
2625+ error = dma_map_sg (dev , req -> src ,
2626+ sg_nents_for_len (req -> src , src_len ),
26152627 DMA_TO_DEVICE );
26162628 if (!error )
26172629 goto err ;
2618- error = dma_map_sg (dev , req -> dst , sg_nents (req -> dst ),
2630+ error = dma_map_sg (dev , req -> dst ,
2631+ sg_nents_for_len (req -> dst , dst_len ),
26192632 DMA_FROM_DEVICE );
26202633 if (!error ) {
2621- dma_unmap_sg (dev , req -> src , sg_nents (req -> src ),
2622- DMA_TO_DEVICE );
2634+ dma_unmap_sg (dev , req -> src ,
2635+ sg_nents_for_len (req -> src , src_len ),
2636+ DMA_TO_DEVICE );
26232637 goto err ;
26242638 }
26252639 }
@@ -2637,24 +2651,37 @@ void chcr_aead_dma_unmap(struct device *dev,
26372651 struct chcr_aead_reqctx * reqctx = aead_request_ctx (req );
26382652 struct crypto_aead * tfm = crypto_aead_reqtfm (req );
26392653 unsigned int authsize = crypto_aead_authsize (tfm );
2640- int dst_size ;
2654+ int src_len , dst_len ;
26412655
2642- dst_size = req -> assoclen + req -> cryptlen + (op_type ?
2643- 0 : authsize );
2644- if (!req -> cryptlen || !dst_size )
2656+ /* calculate and handle src and dst sg length separately
2657+ * for inplace and out-of place operations
2658+ */
2659+ if (req -> src == req -> dst ) {
2660+ src_len = req -> assoclen + req -> cryptlen + (op_type ?
2661+ 0 : authsize );
2662+ dst_len = src_len ;
2663+ } else {
2664+ src_len = req -> assoclen + req -> cryptlen ;
2665+ dst_len = req -> assoclen + req -> cryptlen + (op_type ?
2666+ - authsize : authsize );
2667+ }
2668+
2669+ if (!req -> cryptlen || !src_len || !dst_len )
26452670 return ;
26462671
26472672 dma_unmap_single (dev , reqctx -> iv_dma , (IV + reqctx -> b0_len ),
26482673 DMA_BIDIRECTIONAL );
26492674 if (req -> src == req -> dst ) {
26502675 dma_unmap_sg (dev , req -> src ,
2651- sg_nents_for_len (req -> src , dst_size ),
2676+ sg_nents_for_len (req -> src , src_len ),
26522677 DMA_BIDIRECTIONAL );
26532678 } else {
2654- dma_unmap_sg (dev , req -> src , sg_nents (req -> src ),
2655- DMA_TO_DEVICE );
2656- dma_unmap_sg (dev , req -> dst , sg_nents (req -> dst ),
2657- DMA_FROM_DEVICE );
2679+ dma_unmap_sg (dev , req -> src ,
2680+ sg_nents_for_len (req -> src , src_len ),
2681+ DMA_TO_DEVICE );
2682+ dma_unmap_sg (dev , req -> dst ,
2683+ sg_nents_for_len (req -> dst , dst_len ),
2684+ DMA_FROM_DEVICE );
26582685 }
26592686}
26602687
@@ -4364,22 +4391,32 @@ static int chcr_unregister_alg(void)
43644391 for (i = 0 ; i < ARRAY_SIZE (driver_algs ); i ++ ) {
43654392 switch (driver_algs [i ].type & CRYPTO_ALG_TYPE_MASK ) {
43664393 case CRYPTO_ALG_TYPE_SKCIPHER :
4367- if (driver_algs [i ].is_registered )
4394+ if (driver_algs [i ].is_registered && refcount_read (
4395+ & driver_algs [i ].alg .skcipher .base .cra_refcnt )
4396+ == 1 ) {
43684397 crypto_unregister_skcipher (
43694398 & driver_algs [i ].alg .skcipher );
4399+ driver_algs [i ].is_registered = 0 ;
4400+ }
43704401 break ;
43714402 case CRYPTO_ALG_TYPE_AEAD :
4372- if (driver_algs [i ].is_registered )
4403+ if (driver_algs [i ].is_registered && refcount_read (
4404+ & driver_algs [i ].alg .aead .base .cra_refcnt ) == 1 ) {
43734405 crypto_unregister_aead (
43744406 & driver_algs [i ].alg .aead );
4407+ driver_algs [i ].is_registered = 0 ;
4408+ }
43754409 break ;
43764410 case CRYPTO_ALG_TYPE_AHASH :
4377- if (driver_algs [i ].is_registered )
4411+ if (driver_algs [i ].is_registered && refcount_read (
4412+ & driver_algs [i ].alg .hash .halg .base .cra_refcnt )
4413+ == 1 ) {
43784414 crypto_unregister_ahash (
43794415 & driver_algs [i ].alg .hash );
4416+ driver_algs [i ].is_registered = 0 ;
4417+ }
43804418 break ;
43814419 }
4382- driver_algs [i ].is_registered = 0 ;
43834420 }
43844421 return 0 ;
43854422}
0 commit comments