lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230206143540.15325-1-ron.lee@intel.com>
Date:   Mon,  6 Feb 2023 22:35:40 +0800
From:   Ron Lee <ron.lee.intel@...il.com>
To:     bhelgaas@...gle.com
Cc:     linux-kernel@...r.kernel.org, linux-pci@...r.kernel.org,
        lmajczak@...gle.com, rajatja@...gle.com,
        Ron Lee <ron.lee@...el.com>
Subject: [PATCH v3] PCI: Fix up L1SS capability for Intel Apollo Lake PCIe bridge

On Google Coral and Reef family Chromebooks with Intel Apollo Lake
SoC, the PCIe bridge lost its L1 PM Substates capability after resumed
from D3cold. This patch save the capability header and the pointer
offset to the L1SS capability after this bridge initialized, and
recover them every time resuming from D3cold.

Link:https://lore.kernel.org/linux-pci/CAFJ_xbq0cxcH-cgpXLU4Mjk30+muWyWm1aUZGK7iG53yaLBaQg@mail.gmail.com/T/#u
Signed-off-by: Ron Lee <ron.lee@...el.com>
---
Change from v2: traverse the capability link list to find the L1SS capability header
and pointer offset to the L1SS capability, save them after the bridge initialized and 
restore them after resuming from D3cold.

 drivers/pci/quirks.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 285acc4aaccc..4e1c8c4c7e9a 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -5992,3 +5992,44 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size);
 #endif
+
+#ifdef CONFIG_PCIEASPM
+static u16 pos_to_l1ss;
+static u32 l1ss_header;
+static void chromeos_save_apl_pci_l1ss_capability(struct pci_dev *pdev)
+{
+	u32 header;
+	int pos = PCI_CFG_SPACE_SIZE;
+
+	while (pos) {
+		pci_read_config_dword(pdev, pos, &header);
+		if (PCI_EXT_CAP_NEXT(header) == pdev->l1ss)
+			pos_to_l1ss = pos;
+		else if (PCI_EXT_CAP_ID(header) == PCI_EXT_CAP_ID_L1SS)
+			l1ss_header = header;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+	}
+}
+
+static void chromeos_fixup_apl_pci_l1ss_capability(struct pci_dev *pdev)
+{
+	u32 header;
+
+	if (!pos_to_l1ss || !l1ss_header)
+		return;
+
+	pci_info(pdev, "Fixup L1SS Capability\n");
+	/* Fixup the header of L1SS Capability if missing */
+	pci_read_config_dword(pdev, pdev->l1ss, &header);
+	if (PCI_EXT_CAP_ID(header) != PCI_EXT_CAP_ID_L1SS)
+		pci_write_config_dword(pdev, pdev->l1ss, l1ss_header);
+
+	/* Fixup the link to L1SS Capability if missing*/
+	pci_read_config_dword(pdev, pos_to_l1ss, &header);
+	if (PCI_EXT_CAP_NEXT(header) != pdev->l1ss)
+		pci_write_config_dword(pdev, pos_to_l1ss, pdev->l1ss << 20);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_save_apl_pci_l1ss_capability);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_fixup_apl_pci_l1ss_capability);
+#endif
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