From: "Fabio M. De Francesco" <fabio.m.de.francesco@linux.intel.com>
To: linux-cxl@vger.kernel.org
Cc: Davidlohr Bueso <dave@stgolabs.net>,
Jonathan Cameron <jonathan.cameron@huawei.com>,
Dave Jiang <dave.jiang@intel.com>,
Alison Schofield <alison.schofield@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>,
Ira Weiny <ira.weiny@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
Bjorn Helgaas <bhelgaas@google.com>,
linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
"Fabio M. De Francesco" <fabio.m.de.francesco@linux.intel.com>
Subject: [PATCH 1/2] PCI/CXL: Allow PM Init to complete on cxl_bus reset if ACS SV enabled
Date: Tue, 28 Apr 2026 20:24:34 +0200 [thread overview]
Message-ID: <20260428182454.464655-2-fabio.m.de.francesco@linux.intel.com> (raw)
In-Reply-To: <20260428182454.464655-1-fabio.m.de.francesco@linux.intel.com>
CXL r4.0 sec 8.1.5.1 Implementation Note describes a scenario in which
issuing a Secondary Bus Reset on a CXL Downstream Port leaves the
Port Power Management Initialization Complete bit unset when the PCIe
Access Control Service (ACS) Source Validation bit (SV) is enabled on
the Downstream Port. The spec states that another SBR alone will not
facilitate recovery and shows a software recovery sequence.
Implement the sequence by extending cxl_reset_bus_function() to save,
clear, and restore ACS SV and Bus Master Enable (BME) on the Downstream
Port around the SBR with the use of helpers.
The wait inside pci_bridge_secondary_bus_reset() covers the 100 ms
referenced by the spec. The helpers return when ACS SV is not enabled on
the Downstream Port.
Signed-off-by: Fabio M. De Francesco <fabio.m.de.francesco@linux.intel.com>
---
drivers/pci/pci.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8f7cfcc00090..047d3b4508a5 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4930,10 +4930,55 @@ static int pci_reset_bus_function(struct pci_dev *dev, bool probe)
return rc;
}
+static void cxl_disable_acs_sv_bme(struct pci_dev *bridge, u16 *saved_cmd,
+ u16 *saved_acs_ctrl)
+{
+ if (!bridge->acs_cap)
+ return;
+
+ pci_read_config_word(bridge, bridge->acs_cap + PCI_ACS_CTRL,
+ saved_acs_ctrl);
+ if (!(*saved_acs_ctrl & PCI_ACS_SV))
+ return;
+
+ pci_read_config_word(bridge, PCI_COMMAND, saved_cmd);
+ if (*saved_cmd & PCI_COMMAND_MASTER)
+ pci_clear_master(bridge);
+
+ pci_write_config_word(bridge, bridge->acs_cap + PCI_ACS_CTRL,
+ *saved_acs_ctrl & ~PCI_ACS_SV);
+}
+
+static void cxl_restore_acs_sv_bme(struct pci_dev *bridge, u16 saved_cmd,
+ u16 saved_acs_ctrl)
+{
+ if (!bridge->acs_cap || !(saved_acs_ctrl & PCI_ACS_SV))
+ return;
+
+ pci_write_config_word(bridge, bridge->acs_cap + PCI_ACS_CTRL,
+ saved_acs_ctrl);
+ if (saved_cmd & PCI_COMMAND_MASTER)
+ pci_set_master(bridge);
+}
+
+/**
+ * cxl_reset_bus_function - SBR for a child of a CXL downstream port
+ * @dev: child device whose upstream bridge is a CXL downstream port
+ * @probe: if true, only check whether the reset is supported
+ *
+ * Issues an SBR on @dev's parent bus. Temporarily sets the CXL Port
+ * DVSEC Unmask SBR bit across the reset. When ACS Source Validation
+ * is enabled on the bridge, also temporarily clears Bus Master Enable
+ * and ACS Source Validation, per CXL r4.0 sec 8.1.5.1.
+ *
+ * Return: 0 on success, -ENOTTY if the reset cannot be issued, or an
+ * errno from the reset path.
+ */
static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
{
struct pci_dev *bridge;
u16 dvsec, reg, val;
+ u16 saved_cmd = 0, saved_acs_ctrl = 0;
int rc;
bridge = pci_upstream_bridge(dev);
@@ -4957,6 +5002,8 @@ static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
return rc;
}
+ cxl_disable_acs_sv_bme(bridge, &saved_cmd, &saved_acs_ctrl);
+
if (reg & PCI_DVSEC_CXL_PORT_CTL_UNMASK_SBR) {
val = reg;
} else {
@@ -4971,6 +5018,8 @@ static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
pci_write_config_word(bridge, dvsec + PCI_DVSEC_CXL_PORT_CTL,
reg);
+ cxl_restore_acs_sv_bme(bridge, saved_cmd, saved_acs_ctrl);
+
pci_dev_reset_iommu_done(dev);
return rc;
}
--
2.53.0
next prev parent reply other threads:[~2026-04-28 18:25 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-28 18:24 Fabio M. De Francesco
2026-04-28 18:24 ` Fabio M. De Francesco [this message]
2026-05-01 18:36 ` [PATCH 1/2] PCI/CXL: Allow PM Init to complete on cxl_bus reset if ACS SV enabled Dave Jiang
2026-04-28 18:24 ` [PATCH 2/2] cxl/core: Recover from PM Init failure via cxl_reset_bus_function() Fabio M. De Francesco
2026-05-01 21:59 ` Dave Jiang
2026-05-06 5:54 ` Alison Schofield
2026-05-01 22:01 ` 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=20260428182454.464655-2-fabio.m.de.francesco@linux.intel.com \
--to=fabio.m.de.francesco@linux.intel.com \
--cc=alison.schofield@intel.com \
--cc=bhelgaas@google.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=ira.weiny@intel.com \
--cc=jonathan.cameron@huawei.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox