dmaengine: rcar-dmac: Reject zero-length slave DMA requests [Linux 4.9.188]

This Linux kernel change "dmaengine: rcar-dmac: Reject zero-length slave DMA requests" is included in the Linux 4.9.188 release. This change is authored by Geert Uytterhoeven <geert+renesas [at] glider.be> on Mon Jun 24 14:38:18 2019 +0200. The commit for this change in Linux stable tree is 1235f5e (patch) which is from upstream commit 78efb76. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 78efb76.

dmaengine: rcar-dmac: Reject zero-length slave DMA requests

[ Upstream commit 78efb76ab4dfb8f74f290ae743f34162cd627f19 ]

While the .device_prep_slave_sg() callback rejects empty scatterlists,
it still accepts single-entry scatterlists with a zero-length segment.
These may happen if a driver calls dmaengine_prep_slave_single() with a
zero len parameter.  The corresponding DMA request will never complete,
leading to messages like:

    rcar-dmac e7300000.dma-controller: Channel Address Error happen

and DMA timeouts.

Although requesting a zero-length DMA request is a driver bug, rejecting
it early eases debugging.  Note that the .device_prep_dma_memcpy()
callback already rejects requests to copy zero bytes.

Reported-by: Eugeniu Rosca <erosca@de.adit-jv.com>
Analyzed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 2 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/dma/sh/rcar-dmac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index f37a6ef..e4fe24b 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -1111,7 +1111,7 @@ static int rcar_dmac_map_slave_addr(struct dma_chan *chan,
    struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);

    /* Someone calling slave DMA on a generic channel? */
-   if (rchan->mid_rid < 0 || !sg_len) {
+   if (rchan->mid_rid < 0 || !sg_len || !sg_dma_len(sgl)) {
        dev_warn(chan->device->dev,
             "%s: bad parameter: len=%d, id=%d\n",
             __func__, sg_len, rchan->mid_rid);

Leave a Reply

Your email address will not be published. Required fields are marked *