| From 8debacd60c69beab80736d4af4feca47c2e2bd9e Mon Sep 17 00:00:00 2001 |
| From: Jonathan Cameron <Jonathan.Cameron@huawei.com> |
| Date: Tue, 19 Nov 2019 13:42:56 +0800 |
| Subject: crypto: hisilicon - Fix issue with wrong number of sg elements after dma map |
| |
| From: Jonathan Cameron <Jonathan.Cameron@huawei.com> |
| |
| commit 8debacd60c69beab80736d4af4feca47c2e2bd9e upstream. |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/crypto/hisilicon/sgl.c | 13 ++++++++----- |
| 1 file changed, 8 insertions(+), 5 deletions(-) |
| |
| --- 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 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 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++; |