mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v13 0/5] Simplify PCIe native ownership
@ 2026-09-19 16:26 Kuppuswamy Sathyanarayanan
  2026-09-19 16:26 ` [PATCH v13 1/5] PCI/DPC: Ignore devices with no AER Capability Kuppuswamy Sathyanarayanan
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-19 16:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-pci, linux-acpi, linux-kernel, Rafael J Wysocki,
	Guixin Liu, Olof Johansson

This revives Bjorn's v12 from November 2020, rebased onto v7.3-rc3.

  https://lore.kernel.org/all/20201126011816.711106-1-helgaas@kernel.org/

The goal is unchanged.  Decide who owns each PCIe port service in one
place, when we interpret the _OSC results in acpi_pci_root_create(), so
that everywhere else only has to look at host_bridge->native_X.  For AER
specifically, host_bridge->native_aer becomes the single answer to the
question "may Linux touch the AER Capability?".  Today callers each have
to remember to also test pcie_ports_native and pci_aer_available().

I posted v11.  Bjorn took it over at v12, split the _OSC changes in two
and deferred the "pcie_ports=dpc-native" work.  The v12 review comments
were agreed but never respun, and the series stalled.  v13 is that
respin.  Each patch carries its own changelog.

  https://lore.kernel.org/r/cover.1603766889.git.sathyanarayanan.kuppuswamy@linux.intel.com

Bjorn suggested reviving it in response to Guixin Liu's report that
"pcie_ports=native" no longer enables DPC.  The DPC service binds on
host_bridge->native_aer, and that flag did not reflect the command line,
so DPC stayed off when firmware retained AER control.  Patch 4 fixes it
by making the flag reflect it.

  https://lore.kernel.org/linux-pci/20260901064554.2178688-1-kanie@linux.alibaba.com/

Patch 4 has a side effect worth calling out.  drivers/cxl/core/ras.c did
not exist in 2020 and tests host_bridge->native_aer with no
pcie_ports_native fallback, so it has been quietly ignoring
"pcie_ports=native".  Centralizing the check fixes that.

Two things are left for later, to keep this series a cleanup.

 * pci_aer_available() stays in the DPC arm of
   get_port_device_capability(), because "pcie_ports=dpc-native" still
   needs it there.
 * We still gate the DPC service on native_aer and ignore
   OSC_PCI_EXPRESS_DPC_CONTROL, as Bjorn noted in the v12 cover letter.
   Fixing it changes behavior, so it wants its own patch.

Bjorn Helgaas (2):
  PCI/DPC: Ignore devices with no AER Capability
  PCI: Centralize pci_aer_available() checking

Kuppuswamy Sathyanarayanan (3):
  PCI: Assume control of portdrv-related features only when portdrv
    enabled
  PCI/ACPI: Tidy _OSC control bit checking
  PCI/ACPI: Centralize pcie_ports_native checking

 drivers/acpi/pci_root.c           | 73 ++++++++++++++++++++++++-------
 drivers/pci/hotplug/pciehp_core.c |  2 +-
 drivers/pci/pci-acpi.c            |  3 --
 drivers/pci/pcie/aer.c            |  6 +--
 drivers/pci/pcie/aer_cxl_rch.c    |  2 +-
 drivers/pci/pcie/dpc.c            |  3 ++
 drivers/pci/pcie/err.c            |  2 +-
 drivers/pci/pcie/portdrv.c        |  7 ++-
 drivers/pci/probe.c               |  8 ++--
 9 files changed, 75 insertions(+), 31 deletions(-)


base-commit: fd73f4a6659897191fa0d40695fe370925dd3780
-- 
2.43.0


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

* [PATCH v13 1/5] PCI/DPC: Ignore devices with no AER Capability
  2026-09-19 16:26 [PATCH v13 0/5] Simplify PCIe native ownership Kuppuswamy Sathyanarayanan
@ 2026-09-19 16:26 ` Kuppuswamy Sathyanarayanan
  2026-09-20  6:11   ` Lukas Wunner
  2026-09-19 16:26 ` [PATCH v13 2/5] PCI: Assume control of portdrv-related features only when portdrv enabled Kuppuswamy Sathyanarayanan
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-19 16:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-pci, linux-acpi, linux-kernel, Rafael J Wysocki,
	Guixin Liu, Olof Johansson

From: Bjorn Helgaas <bhelgaas@google.com>

Downstream Ports may support DPC regardless of whether they support AER
(see PCIe r7.0, sec 6.2.11.2).  Previously, if the user booted with
"pcie_ports=dpc-native", it was possible for dpc_probe() to succeed even if
the device had no AER Capability, but dpc_get_aer_uncorrect_severity()
depends on the AER Capability.

dpc_probe() previously failed if:

  !pcie_aer_is_native(pdev) && !pcie_ports_dpc_native
  !(pcie_aer_is_native() || pcie_ports_dpc_native)    # by De Morgan's law

so it succeeded if:

  pcie_aer_is_native() || pcie_ports_dpc_native

Fail dpc_probe() if the device has no AER Capability.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Olof Johansson <olof@lixom.net>
---
Changes since v12

 * Rebased to v7.3-rc3.  No other changes.

v12 posting
https://lore.kernel.org/all/20201126011816.711106-1-helgaas@kernel.org/

 drivers/pci/pcie/dpc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 2b779bd1d861..4c2cfae27a08 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -477,6 +477,9 @@ static int dpc_probe(struct pcie_device *dev)
 	int status;
 	u16 cap;
 
+	if (!pdev->aer_cap)
+		return -ENOTSUPP;
+
 	if (!pcie_aer_is_native(pdev) && !pcie_ports_dpc_native)
 		return -ENOTSUPP;
 
-- 
2.43.0


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

* [PATCH v13 2/5] PCI: Assume control of portdrv-related features only when portdrv enabled
  2026-09-19 16:26 [PATCH v13 0/5] Simplify PCIe native ownership Kuppuswamy Sathyanarayanan
  2026-09-19 16:26 ` [PATCH v13 1/5] PCI/DPC: Ignore devices with no AER Capability Kuppuswamy Sathyanarayanan
@ 2026-09-19 16:26 ` Kuppuswamy Sathyanarayanan
  2026-09-20  6:17   ` Lukas Wunner
  2026-09-19 16:26 ` [PATCH v13 3/5] PCI/ACPI: Tidy _OSC control bit checking Kuppuswamy Sathyanarayanan
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-19 16:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-pci, linux-acpi, linux-kernel, Rafael J Wysocki,
	Guixin Liu, Olof Johansson

