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: octeontx2 - Fix address alignment on CN10K A0/A1 and OcteonTX2

octeontx2 crypto driver allocates memory using kmalloc/kzalloc,
and uses this memory for dma (does dma_map_single()). It assumes
that kmalloc/kzalloc will return 128-byte aligned address. But
kmalloc/kzalloc returns 8-byte aligned address after below changes:
"9382bc44b5f5 arm64: allow kmalloc() caches aligned to the
smaller cache_line_size()

Memory allocated are used for following purpose:
- Input data or scatter list address - 8-Byte alignment
- Output data or gather list address - 8-Byte alignment
- Completion address - 32-Byte alignment.

This patch ensures all addresses are aligned as mentioned above.

Signed-off-by: Bharat Bhushan <bbhushan2@marvell.com>
Cc: <stable@vger.kernel.org> # v6.5+
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Bharat Bhushan and committed by
Herbert Xu
2e13163b b7b88b49

+51 -15
+51 -15
drivers/crypto/marvell/octeontx2/otx2_cpt_reqmgr.h
··· 34 34 #define SG_COMP_2 2 35 35 #define SG_COMP_1 1 36 36 37 + #define OTX2_CPT_DPTR_RPTR_ALIGN 8 38 + #define OTX2_CPT_RES_ADDR_ALIGN 32 39 + 37 40 union otx2_cpt_opcode { 38 41 u16 flags; 39 42 struct { ··· 420 417 otx2_sg_info_create(struct pci_dev *pdev, struct otx2_cpt_req_info *req, 421 418 gfp_t gfp) 422 419 { 423 - int align = OTX2_CPT_DMA_MINALIGN; 424 420 struct otx2_cpt_inst_info *info; 425 - u32 dlen, align_dlen, info_len; 426 - u16 g_sz_bytes, s_sz_bytes; 421 + u32 dlen, info_len; 422 + u16 g_len, s_len; 427 423 u32 total_mem_len; 428 424 429 425 if (unlikely(req->in_cnt > OTX2_CPT_MAX_SG_IN_CNT || ··· 431 429 return NULL; 432 430 } 433 431 434 - g_sz_bytes = ((req->in_cnt + 3) / 4) * 435 - sizeof(struct otx2_cpt_sglist_component); 436 - s_sz_bytes = ((req->out_cnt + 3) / 4) * 437 - sizeof(struct otx2_cpt_sglist_component); 432 + /* Allocate memory to meet below alignment requirement: 433 + * ------------------------------------ 434 + * | struct otx2_cpt_inst_info | 435 + * | (No alignment required) | 436 + * | --------------------------------| 437 + * | | padding for ARCH_DMA_MINALIGN | 438 + * | | alignment | 439 + * |------------------------------------| 440 + * | SG List Header of 8 Byte | 441 + * |------------------------------------| 442 + * | SG List Gather/Input memory | 443 + * | Length = multiple of 32Bytes | 444 + * | Alignment = 8Byte | 445 + * |---------------------------------- | 446 + * | SG List Scatter/Output memory | 447 + * | Length = multiple of 32Bytes | 448 + * | Alignment = 8Byte | 449 + * | -------------------------------| 450 + * | | padding for 32B alignment | 451 + * |------------------------------------| 452 + * | Result response memory | 453 + * | Alignment = 32Byte | 454 + * ------------------------------------ 455 + */ 438 456 439 - dlen = g_sz_bytes + s_sz_bytes + SG_LIST_HDR_SIZE; 440 - align_dlen = ALIGN(dlen, align); 441 - info_len = ALIGN(sizeof(*info), align); 442 - total_mem_len = align_dlen + info_len + sizeof(union otx2_cpt_res_s); 457 + info_len = sizeof(*info); 458 + 459 + g_len = ((req->in_cnt + 3) / 4) * 460 + sizeof(struct otx2_cpt_sglist_component); 461 + s_len = ((req->out_cnt + 3) / 4) * 462 + sizeof(struct otx2_cpt_sglist_component); 463 + 464 + dlen = g_len + s_len + SG_LIST_HDR_SIZE; 465 + 466 + /* Allocate extra memory for SG and response address alignment */ 467 + total_mem_len = ALIGN(info_len, OTX2_CPT_DPTR_RPTR_ALIGN); 468 + total_mem_len += (ARCH_DMA_MINALIGN - 1) & 469 + ~(OTX2_CPT_DPTR_RPTR_ALIGN - 1); 470 + total_mem_len += ALIGN(dlen, OTX2_CPT_RES_ADDR_ALIGN); 471 + total_mem_len += sizeof(union otx2_cpt_res_s); 443 472 444 473 info = kzalloc(total_mem_len, gfp); 445 474 if (unlikely(!info)) 446 475 return NULL; 447 476 448 477 info->dlen = dlen; 449 - info->in_buffer = (u8 *)info + info_len; 478 + info->in_buffer = PTR_ALIGN((u8 *)info + info_len, ARCH_DMA_MINALIGN); 479 + info->out_buffer = info->in_buffer + SG_LIST_HDR_SIZE + g_len; 450 480 451 481 ((u16 *)info->in_buffer)[0] = req->out_cnt; 452 482 ((u16 *)info->in_buffer)[1] = req->in_cnt; ··· 494 460 } 495 461 496 462 if (setup_sgio_components(pdev, req->out, req->out_cnt, 497 - &info->in_buffer[8 + g_sz_bytes])) { 463 + info->out_buffer)) { 498 464 dev_err(&pdev->dev, "Failed to setup scatter list\n"); 499 465 goto destroy_info; 500 466 } ··· 510 476 * Get buffer for union otx2_cpt_res_s response 511 477 * structure and its physical address 512 478 */ 513 - info->completion_addr = info->in_buffer + align_dlen; 514 - info->comp_baddr = info->dptr_baddr + align_dlen; 479 + info->completion_addr = PTR_ALIGN((info->in_buffer + dlen), 480 + OTX2_CPT_RES_ADDR_ALIGN); 481 + info->comp_baddr = ALIGN((info->dptr_baddr + dlen), 482 + OTX2_CPT_RES_ADDR_ALIGN); 515 483 516 484 return info; 517 485