Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp2655307imj; Mon, 11 Feb 2019 06:32:57 -0800 (PST) X-Google-Smtp-Source: AHgI3IZGnGmdIPggUxdcIcOnGRCeVX6l1CNOXRqhXVh0LB2MU/PD0Hheg/vbCSn5onVurZKbT+zd X-Received: by 2002:aa7:8212:: with SMTP id k18mr21296707pfi.48.1549895577875; Mon, 11 Feb 2019 06:32:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549895577; cv=none; d=google.com; s=arc-20160816; b=S6Qfl61NPlvIocwXrs+NwhpQkPi6miAaKtqtTtZDaN3NOwHcPZoeHKXhGsDQk8ojB5 65N89ZlNcaL6J1x+xLu5fGDiDxpSB1XPu+k1CXg1OIlxAtfPuGqrAW8RciTOmCjzbnD8 wuk9Ft/cLwk5nE7Es8KCbU88YjOED6he7GC0Lwo64BUQbstBhYH1M8U+y4tumJp61Qh6 H0WV7QSLzgJlmL24cqNG3E/i4Z+vCxl9uuCOoydgKHJDxDz0/V/hKjym1MoWjk/UB//X BNRkH7/rrYcEgXT/K9Jfl6gvi5Oy/8CU6a0fGPqY0KzxHhD3fByCBAu9Ukl/GKguHLDE TefA== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=FZSXhwxQ6lrOBC+OxW6LRqSf0CvFQwDSMpoo/A+ix+U=; b=SvYyVS5hKtslHKnVUfcIE1DHZTp2tQ4ObqdBn4AjUpqJ8ADt2U/fSnbMRuxbnHaolY 6i43z1mQmWlJ7AMUM4Rnb6Y56U2sVXK63N37AjjnZxeq/AEeHG4RErRA5pOVptpMwjtP ceO0QU/gqZrSA2YccWXmx1M5GpTZ2ic3VVzZlvqc11GE6XrC4svhTEXRxCe/fEA6pNuc smN++JmJxmk1cqXD+RyfMKmVeA2Bg+55sEm9wzBLD0d7sELBYsEcrJqmx2tN1M/ig3ZV 4qng4K35mgBE2itLmLKkrHnFVCH/220txiUWDen1qaUFKcqmc6Qa83sFSDR+BzWn01o2 ZaYA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Ryi2x+YM; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v6si10232431pfv.181.2019.02.11.06.32.41; Mon, 11 Feb 2019 06:32:57 -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=Ryi2x+YM; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730235AbfBKObG (ORCPT + 99 others); Mon, 11 Feb 2019 09:31:06 -0500 Received: from mail.kernel.org ([198.145.29.99]:37732 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729593AbfBKObE (ORCPT ); Mon, 11 Feb 2019 09:31:04 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 61CB420675; Mon, 11 Feb 2019 14:31:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1549895463; bh=gIzvRU08LGY965BkuXGR12BJO9FINRvrm4nnS73jhus=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ryi2x+YM/ybUYlruUW9xpmNoaU8hhx9auDI8XbGRIfi7e8s/VUn++zXKpuceZ1fSx wfBnDNtSXqm4Ea6kxltxq10y4dCnr8vMENQGPNC8cQnS1oPwRD3jUE/hl+cOVJkG81 JAX9lP9sc0SABfuTNdMjdVWaDEQRki5S1JLmJ6rM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Geert Uytterhoeven , Simon Horman , Sasha Levin Subject: [PATCH 4.20 182/352] serial: sh-sci: Fix locking in sci_submit_rx() Date: Mon, 11 Feb 2019 15:16:49 +0100 Message-Id: <20190211141858.671251270@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190211141846.543045703@linuxfoundation.org> References: <20190211141846.543045703@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.20-stable review patch. If anyone has any objections, please let me know. ------------------ [ 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 cc56cb3b3eca..613007d7165e 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