]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
crypto: qat - fix DMA direction for compression on GEN2 devices
authorGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Mon, 14 Jul 2025 07:07:49 +0000 (08:07 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 Aug 2025 10:13:57 +0000 (12:13 +0200)
[ Upstream commit d41d75fe1b751ee6b347bf1cb1cfe9accc4fcb12 ]

QAT devices perform an additional integrity check during compression by
decompressing the output. Starting from QAT GEN4, this verification is
done in-line by the hardware. However, on GEN2 devices, the hardware
reads back the compressed output from the destination buffer and performs
a decompression operation using it as the source.

In the current QAT driver, destination buffers are always marked as
write-only. This is incorrect for QAT GEN2 compression, where the buffer
is also read during verification. Since commit 6f5dc7658094
("iommu/vt-d: Restore WO permissions on second-level paging entries"),
merged in v6.16-rc1, write-only permissions are strictly enforced, leading
to DMAR errors when using QAT GEN2 devices for compression, if VT-d is
enabled.

Mark the destination buffers as DMA_BIDIRECTIONAL. This ensures
compatibility with GEN2 devices, even though it is not required for
QAT GEN4 and later.

Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Fixes: cf5bb835b7c8 ("crypto: qat - fix DMA transfer direction")
Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/crypto/intel/qat/qat_common/qat_bl.c
drivers/crypto/intel/qat/qat_common/qat_compression.c

index 338acf29c487b6784abd04379df282d17309614c..5a7b43f9150d3b59e844661bb936c9f4430145af 100644 (file)
@@ -38,7 +38,7 @@ void qat_bl_free_bufl(struct adf_accel_dev *accel_dev,
                for (i = 0; i < blout->num_mapped_bufs; i++) {
                        dma_unmap_single(dev, blout->buffers[i].addr,
                                         blout->buffers[i].len,
-                                        DMA_FROM_DEVICE);
+                                        DMA_BIDIRECTIONAL);
                }
                dma_unmap_single(dev, blpout, sz_out, DMA_TO_DEVICE);
 
@@ -162,7 +162,7 @@ static int __qat_bl_sgl_to_bufl(struct adf_accel_dev *accel_dev,
                        }
                        buffers[y].addr = dma_map_single(dev, sg_virt(sg) + left,
                                                         sg->length - left,
-                                                        DMA_FROM_DEVICE);
+                                                        DMA_BIDIRECTIONAL);
                        if (unlikely(dma_mapping_error(dev, buffers[y].addr)))
                                goto err_out;
                        buffers[y].len = sg->length;
@@ -204,7 +204,7 @@ err_out:
                if (!dma_mapping_error(dev, buflout->buffers[i].addr))
                        dma_unmap_single(dev, buflout->buffers[i].addr,
                                         buflout->buffers[i].len,
-                                        DMA_FROM_DEVICE);
+                                        DMA_BIDIRECTIONAL);
        }
 
        if (!buf->sgl_dst_valid)
index 2c3aa89b316a83ff400ab33daa0a52c7a9bec1bd..cf94ba3011d51b3f7e54ba44b4e8fe721be61a22 100644 (file)
@@ -205,7 +205,7 @@ static int qat_compression_alloc_dc_data(struct adf_accel_dev *accel_dev)
        if (!obuff)
                goto err;
 
-       obuff_p = dma_map_single(dev, obuff, ovf_buff_sz, DMA_FROM_DEVICE);
+       obuff_p = dma_map_single(dev, obuff, ovf_buff_sz, DMA_BIDIRECTIONAL);
        if (unlikely(dma_mapping_error(dev, obuff_p)))
                goto err;
 
@@ -233,7 +233,7 @@ static void qat_free_dc_data(struct adf_accel_dev *accel_dev)
                return;
 
        dma_unmap_single(dev, dc_data->ovf_buff_p, dc_data->ovf_buff_sz,
-                        DMA_FROM_DEVICE);
+                        DMA_BIDIRECTIONAL);
        kfree_sensitive(dc_data->ovf_buff);
        kfree(dc_data);
        accel_dev->dc_data = NULL;