Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jonathan Cameron and committed by
Herbert Xu
8debacd6 07928d9b

+8 -5
+8 -5
drivers/crypto/hisilicon/sgl.c
··· 202 202 dma_addr_t curr_sgl_dma = 0; 203 203 struct acc_hw_sge *curr_hw_sge; 204 204 struct scatterlist *sg; 205 - int i, ret, sg_n; 205 + int i, sg_n, sg_n_mapped; 206 206 207 207 if (!dev || !sgl || !pool || !hw_sgl_dma) 208 208 return ERR_PTR(-EINVAL); 209 209 210 210 sg_n = sg_nents(sgl); 211 - if (sg_n > pool->sge_nr) 211 + 212 + sg_n_mapped = dma_map_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL); 213 + if (!sg_n_mapped) 212 214 return ERR_PTR(-EINVAL); 213 215 214 - ret = dma_map_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL); 215 - if (!ret) 216 + if (sg_n_mapped > pool->sge_nr) { 217 + dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL); 216 218 return ERR_PTR(-EINVAL); 219 + } 217 220 218 221 curr_hw_sgl = acc_get_sgl(pool, index, &curr_sgl_dma); 219 222 if (IS_ERR(curr_hw_sgl)) { ··· 227 224 curr_hw_sgl->entry_length_in_sgl = cpu_to_le16(pool->sge_nr); 228 225 curr_hw_sge = curr_hw_sgl->sge_entries; 229 226 230 - for_each_sg(sgl, sg, sg_n, i) { 227 + for_each_sg(sgl, sg, sg_n_mapped, i) { 231 228 sg_map_to_hw_sg(sg, curr_hw_sge); 232 229 inc_hw_sgl_sge(curr_hw_sgl); 233 230 curr_hw_sge++;