mirror of
https://github.com/torvalds/linux.git
synced 2026-11-09 13:44:03 +01:00
crypto: atmel-tdes - sync output bounce buffer before DMA
The slow path maps its output bounce buffer once at probe time with dma_map_single() and DMA_FROM_DEVICE, then reuses the mapping for every request. After the CPU copies a result from the buffer, dma_sync_single_for_device() must hand the buffer back to the device before the next DMA transfer. The driver omits this call, so cache lines from the previous result can remain valid while the device writes the next one. This bug was masked by the completion paths calling dma_sync_single_for_device() immediately before the CPU copied the output, where dma_sync_single_for_cpu() was required. For DMA_FROM_DEVICE on ARM926, dma_sync_single_for_device() invokes arm926_dma_map_area(), which invalidates the cache lines. The misplaced call therefore discarded the stale lines before every copy-out. Commitc8a9a64753("crypto: atmel-tdes - fix DMA sync direction") correctly changed the completion paths to call dma_sync_single_for_cpu(). On ARM926, that function invokes arm926_dma_unmap_area(), which is a no-op. The missing pre-DMA dma_sync_single_for_device() was therefore exposed on ARM926-based SAM9X60 and SAM9X7 SoCs. With CONFIG_CRYPTO_SELFTESTS=y all four DES/TDES algorithms fail on SAM9X75: alg: skcipher: atmel-ecb-tdes encryption test failed (wrong result) on test vector 2, cfg="unaligned buffer, offset=1" Call dma_sync_single_for_device() for the output buffer before starting DMA in both atmel_tdes_crypt_pdc() and atmel_tdes_crypt_dma(). Fixes:c8a9a64753("crypto: atmel-tdes - fix DMA sync direction") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Reviewed-by: Thorsten Blum <blum@kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
75ed7550da
commit
a38fdcb9c9
|
|
@ -370,6 +370,8 @@ static int atmel_tdes_crypt_pdc(struct atmel_tdes_dev *dd,
|
|||
if (!(dd->flags & TDES_FLAGS_FAST)) {
|
||||
dma_sync_single_for_device(dd->dev, dma_addr_in, length,
|
||||
DMA_TO_DEVICE);
|
||||
dma_sync_single_for_device(dd->dev, dma_addr_out, length,
|
||||
DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
len32 = DIV_ROUND_UP(length, sizeof(u32));
|
||||
|
|
@ -402,6 +404,8 @@ static int atmel_tdes_crypt_dma(struct atmel_tdes_dev *dd,
|
|||
if (!(dd->flags & TDES_FLAGS_FAST)) {
|
||||
dma_sync_single_for_device(dd->dev, dma_addr_in, length,
|
||||
DMA_TO_DEVICE);
|
||||
dma_sync_single_for_device(dd->dev, dma_addr_out, length,
|
||||
DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user