Native control of PME, AER, DPC, and PCIe hotplug depends on the portdrv,
so default to native handling of them only when CONFIG_PCIEPORTBUS is
enabled.

Native control of LTR and SHPC hotplug does not depend on portdrv, so keep
defaulting those to native regardless.

[bhelgaas: commit log]
Link: https://lore.kernel.org/r/fcbe8a624166a1101a755edfef44a185d32ff493.1603766889.git.sathyanarayanan.kuppuswamy@linux.intel.com
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
Changes since v12

 * Rebased to v7.3-rc3.  No code change.
 * Commit log reworded.  v12 said we can always take control of LTR and
   SHPC hotplug unless a platform interface tells us otherwise, which is
   not true on ACPI systems.

v12 posting
https://lore.kernel.org/all/20201126011816.711106-1-helgaas@kernel.org/

 drivers/pci/probe.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 27008e2ea5af..5f7eb6bc438b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -668,12 +668,14 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge)
 	 * may implement its own AER handling and use _OSC to prevent the
 	 * OS from interfering.
 	 */
+#ifdef CONFIG_PCIEPORTBUS
 	bridge->native_aer = 1;
 	bridge->native_pcie_hotplug = 1;
-	bridge->native_shpc_hotplug = 1;
 	bridge->native_pme = 1;
-	bridge->native_ltr = 1;
 	bridge->native_dpc = 1;
+#endif
+	bridge->native_ltr = 1;
+	bridge->native_shpc_hotplug = 1;
 	bridge->domain_nr = PCI_DOMAIN_NR_NOT_SET;
 	bridge->native_cxl_error = 1;
 	bridge->dev.type = &pci_host_bridge_type;
-- 
2.43.0


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

* [PATCH v13 3/5] PCI/ACPI: Tidy _OSC control bit checking
  2026-09-19 16:26 [PATCH v13 0/5] Simplify PCIe native ownership Kuppuswamy Sathyanarayanan
  2026-09-19 16:26 ` [PATCH v13 1/5] PCI/DPC: Ignore devices with no AER Capability Kuppuswamy Sathyanarayanan
  2026-09-19 16:26 ` [PATCH v13 2/5] PCI: Assume control of portdrv-related features only when portdrv enabled Kuppuswamy Sathyanarayanan
@ 2026-09-19 16:26 ` Kuppuswamy Sathyanarayanan
  2026-09-19 16:26 ` [PATCH v13 4/5] PCI/ACPI: Centralize pcie_ports_native checking Kuppuswamy Sathyanarayanan
  2026-09-19 16:26 ` [PATCH v13 5/5] PCI: Centralize pci_aer_available() checking Kuppuswamy Sathyanarayanan
  4 siblings, 0 replies; 10+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-19 16:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-pci, linux-acpi, linux-kernel, Rafael J Wysocki,
	Guixin Liu, Olof Johansson

Add OSC_OWNER() helper to prettify checking the _OSC control bits to learn
whether the platform has granted us control of PCI features.  No functional
change intended.

[bhelgaas: split to separate patch, commit log]
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
Changes since v12

 * Rebased to v7.3-rc3.  Parenthesized the OSC_OWNER() arguments, as
   checkpatch --strict asks.
 * Also convert native_cxl_error, which v12 left open coded.  Its bit comes
   from the extended control word, so that word gets its own ext_ctrl
   local.

v12 posting
https://lore.kernel.org/all/20201126011816.711106-1-helgaas@kernel.org/

 drivers/acpi/pci_root.c | 37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 88c65f34e305..756dc2f055f5 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -993,6 +993,12 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
 	__acpi_pci_root_release_info(bridge->release_data);
 }
 
+#define OSC_OWNER(ctrl, bit, flag)		\
+	do {					\
+		if (!((ctrl) & (bit)))		\
+			flag = 0;		\
+	} while (0)
+
 struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 				     struct acpi_pci_root_ops *ops,
 				     struct acpi_pci_root_info *info,
@@ -1003,6 +1009,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	int node = acpi_get_node(device->handle);
 	struct pci_bus *bus;
 	struct pci_host_bridge *host_bridge;
+	u32 ctrl, ext_ctrl;
 
 	info->root = root;
 	info->bridge = device;
@@ -1028,21 +1035,21 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 		goto out_release_info;
 
 	host_bridge = to_pci_host_bridge(bus->bridge);
-	if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
-		host_bridge->native_pcie_hotplug = 0;
-	if (!(root->osc_control_set & OSC_PCI_SHPC_NATIVE_HP_CONTROL))
-		host_bridge->native_shpc_hotplug = 0;
-	if (!(root->osc_control_set & OSC_PCI_EXPRESS_AER_CONTROL))
-		host_bridge->native_aer = 0;
-	if (!(root->osc_control_set & OSC_PCI_EXPRESS_PME_CONTROL))
-		host_bridge->native_pme = 0;
-	if (!(root->osc_control_set & OSC_PCI_EXPRESS_LTR_CONTROL))
-		host_bridge->native_ltr = 0;
-	if (!(root->osc_control_set & OSC_PCI_EXPRESS_DPC_CONTROL))
-		host_bridge->native_dpc = 0;
-
-	if (!(root->osc_ext_control_set & OSC_CXL_ERROR_REPORTING_CONTROL))
-		host_bridge->native_cxl_error = 0;
+
+	ctrl = root->osc_control_set;
+	ext_ctrl = root->osc_ext_control_set;
+
+	OSC_OWNER(ctrl, OSC_PCI_EXPRESS_NATIVE_HP_CONTROL,
+		  host_bridge->native_pcie_hotplug);
+	OSC_OWNER(ctrl, OSC_PCI_SHPC_NATIVE_HP_CONTROL,
+		  host_bridge->native_shpc_hotplug);
+	OSC_OWNER(ctrl, OSC_PCI_EXPRESS_AER_CONTROL, host_bridge->native_aer);
+	OSC_OWNER(ctrl, OSC_PCI_EXPRESS_PME_CONTROL, host_bridge->native_pme);
+	OSC_OWNER(ctrl, OSC_PCI_EXPRESS_LTR_CONTROL, host_bridge->native_ltr);
+	OSC_OWNER(ctrl, OSC_PCI_EXPRESS_DPC_CONTROL, host_bridge->native_dpc);
+
+	OSC_OWNER(ext_ctrl, OSC_CXL_ERROR_REPORTING_CONTROL,
+		  host_bridge->native_cxl_error);
 
 	acpi_dev_power_up_children_with_adr(device);
 
-- 
2.43.0


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

* [PATCH v13 4/5] PCI/ACPI: Centralize pcie_ports_native checking
  2026-09-19 16:26 [PATCH v13 0/5] Simplify PCIe native ownership Kuppuswamy Sathyanarayanan
                   ` (2 preceding siblings ...)
  2026-09-19 16:26 ` [PATCH v13 3/5] PCI/ACPI: Tidy _OSC control bit checking Kuppuswamy Sathyanarayanan
@ 2026-09-19 16:26 ` Kuppuswamy Sathyanarayanan
  2026-09-20  7:24   ` Guixin Liu
  2026-09-19 16:26 ` [PATCH v13 5/5] PCI: Centralize pci_aer_available() checking Kuppuswamy Sathyanarayanan
  4 siblings, 1 reply; 10+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-19 16:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-pci, linux-acpi, linux-kernel, Rafael J Wysocki,
	Guixin Liu, Olof Johansson

