Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3631275imu; Mon, 28 Jan 2019 08:08:22 -0800 (PST) X-Google-Smtp-Source: ALg8bN5XRvyHjBCLrfKhdvXUxb418YnTtEekZ/XHPhYd0cxxFqrnE/tXHe0agFFv6dA6nuc04/KG X-Received: by 2002:a63:b34f:: with SMTP id x15mr20513009pgt.243.1548691702392; Mon, 28 Jan 2019 08:08:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548691702; cv=none; d=google.com; s=arc-20160816; b=rKIokDz3eE8jxFx4JKEUziDRO46NuGjM8bW46v9d9QuXOee1ZPAK1+KDZzz8obmDum RNaEDivNOWfLU7dALzCAMe7siQgRZ/QwJqnS06LEiDpAq7Dp9nDXjjUE1q0vlNSDKyju 8sGQFsc8eNFWxh8EyT1um+D+SKPOUSUNjJvAddFNfuVoq8qicRew8KlSUOHgjX20yrnp DNLFGvzlenshh7ZwsPCvwphlR0L4uqxi5j7JSQRtdnJY+MG1m9tkQW7+zPpBaINHnbuD gcKZH2CACQhmwZF4dUiq1kpEkyJaRrPhzweMMg7SQcFAnQWyzKHgmOX3SAV6y+wzoZCk 1hfQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gOfqKW65ksgHCPyrpMQdq5FvAei2XzjIwyMTkhuDbEY=; b=iayd7dCMNhlz54wWx1+45CUuaFEMI0auZIIpypBqT1DiBTIjydgJiFKH0FF9zKPvR6 H4vlf/4PCZqfSEYzSqJFS9B6i/veQW7fVyAIXaeWSpG/0i7O5zUX3WmiaIijor89ivtb BxLSvqvqUL0AxWcd/h/AX5BSbO1OfYKaLJEie5I1h99pFAb8gBGKGK1L1S9FbMoOHB72 HipaHUSPQZHLgL+yU0rKhHzOFpc1DcwMAbtO74V/ex5f3uDdvsCQo5wksMVdVnagpgXZ JnpeJ6LZMT9/E2TC0Ku8npv80ywpUX1/Ys/HwYPNYtcG6k0cCRAzIELqjRJoHLL48ncD ODjw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=jOk7nQf9; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 1si33507336plp.114.2019.01.28.08.08.06; Mon, 28 Jan 2019 08:08:22 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=jOk7nQf9; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732139AbfA1QHE (ORCPT + 99 others); Mon, 28 Jan 2019 11:07:04 -0500 Received: from mail.kernel.org ([198.145.29.99]:56986 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732132AbfA1QHC (ORCPT ); Mon, 28 Jan 2019 11:07:02 -0500 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6E2E620989; Mon, 28 Jan 2019 16:06:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1548691621; bh=0rT4LOsXI2hIjWuZeGDl/KcwQjJqfD3j4JAfoghbJ00=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jOk7nQf92ZPQ5rToiWIJW7r5mljUHuoP2j6vN3AZgGreQ8Rvs7Tkb9sAwkAjNVguS j5W04b3GWGlnEofxvEL7EuD7gkjLEGCNjQS9MEOB0CynskgzrEHa3IFapAs9zQ+ZG+ XoU6oVREOfpwFxw5UpQtdg/eZ8B+Ghs22sL5pNq8= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Geert Uytterhoeven , Greg Kroah-Hartman , Sasha Levin , linux-serial@vger.kernel.org Subject: [PATCH AUTOSEL 4.19 162/258] serial: sh-sci: Fix locking in sci_submit_rx() Date: Mon, 28 Jan 2019 10:57:48 -0500 Message-Id: <20190128155924.51521-162-sashal@kernel.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190128155924.51521-1-sashal@kernel.org> References: <20190128155924.51521-1-sashal@kernel.org> MIME-Version: 1.0 X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Geert Uytterhoeven [ Upstream commit dd1f2250da95e87cb3e612858f94b14f99445a7c ] Some callers of sci_submit_rx() hold the port spinlock, others don't. During fallback to PIO, the driver needs to obtain the port spinlock. If the lock was already held, spinlock recursion is detected, causing a deadlock: BUG: spinlock recursion on CPU#0. Fix this by adding a flag parameter to sci_submit_rx() for the caller to indicate the port spinlock is already held, so spinlock recursion can be avoided. Move the spin_lock_irqsave() up, so all DMA disable steps are protected, which is safe as the recently introduced dmaengine_terminate_async() can be called in atomic context. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/sh-sci.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index effba6ce0caa..5fdd7944b73b 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1331,7 +1331,7 @@ static void sci_tx_dma_release(struct sci_port *s) dma_release_channel(chan); } -static void sci_submit_rx(struct sci_port *s) +static void sci_submit_rx(struct sci_port *s, bool port_lock_held) { struct dma_chan *chan = s->chan_rx; struct uart_port *port = &s->port; @@ -1362,16 +1362,18 @@ static void sci_submit_rx(struct sci_port *s) return; fail: + /* Switch to PIO */ + if (!port_lock_held) + spin_lock_irqsave(&port->lock, flags); if (i) dmaengine_terminate_async(chan); for (i = 0; i < 2; i++) s->cookie_rx[i] = -EINVAL; s->active_rx = -EINVAL; - /* Switch to PIO */ - spin_lock_irqsave(&port->lock, flags); s->chan_rx = NULL; sci_start_rx(port); - spin_unlock_irqrestore(&port->lock, flags); + if (!port_lock_held) + spin_unlock_irqrestore(&port->lock, flags); } static void work_fn_tx(struct work_struct *work) @@ -1491,7 +1493,7 @@ static enum hrtimer_restart rx_timer_fn(struct hrtimer *t) } if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) - sci_submit_rx(s); + sci_submit_rx(s, true); /* Direct new serial port interrupts back to CPU */ scr = serial_port_in(port, SCSCR); @@ -1617,7 +1619,7 @@ static void sci_request_dma(struct uart_port *port) s->chan_rx_saved = s->chan_rx = chan; if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) - sci_submit_rx(s); + sci_submit_rx(s, false); } } @@ -1667,7 +1669,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) scr |= SCSCR_RDRQE; } else { scr &= ~SCSCR_RIE; - sci_submit_rx(s); + sci_submit_rx(s, false); } serial_port_out(port, SCSCR, scr); /* Clear current interrupt */ -- 2.19.1