Commit 8debacd6 authored by Jonathan Cameron's avatar Jonathan Cameron Committed by Herbert Xu

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: dfed0098 (crypto: hisilicon - add hardware SGL support)
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: default avatarZhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 07928d9b
...@@ -202,18 +202,21 @@ hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev, ...@@ -202,18 +202,21 @@ hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,
dma_addr_t curr_sgl_dma = 0; dma_addr_t curr_sgl_dma = 0;
struct acc_hw_sge *curr_hw_sge; struct acc_hw_sge *curr_hw_sge;
struct scatterlist *sg; struct scatterlist *sg;
int i, ret, sg_n; int i, sg_n, sg_n_mapped;
if (!dev || !sgl || !pool || !hw_sgl_dma) if (!dev || !sgl || !pool || !hw_sgl_dma)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
sg_n = sg_nents(sgl); 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); return ERR_PTR(-EINVAL);
ret = dma_map_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL); if (sg_n_mapped > pool->sge_nr) {
if (!ret) dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
}
curr_hw_sgl = acc_get_sgl(pool, index, &curr_sgl_dma); curr_hw_sgl = acc_get_sgl(pool, index, &curr_sgl_dma);
if (IS_ERR(curr_hw_sgl)) { if (IS_ERR(curr_hw_sgl)) {
...@@ -224,7 +227,7 @@ hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev, ...@@ -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_sgl->entry_length_in_sgl = cpu_to_le16(pool->sge_nr);
curr_hw_sge = curr_hw_sgl->sge_entries; 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); sg_map_to_hw_sg(sg, curr_hw_sge);
inc_hw_sgl_sge(curr_hw_sgl); inc_hw_sgl_sge(curr_hw_sgl);
curr_hw_sge++; curr_hw_sge++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment