Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3775158imm; Tue, 17 Jul 2018 10:03:23 -0700 (PDT) X-Google-Smtp-Source: AAOMgpfmBX0y7gPv/MV3ptenFWUZxLEFnkygMqzAksY+afsfzXU82vRAEjio7gemxgQn9DpNhnti X-Received: by 2002:a63:de10:: with SMTP id f16-v6mr2326140pgg.97.1531847003058; Tue, 17 Jul 2018 10:03:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531847003; cv=none; d=google.com; s=arc-20160816; b=MzkMe+i9coMeCRjJpUKVbNoiyCen/K7sM95tI5R14lBAuT4qw2n0jBJfRGvS5Hexs1 Dn5PudmXiKHaFnshcOrTZHwzP6GpyJdzKpzewJzwxRJMFPTekG4/N1844UpgTmcfJAUW 4uHV97XHQNQ1c3ZREml8lkTC8x9b8+kAh54pxBt44Idl/PdRDBEbKOTWcO+BXKhfTEw6 7PmmB+TAgbwYUMaIIE9s7CrHKIoh6goEX8/qffciDHieO5Niu94vOkauUhNAXljvQ9yr rhTy11xwEIeKE8215uX8AtDf6B6pyutLbQTlo82EvHO6hHJoH5Fx1vKw/GvfHVNa7gTv 5tXw== 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=WhG2P2xWyvnxwAYTxSKhDXMm5unBUH0INnEjnRUiQAypPzmWJFgtZ4GanRCkZSrY4v 1bEWnlYQtSj9iDxHFtSLr1Q0s6XpG2uKdrKCWDY3TgkHG04yq8mdO2B/fNBPzoklIzeC 3wVn8CqIb5jL0RZ6rIKZEOvpZOLHE7sYoU8FAtLH/yxW+hb4DnYDFbK7Pm+7MJzOpzL3 wtdDBnI4X5qvyoaqhwpjrjeKOxezD1l85ShkZRabOOyxz10DoOqx/xvR2ygGT0dgCO6K LT8a2VF59qYWQ2s2gRsNNUVmyulWGOY0x/z4d8i/btYI+rWgdAGYoxUCEMzet5/VGktB 4GKg== 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 l6-v6si1245667pgl.567.2018.07.17.10.03.07; Tue, 17 Jul 2018 10:03:23 -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 S1730614AbeGQRgB (ORCPT + 99 others); Tue, 17 Jul 2018 13:36:01 -0400 Received: from ale.deltatee.com ([207.54.116.67]:44630 "EHLO ale.deltatee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730249AbeGQRf7 (ORCPT ); Tue, 17 Jul 2018 13:35:59 -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-0006by-TT; Tue, 17 Jul 2018 11:02:24 -0600 Received: from gunthorp by cgy1-donard.priv.deltatee.com with local (Exim 4.89) (envelope-from ) id 1ffTMT-0007wL-W5; 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:03 -0600 Message-Id: <20180717170204.30470-4-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> 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.7 required=5.0 tests=ALL_TRUSTED,BAYES_00, GREYLIST_ISWHITE,MYRULES_NO_TEXT autolearn=ham autolearn_force=no version=3.4.1 Subject: [PATCH v7 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