--- /dev/null
+From stable+bounces-227585-greg=kroah.com@vger.kernel.org Fri Mar 20 18:29:23 2026
+From: John Hancock <john@kernel.doghat.io>
+Date: Fri, 20 Mar 2026 13:23:35 -0400
+Subject: PCI: Revert "Enable ACS after configuring IOMMU for OF platforms"
+To: stable@vger.kernel.org
+Cc: bhelgaas@google.com, manivannan.sadhasivam@oss.qualcomm.com, joro@8bytes.org, linux-pci@vger.kernel.org, iommu@lists.linux.dev, John Hancock <john@kernel.doghat.io>
+Message-ID: <20260320172335.29778-1-john@kernel.doghat.io>
+
+From: John Hancock <john@kernel.doghat.io>
+
+This reverts 7a126c1b6cfa2c4b5a7013164451ecddd210110d which is
+commit c41e2fb67e26b04d919257875fa954aa5f6e392e upstream.
+
+Commit 7a126c1b6cfa ("PCI: Enable ACS after configuring IOMMU for OF
+platforms") introduced a regression affecting AMD IOMMU group isolation
+on x86 systems, making PCIe passthrough non-functional.
+
+While the commit addresses a legitimate ordering issue on OF/Device Tree
+platforms, the fix modifies pci_dma_configure(), which executes on all
+platforms regardless of firmware interface. On AMD systems with IOMMU,
+moving pci_enable_acs() from pci_acs_init() to pci_dma_configure() alters
+the point at which ACS is evaluated relative to IOMMU group assignment.
+The result is that devices which previously occupied individual, exclusive
+IOMMU groups are merged into a single group containing both passthrough
+and non-passthrough members, violating IOMMU isolation requirements.
+
+The commit author notes that pci_enable_acs() is now called twice per
+device and that this is "presumably not an issue." On AMD IOMMU hardware
+this assumption does not hold -- the change in call ordering has
+observable and breaking consequences for group topology.
+
+It is worth noting that this is a stable/LTS series (6.12.y), where
+changes to fundamental PCI initialization ordering carry significant
+risk for production and specialized workloads that depend on stable
+IOMMU behavior across kernel updates. A regression of this nature --
+silently breaking PCIe passthrough without any configuration change on
+the part of the user -- is particularly disruptive in a series that
+users reasonably expect to be conservative.
+
+This revert restores pci_enable_acs() to pci_acs_init() and marks it
+static again, fully restoring correct IOMMU group topology on affected
+hardware.
+
+Regression introduced in: 6.12.75
+Tested on: 6.12.77 with this revert applied
+
+Hardware:
+ CPU: AMD Ryzen Threadripper 2990WX (family 23h, Zen+)
+ IOMMU: AMD-Vi
+
+Bisect:
+ 6.12.74: GOOD -- IOMMU groups correct, passthrough functional
+ 6.12.75: BAD -- IOMMU groups collapsed, passthrough broken
+ 6.12.76: BAD -- still broken
+ 6.12.77: BAD -- still broken
+
+Fixes: 7a126c1b6cfa ("PCI: Enable ACS after configuring IOMMU for OF platforms")
+Signed-off-by: John Hancock <john@kernel.doghat.io>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/pci-driver.c | 8 --------
+ drivers/pci/pci.c | 10 +++++++++-
+ drivers/pci/pci.h | 1 -
+ 3 files changed, 9 insertions(+), 10 deletions(-)
+
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -1656,14 +1656,6 @@ static int pci_dma_configure(struct devi
+ ret = acpi_dma_configure(dev, acpi_get_dma_attr(adev));
+ }
+
+- /*
+- * Attempt to enable ACS regardless of capability because some Root
+- * Ports (e.g. those quirked with *_intel_pch_acs_*) do not have
+- * the standard ACS capability but still support ACS via those
+- * quirks.
+- */
+- pci_enable_acs(to_pci_dev(dev));
+-
+ pci_put_host_bridge_device(bridge);
+
+ if (!ret && !driver->driver_managed_dma) {
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1072,7 +1072,7 @@ static void pci_std_enable_acs(struct pc
+ * pci_enable_acs - enable ACS if hardware support it
+ * @dev: the PCI device
+ */
+-void pci_enable_acs(struct pci_dev *dev)
++static void pci_enable_acs(struct pci_dev *dev)
+ {
+ struct pci_acs caps;
+ bool enable_acs = false;
+@@ -3718,6 +3718,14 @@ bool pci_acs_path_enabled(struct pci_dev
+ void pci_acs_init(struct pci_dev *dev)
+ {
+ dev->acs_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
++
++ /*
++ * Attempt to enable ACS regardless of capability because some Root
++ * Ports (e.g. those quirked with *_intel_pch_acs_*) do not have
++ * the standard ACS capability but still support ACS via those
++ * quirks.
++ */
++ pci_enable_acs(dev);
+ }
+
+ /**
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -653,7 +653,6 @@ static inline resource_size_t pci_resour
+ }
+
+ void pci_acs_init(struct pci_dev *dev);
+-void pci_enable_acs(struct pci_dev *dev);
+ #ifdef CONFIG_PCI_QUIRKS
+ int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
+ int pci_dev_specific_enable_acs(struct pci_dev *dev);