From patchwork Mon Oct 31 21:39:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Helgaas X-Patchwork-Id: 9406587 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 1521A60234 for ; Mon, 31 Oct 2016 21:39:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06F4B28B8F for ; Mon, 31 Oct 2016 21:39:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EFBAA28D41; Mon, 31 Oct 2016 21:39:08 +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=-6.9 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, 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 95FD528B8F for ; Mon, 31 Oct 2016 21:39:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S947281AbcJaVjH (ORCPT ); Mon, 31 Oct 2016 17:39:07 -0400 Received: from mail.kernel.org ([198.145.29.136]:34864 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S947218AbcJaVjG (ORCPT ); Mon, 31 Oct 2016 17:39:06 -0400 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CCA5E202E5; Mon, 31 Oct 2016 21:39:04 +0000 (UTC) Received: from localhost (50-243-30-238-static.hfc.comcastbusiness.net [50.243.30.238]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AFB822026D; Mon, 31 Oct 2016 21:39:03 +0000 (UTC) Subject: [PATCH] PCI: Warn on possible RW1C corruption for sub-32 bit config writes From: Bjorn Helgaas To: linux-pci@vger.kernel.org Cc: Rob Herring , Heiko Stuebner , Gabriele Paoloni , Jon Mason , Ray Jui , Shawn Lin , Wenrui Li , Scott Branden , Russell King , Zhou Wang , Tanmay Inamdar , Greg Ungerer , Thierry Reding Date: Mon, 31 Oct 2016 16:39:02 -0500 Message-ID: <20161031213902.6340.96123.stgit@bhelgaas-glaptop.roam.corp.google.com> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP 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 Hardware that supports only 32-bit config writes is not spec-compliant. For example, if software performs a 16-bit write, we must do a 32-bit read, merge in the 16 bits we intend to write, followed by a 32-bit write. If the 16 bits we *don't* intend to write happen to have any RW1C (write-one- to-clear) bits set, we just inadvertently cleared something we shouldn't have. Add a rate-limited warning when we do sub-32 bit config writes. Remove similar probe-time warnings from some of the affected host bridge drivers. Signed-off-by: Bjorn Helgaas Acked-by: Shawn Lin Acked-by: Thierry Reding --- drivers/pci/access.c | 17 +++++++++++++++-- drivers/pci/host/pcie-hisi.c | 2 -- drivers/pci/host/pcie-rockchip.c | 3 --- 3 files changed, 15 insertions(+), 7 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d11cdbb..e0cd124 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -142,10 +142,23 @@ int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn, if (size == 4) { writel(val, addr); return PCIBIOS_SUCCESSFUL; - } else { - mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); } + /* + * N.B. In general, hardware that supports only 32-bit writes on + * PCI is not spec-compliant. For example, software may perform a + * 16-bit write. If the hardware only supports 32-bit accesses, we + * must do a 32-bit read, merge in the 16 bits we intend to write, + * followed by a 32-bit write. If the 16 bits we *don't* intend to + * write happen to have any RW1C (write-one-to-clear) bits set, we + * just inadvertently cleared something we shouldn't have. + */ + + dev_warn_ratelimited(&bus->dev, "%d-byte config write to %04x:%02x:%02x.%d offset %#x may corrupt adjacent RW1C bits\n", + size, pci_domain_nr(bus), bus->number, + PCI_SLOT(devfn), PCI_FUNC(devfn), where); + + mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); tmp = readl(addr) & mask; tmp |= val << ((where & 0x3) * 8); writel(tmp, addr); diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c index 56154c2..5b5901d 100644 --- a/drivers/pci/host/pcie-hisi.c +++ b/drivers/pci/host/pcie-hisi.c @@ -194,8 +194,6 @@ static int hisi_pcie_probe(struct platform_device *pdev) if (ret) return ret; - dev_warn(dev, "only 32-bit config accesses supported; smaller writes may corrupt adjacent RW1C fields\n"); - return 0; } diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c index e0b22da..6419d8c 100644 --- a/drivers/pci/host/pcie-rockchip.c +++ b/drivers/pci/host/pcie-rockchip.c @@ -1187,9 +1187,6 @@ static int rockchip_pcie_probe(struct platform_device *pdev) pcie_bus_configure_settings(child); pci_bus_add_devices(bus); - - dev_warn(dev, "only 32-bit config accesses supported; smaller writes may corrupt adjacent RW1C fields\n"); - return err; err_vpcie: