[PATCH 1/1] UBUNTU: SAUCE: PCI: Serialize TGL e1000e PM ops

Kai-Heng Feng kai.heng.feng at canonical.com
Tue Mar 16 13:11:03 UTC 2021


On TGL systems, PCI_COMMAND may randomly flip to 0 on system resume.
This is devastating to drivers that use pci_set_master(), like NVMe and
xHCI, to enable DMA in their resume routine, as pci_set_master() can
inadvertently disable PCI_COMMAND_IO and PCI_COMMAND_MEMORY, making
resources inaccessible.

The issue is reproducible on all kernel releases, but obviously the
situation is exacerbated by commit 6cecf02e77ab ('Revert "e1000e:
disable s0ix entry and exit flows for ME systems"').

Seems like ME is out to lunch until it's finally out of ULP polling. So
ensure e1000e PM ops are serialized by enforcing device links to
workaround the issue. This is another hacky hackish hack that we can't
upstream :)

Of course this will make suspend and resume a bit slower, but at least
we protect other PCI devices by keeping ME from going full basket case.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212039
Signed-off-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
---
 drivers/pci/quirks.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6c2c8dafccfd..fb13b3109a43 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -5702,3 +5702,35 @@ static void pci_fixup_enable_vmd_nvme_ltr(struct pci_dev *pdev)
 }
 DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
 			      PCI_CLASS_STORAGE_EXPRESS, 0, pci_fixup_enable_vmd_nvme_ltr);
+
+static void pci_fixup_serialize_tgl_me_pm(struct pci_dev *pdev)
+{
+	struct pci_dev *rciep = NULL;
+
+	if (!pdev->bus)
+		return;
+
+	for_each_pci_dev(rciep) {
+		/* Most of TGL RCiEPs don't have type PCI_EXP_TYPE_RC_END,
+		 * check parent bridge instead. */
+		if (!rciep->bus)
+			continue;
+
+		if (rciep->bus->self != pdev->bus->self)
+			continue;
+
+		if (&rciep->dev == &pdev->dev)
+			continue;
+
+		if (device_link_add(&rciep->dev, &pdev->dev,
+				    DL_FLAG_STATELESS))
+			pci_info(rciep, "Suspend before and resume after %s\n",
+				 pci_name(pdev));
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15fb, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15fc, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15f9, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15fa, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15f4, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15f5, pci_fixup_serialize_tgl_me_pm);
-- 
2.30.2




More information about the kernel-team mailing list