From patchwork Thu Sep 20 09:45:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 1483481 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 83A2F3FD40 for ; Thu, 20 Sep 2012 09:48:17 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TEdKq-0007PL-PU; Thu, 20 Sep 2012 09:46:16 +0000 Received: from eu1sys200aog110.obsmtp.com ([207.126.144.129]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1TEdKo-0007P6-6n for linux-arm-kernel@lists.infradead.org; Thu, 20 Sep 2012 09:46:15 +0000 Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob110.postini.com ([207.126.147.11]) with SMTP ID DSNKUFrl3Bd8TT8WyWLbJG9VbLXOU1wUo0M1@postini.com; Thu, 20 Sep 2012 09:46:13 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id C0098307; Thu, 20 Sep 2012 09:45:56 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 69BF52767; Thu, 20 Sep 2012 09:45:56 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id A05DA24C2FA; Thu, 20 Sep 2012 11:45:50 +0200 (CEST) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.83.0; Thu, 20 Sep 2012 11:45:55 +0200 From: Linus Walleij To: , Greg Kroah-Hartman Subject: [PATCH 1/3] serial: pl011: safeguard against impossible baudrates Date: Thu, 20 Sep 2012 11:45:46 +0200 Message-ID: <1348134346-25593-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.11.3 MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [207.126.144.129 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Linus Walleij , Guillaume Jaunet , Par-Gunnar Hjalmdahl , Anmar Oueja , Matthias Locher , "Rajanikanth H.V" , Christophe Arnal , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Linus Walleij The PL011 generates it's bitrate from the clock to the block, and this in turn will be divided by a minimum of 16 (ARM PL011) or 8 (ST Micro PL011 derivate). Safeguard against illegal rates exceeding that of what the port clock can be divided down to. Since the clkdiv variable is only ever used for calculating the maximum baud rate, let's skip that variable and add a new max_baud variable instead, then use this to check limits and as parameter for getting the baud rate. Cc: Par-Gunnar Hjalmdahl Cc: Guillaume Jaunet Cc: Christophe Arnal Cc: Matthias Locher Cc: Rajanikanth H.V Signed-off-by: Linus Walleij --- drivers/tty/serial/amba-pl011.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d626d84..9e16ea6 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1492,18 +1492,25 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int lcr_h, old_cr; unsigned long flags; - unsigned int baud, quot, clkdiv; + unsigned int max_baud, baud, quot; if (uap->vendor->oversampling) - clkdiv = 8; + max_baud = port->uartclk / 8; else - clkdiv = 16; + max_baud = port->uartclk / 16; + + if ((termios->c_ispeed > max_baud) || + (termios->c_ospeed > max_baud)) { + dev_err(port->dev, + "requested a baud rate > clock/mindivisor\n"); + return; + } /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, 0, - port->uartclk / clkdiv); + max_baud); if (baud > port->uartclk/16) quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud);