From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73AF9C6FD1D for ; Mon, 20 Mar 2023 15:32:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232731AbjCTPcd (ORCPT ); Mon, 20 Mar 2023 11:32:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47618 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233037AbjCTPcQ (ORCPT ); Mon, 20 Mar 2023 11:32:16 -0400 Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7A9311715A for ; Mon, 20 Mar 2023 08:25:03 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id C0D07CE12FA for ; Mon, 20 Mar 2023 15:24:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B0237C4331E; Mon, 20 Mar 2023 15:24:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1679325877; bh=VtzitmGnVagzTZ2jz2D/JcRzU6x1SGf12rGlVS9Q2ak=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TRScydoJUT/mjBCecTkfGh17xbPdc9PtN1bqSynGjIQk7SWm80ZE7XKfFctuSBfnd 1JHYr3j3oO97h+4r7NL9EpNdbE8f/d42VVWyUv/vKOg3NJs0FI3CLPjktOvxEyBkN3 Bzbze9+XnaCrfO41De6RomLH+Q0KcX+ZkLNxPcDM= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, stable , Alexander Sverdlin Subject: [PATCH 6.2 118/211] tty: serial: fsl_lpuart: fix race on RX DMA shutdown Date: Mon, 20 Mar 2023 15:54:13 +0100 Message-Id: <20230320145518.279946238@linuxfoundation.org> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230320145513.305686421@linuxfoundation.org> References: <20230320145513.305686421@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Alexander Sverdlin commit 1be6f2b15f902c02e055ae0b419ca789200473c9 upstream. >>From time to time DMA completion can come in the middle of DMA shutdown: : : lpuart32_shutdown() lpuart_dma_shutdown() del_timer_sync() lpuart_dma_rx_complete() lpuart_copy_rx_to_tty() mod_timer() lpuart_dma_rx_free() When the timer fires a bit later, sport->dma_rx_desc is NULL: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000004 pc : lpuart_copy_rx_to_tty+0xcc/0x5bc lr : lpuart_timer_func+0x1c/0x2c Call trace: lpuart_copy_rx_to_tty lpuart_timer_func call_timer_fn __run_timers.part.0 run_timer_softirq __do_softirq __irq_exit_rcu irq_exit handle_domain_irq gic_handle_irq call_on_irq_stack do_interrupt_handler ... To fix this fold del_timer_sync() into lpuart_dma_rx_free() after dmaengine_terminate_sync() to make sure timer will not be re-started in lpuart_copy_rx_to_tty() <= lpuart_dma_rx_complete(). Fixes: 4a8588a1cf86 ("serial: fsl_lpuart: delete timer on shutdown") Cc: stable Signed-off-by: Alexander Sverdlin Link: https://lore.kernel.org/r/20230309134302.74940-2-alexander.sverdlin@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1328,6 +1328,7 @@ static void lpuart_dma_rx_free(struct ua struct dma_chan *chan = sport->dma_rx_chan; dmaengine_terminate_sync(chan); + del_timer_sync(&sport->lpuart_timer); dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE); kfree(sport->rx_ring.buf); sport->rx_ring.tail = 0; @@ -1762,7 +1763,6 @@ static int lpuart32_startup(struct uart_ static void lpuart_dma_shutdown(struct lpuart_port *sport) { if (sport->lpuart_dma_rx_use) { - del_timer_sync(&sport->lpuart_timer); lpuart_dma_rx_free(&sport->port); sport->lpuart_dma_rx_use = false; } @@ -1922,10 +1922,8 @@ lpuart_set_termios(struct uart_port *por * Since timer function acqures sport->port.lock, need to stop before * acquring same lock because otherwise del_timer_sync() can deadlock. */ - if (old && sport->lpuart_dma_rx_use) { - del_timer_sync(&sport->lpuart_timer); + if (old && sport->lpuart_dma_rx_use) lpuart_dma_rx_free(&sport->port); - } spin_lock_irqsave(&sport->port.lock, flags); @@ -2159,10 +2157,8 @@ lpuart32_set_termios(struct uart_port *p * Since timer function acqures sport->port.lock, need to stop before * acquring same lock because otherwise del_timer_sync() can deadlock. */ - if (old && sport->lpuart_dma_rx_use) { - del_timer_sync(&sport->lpuart_timer); + if (old && sport->lpuart_dma_rx_use) lpuart_dma_rx_free(&sport->port); - } spin_lock_irqsave(&sport->port.lock, flags); @@ -2962,7 +2958,6 @@ static int lpuart_suspend(struct device * cannot resume as expected, hence gracefully release the * Rx DMA path before suspend and start Rx DMA path on resume. */ - del_timer_sync(&sport->lpuart_timer); lpuart_dma_rx_free(&sport->port); /* Disable Rx DMA to use UART port as wakeup source */