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

Configure Feed

Select the types of activity you want to include in your feed.

crypto: sun8i-ce - save hash buffers and dma info to request context

Similar to sun8i-ce skcipher code, move all request-specific data to
request context. This simplifies sun8i_ce_hash_run() and it eliminates
the remaining kmalloc() calls from the digest path.

Since the 'result' buffer in the request ctx struct is used for from-device
DMA, it needs to be properly aligned to CRYPTO_DMA_ALIGN. Therefore:
- increase reqsize by CRYPTO_DMA_PADDING
- add __aligned(CRYPTO_DMA_ALIGN) attribute for the 'result' buffer
- convert all ahash_request_ctx_dma() calls to ahash_request_ctx_dma()

Signed-off-by: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Ovidiu Panait and committed by
Herbert Xu
c3a61eea 49034c03

+49 -45
+32 -45
drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
··· 58 58 59 59 crypto_ahash_set_reqsize(tfm, 60 60 sizeof(struct sun8i_ce_hash_reqctx) + 61 - crypto_ahash_reqsize(op->fallback_tfm)); 61 + crypto_ahash_reqsize(op->fallback_tfm) + 62 + CRYPTO_DMA_PADDING); 62 63 63 64 if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG)) 64 65 memcpy(algt->fbname, ··· 85 84 86 85 int sun8i_ce_hash_init(struct ahash_request *areq) 87 86 { 88 - struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); 87 + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq); 89 88 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 90 89 struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 91 90 ··· 101 100 102 101 int sun8i_ce_hash_export(struct ahash_request *areq, void *out) 103 102 { 104 - struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); 103 + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq); 105 104 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 106 105 struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 107 106 ··· 115 114 116 115 int sun8i_ce_hash_import(struct ahash_request *areq, const void *in) 117 116 { 118 - struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); 117 + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq); 119 118 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 120 119 struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 121 120 ··· 129 128 130 129 int sun8i_ce_hash_final(struct ahash_request *areq) 131 130 { 132 - struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); 131 + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq); 133 132 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 134 133 struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 135 134 ··· 146 145 147 146 int sun8i_ce_hash_update(struct ahash_request *areq) 148 147 { 149 - struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); 148 + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq); 150 149 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 151 150 struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 152 151 ··· 161 160 162 161 int sun8i_ce_hash_finup(struct ahash_request *areq) 163 162 { 164 - struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); 163 + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq); 165 164 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 166 165 struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 167 166 ··· 179 178 180 179 static int sun8i_ce_hash_digest_fb(struct ahash_request *areq) 181 180 { 182 - struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); 181 + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq); 183 182 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 184 183 struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 185 184 ··· 240 239 { 241 240 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 242 241 struct sun8i_ce_hash_tfm_ctx *ctx = crypto_ahash_ctx(tfm); 243 - struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); 242 + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq); 244 243 struct sun8i_ce_dev *ce = ctx->ce; 245 244 struct crypto_engine *engine; 246 245 int e; ··· 318 317 struct ahash_request *areq = container_of(breq, struct ahash_request, base); 319 318 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 320 319 struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); 321 - struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); 320 + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq); 322 321 struct sun8i_ce_alg_template *algt; 323 322 struct sun8i_ce_dev *ce; 324 323 struct sun8i_ce_flow *chan; ··· 329 328 u32 common; 330 329 u64 byte_count; 331 330 __le32 *bf; 332 - void *buf, *result; 333 331 int j, i, todo; 334 332 u64 bs; 335 333 int digestsize; 336 - dma_addr_t addr_res, addr_pad; 337 - int ns = sg_nents_for_len(areq->src, areq->nbytes); 338 334 339 335 algt = container_of(alg, struct sun8i_ce_alg_template, alg.hash.base); 340 336 ce = algt->ce; ··· 343 345 if (digestsize == SHA384_DIGEST_SIZE) 344 346 digestsize = SHA512_DIGEST_SIZE; 345 347 346 - /* the padding could be up to two block. */ 347 - buf = kcalloc(2, bs, GFP_KERNEL | GFP_DMA); 348 - if (!buf) { 349 - err = -ENOMEM; 350 - goto err_out; 351 - } 352 - bf = (__le32 *)buf; 353 - 354 - result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA); 355 - if (!result) { 356 - err = -ENOMEM; 357 - goto err_free_buf; 358 - } 348 + bf = (__le32 *)rctx->pad; 359 349 360 350 flow = rctx->flow; 361 351 chan = &ce->chanlist[flow]; ··· 364 378 cet->t_sym_ctl = 0; 365 379 cet->t_asym_ctl = 0; 366 380 367 - nr_sgs = dma_map_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE); 381 + rctx->nr_sgs = sg_nents_for_len(areq->src, areq->nbytes); 382 + nr_sgs = dma_map_sg(ce->dev, areq->src, rctx->nr_sgs, DMA_TO_DEVICE); 368 383 if (nr_sgs <= 0 || nr_sgs > MAX_SG) { 369 384 dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs); 370 385 err = -EINVAL; 371 - goto err_free_result; 386 + goto err_out; 372 387 } 373 388 374 389 len = areq->nbytes; ··· 384 397 err = -EINVAL; 385 398 goto err_unmap_src; 386 399 } 387 - addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE); 388 - cet->t_dst[0].addr = desc_addr_val_le32(ce, addr_res); 389 - cet->t_dst[0].len = cpu_to_le32(digestsize / 4); 390 - if (dma_mapping_error(ce->dev, addr_res)) { 400 + 401 + rctx->result_len = digestsize; 402 + rctx->addr_res = dma_map_single(ce->dev, rctx->result, rctx->result_len, 403 + DMA_FROM_DEVICE); 404 + cet->t_dst[0].addr = desc_addr_val_le32(ce, rctx->addr_res); 405 + cet->t_dst[0].len = cpu_to_le32(rctx->result_len / 4); 406 + if (dma_mapping_error(ce->dev, rctx->addr_res)) { 391 407 dev_err(ce->dev, "DMA map dest\n"); 392 408 err = -EINVAL; 393 409 goto err_unmap_src; ··· 418 428 goto err_unmap_result; 419 429 } 420 430 421 - addr_pad = dma_map_single(ce->dev, buf, j * 4, DMA_TO_DEVICE); 422 - cet->t_src[i].addr = desc_addr_val_le32(ce, addr_pad); 431 + rctx->pad_len = j * 4; 432 + rctx->addr_pad = dma_map_single(ce->dev, rctx->pad, rctx->pad_len, 433 + DMA_TO_DEVICE); 434 + cet->t_src[i].addr = desc_addr_val_le32(ce, rctx->addr_pad); 423 435 cet->t_src[i].len = cpu_to_le32(j); 424 - if (dma_mapping_error(ce->dev, addr_pad)) { 436 + if (dma_mapping_error(ce->dev, rctx->addr_pad)) { 425 437 dev_err(ce->dev, "DMA error on padding SG\n"); 426 438 err = -EINVAL; 427 439 goto err_unmap_result; ··· 436 444 437 445 err = sun8i_ce_run_task(ce, flow, crypto_ahash_alg_name(tfm)); 438 446 439 - dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE); 447 + dma_unmap_single(ce->dev, rctx->addr_pad, rctx->pad_len, DMA_TO_DEVICE); 440 448 441 449 err_unmap_result: 442 - dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE); 450 + dma_unmap_single(ce->dev, rctx->addr_res, rctx->result_len, 451 + DMA_FROM_DEVICE); 443 452 if (!err) 444 - memcpy(areq->result, result, crypto_ahash_digestsize(tfm)); 453 + memcpy(areq->result, rctx->result, crypto_ahash_digestsize(tfm)); 445 454 446 455 err_unmap_src: 447 - dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE); 448 - 449 - err_free_result: 450 - kfree(result); 451 - 452 - err_free_buf: 453 - kfree(buf); 456 + dma_unmap_sg(ce->dev, areq->src, rctx->nr_sgs, DMA_TO_DEVICE); 454 457 455 458 err_out: 456 459 local_bh_disable();
+17
drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
··· 110 110 111 111 #define MAXFLOW 4 112 112 113 + #define CE_MAX_HASH_DIGEST_SIZE SHA512_DIGEST_SIZE 114 + #define CE_MAX_HASH_BLOCK_SIZE SHA512_BLOCK_SIZE 115 + 113 116 /* 114 117 * struct ce_clock - Describe clocks used by sun8i-ce 115 118 * @name: Name of clock needed by this variant ··· 307 304 * struct sun8i_ce_hash_reqctx - context for an ahash request 308 305 * @fallback_req: pre-allocated fallback request 309 306 * @flow: the flow to use for this request 307 + * @nr_sgs: number of entries in the source scatterlist 308 + * @result_len: result length in bytes 309 + * @pad_len: padding length in bytes 310 + * @addr_res: DMA address of the result buffer, returned by dma_map_single() 311 + * @addr_pad: DMA address of the padding buffer, returned by dma_map_single() 312 + * @result: per-request result buffer 313 + * @pad: per-request padding buffer (up to 2 blocks) 310 314 */ 311 315 struct sun8i_ce_hash_reqctx { 312 316 int flow; 317 + int nr_sgs; 318 + size_t result_len; 319 + size_t pad_len; 320 + dma_addr_t addr_res; 321 + dma_addr_t addr_pad; 322 + u8 result[CE_MAX_HASH_DIGEST_SIZE] __aligned(CRYPTO_DMA_ALIGN); 323 + u8 pad[2 * CE_MAX_HASH_BLOCK_SIZE]; 313 324 struct ahash_request fallback_req; // keep at the end 314 325 }; 315 326