[PATCH 28/33] scsi: qla2xxx: Use coherent DMA buffer for D_Port diagnostics
Nilesh Javali <[email protected]> Thu, 30 Jul 2026 21:28:33 +0530
| Newsgroups | org.kernel.vger.linux-scsi |
|---|---|
| Message-ID | <[email protected]> |
qla26xx_dport_diagnostics() streaming-maps the caller's result buffer with
dma_map_single(). The bsg path passes &dd->buf from the __packed struct
qla_dport_diag, where buf lands at a 2-byte offset and shares cachelines
with the surrounding options/unused fields. Mapping such a misaligned
sub-buffer violates the DMA API requirement that streaming buffers be
cacheline aligned and not share a cacheline with other data, and can
corrupt data on non-DMA-coherent architectures.
Allocate a dedicated DMA-coherent buffer inside qla26xx_dport_diagnostics()
for the mailbox command and copy the result back into the caller's buffer.
This removes the streaming map of the misaligned sub-buffer entirely; the
caller's buffer is now only a plain CPU buffer, so its packing no longer
matters.
Fixes: ec89146215d1 ("qla2xxx: Add bsg interface to support D_Port Diagnostics.")
Cc: [email protected]
Reported-by: Sashiko <[email protected]>
Signed-off-by: Nilesh Javali <[email protected]>
---
drivers/scsi/qla2xxx/qla_mbx.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 39544deab576..59ec5605930b 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -6579,6 +6579,7 @@ qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
dma_addr_t dd_dma;
+ void *dd;
if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
!IS_QLA28XX(vha->hw) && !IS_QLA29XX(vha->hw))
@@ -6587,15 +6588,12 @@ qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,
"Entered %s.\n", __func__);
- dd_dma = dma_map_single(&vha->hw->pdev->dev,
- dd_buf, size, DMA_FROM_DEVICE);
- if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {
- ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n");
+ dd = dma_alloc_coherent(&vha->hw->pdev->dev, size, &dd_dma, GFP_KERNEL);
+ if (!dd) {
+ ql_log(ql_log_warn, vha, 0x1194, "Failed to allocate dma buffer.\n");
return QLA_MEMORY_ALLOC_FAILED;
}
- memset(dd_buf, 0, size);
-
mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
mcp->mb[1] = options;
mcp->mb[2] = MSW(LSD(dd_dma));
@@ -6617,8 +6615,9 @@ qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
"Done %s.\n", __func__);
}
- dma_unmap_single(&vha->hw->pdev->dev, dd_dma,
- size, DMA_FROM_DEVICE);
+ memcpy(dd_buf, dd, size);
+
+ dma_free_coherent(&vha->hw->pdev->dev, size, dd, dd_dma);
return rval;
}
--
2.47.3