Received: by 10.223.164.202 with SMTP id h10csp221829wrb; Mon, 13 Nov 2017 05:30:50 -0800 (PST) X-Google-Smtp-Source: AGs4zMbQJmX7WGVl/FqWncS93QHhbVwCdrvQdu/Rd/fNSlzSn75UzYOoansKi+tubR0sJowLsHvI X-Received: by 10.99.36.133 with SMTP id k127mr8415008pgk.171.1510579850211; Mon, 13 Nov 2017 05:30:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510579850; cv=none; d=google.com; s=arc-20160816; b=ZvGoGaliTlgCCL+Z0ZkhzXBmW0I8O3c9KJ2mPfbgLtb2h46bSVWrIh47bb2pdWvTED zw3lsLyhNsbcfsx1juF/mwfsHc5bInUj45pm7CMjYISocj4ZyyE8g2qNg5TAk6riaSKp 8HgyrbAeTSEP5gFpWL9NRRF5hwC5a9xv9Vyr2o3TiJG9QwAZfOmA34EHGaQDumrZYNZK 6CTHpz/NTqDoyOVrdjQLuceqByYcY6FMGWstTyxtye8x2+Wv73KajORkd1htSyygkI+K nNelsYH85HmK/ftfbRnwZjzYYZRhugB/krdJA2mnHlxch6COns0jjehuTspqLS1z3n+w hY4g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=6U9sNVVF8CqUriL/PKzmsOzpXVavoRvOxBZsC41Bz+o=; b=S1EaiO3q1k0R5El7FvMPBlzCGboiUNFQGOs2mBj7gzI5fVwZTRlnrNhP0vEMWZ9Jpl F3AJh0q/3XTJw0cslwrzIaf82xTsTZzi1lhoLbro/ODPWvxIACNDhhiBjsfUCMYLGpPX 5HzIlNVFh6hvWoDHlX5lFZLXOqgCQ7Y+A0xPfnGMAjzSDaTiBhUYVrJ9KM+ZcwQQ4XZE bBGGLVYuaGJWIzU/JxL4CgV3fTiKSJ6jWYto3d0cGMIJiFDgRjKv2wvzC/5Uea2rJ977 VEcAiX+0O87VbzJJfsyD0w6pF4ahm8KWF7X1sYNCy3q4CvuEYNZiKzs1SEMU5VVmeYiX xEYw== ARC-Authentication-Results: i=1; mx.google.com; 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 b12si12642847plr.486.2017.11.13.05.30.37; Mon, 13 Nov 2017 05:30:50 -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; 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 S1754044AbdKMM7a (ORCPT + 95 others); Mon, 13 Nov 2017 07:59:30 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:49730 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753993AbdKMM71 (ORCPT ); Mon, 13 Nov 2017 07:59:27 -0500 Received: from localhost (LFbn-1-12253-150.w90-92.abo.wanadoo.fr [90.92.67.150]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id E5C64A95; Mon, 13 Nov 2017 12:59:26 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jason Gunthorpe , Bjorn Helgaas , Jason Cooper , Sasha Levin Subject: [PATCH 4.9 03/87] PCI: mvebu: Handle changes to the bridge windows while enabled Date: Mon, 13 Nov 2017 13:55:20 +0100 Message-Id: <20171113125615.661472210@linuxfoundation.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171113125615.304035578@linuxfoundation.org> References: <20171113125615.304035578@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jason Gunthorpe [ Upstream commit d9bf28e2650fe3eeefed7e34841aea07d10c6543 ] The PCI core will write to the bridge window config multiple times while they are enabled. This can lead to mbus failures like this: mvebu_mbus: cannot add window '4:e8', conflicts with another window mvebu-pcie mbus:pex@e0000000: Could not create MBus window at [mem 0xe0000000-0xe00fffff]: -22 For me this is happening during a hotplug cycle. The PCI core is not changing the values, just writing them twice while active. The patch addresses the general case of any change to an active window, but not atomically. The code is slightly refactored so io and mem can share more of the window logic. Signed-off-by: Jason Gunthorpe Signed-off-by: Bjorn Helgaas Acked-by: Jason Cooper Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pci/host/pci-mvebu.c | 101 +++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 41 deletions(-) --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -133,6 +133,12 @@ struct mvebu_pcie { int nports; }; +struct mvebu_pcie_window { + phys_addr_t base; + phys_addr_t remap; + size_t size; +}; + /* Structure representing one PCIe interface */ struct mvebu_pcie_port { char *name; @@ -150,10 +156,8 @@ struct mvebu_pcie_port { struct mvebu_sw_pci_bridge bridge; struct device_node *dn; struct mvebu_pcie *pcie; - phys_addr_t memwin_base; - size_t memwin_size; - phys_addr_t iowin_base; - size_t iowin_size; + struct mvebu_pcie_window memwin; + struct mvebu_pcie_window iowin; u32 saved_pcie_stat; }; @@ -379,23 +383,45 @@ static void mvebu_pcie_add_windows(struc } } +static void mvebu_pcie_set_window(struct mvebu_pcie_port *port, + unsigned int target, unsigned int attribute, + const struct mvebu_pcie_window *desired, + struct mvebu_pcie_window *cur) +{ + if (desired->base == cur->base && desired->remap == cur->remap && + desired->size == cur->size) + return; + + if (cur->size != 0) { + mvebu_pcie_del_windows(port, cur->base, cur->size); + cur->size = 0; + cur->base = 0; + + /* + * If something tries to change the window while it is enabled + * the change will not be done atomically. That would be + * difficult to do in the general case. + */ + } + + if (desired->size == 0) + return; + + mvebu_pcie_add_windows(port, target, attribute, desired->base, + desired->size, desired->remap); + *cur = *desired; +} + static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) { - phys_addr_t iobase; + struct mvebu_pcie_window desired = {}; /* Are the new iobase/iolimit values invalid? */ if (port->bridge.iolimit < port->bridge.iobase || port->bridge.iolimitupper < port->bridge.iobaseupper || !(port->bridge.command & PCI_COMMAND_IO)) { - - /* If a window was configured, remove it */ - if (port->iowin_base) { - mvebu_pcie_del_windows(port, port->iowin_base, - port->iowin_size); - port->iowin_base = 0; - port->iowin_size = 0; - } - + mvebu_pcie_set_window(port, port->io_target, port->io_attr, + &desired, &port->iowin); return; } @@ -412,32 +438,27 @@ static void mvebu_pcie_handle_iobase_cha * specifications. iobase is the bus address, port->iowin_base * is the CPU address. */ - iobase = ((port->bridge.iobase & 0xF0) << 8) | - (port->bridge.iobaseupper << 16); - port->iowin_base = port->pcie->io.start + iobase; - port->iowin_size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) | - (port->bridge.iolimitupper << 16)) - - iobase) + 1; - - mvebu_pcie_add_windows(port, port->io_target, port->io_attr, - port->iowin_base, port->iowin_size, - iobase); + desired.remap = ((port->bridge.iobase & 0xF0) << 8) | + (port->bridge.iobaseupper << 16); + desired.base = port->pcie->io.start + desired.remap; + desired.size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) | + (port->bridge.iolimitupper << 16)) - + desired.remap) + + 1; + + mvebu_pcie_set_window(port, port->io_target, port->io_attr, &desired, + &port->iowin); } static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) { + struct mvebu_pcie_window desired = {.remap = MVEBU_MBUS_NO_REMAP}; + /* Are the new membase/memlimit values invalid? */ if (port->bridge.memlimit < port->bridge.membase || !(port->bridge.command & PCI_COMMAND_MEMORY)) { - - /* If a window was configured, remove it */ - if (port->memwin_base) { - mvebu_pcie_del_windows(port, port->memwin_base, - port->memwin_size); - port->memwin_base = 0; - port->memwin_size = 0; - } - + mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, + &desired, &port->memwin); return; } @@ -447,14 +468,12 @@ static void mvebu_pcie_handle_membase_ch * window to setup, according to the PCI-to-PCI bridge * specifications. */ - port->memwin_base = ((port->bridge.membase & 0xFFF0) << 16); - port->memwin_size = - (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) - - port->memwin_base + 1; - - mvebu_pcie_add_windows(port, port->mem_target, port->mem_attr, - port->memwin_base, port->memwin_size, - MVEBU_MBUS_NO_REMAP); + desired.base = ((port->bridge.membase & 0xFFF0) << 16); + desired.size = (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) - + desired.base + 1; + + mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, &desired, + &port->memwin); } /* From 1583955742728461401@xxx Mon Nov 13 12:58:30 +0000 2017 X-GM-THRID: 1583955742728461401 X-Gmail-Labels: Inbox,Category Promotions,HistoricalUnread