If the user booted with "pcie_ports=native", we take control of the PCIe
port services unconditionally, regardless of what _OSC says.

Centralize the testing of pcie_ports_native in acpi_pci_root_create(),
where we interpret the _OSC results, so other places only have to check
host_bridge->native_X and we don't have to sprinkle tests of
pcie_ports_native everywhere.

Rather than overriding the host_bridge->native_X flags after the fact,
fold "pcie_ports=native" into the _OSC control mask we evaluate, i.e.,
proceed as though the platform had granted control of the port services.
That way there is a single mechanism deciding each native_X flag, and we
can report exactly which features we are overriding _OSC for instead of
just noting that we are overriding something:

  acpi PNP0A08:00: _OSC: OS forcing control ("pcie_ports=native") of [PCIeHotplug PME AER DPC]

This also extends "pcie_ports=native" to host_bridge->native_dpc, which
had no pcie_ports_native fallback before.  The effect is narrow.
native_dpc is only used by pci_dpc_recovered(), and only when
CONFIG_PCIE_EDR=n, where hotplug now waits for firmware-owned DPC
recovery.

host_bridge->native_ltr is deliberately not forced.  "pcie_ports="
controls PCIe port services and LTR is not one.  There is no
PCIE_PORT_SERVICE_LTR, and native_ltr is only used by
pci_configure_ltr() to enable ASPM L1.2, so forcing it would be an ASPM
policy decision users did not ask for.

SHPC hotplug is left alone for a simpler reason: SHPC is a conventional
PCI feature rather than a PCIe one, so "pcie_ports=" has no bearing on
it.

[bhelgaas: commit log, rework OSC_PCIE_PORT_SERVICE_CONTROLS, logging]
Link: https://lore.kernel.org/r/bc87c9e675118960949043a832bed86bc22becbd.1603766889.git.sathyanarayanan.kuppuswamy@linux.intel.com
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
Changes since v12

 * Rebased to v7.3-rc3.
 * Fold "pcie_ports=native" into the _OSC control mask instead of
   overriding the native_X flags afterwards, and report which features we
   override, as agreed in the v12 review.
 * Do not force native_ltr, which v12 did.  LTR is not a PCIe port
   service, so "pcie_ports=" should not affect it.

v12 posting
https://lore.kernel.org/all/20201126011816.711106-1-helgaas@kernel.org/

 drivers/acpi/pci_root.c           | 36 +++++++++++++++++++++++++++++++
 drivers/pci/hotplug/pciehp_core.c |  2 +-
 drivers/pci/pci-acpi.c            |  3 ---
 drivers/pci/pcie/aer.c            |  6 +++---
 drivers/pci/pcie/aer_cxl_rch.c    |  2 +-
 drivers/pci/pcie/err.c            |  2 +-
 drivers/pci/pcie/portdrv.c        |  6 +++---
 7 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 756dc2f055f5..2494811dd69b 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -999,6 +999,19 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
 			flag = 0;		\
 	} while (0)
 
+#define FLAG(x)		((x) ? '+' : '-')
+
+/*
+ * _OSC control bits for the features implemented by the PCIe port driver,
+ * i.e., the ones "pcie_ports=native" applies to.  LTR and SHPC hotplug are
+ * negotiated via _OSC as well, but they are not portdrv services, so
+ * "pcie_ports=" has no bearing on them.
+ */
+#define OSC_PCIE_PORT_SERVICE_CONTROLS	(OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \
+					 OSC_PCI_EXPRESS_PME_CONTROL | \
+					 OSC_PCI_EXPRESS_AER_CONTROL | \
+					 OSC_PCI_EXPRESS_DPC_CONTROL)
+
 struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 				     struct acpi_pci_root_ops *ops,
 				     struct acpi_pci_root_info *info,
@@ -1039,6 +1052,21 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	ctrl = root->osc_control_set;
 	ext_ctrl = root->osc_ext_control_set;
 
+	/*
+	 * If the user specified "pcie_ports=native", use the PCIe port
+	 * services regardless of what _OSC says, i.e., proceed as though the
+	 * platform had granted us control of them.  This may conflict with
+	 * firmware that expects to own those features.
+	 */
+	if (pcie_ports_native) {
+		u32 override = OSC_PCIE_PORT_SERVICE_CONTROLS & ~ctrl;
+
+		if (override)
+			decode_osc_control(root, "OS forcing control (\"pcie_ports=native\") of",
+					   override);
+		ctrl |= override;
+	}
+
 	OSC_OWNER(ctrl, OSC_PCI_EXPRESS_NATIVE_HP_CONTROL,
 		  host_bridge->native_pcie_hotplug);
 	OSC_OWNER(ctrl, OSC_PCI_SHPC_NATIVE_HP_CONTROL,
@@ -1051,6 +1079,14 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	OSC_OWNER(ext_ctrl, OSC_CXL_ERROR_REPORTING_CONTROL,
 		  host_bridge->native_cxl_error);
 
+	dev_info(&root->device->dev, "OS native features: SHPCHotplug%c PCIeHotplug%c PME%c AER%c DPC%c LTR%c\n",
+		 FLAG(host_bridge->native_shpc_hotplug),
+		 FLAG(host_bridge->native_pcie_hotplug),
+		 FLAG(host_bridge->native_pme),
+		 FLAG(host_bridge->native_aer),
+		 FLAG(host_bridge->native_dpc),
+		 FLAG(host_bridge->native_ltr));
+
 	acpi_dev_power_up_children_with_adr(device);
 
 	pci_scan_child_bus(bus);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 2cafd3b26f34..b42829cf1377 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -258,7 +258,7 @@ static bool pme_is_native(struct pcie_device *dev)
 	const struct pci_host_bridge *host;
 
 	host = pci_find_host_bridge(dev->port->bus);
-	return pcie_ports_native || host->native_pme;
+	return host->native_pme;
 }
 
 static void pciehp_disable_interrupt(struct pcie_device *dev)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 42d545edd7fa..1150f2fbabf4 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -812,9 +812,6 @@ bool pciehp_is_native(struct pci_dev *bridge)
 	if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
 		return false;
 
-	if (pcie_ports_native)
-		return true;
-
 	host = pci_find_host_bridge(bridge->bus);
 	return host->native_pcie_hotplug;
 }
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index d8dcd238fda1..e84dd686582a 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -260,7 +260,7 @@ int pcie_aer_is_native(struct pci_dev *dev)
 	if (!dev->aer_cap)
 		return 0;
 
-	return pcie_ports_native || host->native_aer;
+	return host->native_aer;
 }
 EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, "CXL");
 
@@ -1847,7 +1847,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
 	 */
 	aer = root ? root->aer_cap : 0;
 
-	if ((host->native_aer || pcie_ports_native) && aer)
+	if (host->native_aer && aer)
 		aer_disable_irq(root);
 
 	if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) {
@@ -1862,7 +1862,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
 			pci_is_root_bus(dev->bus) ? "Root" : "Downstream", rc);
 	}
 
