Commit 9dedabe9 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Mark Brown

spi: Assign dummy scatterlist to unidirectional transfers

Commit 8cc3bad9 ("spi: Remove unneded check for orig_nents")
introduced a regression: unmapped data could now be passed to the DMA
APIs, resulting in null pointer dereferences. Commit 9f788ba4 ("spi:
Don't mark message DMA mapped when no transfer in it is") and commit
da560097 ("spi: Check if transfer is mapped before calling DMA sync
APIs") addressed the problem, but only partially. Unidirectional
transactions will still result in null pointer dereference. To prevent
that from happening, assign a dummy scatterlist when no data is mapped,
so that the DMA API can be called and not result in a null pointer
dereference.
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Reported-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Closes: https://lore.kernel.org/r/8ae675b5-fcf9-4c9b-b06a-4462f70e1322@linaro.orgReported-by: default avatarNícolas F. R. A. Prado <nfraprado@collabora.com>
Closes: https://lore.kernel.org/all/d3679496-2e4e-4a7c-97ed-f193bd53af1d@notapiano
Closes: https://lore.kernel.org/all/4748499f-789c-45a8-b50a-2dd09f4bac8c@notapiano
Fixes: 8cc3bad9 ("spi: Remove unneded check for orig_nents")
Tested-by: default avatarNícolas F. R. A. Prado <nfraprado@collabora.com>
[nfraprado: wrote the commit message]
Signed-off-by: default avatarNícolas F. R. A. Prado <nfraprado@collabora.com>
Link: https://msgid.link/r/20240529-dma-oops-dummy-v1-1-bb43aacfb11b@collabora.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4a69c126
...@@ -1220,6 +1220,11 @@ void spi_unmap_buf(struct spi_controller *ctlr, struct device *dev, ...@@ -1220,6 +1220,11 @@ void spi_unmap_buf(struct spi_controller *ctlr, struct device *dev,
spi_unmap_buf_attrs(ctlr, dev, sgt, dir, 0); spi_unmap_buf_attrs(ctlr, dev, sgt, dir, 0);
} }
/* Dummy SG for unidirect transfers */
static struct scatterlist dummy_sg = {
.page_link = SG_END,
};
static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg)
{ {
struct device *tx_dev, *rx_dev; struct device *tx_dev, *rx_dev;
...@@ -1258,6 +1263,8 @@ static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) ...@@ -1258,6 +1263,8 @@ static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg)
attrs); attrs);
if (ret != 0) if (ret != 0)
return ret; return ret;
} else {
xfer->tx_sg.sgl = &dummy_sg;
} }
if (xfer->rx_buf != NULL) { if (xfer->rx_buf != NULL) {
...@@ -1271,6 +1278,8 @@ static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) ...@@ -1271,6 +1278,8 @@ static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg)
return ret; return ret;
} }
} else {
xfer->rx_sg.sgl = &dummy_sg;
} }
} }
/* No transfer has been mapped, bail out with success */ /* No transfer has been mapped, bail out with success */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment