Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3776276imm; Tue, 17 Jul 2018 10:04:08 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcYx5ZgCxHHrBq4k4567WzqwDZhtC8BWS3iCZbj4ED6PaISKcxGLbAtSx3W2jNej0r1BAso X-Received: by 2002:a62:6003:: with SMTP id u3-v6mr1401236pfb.114.1531847048449; Tue, 17 Jul 2018 10:04:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531847048; cv=none; d=google.com; s=arc-20160816; b=KV4SIyKUaWa31CNjizDKDpTRr/kgWT4Q0RrGt+uEqNRZuG+XeNamcpJHwYt7Amoqj7 jQ1YqojbFzUFilQxEhXmqzHZJQ3/IOYDCY92/p3eVkx+/X/XtrILnZJvuCXNUjNrhnIA Thkh1COqqHCxqYEJVXOaEGiard50VqyLlL+pncqbuhbRpXJtuE9E5PE7t6O/EiynI0UM vaiCbk4jUqr7XARpMdhXyJXkUXt1DiZ9l7x/NpcMY7tXHWw1QVd1iv2REdvIQOCuhxGI NAHCeab6ezksnFGDoyQVYj2m1Re54h7Yyr/VUM/wUO5/g8Fk8MFmPGjqf0Oq8IBX6GKp uVKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:subject:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:cc:to:from :arc-authentication-results; bh=wZWOLkt1yCFeedZS5TrBBD2UR3T3qCD/1inFxBbZjJE=; b=Nxzrq/2HlzaqXbOuL8Z5JC7q+WPOpUUQYldsJrXlLGUU6yt9aGGzRh5ESV6xOTSSe/ EY25sAhR4hPl95PPsBVw5CyCeKLqQnibrbgstiobv4jxepSHLV5CLobwK8ynS0aqTeZK eTy1w7iw5RnDeomy4e8bcfzcG+000+Gi6CMZxJffGGBzzQgbva900K2pT9d+oj9Wq5vo e56Fl0LPD1eG05kGzOWQr9b4wMmRu2KQk83uNYlYUSXrzXqSrs4G77Qp59N0/i+EjS4Y tL7FIqXOFW6uAMw8Bx9aG3ul/JBMWXI8ilNNXq0xzuloiT7Ol5B2+0Qf2j2WXxYPsUxE Sicw== 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 23-v6si1358792pgx.323.2018.07.17.10.03.53; Tue, 17 Jul 2018 10:04:08 -0700 (PDT) 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 S1730052AbeGQRf6 (ORCPT + 99 others); Tue, 17 Jul 2018 13:35:58 -0400 Received: from ale.deltatee.com ([207.54.116.67]:44596 "EHLO ale.deltatee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729728AbeGQRf5 (ORCPT ); Tue, 17 Jul 2018 13:35:57 -0400 Received: from cgy1-donard.priv.deltatee.com ([172.16.1.31]) by ale.deltatee.com with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1ffTMh-0006bz-TU; Tue, 17 Jul 2018 11:02:22 -0600 Received: from gunthorp by cgy1-donard.priv.deltatee.com with local (Exim 4.89) (envelope-from ) id 1ffTMU-0007wO-3L; Tue, 17 Jul 2018 11:02:06 -0600 From: Logan Gunthorpe To: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-doc@vger.kernel.org Cc: Stephen Bates , Christoph Hellwig , Bjorn Helgaas , Jonathan Corbet , Ingo Molnar , Thomas Gleixner , "Paul E. McKenney" , Marc Zyngier , Kai-Heng Feng , Frederic Weisbecker , Dan Williams , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Benjamin Herrenschmidt , Alex Williamson , =?UTF-8?q?Christian=20K=C3=B6nig?= , Matthew Wilcox , Logan Gunthorpe Date: Tue, 17 Jul 2018 11:02:04 -0600 Message-Id: <20180717170204.30470-5-logang@deltatee.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180717170204.30470-1-logang@deltatee.com> References: <20180717170204.30470-1-logang@deltatee.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 172.16.1.31 X-SA-Exim-Rcpt-To: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, sbates@raithlin.com, hch@lst.de, bhelgaas@google.com, corbet@lwn.net, tglx@linutronix.de, paulmck@linux.vnet.ibm.com, marc.zyngier@arm.com, kai.heng.feng@canonical.com, mingo@kernel.org, frederic@kernel.org, dan.j.williams@intel.com, benh@kernel.crashing.org, jglisse@redhat.com, alex.williamson@redhat.com, christian.koenig@amd.com, willy@infradead.org, logang@deltatee.com X-SA-Exim-Mail-From: gunthorp@deltatee.com X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on ale.deltatee.com X-Spam-Level: X-Spam-Status: No, score=-8.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, GREYLIST_ISWHITE autolearn=ham autolearn_force=no version=3.4.1 Subject: [PATCH v7 4/4] PCI: Introduce the disable_acs_redir parameter X-SA-Exim-Version: 4.2.1 (built Tue, 02 Aug 2016 21:08:31 +0000) X-SA-Exim-Scanned: Yes (on ale.deltatee.com) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to support P2P traffic on a segment of the PCI hierarchy, we must be able to disable the ACS redirect bits for select PCI bridges. The bridges must be selected before the devices are discovered by the kernel and the IOMMU groups created. Therefore, a kernel command line parameter is created to specify devices which must have their ACS bits disabled. The new parameter takes a list of devices separated by a semicolon. Each device specified will have it's ACS redirect bits disabled. This is similar to the existing 'resource_alignment' parameter. The ACS Request P2P Request Redirect, P2P Completion Redirect and P2P Egress Control bits are disabled which is sufficient to always allow passing P2P traffic uninterrupted. The bits are set after the kernel (optionally) enables the ACS bits itself. It is also done regardless of whether the kernel sets the bits or not seeing some BIOS firmware is known to set the bits on boot. If the user tries to disable the ACS redirct for a device without the ACS capability, a warning is printed to dmesg. Signed-off-by: Logan Gunthorpe Reviewed-by: Stephen Bates Acked-by: Christian König --- Documentation/admin-guide/kernel-parameters.txt | 9 +++ drivers/pci/pci.c | 76 ++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 1fdd1ef03984..ab19ed83f072 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3192,6 +3192,15 @@ Adding the window is slightly risky (it may conflict with unreported devices), so this taints the kernel. + disable_acs_redir=[; ...] + Specify one or more PCI devices (in the format + specified above) separated by semicolons. + Each device specified will have the PCI ACS + redirect capabilities forced off which will + allow P2P traffic between devices through + bridges without forcing it upstream. Note: + this removes isolation between devices and + will make the IOMMU groups less granular. pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power Management. diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 59638075b4df..0aee076efe8b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2983,6 +2983,66 @@ void pci_request_acs(void) pci_acs_enable = 1; } +static const char *disable_acs_redir_param; + +/** + * pci_disable_acs_redir - disable ACS redirect capabilities + * @dev: the PCI device + * + * For only devices specified in the disable_acs_redir parameter. + */ +static void pci_disable_acs_redir(struct pci_dev *dev) +{ + int ret = 0; + const char *p; + int pos; + u16 ctrl; + + if (!disable_acs_redir_param) + return; + + p = disable_acs_redir_param; + while (*p) { + ret = pci_dev_str_match(dev, p, &p); + if (ret < 0) { + pr_info_once("PCI: Can't parse disable_acs_redir parameter: %s\n", + disable_acs_redir_param); + + break; + } else if (ret == 1) { + /* Found a match */ + break; + } + + if (*p != ';' && *p != ',') { + /* End of param or invalid format */ + break; + } + p++; + } + + if (ret != 1) + return; + + if (!pci_dev_specific_disable_acs_redir(dev)) + return; + + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); + if (!pos) { + pci_warn(dev, "cannot disable ACS redirect for this hardware as it does not have ACS capabilities\n"); + return; + } + + pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); + + /* P2P Request & Completion Redirect */ + ctrl &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC); + + pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); + + pci_info(dev, "disabled ACS redirect\n"); +} + /** * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites * @dev: the PCI device @@ -3022,12 +3082,22 @@ static void pci_std_enable_acs(struct pci_dev *dev) void pci_enable_acs(struct pci_dev *dev) { if (!pci_acs_enable) - return; + goto disable_acs_redir; if (!pci_dev_specific_enable_acs(dev)) - return; + goto disable_acs_redir; pci_std_enable_acs(dev); + +disable_acs_redir: + /* + * Note: pci_disable_acs_redir() must be called even if + * ACS is not enabled by the kernel because the firmware + * may have unexpectedly set the flags. So if we are told + * to disable it, we should always disable it after setting + * the kernel's default preferences. + */ + pci_disable_acs_redir(dev); } static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags) @@ -5967,6 +6037,8 @@ static int __init pci_setup(char *str) pcie_bus_config = PCIE_BUS_PEER2PEER; } else if (!strncmp(str, "pcie_scan_all", 13)) { pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); + } else if (!strncmp(str, "disable_acs_redir=", 18)) { + disable_acs_redir_param = str + 18; } else { printk(KERN_ERR "PCI: Unknown option `%s'\n", str); -- 2.11.0