From: Giovanni Cabiddu Date: Mon, 14 Jul 2025 07:07:49 +0000 (+0100) Subject: crypto: qat - fix DMA direction for compression on GEN2 devices X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d41d75fe1b751ee6b347bf1cb1cfe9accc4fcb12;p=thirdparty%2Flinux.git crypto: qat - fix DMA direction for compression on GEN2 devices 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 Fixes: cf5bb835b7c8 ("crypto: qat - fix DMA transfer direction") Reviewed-by: Ahsan Atta Signed-off-by: Herbert Xu --- diff --git a/drivers/crypto/intel/qat/qat_common/qat_bl.c b/drivers/crypto/intel/qat/qat_common/qat_bl.c index 5e4dad4693caa..9b2338f58d97c 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_bl.c +++ b/drivers/crypto/intel/qat/qat_common/qat_bl.c @@ -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) diff --git a/drivers/crypto/intel/qat/qat_common/qat_compression.c b/drivers/crypto/intel/qat/qat_common/qat_compression.c index 0a77ca65c8d48..53a4db5507ec2 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_compression.c +++ b/drivers/crypto/intel/qat/qat_common/qat_compression.c @@ -204,7 +204,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; @@ -232,7 +232,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;