[PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation
Hans Zhang
18255117159 at 163.com
Sun Mar 29 07:47:26 PDT 2026
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@163.com/
Best regards,
Hans
More information about the linux-arm-kernel
mailing list