public inbox for linux-pci@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2
@ 2026-01-29 17:52 Håkon Bugge
  2026-01-29 17:52 ` [PATCH v4 1/2] PCI: Initialize RCB from pci_configure_device() Håkon Bugge
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Håkon Bugge @ 2026-01-29 17:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Niklas Schnelle
  Cc: Alex Williamson, Johannes Thumshirn, linux-pci, linux-kernel,
	linux-acpi

This series add the initialization of the Link Control register's RCB
to pci_configure_rcb() called from pci_configure_device() and also
cleans up the incorrect program_hpx_type2():

1. It should only be called when we own the PCIe native hotplug and
   not the AER ownership
2. It should only manipulate the AER-bits

In addition, the second commit adds a warning if the _HPX type2
record attempts to modify the Link Control register.

The programming of the device's RCB is constrained to the device types
where it is applicable and also skips VFs. If the Root Port's RCB
cannot be determined, we also skip the programming of the device's
RCB.

Then, we program the device's RCB according to the Root Port's setting.

Håkon Bugge (2):
  PCI: Initialize RCB from pci_configure_device()
  PCI/ACPI: Restrict program_hpx_type2() to AER bits

 drivers/pci/pci-acpi.c | 65 ++++++++++++++++++------------------------
 drivers/pci/pci.h      |  3 ++
 drivers/pci/pcie/aer.c |  3 --
 drivers/pci/probe.c    | 33 +++++++++++++++++++++
 4 files changed, 63 insertions(+), 41 deletions(-)

--
2.43.5


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v4 1/2] PCI: Initialize RCB from pci_configure_device()
  2026-01-29 17:52 [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2 Håkon Bugge
@ 2026-01-29 17:52 ` Håkon Bugge
  2026-01-29 17:52 ` [PATCH v4 2/2] PCI/ACPI: Restrict program_hpx_type2() to AER bits Håkon Bugge
  2026-01-29 18:50 ` [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2 Bjorn Helgaas
  2 siblings, 0 replies; 5+ messages in thread
From: Håkon Bugge @ 2026-01-29 17:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Niklas Schnelle
  Cc: Alex Williamson, Johannes Thumshirn, linux-pci, linux-kernel,
	linux-acpi, Håkon Bugge

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@oracle.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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v4 2/2] PCI/ACPI: Restrict program_hpx_type2() to AER bits
  2026-01-29 17:52 [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2 Håkon Bugge
  2026-01-29 17:52 ` [PATCH v4 1/2] PCI: Initialize RCB from pci_configure_device() Håkon Bugge
@ 2026-01-29 17:52 ` Håkon Bugge
  2026-01-29 18:50 ` [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2 Bjorn Helgaas
  2 siblings, 0 replies; 5+ messages in thread
From: Håkon Bugge @ 2026-01-29 17:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Niklas Schnelle, Rafael J. Wysocki, Len Brown,
	Mahesh J Salgaonkar, Oliver O'Halloran, Kenji Kaneshige,
	Greg Kroah-Hartman
  Cc: Alex Williamson, Johannes Thumshirn, linux-pci, linux-kernel,
	linux-acpi, Håkon Bugge, linuxppc-dev

Previously program_hpx_type2() applied PCIe settings unconditionally,
which could incorrectly change bits like Extended Tag Field Enable and
Enable Relaxed Ordering.

When _HPX was added to ACPI r3.0, the intent of the PCIe Setting
Record (Type 2) in sec 6.2.7.3 was to configure AER registers when the
OS does not own the AER Capability:

  The PCI Express setting record contains ... [the AER] Uncorrectable
  Error Mask, Uncorrectable Error Severity, Correctable Error Mask
  ... to be used when configuring registers in the Advanced Error
  Reporting Extended Capability Structure ...

  OSPM [1] will only evaluate _HPX with Setting Record – Type 2 if
  OSPM is not controlling the PCI Express Advanced Error Reporting
  capability.

ACPI r3.0b, sec 6.2.7.3, added more AER registers, including registers
in the PCIe Capability with AER-related bits, and the restriction that
the OS use this only when it owns PCIe native hotplug:

  ... when configuring PCI Express registers in the Advanced Error
  Reporting Extended Capability Structure *or PCI Express Capability
  Structure* ...

  An OS that has assumed ownership of native hot plug but does not
  ... have ownership of the AER register set must use ... the Type 2
  record to program the AER registers ...

  However, since the Type 2 record also includes register bits that
  have functions other than AER, the OS must ignore values ... that
  are not applicable.

Restrict program_hpx_type2() to only the intended purpose:

  - Apply settings only when OS owns PCIe native hotplug but not AER,

  - Only touch the AER-related bits (Error Reporting Enables) in Device
    Control

  - Don't touch Link Control at all, since nothing there seems AER-related,
    but log _HPX settings for debugging purposes

Note that Read Completion Boundary is now configured elsewhere, since it is
unrelated to _HPX.

[1] Operating System-directed configuration and Power Management

Fixes: 40abb96c51bb ("[PATCH] pciehp: Fix programming hotplug parameters")
Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>

---

v3 -> v4:
   * Improved commit message
   * Corrected info log when _HPX attempts to modify the Link Control
     register

v2 -> v3:
   * No changes

v1 -> v2:
   * Fixed comment style
   * Simplified the and/or logic when programming the Device Control
     register
   * Fixed the incorrect and brutal warning about Link Control
     register bits set and changed it to an info message about _HPX
     attempting to set/reset bits therein.
   * Removed the RCB programming from program_hpx_type2()
   * Moved the PCI_EXP_AER_FLAGS definition from
     drivers/pci/pcie/aer.c to drivers/pci/pci.h
---
 drivers/pci/pci-acpi.c | 58 +++++++++++++++++-------------------------
 drivers/pci/pci.h      |  3 +++
 drivers/pci/pcie/aer.c |  3 ---
 3 files changed, 27 insertions(+), 37 deletions(-)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 9369377725fa0..3ffceaa7603c0 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -271,21 +271,6 @@ static acpi_status decode_type1_hpx_record(union acpi_object *record,
 	return AE_OK;
 }
 
-static bool pcie_root_rcb_set(struct pci_dev *dev)
-{
-	struct pci_dev *rp = pcie_find_root_port(dev);
-	u16 lnkctl;
-
-	if (!rp)
-		return false;
-
-	pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &lnkctl);
-	if (lnkctl & PCI_EXP_LNKCTL_RCB)
-		return true;
-
-	return false;
-}
-
 /* _HPX PCI Express Setting Record (Type 2) */
 struct hpx_type2 {
 	u32 revision;
@@ -311,6 +296,7 @@ static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
 {
 	int pos;
 	u32 reg32;
+	const struct pci_host_bridge *host;
 
 	if (!hpx)
 		return;
@@ -318,6 +304,15 @@ static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
 	if (!pci_is_pcie(dev))
 		return;
 
+	host = pci_find_host_bridge(dev->bus);
+
+	/*
+	 * We only do the HP programming if we own the PCIe native
+	 * hotplug and not the AER ownership
+	 */
+	if (!host->native_pcie_hotplug || host->native_aer)
+		return;
+
 	if (hpx->revision > 1) {
 		pci_warn(dev, "PCIe settings rev %d not supported\n",
 			 hpx->revision);
@@ -325,33 +320,28 @@ static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
 	}
 
 	/*
-	 * Don't allow _HPX to change MPS or MRRS settings.  We manage
-	 * those to make sure they're consistent with the rest of the
+	 * We only allow _HPX to program the AER registers, namely
+	 * PCI_EXP_DEVCTL_CERE, PCI_EXP_DEVCTL_NFERE,
+	 * PCI_EXP_DEVCTL_FERE, and PCI_EXP_DEVCTL_URRE.
+	 *
+	 * The other settings in PCIe DEVCTL are managed by OS in
+	 * order to make sure they're consistent with the rest of the
 	 * platform.
 	 */
-	hpx->pci_exp_devctl_and |= PCI_EXP_DEVCTL_PAYLOAD |
-				    PCI_EXP_DEVCTL_READRQ;
-	hpx->pci_exp_devctl_or &= ~(PCI_EXP_DEVCTL_PAYLOAD |
-				    PCI_EXP_DEVCTL_READRQ);
+	hpx->pci_exp_devctl_and |= ~PCI_EXP_AER_FLAGS;
+	hpx->pci_exp_devctl_or &= PCI_EXP_AER_FLAGS;
 
 	/* Initialize Device Control Register */
 	pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
 			~hpx->pci_exp_devctl_and, hpx->pci_exp_devctl_or);
 
-	/* Initialize Link Control Register */
+	/* Log if _HPX attempts to modify PCIe Link Control register */
 	if (pcie_cap_has_lnkctl(dev)) {
-
-		/*
-		 * If the Root Port supports Read Completion Boundary of
-		 * 128, set RCB to 128.  Otherwise, clear it.
-		 */
-		hpx->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
-		hpx->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
-		if (pcie_root_rcb_set(dev))
-			hpx->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
-
-		pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
-			~hpx->pci_exp_lnkctl_and, hpx->pci_exp_lnkctl_or);
+		if (hpx->pci_exp_lnkctl_and != 0xffff ||
+		    hpx->pci_exp_lnkctl_or != 0)
+			pci_info(dev, "_HPX attempts Link Control setting (AND %#06x OR %#06x)\n",
+				 hpx->pci_exp_lnkctl_and,
+				 hpx->pci_exp_lnkctl_or);
 	}
 
 	/* Find Advanced Error Reporting Enhanced Capability */
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 0e67014aa0013..f388d4414dd3a 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -88,6 +88,9 @@ struct pcie_tlp_log;
 #define PCI_BUS_BRIDGE_MEM_WINDOW	1
 #define PCI_BUS_BRIDGE_PREF_MEM_WINDOW	2
 
+#define	PCI_EXP_AER_FLAGS	(PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
+				 PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
+
 extern const unsigned char pcie_link_speed[];
 extern bool pci_early_dump;
 
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index e0bcaa896803c..9472d86cef552 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -239,9 +239,6 @@ void pcie_ecrc_get_policy(char *str)
 }
 #endif	/* CONFIG_PCIE_ECRC */
 
-#define	PCI_EXP_AER_FLAGS	(PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
-				 PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
-
 int pcie_aer_is_native(struct pci_dev *dev)
 {
 	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2
  2026-01-29 17:52 [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2 Håkon Bugge
  2026-01-29 17:52 ` [PATCH v4 1/2] PCI: Initialize RCB from pci_configure_device() Håkon Bugge
  2026-01-29 17:52 ` [PATCH v4 2/2] PCI/ACPI: Restrict program_hpx_type2() to AER bits Håkon Bugge
@ 2026-01-29 18:50 ` Bjorn Helgaas
  2026-01-30 16:54   ` Haakon Bugge
  2 siblings, 1 reply; 5+ messages in thread
From: Bjorn Helgaas @ 2026-01-29 18:50 UTC (permalink / raw)
  To: Håkon Bugge
  Cc: Bjorn Helgaas, Niklas Schnelle, Alex Williamson,
	Johannes Thumshirn, linux-pci, linux-kernel, linux-acpi

On Thu, Jan 29, 2026 at 06:52:31PM +0100, Håkon Bugge wrote:
> This series add the initialization of the Link Control register's RCB
> to pci_configure_rcb() called from pci_configure_device() and also
> cleans up the incorrect program_hpx_type2():
> 
> 1. It should only be called when we own the PCIe native hotplug and
>    not the AER ownership
> 2. It should only manipulate the AER-bits
> 
> In addition, the second commit adds a warning if the _HPX type2
> record attempts to modify the Link Control register.
> 
> The programming of the device's RCB is constrained to the device types
> where it is applicable and also skips VFs. If the Root Port's RCB
> cannot be determined, we also skip the programming of the device's
> RCB.
> 
> Then, we program the device's RCB according to the Root Port's setting.
> 
> Håkon Bugge (2):
>   PCI: Initialize RCB from pci_configure_device()
>   PCI/ACPI: Restrict program_hpx_type2() to AER bits
> 
>  drivers/pci/pci-acpi.c | 65 ++++++++++++++++++------------------------
>  drivers/pci/pci.h      |  3 ++
>  drivers/pci/pcie/aer.c |  3 --
>  drivers/pci/probe.c    | 33 +++++++++++++++++++++
>  4 files changed, 63 insertions(+), 41 deletions(-)

Applied to pci/enumeration for v6.20.

Thanks for your patience and persistence, I think this all looks great!

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2
  2026-01-29 18:50 ` [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2 Bjorn Helgaas
@ 2026-01-30 16:54   ` Haakon Bugge
  0 siblings, 0 replies; 5+ messages in thread
From: Haakon Bugge @ 2026-01-30 16:54 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Bjorn Helgaas, Niklas Schnelle, Alex Williamson,
	Johannes Thumshirn, linux-pci@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org



> On 29 Jan 2026, at 19:50, Bjorn Helgaas <helgaas@kernel.org> wrote:
> 
> On Thu, Jan 29, 2026 at 06:52:31PM +0100, Håkon Bugge wrote:
>> This series add the initialization of the Link Control register's RCB
>> to pci_configure_rcb() called from pci_configure_device() and also
>> cleans up the incorrect program_hpx_type2():
>> 
>> 1. It should only be called when we own the PCIe native hotplug and
>>   not the AER ownership
>> 2. It should only manipulate the AER-bits
>> 
>> In addition, the second commit adds a warning if the _HPX type2
>> record attempts to modify the Link Control register.
>> 
>> The programming of the device's RCB is constrained to the device types
>> where it is applicable and also skips VFs. If the Root Port's RCB
>> cannot be determined, we also skip the programming of the device's
>> RCB.
>> 
>> Then, we program the device's RCB according to the Root Port's setting.
>> 
>> Håkon Bugge (2):
>>  PCI: Initialize RCB from pci_configure_device()
>>  PCI/ACPI: Restrict program_hpx_type2() to AER bits
>> 
>> drivers/pci/pci-acpi.c | 65 ++++++++++++++++++------------------------
>> drivers/pci/pci.h      |  3 ++
>> drivers/pci/pcie/aer.c |  3 --
>> drivers/pci/probe.c    | 33 +++++++++++++++++++++
>> 4 files changed, 63 insertions(+), 41 deletions(-)
> 
> Applied to pci/enumeration for v6.20.
> 
> Thanks for your patience and persistence, I think this all looks great!

Thank you for your kind words! I must say, that your thorough reviews and excellent suggestions for improvements made it easy for me:-)


Thxs, Håkon



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-01-30 16:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-29 17:52 [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2 Håkon Bugge
2026-01-29 17:52 ` [PATCH v4 1/2] PCI: Initialize RCB from pci_configure_device() Håkon Bugge
2026-01-29 17:52 ` [PATCH v4 2/2] PCI/ACPI: Restrict program_hpx_type2() to AER bits Håkon Bugge
2026-01-29 18:50 ` [PATCH v4 0/2] PCI: Init RCB from pci_configure_device and fix program_hpx_type2 Bjorn Helgaas
2026-01-30 16:54   ` Haakon Bugge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox