Torsten Duwe 4b02da
From cf5bb835b7c8a5fee7f26455099cca7feb57f5e9 Mon Sep 17 00:00:00 2001
Torsten Duwe 4b02da
From: Damian Muszynski <damian.muszynski@intel.com>
Torsten Duwe 4b02da
Date: Fri, 9 Sep 2022 11:49:12 +0100
Torsten Duwe 4b02da
Subject: [PATCH] crypto: qat - fix DMA transfer direction
Torsten Duwe 4b02da
Git-commit: cf5bb835b7c8a5fee7f26455099cca7feb57f5e9
Torsten Duwe 4b02da
Patch-mainline: v6.1-rc1
Torsten Duwe 4b02da
References: jsc#PED-1073
Torsten Duwe 4b02da
Torsten Duwe 4b02da
When CONFIG_DMA_API_DEBUG is selected, while running the crypto self
Torsten Duwe 4b02da
test on the QAT crypto algorithms, the function add_dma_entry() reports
Torsten Duwe 4b02da
a warning similar to the one below, saying that overlapping mappings
Torsten Duwe 4b02da
are not supported. This occurs in tests where the input and the output
Torsten Duwe 4b02da
scatter list point to the same buffers (i.e. two different scatter lists
Torsten Duwe 4b02da
which point to the same chunks of memory).
Torsten Duwe 4b02da
Torsten Duwe 4b02da
The logic that implements the mapping uses the flag DMA_BIDIRECTIONAL
Torsten Duwe 4b02da
for both the input and the output scatter lists which leads to
Torsten Duwe 4b02da
overlapped write mappings. These are not supported by the DMA layer.
Torsten Duwe 4b02da
Torsten Duwe 4b02da
Fix by specifying the correct DMA transfer directions when mapping
Torsten Duwe 4b02da
buffers. For in-place operations where the input scatter list
Torsten Duwe 4b02da
matches the output scatter list, buffers are mapped once with
Torsten Duwe 4b02da
DMA_BIDIRECTIONAL, otherwise input buffers are mapped using the flag
Torsten Duwe 4b02da
DMA_TO_DEVICE and output buffers are mapped with DMA_FROM_DEVICE.
Torsten Duwe 4b02da
Overlapping a read mapping with a write mapping is a valid case in
Torsten Duwe 4b02da
dma-coherent devices like QAT.
Torsten Duwe 4b02da
The function that frees and unmaps the buffers, qat_alg_free_bufl()
Torsten Duwe 4b02da
has been changed accordingly to the changes to the mapping function.
Torsten Duwe 4b02da
Torsten Duwe 4b02da
   DMA-API: 4xxx 0000:06:00.0: cacheline tracking EEXIST, overlapping mappings aren't supported
Torsten Duwe 4b02da
   WARNING: CPU: 53 PID: 4362 at kernel/dma/debug.c:570 add_dma_entry+0x1e9/0x270
Torsten Duwe 4b02da
   ...
Torsten Duwe 4b02da
   Call Trace:
Torsten Duwe 4b02da
   dma_map_page_attrs+0x82/0x2d0
Torsten Duwe 4b02da
   ? preempt_count_add+0x6a/0xa0
Torsten Duwe 4b02da
   qat_alg_sgl_to_bufl+0x45b/0x990 [intel_qat]
Torsten Duwe 4b02da
   qat_alg_aead_dec+0x71/0x250 [intel_qat]
Torsten Duwe 4b02da
   crypto_aead_decrypt+0x3d/0x70
Torsten Duwe 4b02da
   test_aead_vec_cfg+0x649/0x810
Torsten Duwe 4b02da
   ? number+0x310/0x3a0
Torsten Duwe 4b02da
   ? vsnprintf+0x2a3/0x550
Torsten Duwe 4b02da
   ? scnprintf+0x42/0x70
Torsten Duwe 4b02da
   ? valid_sg_divisions.constprop.0+0x86/0xa0
Torsten Duwe 4b02da
   ? test_aead_vec+0xdf/0x120