-	if ((host->native_aer || pcie_ports_native) && aer) {
+	if (host->native_aer && aer) {
 		/* Clear Root Error Status */
 		pci_read_config_dword(root, aer + PCI_ERR_ROOT_STATUS, &reg32);
 		pci_write_config_dword(root, aer + PCI_ERR_ROOT_STATUS, reg32);
diff --git a/drivers/pci/pcie/aer_cxl_rch.c b/drivers/pci/pcie/aer_cxl_rch.c
index e471eefec9c4..b480dad8bbf4 100644
--- a/drivers/pci/pcie/aer_cxl_rch.c
+++ b/drivers/pci/pcie/aer_cxl_rch.c
@@ -31,7 +31,7 @@ static bool cxl_error_is_native(struct pci_dev *dev)
 {
 	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
 
-	return (pcie_ports_native || host->native_aer);
+	return host->native_aer;
 }
 
 static int cxl_rch_handle_error_iter(struct pci_dev *dev, void *data)
diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index d77403d8855b..1a7fc71c79d8 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -273,7 +273,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
 	 * it is responsible for clearing this status.  In that case, the
 	 * signaling device may not even be visible to the OS.
 	 */
-	if (host->native_aer || pcie_ports_native) {
+	if (host->native_aer) {
 		pcie_clear_device_status(dev);
 		pci_aer_clear_nonfatal_status(dev);
 	}
diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index a9cbfc1d2bc7..32fc623dd410 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -223,7 +223,7 @@ static int get_port_device_capability(struct pci_dev *dev)
 	if (dev->is_pciehp &&
 	    (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
 	     pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) &&
-	    (pcie_ports_native || host->native_pcie_hotplug)) {
+	    host->native_pcie_hotplug) {
 		services |= PCIE_PORT_SERVICE_HP;
 
 		/*
@@ -240,14 +240,14 @@ static int get_port_device_capability(struct pci_dev *dev)
 	if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
              pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
 	    dev->aer_cap && pci_aer_available() &&
-	    (pcie_ports_native || host->native_aer))
+	    host->native_aer)
 		services |= PCIE_PORT_SERVICE_AER;
 #endif
 
 	/* Root Ports and Root Complex Event Collectors may generate PMEs */
 	if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
 	     pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
-	    (pcie_ports_native || host->native_pme)) {
+	    host->native_pme) {
 		services |= PCIE_PORT_SERVICE_PME;
 
 		/*
-- 
2.43.0


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

* [PATCH v13 5/5] PCI: Centralize pci_aer_available() checking
  2026-09-19 16:26 [PATCH v13 0/5] Simplify PCIe native ownership Kuppuswamy Sathyanarayanan
                   ` (3 preceding siblings ...)
  2026-09-19 16:26 ` [PATCH v13 4/5] PCI/ACPI: Centralize pcie_ports_native checking Kuppuswamy Sathyanarayanan
@ 2026-09-19 16:26 ` Kuppuswamy Sathyanarayanan
  4 siblings, 0 replies; 10+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-19 16:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-pci, linux-acpi, linux-kernel, Rafael J Wysocki,
	Guixin Liu, Olof Johansson

From: Bjorn Helgaas <bhelgaas@google.com>

"pci=noaer" tells us not to use AER.  pci_aer_available() reports that,
and it also reports the other cases where the OS cannot use AER at all,
namely CONFIG_PCIEAER=n and MSI being unavailable.

Set host_bridge->native_aer from pci_aer_available() when we initialize
the host bridge, so callers only have to look at native_aer and we do not
have to test pci_aer_available() separately in each of them.

Do this in pci_init_host_bridge() rather than in acpi_pci_root_create()
so it also covers host bridges that are not described by ACPI and never
reach acpi_pci_root_create().

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Co-developed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
Changes since v12

 * Rebased to v7.3-rc3.
 * Set native_aer from pci_aer_available() in pci_init_host_bridge()
   rather than clearing it in acpi_pci_root_create(), so "pci=noaer" also
   works on host bridges that ACPI does not describe.
 * pci_aer_available() stays in the DPC arm of
   get_port_device_capability(), where pcie_ports_dpc_native still needs
   it.

v12 posting
https://lore.kernel.org/all/20201126011816.711106-1-helgaas@kernel.org/

 drivers/pci/pcie/portdrv.c | 3 +--
 drivers/pci/probe.c        | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index 32fc623dd410..9f8c6dd434c5 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -239,8 +239,7 @@ static int get_port_device_capability(struct pci_dev *dev)
 #ifdef CONFIG_PCIEAER
 	if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
              pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
-	    dev->aer_cap && pci_aer_available() &&
-	    host->native_aer)
+	    dev->aer_cap && host->native_aer)
 		services |= PCIE_PORT_SERVICE_AER;
 #endif
 
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5f7eb6bc438b..0429f5671c63 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -669,7 +669,7 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge)
 	 * OS from interfering.
 	 */
 #ifdef CONFIG_PCIEPORTBUS
-	bridge->native_aer = 1;
+	bridge->native_aer = pci_aer_available();
 	bridge->native_pcie_hotplug = 1;
 	bridge->native_pme = 1;
 	bridge->native_dpc = 1;
-- 
2.43.0


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

* Re: [PATCH v13 1/5] PCI/DPC: Ignore devices with no AER Capability
  2026-09-19 16:26 ` [PATCH v13 1/5] PCI/DPC: Ignore devices with no AER Capability Kuppuswamy Sathyanarayanan
@ 2026-09-20  6:11   ` Lukas Wunner
  0 siblings, 0 replies; 10+ messages in thread
From: Lukas Wunner @ 2026-09-20  6:11 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan
  Cc: Bjorn Helgaas, linux-pci, linux-acpi, linux-kernel,
	Rafael J Wysocki, Guixin Liu, Olof Johansson

On Sat, Sep 19, 2026 at 09:26:51AM -0700, Kuppuswamy Sathyanarayanan wrote:
> Downstream Ports may support DPC regardless of whether they support AER
> (see PCIe r7.0, sec 6.2.11.2).  Previously, if the user booted with
> "pcie_ports=dpc-native", it was possible for dpc_probe() to succeed even if
> the device had no AER Capability, but dpc_get_aer_uncorrect_severity()
> depends on the AER Capability.
[...]
> +++ b/drivers/pci/pcie/dpc.c
> @@ -477,6 +477,9 @@ static int dpc_probe(struct pcie_device *dev)
>  	int status;
>  	u16 cap;
>  
> +	if (!pdev->aer_cap)
> +		return -ENOTSUPP;
> +
>  	if (!pcie_aer_is_native(pdev) && !pcie_ports_dpc_native)
>  		return -ENOTSUPP;

I've got patches which make DPC work (again) on AER-unsupporting ports:

  https://github.com/l1k/linux/commits/aer_baseline_v1/

In particular:

  PCI/DPC: Avoid access to non-existent AER capability
  https://github.com/l1k/linux/commit/85f209fd4732

  PCI/DPC: Reinstate support for AER-incapable ports
  https://github.com/l1k/linux/commit/2de89b762d79

I'm almost done with that series and hope to submit it this cycle.
Your patch [1/5] will cause a conflict with my patches.
Would you mind holding off on patch [1/5] for now?

There's another reason:  I know of one product in particular,
Intel "Ponte Vecchio" data center GPUs, which support DPC but
lack an AER capability.  DPC was tested and made to work on
those cards (see 53b54ad074de).

I didn't realize back then but know now that validation engineers
specifically used pcie_ports=dpc-native to be able to use DPC on
that product.  And I believe this was also communicated to customers
as "best known method" for DPC on Ponte Vecchio.  In other words,
using pcie_ports=dpc-native to make DPC work on non-AER-capable products
has become a feature.  Your patch breaks those use cases.

That's why I chose to make DPC work (again) on non-AER-capable products
with the above-linked patches, instead of closing this loophole to
force-enable it.

Thanks,

Lukas

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

* Re: [PATCH v13 2/5] PCI: Assume control of portdrv-related features only when portdrv enabled
  2026-09-19 16:26 ` [PATCH v13 2/5] PCI: Assume control of portdrv-related features only when portdrv enabled Kuppuswamy Sathyanarayanan
@ 2026-09-20  6:17   ` Lukas Wunner
  0 siblings, 0 replies; 10+ messages in thread
From: Lukas Wunner @ 2026-09-20  6:17 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan
  Cc: Bjorn Helgaas, linux-pci, linux-acpi, linux-kernel,
	Rafael J Wysocki, Guixin Liu, Olof Johansson

On Sat, Sep 19, 2026 at 09:26:52AM -0700, Kuppuswamy Sathyanarayanan wrote:
> +++ b/drivers/pci/probe.c
> @@ -668,12 +668,14 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge)
>  	 * may implement its own AER handling and use _OSC to prevent the
>  	 * OS from interfering.
>  	 */
> +#ifdef CONFIG_PCIEPORTBUS
>  	bridge->native_aer = 1;
>  	bridge->native_pcie_hotplug = 1;
> -	bridge->native_shpc_hotplug = 1;
>  	bridge->native_pme = 1;
> -	bridge->native_ltr = 1;
>  	bridge->native_dpc = 1;
> +#endif
> +	bridge->native_ltr = 1;
> +	bridge->native_shpc_hotplug = 1;
>  	bridge->domain_nr = PCI_DOMAIN_NR_NOT_SET;

How about (e.g.)

 	bridge->native_pcie_hotplug = IS_ENABLED(CONFIG_PCIEPORTBUS);

instead of using #ifdef?  That's the preferred style according to
section 21 of Documentation/process/coding-style.rst

>  	bridge->native_cxl_error = 1;

Hm, this one depends on CONFIG_PCIEAER I believe.
(But Terry Bowman is the expert.)

Thanks,

Lukas

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

* Re: [PATCH v13 4/5] PCI/ACPI: Centralize pcie_ports_native checking
  2026-09-19 16:26 ` [PATCH v13 4/5] PCI/ACPI: Centralize pcie_ports_native checking Kuppuswamy Sathyanarayanan
@ 2026-09-20  7:24   ` Guixin Liu
  0 siblings, 0 replies; 10+ messages in thread
From: Guixin Liu @ 2026-09-20  7:24 UTC (permalink / raw)
  To: Kuppuswamy Sathyanarayanan, Bjorn Helgaas
  Cc: linux-pci, linux-acpi, linux-kernel, Rafael J Wysocki, Olof Johansson



在 2026/9/20 00:26, Kuppuswamy Sathyanarayanan 写道:
> If the user booted with "pcie_ports=native", we take control of the PCIe
> port services unconditionally, regardless of what _OSC says.
>
> Centralize the testing of pcie_ports_native in acpi_pci_root_create(),
> where we interpret the _OSC results, so other places only have to check
> host_bridge->native_X and we don't have to sprinkle tests of
> pcie_ports_native everywhere.
>
> Rather than overriding the host_bridge->native_X flags after the fact,
> fold "pcie_ports=native" into the _OSC control mask we evaluate, i.e.,
> proceed as though the platform had granted control of the port services.
> That way there is a single mechanism deciding each native_X flag, and we
> can report exactly which features we are overriding _OSC for instead of
> just noting that we are overriding something:
>
>   acpi PNP0A08:00: _OSC: OS forcing control ("pcie_ports=native") of [PCIeHotplug PME AER DPC]
>
> This also extends "pcie_ports=native" to host_bridge->native_dpc, which
> had no pcie_ports_native fallback before.  The effect is narrow.
> native_dpc is only used by pci_dpc_recovered(), and only when
> CONFIG_PCIE_EDR=n, where hotplug now waits for firmware-owned DPC
> recovery.
>
> host_bridge->native_ltr is deliberately not forced.  "pcie_ports="
> controls PCIe port services and LTR is not one.  There is no
> PCIE_PORT_SERVICE_LTR, and native_ltr is only used by
> pci_configure_ltr() to enable ASPM L1.2, so forcing it would be an ASPM
> policy decision users did not ask for.
>
> SHPC hotplug is left alone for a simpler reason: SHPC is a conventional
> PCI feature rather than a PCIe one, so "pcie_ports=" has no bearing on
> it.
>
> [bhelgaas: commit log, rework OSC_PCIE_PORT_SERVICE_CONTROLS, logging]
> Link: https://lore.kernel.org/r/bc87c9e675118960949043a832bed86bc22becbd.1603766889.git.sathyanarayanan.kuppuswamy@linux.intel.com
> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>、
Should add Fixes: 97ca178c899d ("PCI/DPC: Allow DPC on all Downstream Ports when OS controls AER").

Best Regards,
Guixin Liu
> ---
> Changes since v12
>
>  * Rebased to v7.3-rc3.
>  * Fold "pcie_ports=native" into the _OSC control mask instead of
>    overriding the native_X flags afterwards, and report which features we
>    override, as agreed in the v12 review.
>  * Do not force native_ltr, which v12 did.  LTR is not a PCIe port
>    service, so "pcie_ports=" should not affect it.
>
> v12 posting
> https://lore.kernel.org/all/20201126011816.711106-1-helgaas@kernel.org/
>
>  drivers/acpi/pci_root.c           | 36 +++++++++++++++++++++++++++++++
>  drivers/pci/hotplug/pciehp_core.c |  2 +-
>  drivers/pci/pci-acpi.c            |  3 ---
>  drivers/pci/pcie/aer.c            |  6 +++---
>  drivers/pci/pcie/aer_cxl_rch.c    |  2 +-
>  drivers/pci/pcie/err.c            |  2 +-
>  drivers/pci/pcie/portdrv.c        |  6 +++---
>  7 files changed, 45 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 756dc2f055f5..2494811dd69b 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -999,6 +999,19 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
>  			flag = 0;		\
>  	} while (0)
>  
> +#define FLAG(x)		((x) ? '+' : '-')
> +
> +/*
> + * _OSC control bits for the features implemented by the PCIe port driver,
> + * i.e., the ones "pcie_ports=native" applies to.  LTR and SHPC hotplug are
> + * negotiated via _OSC as well, but they are not portdrv services, so
> + * "pcie_ports=" has no bearing on them.
> + */
> +#define OSC_PCIE_PORT_SERVICE_CONTROLS	(OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \
> +					 OSC_PCI_EXPRESS_PME_CONTROL | \
> +					 OSC_PCI_EXPRESS_AER_CONTROL | \
> +					 OSC_PCI_EXPRESS_DPC_CONTROL)
> +
>  struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>  				     struct acpi_pci_root_ops *ops,
>  				     struct acpi_pci_root_info *info,
> @@ -1039,6 +1052,21 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>  	ctrl = root->osc_control_set;
>  	ext_ctrl = root->osc_ext_control_set;
>  
> +	/*
> +	 * If the user specified "pcie_ports=native", use the PCIe port
> +	 * services regardless of what _OSC says, i.e., proceed as though the
> +	 * platform had granted us control of them.  This may conflict with
> +	 * firmware that expects to own those features.
> +	 */
> +	if (pcie_ports_native) {
> +		u32 override = OSC_PCIE_PORT_SERVICE_CONTROLS & ~ctrl;
> +
> +		if (override)
> +			decode_osc_control(root, "OS forcing control (\"pcie_ports=native\") of",
> +					   override);
> +		ctrl |= override;
> +	}
> +
>  	OSC_OWNER(ctrl, OSC_PCI_EXPRESS_NATIVE_HP_CONTROL,
>  		  host_bridge->native_pcie_hotplug);
>  	OSC_OWNER(ctrl, OSC_PCI_SHPC_NATIVE_HP_CONTROL,
> @@ -1051,6 +1079,14 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>  	OSC_OWNER(ext_ctrl, OSC_CXL_ERROR_REPORTING_CONTROL,
>  		  host_bridge->native_cxl_error);
>  
> +	dev_info(&root->device->dev, "OS native features: SHPCHotplug%c PCIeHotplug%c PME%c AER%c DPC%c LTR%c\n",
> +		 FLAG(host_bridge->native_shpc_hotplug),
> +		 FLAG(host_bridge->native_pcie_hotplug),
> +		 FLAG(host_bridge->native_pme),
> +		 FLAG(host_bridge->native_aer),
> +		 FLAG(host_bridge->native_dpc),
> +		 FLAG(host_bridge->native_ltr));
> +
>  	acpi_dev_power_up_children_with_adr(device);
>  
>  	pci_scan_child_bus(bus);
> diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
> index 2cafd3b26f34..b42829cf1377 100644
> --- a/drivers/pci/hotplug/pciehp_core.c
> +++ b/drivers/pci/hotplug/pciehp_core.c
> @@ -258,7 +258,7 @@ static bool pme_is_native(struct pcie_device *dev)
>  	const struct pci_host_bridge *host;
>  
>  	host = pci_find_host_bridge(dev->port->bus);
> -	return pcie_ports_native || host->native_pme;
> +	return host->native_pme;
>  }
>  
>  static void pciehp_disable_interrupt(struct pcie_device *dev)
> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
> index 42d545edd7fa..1150f2fbabf4 100644
> --- a/drivers/pci/pci-acpi.c
> +++ b/drivers/pci/pci-acpi.c
> @@ -812,9 +812,6 @@ bool pciehp_is_native(struct pci_dev *bridge)
>  	if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
>  		return false;
>  
> -	if (pcie_ports_native)
> -		return true;
> -
>  	host = pci_find_host_bridge(bridge->bus);
>  	return host->native_pcie_hotplug;
>  }
> diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
> index d8dcd238fda1..e84dd686582a 100644
> --- a/drivers/pci/pcie/aer.c
> +++ b/drivers/pci/pcie/aer.c
> @@ -260,7 +260,7 @@ int pcie_aer_is_native(struct pci_dev *dev)
>  	if (!dev->aer_cap)
>  		return 0;
>  
> -	return pcie_ports_native || host->native_aer;
> +	return host->native_aer;
>  }
>  EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, "CXL");
>  
> @@ -1847,7 +1847,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
>  	 */
>  	aer = root ? root->aer_cap : 0;
>  
> -	if ((host->native_aer || pcie_ports_native) && aer)
> +	if (host->native_aer && aer)
>  		aer_disable_irq(root);
>  
>  	if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) {
> @@ -1862,7 +1862,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
>  			pci_is_root_bus(dev->bus) ? "Root" : "Downstream", rc);
>  	}
>  
> -	if ((host->native_aer || pcie_ports_native) && aer) {
> +	if (host->native_aer && aer) {
>  		/* Clear Root Error Status */
>  		pci_read_config_dword(root, aer + PCI_ERR_ROOT_STATUS, &reg32);
>  		pci_write_config_dword(root, aer + PCI_ERR_ROOT_STATUS, reg32);
> diff --git a/drivers/pci/pcie/aer_cxl_rch.c b/drivers/pci/pcie/aer_cxl_rch.c
> index e471eefec9c4..b480dad8bbf4 100644
> --- a/drivers/pci/pcie/aer_cxl_rch.c
> +++ b/drivers/pci/pcie/aer_cxl_rch.c
> @@ -31,7 +31,7 @@ static bool cxl_error_is_native(struct pci_dev *dev)
>  {
>  	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
>  
> -	return (pcie_ports_native || host->native_aer);
> +	return host->native_aer;
>  }
>  
>  static int cxl_rch_handle_error_iter(struct pci_dev *dev, void *data)
> diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
> index d77403d8855b..1a7fc71c79d8 100644
> --- a/drivers/pci/pcie/err.c
> +++ b/drivers/pci/pcie/err.c
> @@ -273,7 +273,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
>  	 * it is responsible for clearing this status.  In that case, the
>  	 * signaling device may not even be visible to the OS.
>  	 */
> -	if (host->native_aer || pcie_ports_native) {
> +	if (host->native_aer) {
>  		pcie_clear_device_status(dev);
>  		pci_aer_clear_nonfatal_status(dev);
>  	}
> diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
> index a9cbfc1d2bc7..32fc623dd410 100644
> --- a/drivers/pci/pcie/portdrv.c
> +++ b/drivers/pci/pcie/portdrv.c
> @@ -223,7 +223,7 @@ static int get_port_device_capability(struct pci_dev *dev)
>  	if (dev->is_pciehp &&
>  	    (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
>  	     pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) &&
> -	    (pcie_ports_native || host->native_pcie_hotplug)) {
> +	    host->native_pcie_hotplug) {
>  		services |= PCIE_PORT_SERVICE_HP;
>  
>  		/*
> @@ -240,14 +240,14 @@ static int get_port_device_capability(struct pci_dev *dev)
>  	if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
>               pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
>  	    dev->aer_cap && pci_aer_available() &&
> -	    (pcie_ports_native || host->native_aer))
> +	    host->native_aer)
>  		services |= PCIE_PORT_SERVICE_AER;
>  #endif
>  
>  	/* Root Ports and Root Complex Event Collectors may generate PMEs */
>  	if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
>  	     pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
> -	    (pcie_ports_native || host->native_pme)) {
> +	    host->native_pme) {
>  		services |= PCIE_PORT_SERVICE_PME;
>  
>  		/*


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

* [PATCH v13 4/5] PCI/ACPI: Centralize pcie_ports_native checking
  2021-01-23  1:11 [PATCH v13 0/5] Simplify PCIe native ownership Kuppuswamy Sathyanarayanan
@ 2021-01-23  1:11 ` Kuppuswamy Sathyanarayanan
  0 siblings, 0 replies; 10+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2021-01-23  1:11 UTC (permalink / raw)
  To: bhelgaas; +Cc: linux-pci, linux-kernel, ashok.raj, sathyanarayanan.kuppuswamy

If the user booted with "pcie_ports=native", we take control of the PCIe
features unconditionally, regardless of what _OSC says.

Centralize the testing of pcie_ports_native in acpi_pci_root_create(),
where we interpret the _OSC results, so other places only have to check
host_bridge->native_X and we don't have to sprinkle tests of
pcie_ports_native everywhere.

[bhelgaas: commit log, rework OSC_PCI_EXPRESS_CONTROL_MASKS, logging]
Link: https://lore.kernel.org/r/bc87c9e675118960949043a832bed86bc22becbd.1603766889.git.sathyanarayanan.kuppuswamy@linux.intel.com
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/acpi/pci_root.c           | 19 +++++++++++++++++++
 drivers/pci/hotplug/pciehp_core.c |  2 +-
 drivers/pci/pci-acpi.c            |  3 ---
 drivers/pci/pcie/aer.c            |  2 +-
 drivers/pci/pcie/portdrv_core.c   | 11 ++++-------
 5 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 601fbe905993..16ca58d58fef 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -880,6 +880,8 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
 			flag = 0;	\
 	} while (0)
 
+#define FLAG(x)		((x) ? '+' : '-')
+
 struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 				     struct acpi_pci_root_ops *ops,
 				     struct acpi_pci_root_info *info,
@@ -928,6 +930,23 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	OSC_OWNER(ctrl, OSC_PCI_EXPRESS_LTR_CONTROL, host_bridge->native_ltr);
 	OSC_OWNER(ctrl, OSC_PCI_EXPRESS_DPC_CONTROL, host_bridge->native_dpc);
 
+	if (pcie_ports_native) {
+		dev_info(&root->device->dev, "Taking control of PCIe-related features because \"pcie_ports=native\" specified; may conflict with firmware\n");
+		host_bridge->native_pcie_hotplug = 1;
+		host_bridge->native_aer = 1;
+		host_bridge->native_pme = 1;
+		host_bridge->native_ltr = 1;
+		host_bridge->native_dpc = 1;
+	}
+
+	dev_info(&root->device->dev, "OS native features: SHPCHotplug%c PCIeHotplug%c PME%c AER%c DPC%c LTR%c\n",
+		FLAG(host_bridge->native_shpc_hotplug),
+		FLAG(host_bridge->native_pcie_hotplug),
+		FLAG(host_bridge->native_pme),
+		FLAG(host_bridge->native_aer),
+		FLAG(host_bridge->native_dpc),
+		FLAG(host_bridge->native_ltr));
+
 	/*
 	 * Evaluate the "PCI Boot Configuration" _DSM Function.  If it
 	 * exists and returns 0, we must preserve any PCI resource
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index ad3393930ecb..d1831e6bf60a 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -256,7 +256,7 @@ static bool pme_is_native(struct pcie_device *dev)
 	const struct pci_host_bridge *host;
 
 	host = pci_find_host_bridge(dev->port->bus);
-	return pcie_ports_native || host->native_pme;
+	return host->native_pme;
 }
 
 static void pciehp_disable_interrupt(struct pcie_device *dev)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 53502a751914..f6327cf0601b 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -800,9 +800,6 @@ bool pciehp_is_native(struct pci_dev *bridge)
 	if (!(slot_cap & PCI_EXP_SLTCAP_HPC))
 		return false;
 
-	if (pcie_ports_native)
-		return true;
-
 	host = pci_find_host_bridge(bridge->bus);
 	return host->native_pcie_hotplug;
 }
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index 77b0f2c45bc0..7fdeaadc40fe 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -219,7 +219,7 @@ int pcie_aer_is_native(struct pci_dev *dev)
 	if (!dev->aer_cap)
 		return 0;
 
-	return pcie_ports_native || host->native_aer;
+	return host->native_aer;
 }
 
 int pci_enable_pcie_error_reporting(struct pci_dev *dev)
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index e1fed6649c41..ea1099908d5d 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -208,8 +208,7 @@ static int get_port_device_capability(struct pci_dev *dev)
 	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
 	int services = 0;
 
-	if (dev->is_hotplug_bridge &&
-	    (pcie_ports_native || host->native_pcie_hotplug)) {
+	if (host->native_pcie_hotplug && dev->is_hotplug_bridge) {
 		services |= PCIE_PORT_SERVICE_HP;
 
 		/*
@@ -221,8 +220,7 @@ static int get_port_device_capability(struct pci_dev *dev)
 	}
 
 #ifdef CONFIG_PCIEAER
-	if (dev->aer_cap && pci_aer_available() &&
-	    (pcie_ports_native || host->native_aer)) {
+	if (host->native_aer && dev->aer_cap && pci_aer_available()) {
 		services |= PCIE_PORT_SERVICE_AER;
 
 		/*
@@ -234,9 +232,8 @@ static int get_port_device_capability(struct pci_dev *dev)
 #endif
 
 	/* Root Ports and Root Complex Event Collectors may generate PMEs */
-	if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
-	     pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
-	    (pcie_ports_native || host->native_pme)) {
+	if (host->native_pme && (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
+				 pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC)) {
 		services |= PCIE_PORT_SERVICE_PME;
 
 		/*
-- 
2.25.1


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

end of thread, other threads:[~2026-09-20  7:30 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-19 16:26 [PATCH v13 0/5] Simplify PCIe native ownership Kuppuswamy Sathyanarayanan
2026-09-19 16:26 ` [PATCH v13 1/5] PCI/DPC: Ignore devices with no AER Capability Kuppuswamy Sathyanarayanan
2026-09-20  6:11   ` Lukas Wunner
2026-09-19 16:26 ` [PATCH v13 2/5] PCI: Assume control of portdrv-related features only when portdrv enabled Kuppuswamy Sathyanarayanan
2026-09-20  6:17   ` Lukas Wunner
2026-09-19 16:26 ` [PATCH v13 3/5] PCI/ACPI: Tidy _OSC control bit checking Kuppuswamy Sathyanarayanan
2026-09-19 16:26 ` [PATCH v13 4/5] PCI/ACPI: Centralize pcie_ports_native checking Kuppuswamy Sathyanarayanan
2026-09-20  7:24   ` Guixin Liu
2026-09-19 16:26 ` [PATCH v13 5/5] PCI: Centralize pci_aer_available() checking Kuppuswamy Sathyanarayanan
  -- strict thread matches above, loose matches on Subject: below --
2021-01-23  1:11 [PATCH v13 0/5] Simplify PCIe native ownership Kuppuswamy Sathyanarayanan
2021-01-23  1:11 ` [PATCH v13 4/5] PCI/ACPI: Centralize pcie_ports_native checking Kuppuswamy Sathyanarayanan

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

all inboxes | Powered by JetHome®