Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp34697imm; Fri, 13 Jul 2018 16:33:09 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdUxLM6CqNRdro0KZcwWTFMu5z5o+BY4h8t4+GAoTlpYxMFF/M3Pr9PULZXPpIkGPDbBXPC X-Received: by 2002:a63:2013:: with SMTP id g19-v6mr7792174pgg.68.1531524789205; Fri, 13 Jul 2018 16:33:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531524789; cv=none; d=google.com; s=arc-20160816; b=NWYyCIr90RsoAOXO93dT3u8V5LZDP+14OOroxz1mEtGje+Ak/sZP3fNlb39G8YlHAA GFTSPSQr4Dikuxson4ZzJ56rt/QSFxwM6WGQ9BIxY305JbvpbRs2SyzoSZmbB9DA3rQL y9rNaY7Uk5jYWF+B/vdvpx2Zd3aLdFlO+Vtyk6Br/dl5b5WXlUYRQcF+pEXgf7jZgF8X R6kpvpmoZjAGISao9L4j0tzN6c6neAgEF9F8ZfDU1qcqrG+y9BlsKnw1UWzksxSZtauR uh6C0ZG+MZbwMvwJYWYeS8b1Gg9patQSC7IDrCRVUUBI4zAP00snYmShioeXg+O6aGrj l8/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:subject:references:in-reply-to:message-id :date:cc:to:from:arc-authentication-results; bh=uxyBCy5iwDcRi7JkIVvDNk6WDDhPA0ltZ+CcVAEBziU=; b=FL2HVQ2wXKBj//VPkUg0dAq1Oc49SohCw5bFU9iLkn716wVcePpVW2+8VFJHwmNIB4 t2/1TxVOkiCiP2WEGqIZUN3OMuCM4ggHs2TQhNe8jBCy/X/IGboGHt1h2/8cQ5BGt/Uk g6OTbm1ZSRM/YzVLwJWWz6lJ0/JIDvmEjGFxjM0oCdtKWh+pK8mMz0Ck0Bdc+RN40LAx w0PdMWJ1c9UIJ9gaPKeNjzssCyUTCGI2BtwwJ2YzF91pwv/qk4jQZQPINFObj2w7ZlSb lDD9MkUAPiM/fao1Kcz9TpbeAyyfdf5mucGNhS9op73T5sw+22A+xAKoK1iTN9/ePn5c hoZQ== 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 y78-v6si28378360pfj.159.2018.07.13.16.32.54; Fri, 13 Jul 2018 16:33:09 -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 S1732704AbeGMXtD (ORCPT + 99 others); Fri, 13 Jul 2018 19:49:03 -0400 Received: from ale.deltatee.com ([207.54.116.67]:48352 "EHLO ale.deltatee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731571AbeGMXtB (ORCPT ); Fri, 13 Jul 2018 19:49:01 -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 1fe7Xm-000248-1V; Fri, 13 Jul 2018 17:32:10 -0600 Received: from gunthorp by cgy1-donard.priv.deltatee.com with local (Exim 4.89) (envelope-from ) id 1fe7Xd-00055r-VY; Fri, 13 Jul 2018 17:32:02 -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: Fri, 13 Jul 2018 17:31:57 -0600 Message-Id: <20180713233158.19528-4-logang@deltatee.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180713233158.19528-1-logang@deltatee.com> References: <20180713233158.19528-1-logang@deltatee.com> 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=-6.7 required=5.0 tests=ALL_TRUSTED,BAYES_00, MYRULES_NO_TEXT autolearn=no autolearn_force=no version=3.4.1 Subject: [PATCH v6 3/4] PCI: Introduce disable_acs_redir quirk 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 Intel SPT PCH hardware has an implementation of the ACS bits that does not comply with the PCI express standard. To deal with this the existing code has an enable_acs() quirk for the hardware. In order to be able to correctly disable the ACS redirect bits for all hardware we need an analagous quirk to disable those bits. This adds the function pci_dev_specific_disable_acs_redir() which behaves similarly to pci_dev_specific_enable_acs() but uses a new function pointer for quirks which disables the ACS redirect bits. Signed-off-by: Logan Gunthorpe --- drivers/pci/quirks.c | 78 ++++++++++++++++++++++++++++++++++++++++++++-------- include/linux/pci.h | 5 ++++ 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f439de848658..414b22dc06b8 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4553,27 +4553,81 @@ static int pci_quirk_enable_intel_spt_pch_acs(struct pci_dev *dev) return 0; } -static const struct pci_dev_enable_acs { +static int pci_quirk_disable_intel_spt_pch_acs_redir(struct pci_dev *dev) +{ + int pos; + u32 cap, ctrl; + + if (!pci_quirk_intel_spt_pch_acs_match(dev)) + return -ENOTTY; + + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); + if (!pos) + return -ENOTTY; + + pci_read_config_dword(dev, pos + PCI_ACS_CAP, &cap); + pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl); + + ctrl &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC); + + pci_write_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, ctrl); + + pci_info(dev, "Intel SPT PCH root port workaround: disabled ACS redirect\n"); + + return 0; +} + +static const struct pci_dev_acs_ops { u16 vendor; u16 device; int (*enable_acs)(struct pci_dev *dev); -} pci_dev_enable_acs[] = { - { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_pch_acs }, - { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_spt_pch_acs }, - { 0 } + int (*disable_acs_redir)(struct pci_dev *dev); +} pci_dev_acs_ops[] = { + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, + .enable_acs = pci_quirk_enable_intel_pch_acs, + }, + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, + .enable_acs = pci_quirk_enable_intel_spt_pch_acs, + .disable_acs_redir = pci_quirk_disable_intel_spt_pch_acs_redir + }, }; int pci_dev_specific_enable_acs(struct pci_dev *dev) { - const struct pci_dev_enable_acs *i; + const struct pci_dev_acs_ops *p; + int i; int ret; - for (i = pci_dev_enable_acs; i->enable_acs; i++) { - if ((i->vendor == dev->vendor || - i->vendor == (u16)PCI_ANY_ID) && - (i->device == dev->device || - i->device == (u16)PCI_ANY_ID)) { - ret = i->enable_acs(dev); + for (i = 0; i < ARRAY_SIZE(pci_dev_acs_ops); i++) { + p = &pci_dev_acs_ops[i]; + if ((p->vendor == dev->vendor || + p->vendor == (u16)PCI_ANY_ID) && + (p->device == dev->device || + p->device == (u16)PCI_ANY_ID) && + p->enable_acs) { + ret = p->enable_acs(dev); + if (ret >= 0) + return ret; + } + } + + return -ENOTTY; +} + +int pci_dev_specific_disable_acs_redir(struct pci_dev *dev) +{ + const struct pci_dev_acs_ops *p; + int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(pci_dev_acs_ops); i++) { + p = &pci_dev_acs_ops[i]; + if ((p->vendor == dev->vendor || + p->vendor == (u16)PCI_ANY_ID) && + (p->device == dev->device || + p->device == (u16)PCI_ANY_ID) && + p->disable_acs_redir) { + ret = p->disable_acs_redir(dev); if (ret >= 0) return ret; } diff --git a/include/linux/pci.h b/include/linux/pci.h index 340029b2fb38..3b61068dc7d1 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1878,6 +1878,7 @@ enum pci_fixup_pass { void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags); int pci_dev_specific_enable_acs(struct pci_dev *dev); +int pci_dev_specific_disable_acs_redir(struct pci_dev *dev); #else static inline void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) { } @@ -1890,6 +1891,10 @@ static inline int pci_dev_specific_enable_acs(struct pci_dev *dev) { return -ENOTTY; } +static inline int pci_dev_specific_disable_acs_redir(struct pci_dev *dev) +{ + return -ENOTTY; +} #endif void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); -- 2.11.0