Torsten Duwe 4b02da
   test_aead_vec+0xdf/0x120
Torsten Duwe 4b02da
   alg_test_aead+0x185/0x400
Torsten Duwe 4b02da
   alg_test+0x3d8/0x500
Torsten Duwe 4b02da
   ? crypto_acomp_scomp_free_ctx+0x30/0x30
Torsten Duwe 4b02da
   ? __schedule+0x32a/0x12a0
Torsten Duwe 4b02da
   ? ttwu_queue_wakelist+0xbf/0x110
Torsten Duwe 4b02da
   ? _raw_spin_unlock_irqrestore+0x23/0x40
Torsten Duwe 4b02da
   ? try_to_wake_up+0x83/0x570
Torsten Duwe 4b02da
   ? _raw_spin_unlock_irqrestore+0x23/0x40
Torsten Duwe 4b02da
   ? __set_cpus_allowed_ptr_locked+0xea/0x1b0
Torsten Duwe 4b02da
   ? crypto_acomp_scomp_free_ctx+0x30/0x30
Torsten Duwe 4b02da
   cryptomgr_test+0x27/0x50
Torsten Duwe 4b02da
   kthread+0xe6/0x110
Torsten Duwe 4b02da
   ? kthread_complete_and_exit+0x20/0x20
Torsten Duwe 4b02da
   ret_from_fork+0x1f/0x30
Torsten Duwe 4b02da
Torsten Duwe 4b02da
Fixes: d370cec ("crypto: qat - Intel(R) QAT crypto interface")
Torsten Duwe 4b02da
Link: https://lore.kernel.org/linux-crypto/20220223080400.139367-1-gilad@benyossef.com/
Torsten Duwe 4b02da
Signed-off-by: Damian Muszynski <damian.muszynski@intel.com>
Torsten Duwe 4b02da
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Torsten Duwe 4b02da
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Torsten Duwe 4b02da
Signed-off-by: Torsten Duwe <duwe@suse.de>
Torsten Duwe 4b02da
Torsten Duwe 4b02da
---
Torsten Duwe 4b02da
 drivers/crypto/qat/qat_common/qat_algs.c | 18 ++++++++++++------
Torsten Duwe 4b02da
 1 file changed, 12 insertions(+), 6 deletions(-)
Torsten Duwe 4b02da
Torsten Duwe 4b02da
diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
Torsten Duwe 4b02da
index fb45fa83841c5..cad9c58caab13 100644
Torsten Duwe 4b02da
--- a/drivers/crypto/qat/qat_common/qat_algs.c
Torsten Duwe 4b02da
+++ b/drivers/crypto/qat/qat_common/qat_algs.c
Torsten Duwe 4b02da
@@ -673,11 +673,14 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,
Torsten Duwe 4b02da
 	dma_addr_t blpout = qat_req->buf.bloutp;
Torsten Duwe 4b02da
 	size_t sz = qat_req->buf.sz;
Torsten Duwe 4b02da
 	size_t sz_out = qat_req->buf.sz_out;
Torsten Duwe 4b02da
+	int bl_dma_dir;
Torsten Duwe 4b02da
 	int i;
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
+	bl_dma_dir = blp != blpout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
Torsten Duwe 4b02da
+
Torsten Duwe 4b02da
 	for (i = 0; i < bl->num_bufs; i++)
Torsten Duwe 4b02da
 		dma_unmap_single(dev, bl->bufers[i].addr,
Torsten Duwe 4b02da
-				 bl->bufers[i].len, DMA_BIDIRECTIONAL);
Torsten Duwe 4b02da
+				 bl->bufers[i].len, bl_dma_dir);
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
 	dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE);
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
@@ -691,7 +694,7 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,
Torsten Duwe 4b02da
 		for (i = bufless; i < blout->num_bufs; i++) {
Torsten Duwe 4b02da
 			dma_unmap_single(dev, blout->bufers[i].addr,
Torsten Duwe 4b02da
 					 blout->bufers[i].len,
Torsten Duwe 4b02da
-					 DMA_BIDIRECTIONAL);
Torsten Duwe 4b02da
+					 DMA_FROM_DEVICE);
Torsten Duwe 4b02da
 		}
Torsten Duwe 4b02da
 		dma_unmap_single(dev, blpout, sz_out, DMA_TO_DEVICE);
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
@@ -716,6 +719,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
Torsten Duwe 4b02da
 	struct scatterlist *sg;
Torsten Duwe 4b02da
 	size_t sz_out, sz = struct_size(bufl, bufers, n);
Torsten Duwe 4b02da
 	int node = dev_to_node(&GET_DEV(inst->accel_dev));
Torsten Duwe 4b02da
+	int bufl_dma_dir;
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
 	if (unlikely(!n))
Torsten Duwe 4b02da
 		return -EINVAL;
Torsten Duwe 4b02da
@@ -733,6 +737,8 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
Torsten Duwe 4b02da
 		qat_req->buf.sgl_src_valid = true;
Torsten Duwe 4b02da
 	}
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
+	bufl_dma_dir = sgl != sglout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
Torsten Duwe 4b02da
+
Torsten Duwe 4b02da
 	for_each_sg(sgl, sg, n, i)
Torsten Duwe 4b02da
 		bufl->bufers[i].addr = DMA_MAPPING_ERROR;
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
@@ -744,7 +750,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
 		bufl->bufers[y].addr = dma_map_single(dev, sg_virt(sg),
Torsten Duwe 4b02da
 						      sg->length,
Torsten Duwe 4b02da
-						      DMA_BIDIRECTIONAL);
Torsten Duwe 4b02da
+						      bufl_dma_dir);
Torsten Duwe 4b02da
 		bufl->bufers[y].len = sg->length;
Torsten Duwe 4b02da
 		if (unlikely(dma_mapping_error(dev, bufl->bufers[y].addr)))
Torsten Duwe 4b02da
 			goto err_in;
Torsten Duwe 4b02da
@@ -787,7 +793,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
 			bufers[y].addr = dma_map_single(dev, sg_virt(sg),
Torsten Duwe 4b02da
 							sg->length,
Torsten Duwe 4b02da
-							DMA_BIDIRECTIONAL);
Torsten Duwe 4b02da
+							DMA_FROM_DEVICE);
Torsten Duwe 4b02da
 			if (unlikely(dma_mapping_error(dev, bufers[y].addr)))
Torsten Duwe 4b02da
 				goto err_out;
Torsten Duwe 4b02da
 			bufers[y].len = sg->length;
Torsten Duwe 4b02da
@@ -817,7 +823,7 @@ err_out:
Torsten Duwe 4b02da
 		if (!dma_mapping_error(dev, buflout->bufers[i].addr))
Torsten Duwe 4b02da
 			dma_unmap_single(dev, buflout->bufers[i].addr,
Torsten Duwe 4b02da
 					 buflout->bufers[i].len,
Torsten Duwe 4b02da
-					 DMA_BIDIRECTIONAL);
Torsten Duwe 4b02da
+					 DMA_FROM_DEVICE);
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
 	if (!qat_req->buf.sgl_dst_valid)
Torsten Duwe 4b02da
 		kfree(buflout);
Torsten Duwe 4b02da
@@ -831,7 +837,7 @@ err_in:
Torsten Duwe 4b02da
 		if (!dma_mapping_error(dev, bufl->bufers[i].addr))
Torsten Duwe 4b02da
 			dma_unmap_single(dev, bufl->bufers[i].addr,
Torsten Duwe 4b02da
 					 bufl->bufers[i].len,
Torsten Duwe 4b02da
-					 DMA_BIDIRECTIONAL);
Torsten Duwe 4b02da
+					 bufl_dma_dir);
Torsten Duwe 4b02da
 
Torsten Duwe 4b02da
 	if (!qat_req->buf.sgl_src_valid)
Torsten Duwe 4b02da
 		kfree(bufl);
Torsten Duwe 4b02da
-- 
Torsten Duwe 4b02da
2.35.3
Torsten Duwe 4b02da