Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: mxs-dcp - Optimize hashing

Optimize the hashing operation in the MXS-DCP by doing two adjustments:
1) Given that the output buffer for the hash is now always correctly aligned,
we can just use the buffer for the DCP DMA to store the resulting hash.
We thus get rid of one copying of data. Moreover, we remove an entry from
dcp_coherent_block{} and thus lower the memory footprint of the driver.
2) We map the output buffer for the hash for DMA only in case we will output
the hash, not always, as it was now.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Marek Vasut and committed by
Herbert Xu
04d088cc 1a7c6856

+17 -11
+17 -11
drivers/crypto/mxs-dcp.c
··· 50 50 uint8_t sha_in_buf[DCP_BUF_SZ]; 51 51 52 52 uint8_t aes_key[2 * AES_KEYSIZE_128]; 53 - uint8_t sha_digest[SHA256_DIGEST_SIZE]; 54 53 55 54 struct dcp_dma_desc desc[DCP_MAX_CHANS]; 56 55 }; ··· 515 516 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 516 517 struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm); 517 518 struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req); 519 + struct hash_alg_common *halg = crypto_hash_alg_common(tfm); 518 520 519 521 struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan]; 520 - dma_addr_t digest_phys = dma_map_single(sdcp->dev, 521 - sdcp->coh->sha_digest, 522 - SHA256_DIGEST_SIZE, 523 - DMA_FROM_DEVICE); 524 522 523 + dma_addr_t digest_phys = 0; 525 524 dma_addr_t buf_phys = dma_map_single(sdcp->dev, sdcp->coh->sha_in_buf, 526 525 DCP_BUF_SZ, DMA_TO_DEVICE); 527 526 ··· 540 543 541 544 /* Set HASH_TERM bit for last transfer block. */ 542 545 if (rctx->fini) { 546 + digest_phys = dma_map_single(sdcp->dev, req->result, 547 + halg->digestsize, DMA_FROM_DEVICE); 543 548 desc->control0 |= MXS_DCP_CONTROL0_HASH_TERM; 544 549 desc->payload = digest_phys; 545 550 } 546 551 547 552 ret = mxs_dcp_start_dma(actx); 548 553 549 - dma_unmap_single(sdcp->dev, digest_phys, SHA256_DIGEST_SIZE, 550 - DMA_FROM_DEVICE); 554 + if (rctx->fini) 555 + dma_unmap_single(sdcp->dev, digest_phys, halg->digestsize, 556 + DMA_FROM_DEVICE); 557 + 551 558 dma_unmap_single(sdcp->dev, buf_phys, DCP_BUF_SZ, DMA_TO_DEVICE); 552 559 553 560 return ret; ··· 568 567 struct hash_alg_common *halg = crypto_hash_alg_common(tfm); 569 568 const int nents = sg_nents(req->src); 570 569 571 - uint8_t *digest = sdcp->coh->sha_digest; 572 570 uint8_t *in_buf = sdcp->coh->sha_in_buf; 573 571 574 572 uint8_t *src_buf; ··· 614 614 rctx->fini = 1; 615 615 616 616 /* Submit whatever is left. */ 617 + if (!req->result) 618 + return -EINVAL; 619 + 617 620 ret = mxs_dcp_run_sha(req); 618 - if (ret || !req->result) 621 + if (ret) 619 622 return ret; 623 + 620 624 actx->fill = 0; 621 625 622 626 /* For some reason, the result is flipped. */ 623 - for (i = 0; i < halg->digestsize; i++) 624 - req->result[i] = digest[halg->digestsize - i - 1]; 627 + for (i = 0; i < halg->digestsize / 2; i++) { 628 + swap(req->result[i], 629 + req->result[halg->digestsize - i - 1]); 630 + } 625 631 } 626 632 627 633 return 0;