aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@free-electrons.com>2015-10-18 12:24:57 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-10-20 10:11:09 -0400
commit8c07f3a8c487df241f5e809e8f6d5dd7c9d75b54 (patch)
tree611dc873e4151a7957b9fd0a5ff1c06e68dcc28c /drivers/crypto
parent8efbc2c0f6b4e52e384ecb1714511f0194c4d56a (diff)
crypto: marvell/cesa - fix memory leak
To: Boris Brezillon <boris.brezillon@free-electrons.com>,Arnaud Ebalard <arno@natisbad.org>,Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,Jason Cooper <jason@lakedaemon.net> The local chain variable is not cleaned up if an error occurs in the middle of DMA chain creation. Fix that by dropping the local chain variable and using the dreq->chain field which will be cleaned up by mv_cesa_dma_cleanup() in case of errors. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Reported-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/marvell/hash.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c
index 4c80126de3ad..d813de604b8f 100644
--- a/drivers/crypto/marvell/hash.c
+++ b/drivers/crypto/marvell/hash.c
@@ -602,7 +602,6 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
602 GFP_KERNEL : GFP_ATOMIC; 602 GFP_KERNEL : GFP_ATOMIC;
603 struct mv_cesa_ahash_dma_req *ahashdreq = &creq->req.dma; 603 struct mv_cesa_ahash_dma_req *ahashdreq = &creq->req.dma;
604 struct mv_cesa_tdma_req *dreq = &ahashdreq->base; 604 struct mv_cesa_tdma_req *dreq = &ahashdreq->base;
605 struct mv_cesa_tdma_chain chain;
606 struct mv_cesa_ahash_dma_iter iter; 605 struct mv_cesa_ahash_dma_iter iter;
607 struct mv_cesa_op_ctx *op = NULL; 606 struct mv_cesa_op_ctx *op = NULL;
608 unsigned int frag_len; 607 unsigned int frag_len;
@@ -620,14 +619,14 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
620 } 619 }
621 } 620 }
622 621
623 mv_cesa_tdma_desc_iter_init(&chain); 622 mv_cesa_tdma_desc_iter_init(&dreq->chain);
624 mv_cesa_ahash_req_iter_init(&iter, req); 623 mv_cesa_ahash_req_iter_init(&iter, req);
625 624
626 /* 625 /*
627 * Add the cache (left-over data from a previous block) first. 626 * Add the cache (left-over data from a previous block) first.
628 * This will never overflow the SRAM size. 627 * This will never overflow the SRAM size.
629 */ 628 */
630 ret = mv_cesa_ahash_dma_add_cache(&chain, &iter, creq, flags); 629 ret = mv_cesa_ahash_dma_add_cache(&dreq->chain, &iter, creq, flags);
631 if (ret) 630 if (ret)
632 goto err_free_tdma; 631 goto err_free_tdma;
633 632
@@ -638,7 +637,8 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
638 * data. We intentionally do not add the final op block. 637 * data. We intentionally do not add the final op block.
639 */ 638 */
640 while (true) { 639 while (true) {
641 ret = mv_cesa_dma_add_op_transfers(&chain, &iter.base, 640 ret = mv_cesa_dma_add_op_transfers(&dreq->chain,
641 &iter.base,
642 &iter.src, flags); 642 &iter.src, flags);
643 if (ret) 643 if (ret)
644 goto err_free_tdma; 644 goto err_free_tdma;
@@ -648,7 +648,7 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
648 if (!mv_cesa_ahash_req_iter_next_op(&iter)) 648 if (!mv_cesa_ahash_req_iter_next_op(&iter))
649 break; 649 break;
650 650
651 op = mv_cesa_dma_add_frag(&chain, &creq->op_tmpl, 651 op = mv_cesa_dma_add_frag(&dreq->chain, &creq->op_tmpl,
652 frag_len, flags); 652 frag_len, flags);
653 if (IS_ERR(op)) { 653 if (IS_ERR(op)) {
654 ret = PTR_ERR(op); 654 ret = PTR_ERR(op);
@@ -666,11 +666,11 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
666 * operation, which depends whether this is the final request. 666 * operation, which depends whether this is the final request.
667 */ 667 */
668 if (creq->last_req) 668 if (creq->last_req)
669 op = mv_cesa_ahash_dma_last_req(&chain, &iter, creq, frag_len, 669 op = mv_cesa_ahash_dma_last_req(&dreq->chain, &iter, creq,
670 flags); 670 frag_len, flags);
671 else if (frag_len) 671 else if (frag_len)
672 op = mv_cesa_dma_add_frag(&chain, &creq->op_tmpl, frag_len, 672 op = mv_cesa_dma_add_frag(&dreq->chain, &creq->op_tmpl,
673 flags); 673 frag_len, flags);
674 674
675 if (IS_ERR(op)) { 675 if (IS_ERR(op)) {
676 ret = PTR_ERR(op); 676 ret = PTR_ERR(op);
@@ -679,7 +679,7 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
679 679
680 if (op) { 680 if (op) {
681 /* Add dummy desc to wait for crypto operation end */ 681 /* Add dummy desc to wait for crypto operation end */
682 ret = mv_cesa_dma_add_dummy_end(&chain, flags); 682 ret = mv_cesa_dma_add_dummy_end(&dreq->chain, flags);
683 if (ret) 683 if (ret)
684 goto err_free_tdma; 684 goto err_free_tdma;
685 } 685 }
@@ -690,8 +690,6 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
690 else 690 else
691 creq->cache_ptr = 0; 691 creq->cache_ptr = 0;
692 692
693 dreq->chain = chain;
694
695 return 0; 693 return 0;
696 694
697err_free_tdma: 695err_free_tdma: