[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260129175237.727059-2-haakon.bugge@oracle.com>
Date: Thu, 29 Jan 2026 18:52:32 +0100
From: Håkon Bugge <haakon.bugge@...cle.com>
To: Bjorn Helgaas <bhelgaas@...gle.com>,
Niklas Schnelle <schnelle@...ux.ibm.com>
Cc: Alex Williamson <alex@...zbot.org>,
Johannes Thumshirn <morbidrsa@...il.com>, linux-pci@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-acpi@...r.kernel.org,
Håkon Bugge <haakon.bugge@...cle.com>
Subject: [PATCH v4 1/2] PCI: Initialize RCB from pci_configure_device()
Commit e42010d8207f ("PCI: Set Read Completion Boundary to 128 iff
Root Port supports it (_HPX)") worked around a bogus _HPX type 2
record, which caused program_hpx_type2() to set the RCB in an endpoint
even though the Root Port did not have the RCB bit set.
e42010d8207f fixed that by setting the RCB in the endpoint only when
it was set in the Root Port.
In retrospect, program_hpx_type2() is intended for AER-related
settings, and the RCB should be configured elsewhere so it doesn't
depend on the presence or contents of an _HPX record.
Explicitly program the RCB from pci_configure_device() so it matches
the Root Port's RCB. The Root Port may not be visible to virtualized
guests; in that case, leave RCB alone.
Fixes: Commit e42010d8207f ("PCI: Set Read Completion Boundary to 128 iff Root Port supports it (_HPX)")
Signed-off-by: Håkon Bugge <haakon.bugge@...cle.com>
---
v3 -> v4:
* Use open coding to read the Root Port's RCB
* Remove info log
v2 -> v3:
* Qualified the device types more strictly
* s/pcie_root_rcb_set/pcie_read_root_rcb/ and changed signature
* Do nothing if the RP's RCB cannot be determined
* Reset the device's RCB if not set in the RP
---
drivers/pci/probe.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 41183aed8f5d9..460f8af1c3429 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2410,6 +2410,38 @@ static void pci_configure_serr(struct pci_dev *dev)
}
}
+static void pci_configure_rcb(struct pci_dev *dev)
+{
+ struct pci_dev *rp;
+ u16 rp_lnkctl;
+
+ /*
+ * Per PCIe r7.0, sec 7.5.3.7, RCB is only meaningful in Root
+ * Ports (where it is read-only), Endpoints, and Bridges. It
+ * may only be set for Endpoints and Bridges if it is set in
+ * the Root Port. For Endpoints, it is 'RsvdP' for Virtual
+ * Functions.
+ */
+ if (!pci_is_pcie(dev) ||
+ pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
+ pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM ||
+ pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||
+ pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC ||
+ dev->is_virtfn)
+ return;
+
+ /* Root Port often not visible to virtualized guests */
+ rp = pcie_find_root_port(dev);
+ if (!rp)
+ return;
+
+ pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &rp_lnkctl);
+ pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_RCB,
+ (rp_lnkctl & PCI_EXP_LNKCTL_RCB) ?
+ PCI_EXP_LNKCTL_RCB : 0);
+}
+
static void pci_configure_device(struct pci_dev *dev)
{
pci_configure_mps(dev);
@@ -2419,6 +2451,7 @@ static void pci_configure_device(struct pci_dev *dev)
pci_configure_aspm_l1ss(dev);
pci_configure_eetlp_prefix(dev);
pci_configure_serr(dev);
+ pci_configure_rcb(dev);
pci_acpi_program_hp_params(dev);
}
--
2.43.5
Powered by blists - more mailing lists