Re: [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation

From: Hans Zhang

Date: Sun Mar 29 2026 - 10:50:38 EST




On 3/28/26 00:42, Bjorn Helgaas wrote:
On Sat, Mar 14, 2026 at 12:55:17AM +0800, Hans Zhang wrote:
Hi,

This series moves the validation from the common OF function to the
individual PCIe controller drivers. To protect against out-of-bounds
accesses to the pcie_link_speed[] array, we first introduce a helper
function pcie_get_link_speed() that safely returns the speed value
(or PCI_SPEED_UNKNOWN) for a given generation number.

Then all direct uses of pcie_link_speed[] as an array are converted to
use the new helper, ensuring that even if an invalid generation number
reaches those code paths, no out-of-bounds access occurs.

For several drivers that read the "max-link-speed" property
(pci-j721e, brcmstb, mediatek-gen3, rzg3s-host), we add an explicit
validation step: if the value is missing, out of range, or unsupported
by the hardware, a safe default is used (usually Gen2). Other drivers
(mainly DesignWare glue drivers) rely on the helper to safely handle
invalid values, but do not yet include fallback logic or warnings.

Finally, the range check is removed from of_pci_get_max_link_speed(),
so that future PCIe generations can be supported without modifying
drivers/pci/of.c.

Thanks for this series.

We still have a couple references to pcie_link_speed[] that bypass
pcie_get_link_speed(). These are safe because PCI_EXP_LNKSTA_CLS is
0xf and pcie_link_speed[] is size 16, but I'm not sure the direct
reference is necessary.

The array itself is exported, which I suppose we needed for modular
PCI controller drivers, but we probably don't need it now that
pcie_get_link_speed() is exported?

$ git grep "\<pcie_link_speed\>"
drivers/pci/pci-sysfs.c: speed = pcie_link_speed[linkstat & PCI_EXP_LNKSTA_CLS];
drivers/pci/pci.c: return pcie_link_speed[FIELD_GET(PCI_EXP_LNKSTA_CLS, lnksta)];
drivers/pci/pci.h:extern const unsigned char pcie_link_speed[];
drivers/pci/pci.h: bus->cur_bus_speed = pcie_link_speed[linksta & PCI_EXP_LNKSTA_CLS];
drivers/pci/probe.c:const unsigned char pcie_link_speed[] = {
drivers/pci/probe.c:EXPORT_SYMBOL_GPL(pcie_link_speed);
drivers/pci/probe.c: if (speed >= ARRAY_SIZE(pcie_link_speed))
drivers/pci/probe.c: return pcie_link_speed[speed];
drivers/pci/probe.c: bus->max_bus_speed = pcie_link_speed[linkcap & PCI_EXP_LNKCAP_SLS];

Hi Bjorn,

Yes, I also realized that this array is directly used in other places. So I submitted this series and I would appreciate it if you could review it to ensure its correctness.

See also this series:
https://patchwork.kernel.org/project/linux-pci/patch/20260315160057.127639-1-18255117159@xxxxxxx/

Best regards,
Hans