mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
scsi: qla2xxx: Use coherent DMA buffer for D_Port diagnostics
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: ec89146215 ("qla2xxx: Add bsg interface to support D_Port Diagnostics.")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-29-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
parent
76da0c43c6
commit
7c4f3f50d8
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user