| From 54375f0b608e98a0591ba15120897c32deb670e1 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 29 Jan 2026 18:52:32 +0100 |
| Subject: PCI: Initialize RCB from pci_configure_device() |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Håkon Bugge <haakon.bugge@oracle.com> |
| |
| [ Upstream commit 1a6845aaa6de81f95959b380b45de8f10d6a8502 ] |
| |
| 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: e42010d8207f ("PCI: Set Read Completion Boundary to 128 iff Root Port supports it (_HPX)") |
| Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com> |
| Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> |
| Link: https://patch.msgid.link/20260129175237.727059-2-haakon.bugge@oracle.com |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/pci/probe.c | 32 ++++++++++++++++++++++++++++++++ |
| 1 file changed, 32 insertions(+) |
| |
| diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c |
| index 9b277a91d0cb4..e51a5c38739a4 100644 |
| --- a/drivers/pci/probe.c |
| +++ b/drivers/pci/probe.c |
| @@ -2288,6 +2288,37 @@ 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); |
| @@ -2296,6 +2327,7 @@ static void pci_configure_device(struct pci_dev *dev) |
| pci_configure_ltr(dev); |
| pci_configure_eetlp_prefix(dev); |
| pci_configure_serr(dev); |
| + pci_configure_rcb(dev); |
| |
| pci_acpi_program_hp_params(dev); |
| } |
| -- |
| 2.51.0 |
| |