From patchwork Sun Jul 15 16:03:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Shtylyov X-Patchwork-Id: 10525069 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 572826020A for ; Sun, 15 Jul 2018 16:03:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3859528429 for ; Sun, 15 Jul 2018 16:03:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2B4D0288BC; Sun, 15 Jul 2018 16:03:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8ADD828429 for ; Sun, 15 Jul 2018 16:03:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726636AbeGOQ1T (ORCPT ); Sun, 15 Jul 2018 12:27:19 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:33309 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726455AbeGOQ1T (ORCPT ); Sun, 15 Jul 2018 12:27:19 -0400 Received: by mail-lj1-f196.google.com with SMTP id t21-v6so27914356lji.0 for ; Sun, 15 Jul 2018 09:03:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cogentembedded-com.20150623.gappssmtp.com; s=20150623; h=subject:from:to:cc:references:organization:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=ptsp8W57JO9D0ujwxOeCCVoeL8SvCtIQ2du1plFpMJw=; b=yKRH/6NPcQ++XS7lu7Sv7V+/vd/tuzEZ3ddzL1IQc/PMfqAsH/OSkPIvWeFXQmDP5Z 7Od/8k9+rC+2GuIoNNRekeCPB9IVki6qdmavSHBeUugPtzy3v8YTCEiywQxO23AjtT/C 6gzTYEIdrvd+2oxgJcy1IyWxBfjAda9nVrpwS3wq1mNW1TANOPm16zwddyfjHcuQ0P9G xucYhucp1WlvhG+HIA5hiy6V8irdwFavn0i8Z9wj5wziucgfjTPMFvQCHq0L85SlEb2J AXii/tf6exqn8kEQ6pgU718e2ld5rnsUh0UT3miSFvy/bA8JCnpsRG21kZv/DlKd+Ts4 rnvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:organization :message-id:date:user-agent:mime-version:in-reply-to :content-language:content-transfer-encoding; bh=ptsp8W57JO9D0ujwxOeCCVoeL8SvCtIQ2du1plFpMJw=; b=fb1cMy7+L2wFsL446vYmDc4w1wAq0Fp/WmlPt8+fbTCTJdjaLsxEEEUM0ZQaZdORHo gGbON2n1OuFuEofkC6smUfdNmd5G2Oe0gtyqiK/6taavciltY8+KPuk8Vapl3oU63L6+ NR+qAdQOdmcADyzqqdNOXQK9vvrfC0d4XYCtKC1CBmy6BOXIgexa+X9QZrVx5vgpSvUC bqPzllD+zHJ4lFXGKw8Q5P0tYGGskYlRJl575joA87TwPXchioEcGYdYV9+ZJko7QCYL iFG0VxVYRR8cLIpg0CaWrJrXGS9IXvHMX/aF4ijsE4S+IrqCxywJlF0TpaCz0xNMqP4X Mlwg== X-Gm-Message-State: AOUpUlHbgusOuMIEk2gPWC2zYuWd7oXKcq0/VgPDkwS3yp74qeLZplcQ Nu7p1U3tS8E+QRDb3gL0k5tBembH0Pg= X-Google-Smtp-Source: AAOMgpc2R5aLp6IUKCegSna7xVVFBn9mmI+G0R9eJoUKuwu7AFfhF9VH6X2OtkC5f+jiviUvhF25Cw== X-Received: by 2002:a2e:4e02:: with SMTP id c2-v6mr8530342ljb.108.1531670632863; Sun, 15 Jul 2018 09:03:52 -0700 (PDT) Received: from wasted.cogentembedded.com ([31.173.81.22]) by smtp.gmail.com with ESMTPSA id l3-v6sm6331565lfi.36.2018.07.15.09.03.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 15 Jul 2018 09:03:51 -0700 (PDT) Subject: [PATCH 1/8] PCI: xgene: Fix I/O space page leak From: Sergei Shtylyov To: Bjorn Helgaas , linux-pci@vger.kernel.org, Lorenzo Pieralisi Cc: linux-arm-kernel@lists.infradead.org References: <3e862a05-084a-d732-3060-6e2b234e9718@cogentembedded.com> Organization: Cogent Embedded Message-ID: Date: Sun, 15 Jul 2018 19:03:51 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 MIME-Version: 1.0 In-Reply-To: <3e862a05-084a-d732-3060-6e2b234e9718@cogentembedded.com> Content-Language: en-MW Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When testing the R-Car PCIe driver on the Condor board, I noticed that if I left the PCIe PHY driver disabled, the kernel crashed with this BUG: [ 1.225819] kernel BUG at lib/ioremap.c:72! [ 1.230007] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP [ 1.235496] Modules linked in: [ 1.238561] CPU: 0 PID: 39 Comm: kworker/0:1 Not tainted 4.17.0-dirty #1092 [ 1.245526] Hardware name: Renesas Condor board based on r8a77980 (DT) [ 1.252075] Workqueue: events deferred_probe_work_func [ 1.257220] pstate: 80000005 (Nzcv daif -PAN -UAO) [ 1.262024] pc : ioremap_page_range+0x370/0x3c8 [ 1.266558] lr : ioremap_page_range+0x40/0x3c8 [ 1.271002] sp : ffff000008da39e0 [ 1.274317] x29: ffff000008da39e0 x28: 00e8000000000f07 [ 1.279636] x27: ffff7dfffee00000 x26: 0140000000000000 [ 1.284954] x25: ffff7dfffef00000 x24: 00000000000fe100 [ 1.290272] x23: ffff80007b906000 x22: ffff000008ab8000 [ 1.295590] x21: ffff000008bb1d58 x20: ffff7dfffef00000 [ 1.300909] x19: ffff800009c30fb8 x18: 0000000000000001 [ 1.306226] x17: 00000000000152d0 x16: 00000000014012d0 [ 1.311544] x15: 0000000000000000 x14: 0720072007200720 [ 1.316862] x13: 0720072007200720 x12: 0720072007200720 [ 1.322180] x11: 0720072007300730 x10: 00000000000000ae [ 1.327498] x9 : 0000000000000000 x8 : ffff7dffff000000 [ 1.332816] x7 : 0000000000000000 x6 : 0000000000000100 [ 1.338134] x5 : 0000000000000000 x4 : 000000007b906000 [ 1.343452] x3 : ffff80007c61a880 x2 : ffff7dfffeefffff [ 1.348770] x1 : 0000000040000000 x0 : 00e80000fe100f07 [ 1.354090] Process kworker/0:1 (pid: 39, stack limit = 0x (ptrval)) [ 1.361056] Call trace: [ 1.363504] ioremap_page_range+0x370/0x3c8 [ 1.367695] pci_remap_iospace+0x7c/0xac [ 1.371624] pci_parse_request_of_pci_ranges+0x13c/0x190 [ 1.376945] rcar_pcie_probe+0x4c/0xb04 [ 1.380786] platform_drv_probe+0x50/0xbc [ 1.384799] driver_probe_device+0x21c/0x308 [ 1.389072] __device_attach_driver+0x98/0xc8 [ 1.393431] bus_for_each_drv+0x54/0x94 [ 1.397269] __device_attach+0xc4/0x12c [ 1.401107] device_initial_probe+0x10/0x18 [ 1.405292] bus_probe_device+0x90/0x98 [ 1.409130] deferred_probe_work_func+0xb0/0x150 [ 1.413756] process_one_work+0x12c/0x29c [ 1.417768] worker_thread+0x200/0x3fc [ 1.421522] kthread+0x108/0x134 [ 1.424755] ret_from_fork+0x10/0x18 [ 1.428334] Code: f9004ba2 54000080 aa0003fb 17ffff48 (d4210000) It turned out that pci_remap_iospace() wasn't undone when the driver's probe failed, and since devm_phy_optional_get() returned -EPROBE_DEFER, the probe was retried, finally causing the BUG due to trying to remap already remapped pages. The most feasible solution seemed to introduce devm_pci_remap_iospace() and call it instead of pci_remap_iospace(), so that the pages get unmapped automagically on any probe failure. Looking at the PCI drivers having the same issue, the XGene driver turned out to be the earliest broken, so I'll have to start with fixing it... Fixes: 5f6b6ccdbe1c ("PCI: xgene: Add APM X-Gene PCIe driver") Signed-off-by: Sergei Shtylyov Reviewed-by: Linus Walleij Acked-by: Bjorn Helgaas --- drivers/pci/controller/pci-xgene.c | 2 - drivers/pci/pci.c | 38 +++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 2 + 3 files changed, 41 insertions(+), 1 deletion(-) Index: pci/drivers/pci/controller/pci-xgene.c =================================================================== --- pci.orig/drivers/pci/controller/pci-xgene.c +++ pci/drivers/pci/controller/pci-xgene.c @@ -423,7 +423,7 @@ static int xgene_pcie_map_ranges(struct case IORESOURCE_IO: xgene_pcie_setup_ob_reg(port, res, OMR3BARL, io_base, res->start - window->offset); - ret = pci_remap_iospace(res, io_base); + ret = devm_pci_remap_iospace(dev, res, io_base); if (ret < 0) return ret; break; Index: pci/drivers/pci/pci.c =================================================================== --- pci.orig/drivers/pci/pci.c +++ pci/drivers/pci/pci.c @@ -3579,6 +3579,44 @@ void pci_unmap_iospace(struct resource * } EXPORT_SYMBOL(pci_unmap_iospace); +static void devm_pci_unmap_iospace(struct device *dev, void *ptr) +{ + struct resource **res = ptr; + + pci_unmap_iospace(*res); +} + +/** + * devm_pci_remap_iospace - Managed pci_remap_iospace() + * @dev: Generic device to remap IO address for + * @res: Resource describing the I/O space + * @phys_addr: physical address of range to be mapped + * + * Managed pci_remap_iospace(). Map is automatically unmapped on driver + * detach. + */ +int devm_pci_remap_iospace(struct device *dev, const struct resource *res, + phys_addr_t phys_addr) +{ + const struct resource **ptr; + int error; + + ptr = devres_alloc(devm_pci_unmap_iospace, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + error = pci_remap_iospace(res, phys_addr); + if (error) { + devres_free(ptr); + } else { + *ptr = res; + devres_add(dev, ptr); + } + + return error; +} +EXPORT_SYMBOL(devm_pci_remap_iospace); + /** * devm_pci_remap_cfgspace - Managed pci_remap_cfgspace() * @dev: Generic device to remap IO address for Index: pci/include/linux/pci.h =================================================================== --- pci.orig/include/linux/pci.h +++ pci/include/linux/pci.h @@ -1240,6 +1240,8 @@ int pci_register_io_range(struct fwnode_ unsigned long pci_address_to_pio(phys_addr_t addr); phys_addr_t pci_pio_to_address(unsigned long pio); int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); +int devm_pci_remap_iospace(struct device *dev, const struct resource *res, + phys_addr_t phys_addr); void pci_unmap_iospace(struct resource *res); void __iomem *devm_pci_remap_cfgspace(struct device *dev, resource_size_t offset,