All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Jiang <dave.jiang@intel.com>
To: linux-cxl@vger.kernel.org, linux-pci@vger.kernel.org
Cc: dan.j.williams@intel.com, ira.weiny@intel.com,
	vishal.l.verma@intel.com, alison.schofield@intel.com,
	Jonathan.Cameron@huawei.com, dave@stgolabs.net,
	bhelgaas@google.com, lukas@wunner.de
Subject: [PATCH 1/3] PCI: Add check for CXL Secondary Bus Reset
Date: Mon, 11 Mar 2024 13:39:53 -0700	[thread overview]
Message-ID: <20240311204132.62757-2-dave.jiang@intel.com> (raw)
In-Reply-To: <20240311204132.62757-1-dave.jiang@intel.com>

Per CXL spec r3.1 8.1.5.2, secondary bus reset is masked unless the
"Unmask SBR" bit is set. Add a check to the PCI secondary bus reset
path to fail the CXL SBR request if the "Unmask SBR" bit is clear in
the CXL Port Control Extensions regiser by returning -EPERM.

The expectation is that if a user overrides the "Unmask SBR" via a
user tool such as setpci, they can trigger a bus reset after that.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
 drivers/cxl/cxlpci.h          |  2 --
 drivers/pci/pci.c             | 45 +++++++++++++++++++++++++++++++++++
 include/uapi/linux/pci_regs.h |  7 ++++++
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
index 711b05d9a370..8d7952d7ca59 100644
--- a/drivers/cxl/cxlpci.h
+++ b/drivers/cxl/cxlpci.h
@@ -13,10 +13,8 @@
  * "DVSEC" redundancies removed. When obvious, abbreviations may be used.
  */
 #define PCI_DVSEC_HEADER1_LENGTH_MASK	GENMASK(31, 20)
-#define PCI_DVSEC_VENDOR_ID_CXL		0x1E98
 
 /* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
-#define CXL_DVSEC_PCIE_DEVICE					0
 #define   CXL_DVSEC_CAP_OFFSET		0xA
 #define     CXL_DVSEC_MEM_CAPABLE	BIT(2)
 #define     CXL_DVSEC_HDM_COUNT_MASK	GENMASK(5, 4)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c3585229c12a..5e5550f54053 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5347,10 +5347,55 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, bool probe)
 	return pci_reset_hotplug_slot(dev->slot->hotplug, probe);
 }
 
+static bool is_cxl_device(struct pci_dev *dev)
+{
+	return pci_find_dvsec_capability(dev, PCI_DVSEC_VENDOR_ID_CXL,
+					 CXL_DVSEC_PCIE_DEVICE);
+}
+
+static bool is_cxl_port_sbr_masked(struct pci_dev *dev)
+{
+	int dvsec;
+	int rc;
+	u16 reg;
+
+	/*
+	 * No DVSEC found, must not be CXL port.
+	 */
+	dvsec = pci_find_dvsec_capability(dev, PCI_DVSEC_VENDOR_ID_CXL,
+					  CXL_DVSEC_PCIE_PORT);
+	if (!dvsec)
+		return false;
+
+	rc = pci_read_config_word(dev, dvsec + CXL_DVSEC_PORT_CONTROL, &reg);
+	if (rc)
+		return true;
+
+	/*
+	 * CXL spec r3.1 8.1.5.2
+	 * When 0, SBR bit in Bridge Control register of this Port has no effect.
+	 * When 1, the Port shall generate hot reset when SBR bit in Bridge
+	 * Control gets set to 1.
+	 */
+	if (reg & CXL_DVSEC_PORT_CONTROL_UNMASK_SBR)
+		return false;
+
+	return true;
+}
+
 static int pci_reset_bus_function(struct pci_dev *dev, bool probe)
 {
 	int rc;
 
+	/* If it's a CXL port and the SBR control is masked, fail the SBR */
+	if (is_cxl_device(dev) && dev->bus->self &&
+	    is_cxl_port_sbr_masked(dev->bus->self)) {
+		if (probe)
+			return 0;
+
+		return -EPERM;
+	}
+
 	rc = pci_dev_reset_slot_function(dev, probe);
 	if (rc != -ENOTTY)
 		return rc;
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index a39193213ff2..5f2c66987299 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -1148,4 +1148,11 @@
 #define PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL		0x00ff0000
 #define PCI_DOE_DATA_OBJECT_DISC_RSP_3_NEXT_INDEX	0xff000000
 
+/* Compute Express Link (CXL) */
+#define PCI_DVSEC_VENDOR_ID_CXL				0x1e98
+#define CXL_DVSEC_PCIE_DEVICE				0
+#define CXL_DVSEC_PCIE_PORT				3
+#define CXL_DVSEC_PORT_CONTROL				0x0c
+#define  CXL_DVSEC_PORT_CONTROL_UNMASK_SBR		0x00000001
+
 #endif /* LINUX_PCI_REGS_H */
-- 
2.44.0


  reply	other threads:[~2024-03-11 20:41 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-11 20:39 [PATCH 0/3] PCI: Add Secondary Bus Reset (SBR) support for CXL Dave Jiang
2024-03-11 20:39 ` Dave Jiang [this message]
2024-03-12  7:30   ` [PATCH 1/3] PCI: Add check for CXL Secondary Bus Reset Lukas Wunner
2024-03-12 21:35     ` Dave Jiang
2024-03-11 20:39 ` [PATCH 2/3] PCI: Create new reset method to force SBR for CXL Dave Jiang
2024-03-12  7:50   ` Lukas Wunner
2024-03-11 20:39 ` [PATCH 3/3] cxl: Add post reset warning if reset is detected as Secondary Bus Reset (SBR) Dave Jiang
2024-03-12  7:46 ` [PATCH 0/3] PCI: Add Secondary Bus Reset (SBR) support for CXL Lukas Wunner
2024-03-12 21:31   ` Dave Jiang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240311204132.62757-2-dave.jiang@intel.com \
    --to=dave.jiang@intel.com \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=alison.schofield@intel.com \
    --cc=bhelgaas@google.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave@stgolabs.net \
    --cc=ira.weiny@intel.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=vishal.l.verma@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.