From 059d73eea6409873446a858dd64a5bec9bf68b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horia=20Geant=C4=83?= Date: Mon, 10 Jun 2019 16:30:58 +0300 Subject: crypto: caam - use len instead of nents for bulding HW S/G table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, conversion of SW S/G table into HW S/G layout relies on nents returned by sg_nents_for_len(sg, len). However this leaves the possibility of HW S/G referencing more data then needed: since buffer length in HW S/G entries is filled using sg_dma_len(sg), the last entry in HW S/G table might have a length that is bigger than needed for the crypto request. This way of S/G table conversion is fine, unless after converting a table more entries have to be appended to the HW S/G table. In this case, crypto engine would access data from the S/G entry having the incorrect length, instead of advancing in the S/G table. This situation doesn't exist, but the upcoming implementation of IV update for skcipher algorithms needs to add a S/G entry after req->dst S/G (corresponding to output IV). Signed-off-by: Horia Geantă Signed-off-by: Herbert Xu --- drivers/crypto/caam/sg_sw_qm2.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers/crypto/caam/sg_sw_qm2.h') diff --git a/drivers/crypto/caam/sg_sw_qm2.h b/drivers/crypto/caam/sg_sw_qm2.h index c9378402a5f8..b8b737d2b0ea 100644 --- a/drivers/crypto/caam/sg_sw_qm2.h +++ b/drivers/crypto/caam/sg_sw_qm2.h @@ -25,15 +25,19 @@ static inline void dma_to_qm_sg_one(struct dpaa2_sg_entry *qm_sg_ptr, * but does not have final bit; instead, returns last entry */ static inline struct dpaa2_sg_entry * -sg_to_qm_sg(struct scatterlist *sg, int sg_count, +sg_to_qm_sg(struct scatterlist *sg, int len, struct dpaa2_sg_entry *qm_sg_ptr, u16 offset) { - while (sg_count && sg) { - dma_to_qm_sg_one(qm_sg_ptr, sg_dma_address(sg), - sg_dma_len(sg), offset); + int ent_len; + + while (len) { + ent_len = min_t(int, sg_dma_len(sg), len); + + dma_to_qm_sg_one(qm_sg_ptr, sg_dma_address(sg), ent_len, + offset); qm_sg_ptr++; sg = sg_next(sg); - sg_count--; + len -= ent_len; } return qm_sg_ptr - 1; } @@ -42,11 +46,11 @@ sg_to_qm_sg(struct scatterlist *sg, int sg_count, * convert scatterlist to h/w link table format * scatterlist must have been previously dma mapped */ -static inline void sg_to_qm_sg_last(struct scatterlist *sg, int sg_count, +static inline void sg_to_qm_sg_last(struct scatterlist *sg, int len, struct dpaa2_sg_entry *qm_sg_ptr, u16 offset) { - qm_sg_ptr = sg_to_qm_sg(sg, sg_count, qm_sg_ptr, offset); + qm_sg_ptr = sg_to_qm_sg(sg, len, qm_sg_ptr, offset); dpaa2_sg_set_final(qm_sg_ptr, true); } -- cgit v1.2.3