From patchwork Wed May 20 18:06:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 6448291 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 5D7849F1CC for ; Wed, 20 May 2015 18:06:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7FA9E2034F for ; Wed, 20 May 2015 18:06:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8F13D20382 for ; Wed, 20 May 2015 18:06:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753366AbbETSGU (ORCPT ); Wed, 20 May 2015 14:06:20 -0400 Received: from laurent.telenet-ops.be ([195.130.137.89]:43233 "EHLO laurent.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753651AbbETSGS (ORCPT ); Wed, 20 May 2015 14:06:18 -0400 Received: from ayla.of.borg ([84.193.93.87]) by laurent.telenet-ops.be with bizsmtp id WJ6G1q00j1t5w8s01J6GV8; Wed, 20 May 2015 20:06:17 +0200 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1Yv8Nk-0006Ud-MT; Wed, 20 May 2015 20:06:16 +0200 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1Yv8Np-00030v-1g; Wed, 20 May 2015 20:06:21 +0200 From: Geert Uytterhoeven To: Magnus Damm , Laurent Pinchart , Nobuhiro Iwamatsu , Yoshihiro Kaneko , Wolfram Sang , Guennadi Liakhovetski Cc: linux-sh@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH/RFC 2/8] serial: sh-sci: Fix scatterlist mapping leak Date: Wed, 20 May 2015 20:06:08 +0200 Message-Id: <1432145174-11534-3-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1432145174-11534-1-git-send-email-geert+renesas@glider.be> References: <1432145174-11534-1-git-send-email-geert+renesas@glider.be> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The mapped scatterlist is never unmapped. This leaks quite some mappings, as the mapping is done in uart_ops.startup(), i.e. every time the device is opened. Unmap the scatterlist on device close. Note that we have to restore the original DMA entry length and DMA address, as it has been modified in work_fn_tx(). Else warnings are printed if CONFIG_DMA_API_DEBUG=y: WARNING: CPU: 0 PID: 20 at lib/dma-debug.c:1103 check_unmap+0x24c/0x85c() rcar-dmac e6700000.dma-controller: DMA-API: device driver frees DMA memory with different size [device address=0x000000006e15f000] [map size=4096 bytes] [unmap size=3 bytes] and: WARNING: CPU: 0 PID: 1364 at lib/dma-debug.c:1093 check_unmap+0x178/0x85c() rcar-dmac e6700000.dma-controller: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x000000006e16b006] [size=4096 bytes] Signed-off-by: Geert Uytterhoeven --- As the transmit scatterlist contains one single entry, which is reused and modified, I think it's better to use dma_{,un}map_single() instead of dma_{,un}map_sg(). But that requires more invasive changes. --- drivers/tty/serial/sh-sci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 8756d186e86891ac..0aec66cf68615972 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1390,6 +1390,14 @@ static void sci_tx_dma_release(struct sci_port *s, bool enable_pio) s->chan_tx = NULL; s->cookie_tx = -EINVAL; + if (s->sg_len_tx) { + /* Restore sg_dma_len() and sg_dma_address() */ + sg_dma_len(&s->sg_tx) = UART_XMIT_SIZE; + sg_dma_address(&s->sg_tx) = sg_dma_address(&s->sg_tx) & + ~(UART_XMIT_SIZE - 1); + dma_unmap_sg(chan->device->dev, &s->sg_tx, 1, DMA_TO_DEVICE); + s->sg_len_tx = 0; + } dma_release_channel(chan); if (enable_pio) sci_start_tx(port);