lkml.org 
[lkml]   [2020]   [Jan]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 67/71] dmaengine: k3dma: Avoid null pointer traversal
    Date
    From: John Stultz <john.stultz@linaro.org>

    [ Upstream commit 2f42e05b942fe2fbfb9bbc6e34e1dd8c3ce4f3a4 ]

    In some cases we seem to submit two transactions in a row, which
    causes us to lose track of the first. If we then cancel the
    request, we may still get an interrupt, which traverses a null
    ds_run value.

    So try to avoid starting a new transaction if the ds_run value
    is set.

    While this patch avoids the null pointer crash, I've had some
    reports of the k3dma driver still getting confused, which
    suggests the ds_run/ds_done value handling still isn't quite
    right. However, I've not run into an issue recently with it
    so I think this patch is worth pushing upstream to avoid the
    crash.

    Signed-off-by: John Stultz <john.stultz@linaro.org>
    [add ss tag]
    Link: https://lore.kernel.org/r/20191218190906.6641-1-john.stultz@linaro.org
    Signed-off-by: Vinod Koul <vkoul@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/dma/k3dma.c | 12 +++++++++---
    1 file changed, 9 insertions(+), 3 deletions(-)

    diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c
    index 219ae3b545db..803045c92f3b 100644
    --- a/drivers/dma/k3dma.c
    +++ b/drivers/dma/k3dma.c
    @@ -222,9 +222,11 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id)
    c = p->vchan;
    if (c && (tc1 & BIT(i))) {
    spin_lock_irqsave(&c->vc.lock, flags);
    - vchan_cookie_complete(&p->ds_run->vd);
    - p->ds_done = p->ds_run;
    - p->ds_run = NULL;
    + if (p->ds_run != NULL) {
    + vchan_cookie_complete(&p->ds_run->vd);
    + p->ds_done = p->ds_run;
    + p->ds_run = NULL;
    + }
    spin_unlock_irqrestore(&c->vc.lock, flags);
    }
    if (c && (tc2 & BIT(i))) {
    @@ -264,6 +266,10 @@ static int k3_dma_start_txd(struct k3_dma_chan *c)
    if (BIT(c->phy->idx) & k3_dma_get_chan_stat(d))
    return -EAGAIN;

    + /* Avoid losing track of ds_run if a transaction is in flight */
    + if (c->phy->ds_run)
    + return -EAGAIN;
    +
    if (vd) {
    struct k3_dma_desc_sw *ds =
    container_of(vd, struct k3_dma_desc_sw, vd);
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-01-17 00:34    [W:3.419 / U:1.116 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site