crypto: atmel-{aes,sha} - Fix incorrect use of dmaengine_terminate_all()

device_terminate_all() is used to abort all the pending and
ongoing transfers on the channel, it should be used just in the
error path.

Also, dmaengine_terminate_all() is deprecated and one should use
dmaengine_terminate_async() or dmaengine_terminate_sync(). The method
is not used in atomic context, use dmaengine_terminate_sync().

A secondary aspect of this patch is that it luckily avoids a deadlock
between atmel_aes and at_hdmac.c. While in tasklet with the lock held,
the dma controller invokes the client callback (dmaengine_terminate_all),
which tries to get the same lock. The at_hdmac fix would be to drop the
lock before invoking the client callback, a fix on at_hdmac will follow.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Tudor Ambarus 2019-12-13 09:54:42 +00:00 committed by Herbert Xu
parent 7d07de2c18
commit 0e69378940
2 changed files with 2 additions and 31 deletions

View file

@ -857,27 +857,6 @@ static int atmel_aes_dma_transfer_start(struct atmel_aes_dev *dd,
return 0;
}
static void atmel_aes_dma_transfer_stop(struct atmel_aes_dev *dd,
enum dma_transfer_direction dir)
{
struct atmel_aes_dma *dma;
switch (dir) {
case DMA_MEM_TO_DEV:
dma = &dd->src;
break;
case DMA_DEV_TO_MEM:
dma = &dd->dst;
break;
default:
return;
}
dmaengine_terminate_all(dma->chan);
}
static int atmel_aes_dma_start(struct atmel_aes_dev *dd,
struct scatterlist *src,
struct scatterlist *dst,
@ -936,25 +915,18 @@ static int atmel_aes_dma_start(struct atmel_aes_dev *dd,
return -EINPROGRESS;
output_transfer_stop:
atmel_aes_dma_transfer_stop(dd, DMA_DEV_TO_MEM);
dmaengine_terminate_sync(dd->dst.chan);
unmap:
atmel_aes_unmap(dd);
exit:
return atmel_aes_complete(dd, err);
}
static void atmel_aes_dma_stop(struct atmel_aes_dev *dd)
{
atmel_aes_dma_transfer_stop(dd, DMA_MEM_TO_DEV);
atmel_aes_dma_transfer_stop(dd, DMA_DEV_TO_MEM);
atmel_aes_unmap(dd);
}
static void atmel_aes_dma_callback(void *data)
{
struct atmel_aes_dev *dd = data;
atmel_aes_dma_stop(dd);
atmel_aes_unmap(dd);
dd->is_async = true;
(void)dd->resume(dd);
}

View file

@ -1429,7 +1429,6 @@ static void atmel_sha_dma_callback2(void *data)
struct scatterlist *sg;
int nents;
dmaengine_terminate_all(dma->chan);
dma_unmap_sg(dd->dev, dma->sg, dma->nents, DMA_TO_DEVICE);
sg = dma->sg;