summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Cameron <Jonathan.Cameron@huawei.com>2019-11-19 13:42:56 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2019-12-11 16:34:44 +0800
commit8debacd60c69beab80736d4af4feca47c2e2bd9e (patch)
tree02ea8a9abab64a8f3abda061afc521a55b988456
parent07928d9bfc81640bab36f5190e8725894d93b659 (diff)
downloadlinux-8debacd60c69beab80736d4af4feca47c2e2bd9e.tar.bz2
crypto: hisilicon - Fix issue with wrong number of sg elements after dma map
We fill the hardware scatter gather list assuming it will need the same number of elements at the original scatterlist. If an IOMMU is involved, then it may well need fewer. The return value of dma_map_sg tells us how many. Probably never caused visible problems as the hardware won't get to the elements that are incorrect before it finds enough space. Fixes: dfed0098ab91 (crypto: hisilicon - add hardware SGL support) Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/hisilicon/sgl.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/crypto/hisilicon/sgl.c b/drivers/crypto/hisilicon/sgl.c
index 012023c347b1..1e153a0d7c10 100644
--- a/drivers/crypto/hisilicon/sgl.c
+++ b/drivers/crypto/hisilicon/sgl.c
@@ -202,18 +202,21 @@ hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,
dma_addr_t curr_sgl_dma = 0;
struct acc_hw_sge *curr_hw_sge;
struct scatterlist *sg;
- int i, ret, sg_n;
+ int i, sg_n, sg_n_mapped;
if (!dev || !sgl || !pool || !hw_sgl_dma)
return ERR_PTR(-EINVAL);
sg_n = sg_nents(sgl);
- if (sg_n > pool->sge_nr)
+
+ sg_n_mapped = dma_map_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
+ if (!sg_n_mapped)
return ERR_PTR(-EINVAL);
- ret = dma_map_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
- if (!ret)
+ if (sg_n_mapped > pool->sge_nr) {
+ dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
return ERR_PTR(-EINVAL);
+ }
curr_hw_sgl = acc_get_sgl(pool, index, &curr_sgl_dma);
if (IS_ERR(curr_hw_sgl)) {
@@ -224,7 +227,7 @@ hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,
curr_hw_sgl->entry_length_in_sgl = cpu_to_le16(pool->sge_nr);
curr_hw_sge = curr_hw_sgl->sge_entries;
- for_each_sg(sgl, sg, sg_n, i) {
+ for_each_sg(sgl, sg, sg_n_mapped, i) {
sg_map_to_hw_sg(sg, curr_hw_sge);
inc_hw_sgl_sge(curr_hw_sgl);
curr_hw_sge++;