* [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation
@ 2026-03-13 16:55 Hans Zhang
2026-03-13 16:55 ` [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access Hans Zhang
` (6 more replies)
0 siblings, 7 replies; 13+ messages in thread
From: Hans Zhang @ 2026-03-13 16:55 UTC (permalink / raw)
To: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas, helgaas,
florian.fainelli, jim2101024
Cc: robh, ilpo.jarvinen, linux-arm-msm, linux-arm-kernel,
linux-renesas-soc, claudiu.beznea.uj, linux-mediatek, linux-tegra,
linux-omap, bcm-kernel-feedback-list, linux-pci, linux-kernel,
shawn.lin, Hans Zhang
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.
---
Changes for v9:
- Modify the parameter passed to pcie_get_link_speed to unsigned int. If the DT
configuration specifies max-link-speed = -1, the obtained max_link_speed will
be 0xff. Therefore, it will be greater than the length of the array pcie_link_speed.
Thus, the condition speed <= 0 is removed. (For patch 0001. Shawn)
- Modify the commit message for patch 0005. (Shawn)
Changes for v8:
https://patchwork.kernel.org/project/linux-pci/cover/20260312163652.113228-1-18255117159@163.com/
- Expand series from 2 to 5 patches to introduce pcie_get_link_speed() helper
and split validation into per-driver changes.
- Add pcie_get_link_speed() helper for safe pcie_link_speed[] array access (Bjorn)
- Move max-link-speed validation from DWC core to individual drivers; add explicit
fallback logic only for pci-j721e, brcmstb, mediatek-gen3, rzg3s-host.
- Convert all remaining direct pcie_link_speed[] accesses to use the new helper.
- Update commit messages to reflect the new design.
Changes for v7:
https://patchwork.kernel.org/project/linux-pci/cover/20260308142629.75392-1-18255117159@163.com/
- Add validation in dw_pcie_get_link_speed() (Bjorn)
- Modify it so that two patches constitute one series.
Changes for v6:
https://patchwork.kernel.org/project/linux-pci/patch/20251218132036.308094-1-18255117159@163.com/
- It'd be good to return the actual errno as of_property_read_u32() can return
-EINVAL, -ENODATA and -EOVERFLOW. (Mani)
Changes for v5:
https://patchwork.kernel.org/project/linux-pci/patch/20251218125909.305300-1-18255117159@163.com/
- Delete the check for speed. (Mani)
Changes for v4:
https://patchwork.kernel.org/project/linux-pci/patch/20251105134701.182795-1-18255117159@163.com/
- Add pcie_max_supported_link_speed.(Ilpo)
Changes for v3:
https://patchwork.kernel.org/project/linux-pci/patch/20251101164132.14145-1-18255117159@163.com/
- Modify the commit message.
- Add Reviewed-by tag.
Changes for v2:
https://patchwork.kernel.org/project/linux-pci/cover/20250529021026.475861-1-18255117159@163.com/
- The following files have been deleted:
Documentation/devicetree/bindings/pci/pci.txt
Update to this file again:
dtschema/schemas/pci/pci-bus-common.yaml
---
Hans Zhang (5):
PCI: Add pcie_get_link_speed() helper for safe array access
PCI: dwc: Use pcie_get_link_speed() and validate max-link-speed
PCI: j721e: Validate max-link-speed from DT
PCI: controller: Validate max-link-speed
PCI: of: Remove max-link-speed generation validation
drivers/pci/controller/cadence/pci-j721e.c | 3 ++-
.../pci/controller/dwc/pcie-designware-host.c | 2 +-
drivers/pci/controller/dwc/pcie-designware.c | 2 +-
drivers/pci/controller/dwc/pcie-qcom-common.c | 2 +-
drivers/pci/controller/dwc/pcie-qcom-ep.c | 4 ++--
drivers/pci/controller/dwc/pcie-qcom.c | 6 +++---
drivers/pci/controller/dwc/pcie-tegra194.c | 2 +-
drivers/pci/controller/pcie-brcmstb.c | 5 +++--
drivers/pci/controller/pcie-mediatek-gen3.c | 2 +-
drivers/pci/controller/pcie-rzg3s-host.c | 2 +-
drivers/pci/of.c | 16 ++++++++--------
drivers/pci/pci.h | 2 ++
drivers/pci/probe.c | 16 ++++++++++++++++
13 files changed, 42 insertions(+), 22 deletions(-)
base-commit: 80234b5ab240f52fa45d201e899e207b9265ef91
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access
2026-03-13 16:55 [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
@ 2026-03-13 16:55 ` Hans Zhang
2026-03-26 17:40 ` Manivannan Sadhasivam
` (2 more replies)
2026-03-13 16:55 ` [PATCH v9 2/5] PCI: dwc: Use " Hans Zhang
` (5 subsequent siblings)
6 siblings, 3 replies; 13+ messages in thread
From: Hans Zhang @ 2026-03-13 16:55 UTC (permalink / raw)
To: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas, helgaas,
florian.fainelli, jim2101024
Cc: robh, ilpo.jarvinen, linux-arm-msm, linux-arm-kernel,
linux-renesas-soc, claudiu.beznea.uj, linux-mediatek, linux-tegra,
linux-omap, bcm-kernel-feedback-list, linux-pci, linux-kernel,
shawn.lin, Hans Zhang
The pcie_link_speed[] array is indexed by PCIe generation numbers
(1 = 2.5 GT/s, 2 = 5 GT/s, ...). Several drivers use it directly,
which can lead to out-of-bounds accesses if an invalid generation
number is used.
Introduce a helper function pcie_get_link_speed() that returns the
corresponding enum pci_bus_speed value for a given generation number,
or PCI_SPEED_UNKNOWN if the generation is out of range. This will
allow us to safely handle invalid values after the range check is
removed from of_pci_get_max_link_speed().
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/pci.h | 2 ++
drivers/pci/probe.c | 16 ++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 13d998fbacce..409aca7d737a 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -108,6 +108,8 @@ struct pcie_tlp_log;
PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
extern const unsigned char pcie_link_speed[];
+unsigned char pcie_get_link_speed(unsigned int speed);
+
extern bool pci_early_dump;
extern struct mutex pci_rescan_remove_lock;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bccc7a4bdd79..d6592898330c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -783,6 +783,22 @@ const unsigned char pcie_link_speed[] = {
};
EXPORT_SYMBOL_GPL(pcie_link_speed);
+/**
+ * pcie_link_speed_value - Get speed value from PCIe generation number
+ * @speed: PCIe speed (1-based: 1 = 2.5GT, 2 = 5GT, ...)
+ *
+ * Returns the speed value (e.g., PCIE_SPEED_2_5GT) if @speed is valid,
+ * otherwise returns PCI_SPEED_UNKNOWN.
+ */
+unsigned char pcie_get_link_speed(unsigned int speed)
+{
+ if (speed >= ARRAY_SIZE(pcie_link_speed))
+ return PCI_SPEED_UNKNOWN;
+
+ return pcie_link_speed[speed];
+}
+EXPORT_SYMBOL_GPL(pcie_get_link_speed);
+
const char *pci_speed_string(enum pci_bus_speed speed)
{
/* Indexed by the pci_bus_speed enum */
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v9 2/5] PCI: dwc: Use pcie_get_link_speed() helper for safe array access
2026-03-13 16:55 [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
2026-03-13 16:55 ` [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access Hans Zhang
@ 2026-03-13 16:55 ` Hans Zhang
2026-03-13 16:55 ` [PATCH v9 3/5] PCI: j721e: Validate max-link-speed from DT Hans Zhang
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Hans Zhang @ 2026-03-13 16:55 UTC (permalink / raw)
To: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas, helgaas,
florian.fainelli, jim2101024
Cc: robh, ilpo.jarvinen, linux-arm-msm, linux-arm-kernel,
linux-renesas-soc, claudiu.beznea.uj, linux-mediatek, linux-tegra,
linux-omap, bcm-kernel-feedback-list, linux-pci, linux-kernel,
shawn.lin, Hans Zhang
Replace direct indexing of pcie_link_speed[] with the new helper
pcie_get_link_speed() in all DesignWare core and glue drivers. This
ensures that out-of-range generation numbers do not cause out-of-bounds
accesses when the helper returns PCI_SPEED_UNKNOWN, and prepares for
the removal of the range check in of_pci_get_max_link_speed().
The actual validation of the "max-link-speed" DT property (e.g., fallback
to a safe default and warning) is added in subsequent patches for each
driver that reads the property.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 2 +-
drivers/pci/controller/dwc/pcie-designware.c | 2 +-
drivers/pci/controller/dwc/pcie-qcom-common.c | 2 +-
drivers/pci/controller/dwc/pcie-qcom-ep.c | 4 ++--
drivers/pci/controller/dwc/pcie-qcom.c | 6 +++---
drivers/pci/controller/dwc/pcie-tegra194.c | 2 +-
6 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 6ae6189e9b8a..0e05c5280344 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1081,7 +1081,7 @@ static void dw_pcie_program_presets(struct dw_pcie_rp *pp, enum pci_bus_speed sp
static void dw_pcie_config_presets(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- enum pci_bus_speed speed = pcie_link_speed[pci->max_link_speed];
+ enum pci_bus_speed speed = pcie_get_link_speed(pci->max_link_speed);
/*
* Lane equalization settings need to be applied for all data rates the
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 5741c09dde7f..06792ba92aa7 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -861,7 +861,7 @@ static void dw_pcie_link_set_max_speed(struct dw_pcie *pci)
ctrl2 = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCTL2);
ctrl2 &= ~PCI_EXP_LNKCTL2_TLS;
- switch (pcie_link_speed[pci->max_link_speed]) {
+ switch (pcie_get_link_speed(pci->max_link_speed)) {
case PCIE_SPEED_2_5GT:
link_speed = PCI_EXP_LNKCTL2_TLS_2_5GT;
break;
diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.c b/drivers/pci/controller/dwc/pcie-qcom-common.c
index 01c5387e53bf..5aa73c628737 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-common.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-common.c
@@ -22,7 +22,7 @@ void qcom_pcie_common_set_equalization(struct dw_pcie *pci)
* applied.
*/
- for (speed = PCIE_SPEED_8_0GT; speed <= pcie_link_speed[pci->max_link_speed]; speed++) {
+ for (speed = PCIE_SPEED_8_0GT; speed <= pcie_get_link_speed(pci->max_link_speed); speed++) {
if (speed > PCIE_SPEED_32_0GT) {
dev_warn(dev, "Skipped equalization settings for unsupported data rate\n");
break;
diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 18460f01b2c6..4b7184d4a6fa 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -152,7 +152,7 @@
#define WAKE_DELAY_US 2000 /* 2 ms */
#define QCOM_PCIE_LINK_SPEED_TO_BW(speed) \
- Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_link_speed[speed]))
+ Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_get_link_speed(speed)))
#define to_pcie_ep(x) dev_get_drvdata((x)->dev)
@@ -531,7 +531,7 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
qcom_pcie_common_set_equalization(pci);
- if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
+ if (pcie_get_link_speed(pci->max_link_speed) == PCIE_SPEED_16_0GT)
qcom_pcie_common_set_16gt_lane_margining(pci);
/*
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 67a16af69ddc..5c7c105bb745 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -170,7 +170,7 @@
#define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))
#define QCOM_PCIE_LINK_SPEED_TO_BW(speed) \
- Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_link_speed[speed]))
+ Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_get_link_speed(speed)))
struct qcom_pcie_resources_1_0_0 {
struct clk_bulk_data *clks;
@@ -320,7 +320,7 @@ static int qcom_pcie_start_link(struct dw_pcie *pci)
qcom_pcie_common_set_equalization(pci);
- if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
+ if (pcie_get_link_speed(pci->max_link_speed) == PCIE_SPEED_16_0GT)
qcom_pcie_common_set_16gt_lane_margining(pci);
/* Enable Link Training state machine */
@@ -1579,7 +1579,7 @@ static void qcom_pcie_icc_opp_update(struct qcom_pcie *pcie)
ret);
}
} else if (pcie->use_pm_opp) {
- freq_mbps = pcie_dev_speed_mbps(pcie_link_speed[speed]);
+ freq_mbps = pcie_dev_speed_mbps(pcie_get_link_speed(speed));
if (freq_mbps < 0)
return;
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 06571d806ab3..47f08adfbd79 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -310,7 +310,7 @@ static void tegra_pcie_icc_set(struct tegra_pcie_dw *pcie)
speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, val);
width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val);
- val = width * PCIE_SPEED2MBS_ENC(pcie_link_speed[speed]);
+ val = width * PCIE_SPEED2MBS_ENC(pcie_get_link_speed(speed));
if (icc_set_bw(pcie->icc_path, Mbps_to_icc(val), 0))
dev_err(pcie->dev, "can't set bw[%u]\n", val);
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v9 3/5] PCI: j721e: Validate max-link-speed from DT
2026-03-13 16:55 [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
2026-03-13 16:55 ` [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access Hans Zhang
2026-03-13 16:55 ` [PATCH v9 2/5] PCI: dwc: Use " Hans Zhang
@ 2026-03-13 16:55 ` Hans Zhang
2026-03-13 16:55 ` [PATCH v9 4/5] PCI: controller: Validate max-link-speed Hans Zhang
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Hans Zhang @ 2026-03-13 16:55 UTC (permalink / raw)
To: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas, helgaas,
florian.fainelli, jim2101024
Cc: robh, ilpo.jarvinen, linux-arm-msm, linux-arm-kernel,
linux-renesas-soc, claudiu.beznea.uj, linux-mediatek, linux-tegra,
linux-omap, bcm-kernel-feedback-list, linux-pci, linux-kernel,
shawn.lin, Hans Zhang
Use the new pcie_get_link_speed() helper to validate the value read from
the "max-link-speed" DT property. If the value is missing or invalid,
fall back to Gen2 (speed = 2). This prepares for the removal of the
range check in of_pci_get_max_link_speed().
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/cadence/pci-j721e.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 6f2501479c70..bfdfe98d5aba 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -202,7 +202,8 @@ static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
int ret;
link_speed = of_pci_get_max_link_speed(np);
- if (link_speed < 2)
+ if ((link_speed < 2) ||
+ (pcie_get_link_speed(link_speed) == PCI_SPEED_UNKNOWN))
link_speed = 2;
val = link_speed - 1;
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v9 4/5] PCI: controller: Validate max-link-speed
2026-03-13 16:55 [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
` (2 preceding siblings ...)
2026-03-13 16:55 ` [PATCH v9 3/5] PCI: j721e: Validate max-link-speed from DT Hans Zhang
@ 2026-03-13 16:55 ` Hans Zhang
2026-03-13 16:55 ` [PATCH v9 5/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
` (2 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Hans Zhang @ 2026-03-13 16:55 UTC (permalink / raw)
To: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas, helgaas,
florian.fainelli, jim2101024
Cc: robh, ilpo.jarvinen, linux-arm-msm, linux-arm-kernel,
linux-renesas-soc, claudiu.beznea.uj, linux-mediatek, linux-tegra,
linux-omap, bcm-kernel-feedback-list, linux-pci, linux-kernel,
shawn.lin, Hans Zhang
Add validation for the "max-link-speed" DT property in three more
drivers, using the pcie_get_link_speed() helper.
- brcmstb: If the value is missing or invalid, fall back to no
limitation (pcie->gen = 0). Fix the previous incorrect logic.
- mediatek-gen3: If the value is missing or invalid, use the maximum
speed supported by the controller.
- rzg3s-host: If the value is missing or invalid, fall back to Gen2.
This ensures that all users of of_pci_get_max_link_speed() are ready
for the removal of the central range check.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/pcie-brcmstb.c | 5 +++--
drivers/pci/controller/pcie-mediatek-gen3.c | 2 +-
drivers/pci/controller/pcie-rzg3s-host.c | 2 +-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 062f55690012..714bcab97b60 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -1442,7 +1442,7 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
cls = FIELD_GET(PCI_EXP_LNKSTA_CLS, lnksta);
nlw = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta);
dev_info(dev, "link up, %s x%u %s\n",
- pci_speed_string(pcie_link_speed[cls]), nlw,
+ pci_speed_string(pcie_get_link_speed(cls)), nlw,
ssc_good ? "(SSC)" : "(!SSC)");
return 0;
@@ -2072,7 +2072,8 @@ static int brcm_pcie_probe(struct platform_device *pdev)
return PTR_ERR(pcie->clk);
ret = of_pci_get_max_link_speed(np);
- pcie->gen = (ret < 0) ? 0 : ret;
+ if (pcie_get_link_speed(ret) == PCI_SPEED_UNKNOWN)
+ pcie->gen = 0;
pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc");
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index 75ddb8bee168..3b903ef7d3cf 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -1150,7 +1150,7 @@ static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie)
return err;
err = of_pci_get_max_link_speed(pcie->dev->of_node);
- if (err) {
+ if (pcie_get_link_speed(err) != PCI_SPEED_UNKNOWN) {
/* Get the maximum speed supported by the controller */
max_speed = mtk_pcie_get_controller_max_link_speed(pcie);
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index 2809112e6317..00a11f986117 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -966,7 +966,7 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host)
ls = readw_relaxed(host->pcie + pcie_cap + PCI_EXP_LNKSTA);
cs2 = readl_relaxed(host->axi + RZG3S_PCI_PCSTAT2);
- switch (pcie_link_speed[host->max_link_speed]) {
+ switch (pcie_get_link_speed(host->max_link_speed)) {
case PCIE_SPEED_5_0GT:
max_supported_link_speeds = GENMASK(PCI_EXP_LNKSTA_CLS_5_0GB - 1, 0);
link_speed = PCI_EXP_LNKCTL2_TLS_5_0GT;
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v9 5/5] PCI: of: Remove max-link-speed generation validation
2026-03-13 16:55 [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
` (3 preceding siblings ...)
2026-03-13 16:55 ` [PATCH v9 4/5] PCI: controller: Validate max-link-speed Hans Zhang
@ 2026-03-13 16:55 ` Hans Zhang
2026-03-26 18:29 ` [PATCH v9 0/5] " Manivannan Sadhasivam
2026-03-27 16:42 ` Bjorn Helgaas
6 siblings, 0 replies; 13+ messages in thread
From: Hans Zhang @ 2026-03-13 16:55 UTC (permalink / raw)
To: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas, helgaas,
florian.fainelli, jim2101024
Cc: robh, ilpo.jarvinen, linux-arm-msm, linux-arm-kernel,
linux-renesas-soc, claudiu.beznea.uj, linux-mediatek, linux-tegra,
linux-omap, bcm-kernel-feedback-list, linux-pci, linux-kernel,
shawn.lin, Hans Zhang
The of_pci_get_max_link_speed() function currently validates the
"max-link-speed" DT property to be in the range 1..4 (Gen1..Gen4).
This imposes a maintenance burden because each new PCIe generation
would require updating this validation.
Remove the range check so the function returns the raw property value
(or a negative error code if the property is missing or malformed).
Callers must now validate the returned speed against the range they
support. A subsequent patch adds such validation to the DWC driver,
which is the primary user of this function.
Removing the validation from this common function allows future PCIe
generations to be supported without modifying drivers/pci/of.c.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/of.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 9f8eb5df279e..d645041f5125 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -875,24 +875,24 @@ EXPORT_SYMBOL_GPL(of_pci_supply_present);
* of_pci_get_max_link_speed - Find the maximum link speed of the given device node.
* @node: Device tree node with the maximum link speed information.
*
- * This function will try to find the limitation of link speed by finding
- * a property called "max-link-speed" of the given device node.
+ * This function will try to read the "max-link-speed" property of the given
+ * device tree node. It does NOT validate the value of the property.
*
* Return:
* * > 0 - On success, a maximum link speed.
- * * -EINVAL - Invalid "max-link-speed" property value, or failure to access
- * the property of the device tree node.
+ * * -EINVAL - Failure to access the property of the device tree node.
*
* Returns the associated max link speed from DT, or a negative value if the
- * required property is not found or is invalid.
+ * required property is not found.
*/
int of_pci_get_max_link_speed(struct device_node *node)
{
u32 max_link_speed;
+ int ret;
- if (of_property_read_u32(node, "max-link-speed", &max_link_speed) ||
- max_link_speed == 0 || max_link_speed > 4)
- return -EINVAL;
+ ret = of_property_read_u32(node, "max-link-speed", &max_link_speed);
+ if (ret)
+ return ret;
return max_link_speed;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access
2026-03-13 16:55 ` [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access Hans Zhang
@ 2026-03-26 17:40 ` Manivannan Sadhasivam
2026-03-26 18:09 ` Bjorn Helgaas
2026-03-26 18:16 ` Bjorn Helgaas
2 siblings, 0 replies; 13+ messages in thread
From: Manivannan Sadhasivam @ 2026-03-26 17:40 UTC (permalink / raw)
To: Hans Zhang, bhelgaas, helgaas
Cc: lpieralisi, jingoohan1, kwilczynski, florian.fainelli, jim2101024,
robh, ilpo.jarvinen, linux-arm-msm, linux-arm-kernel,
linux-renesas-soc, claudiu.beznea.uj, linux-mediatek, linux-tegra,
linux-omap, bcm-kernel-feedback-list, linux-pci, linux-kernel,
shawn.lin
On Sat, Mar 14, 2026 at 12:55:18AM +0800, Hans Zhang wrote:
> The pcie_link_speed[] array is indexed by PCIe generation numbers
> (1 = 2.5 GT/s, 2 = 5 GT/s, ...). Several drivers use it directly,
> which can lead to out-of-bounds accesses if an invalid generation
> number is used.
>
> Introduce a helper function pcie_get_link_speed() that returns the
> corresponding enum pci_bus_speed value for a given generation number,
> or PCI_SPEED_UNKNOWN if the generation is out of range. This will
> allow us to safely handle invalid values after the range check is
> removed from of_pci_get_max_link_speed().
>
Bjorn: Could you please take a look at this patch and ack if looks good? Rest of
the patches look good to me (I might squash patch 5 with 4 while applying).
- Mani
> Signed-off-by: Hans Zhang <18255117159@163.com>
> ---
> drivers/pci/pci.h | 2 ++
> drivers/pci/probe.c | 16 ++++++++++++++++
> 2 files changed, 18 insertions(+)
>
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 13d998fbacce..409aca7d737a 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -108,6 +108,8 @@ struct pcie_tlp_log;
> PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
>
> extern const unsigned char pcie_link_speed[];
> +unsigned char pcie_get_link_speed(unsigned int speed);
> +
> extern bool pci_early_dump;
>
> extern struct mutex pci_rescan_remove_lock;
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index bccc7a4bdd79..d6592898330c 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -783,6 +783,22 @@ const unsigned char pcie_link_speed[] = {
> };
> EXPORT_SYMBOL_GPL(pcie_link_speed);
>
> +/**
> + * pcie_link_speed_value - Get speed value from PCIe generation number
> + * @speed: PCIe speed (1-based: 1 = 2.5GT, 2 = 5GT, ...)
> + *
> + * Returns the speed value (e.g., PCIE_SPEED_2_5GT) if @speed is valid,
> + * otherwise returns PCI_SPEED_UNKNOWN.
> + */
> +unsigned char pcie_get_link_speed(unsigned int speed)
> +{
> + if (speed >= ARRAY_SIZE(pcie_link_speed))
> + return PCI_SPEED_UNKNOWN;
> +
> + return pcie_link_speed[speed];
> +}
> +EXPORT_SYMBOL_GPL(pcie_get_link_speed);
> +
> const char *pci_speed_string(enum pci_bus_speed speed)
> {
> /* Indexed by the pci_bus_speed enum */
> --
> 2.34.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access
2026-03-13 16:55 ` [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access Hans Zhang
2026-03-26 17:40 ` Manivannan Sadhasivam
@ 2026-03-26 18:09 ` Bjorn Helgaas
2026-03-26 18:16 ` Bjorn Helgaas
2 siblings, 0 replies; 13+ messages in thread
From: Bjorn Helgaas @ 2026-03-26 18:09 UTC (permalink / raw)
To: Hans Zhang
Cc: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas,
florian.fainelli, jim2101024, robh, ilpo.jarvinen, linux-arm-msm,
linux-arm-kernel, linux-renesas-soc, claudiu.beznea.uj,
linux-mediatek, linux-tegra, linux-omap, bcm-kernel-feedback-list,
linux-pci, linux-kernel, shawn.lin
On Sat, Mar 14, 2026 at 12:55:18AM +0800, Hans Zhang wrote:
> The pcie_link_speed[] array is indexed by PCIe generation numbers
> (1 = 2.5 GT/s, 2 = 5 GT/s, ...). Several drivers use it directly,
> which can lead to out-of-bounds accesses if an invalid generation
> number is used.
>
> Introduce a helper function pcie_get_link_speed() that returns the
> corresponding enum pci_bus_speed value for a given generation number,
> or PCI_SPEED_UNKNOWN if the generation is out of range. This will
> allow us to safely handle invalid values after the range check is
> removed from of_pci_get_max_link_speed().
>
> Signed-off-by: Hans Zhang <18255117159@163.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
> drivers/pci/pci.h | 2 ++
> drivers/pci/probe.c | 16 ++++++++++++++++
> 2 files changed, 18 insertions(+)
>
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 13d998fbacce..409aca7d737a 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -108,6 +108,8 @@ struct pcie_tlp_log;
> PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
>
> extern const unsigned char pcie_link_speed[];
> +unsigned char pcie_get_link_speed(unsigned int speed);
> +
> extern bool pci_early_dump;
>
> extern struct mutex pci_rescan_remove_lock;
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index bccc7a4bdd79..d6592898330c 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -783,6 +783,22 @@ const unsigned char pcie_link_speed[] = {
> };
> EXPORT_SYMBOL_GPL(pcie_link_speed);
>
> +/**
> + * pcie_link_speed_value - Get speed value from PCIe generation number
> + * @speed: PCIe speed (1-based: 1 = 2.5GT, 2 = 5GT, ...)
> + *
> + * Returns the speed value (e.g., PCIE_SPEED_2_5GT) if @speed is valid,
> + * otherwise returns PCI_SPEED_UNKNOWN.
> + */
> +unsigned char pcie_get_link_speed(unsigned int speed)
> +{
> + if (speed >= ARRAY_SIZE(pcie_link_speed))
> + return PCI_SPEED_UNKNOWN;
> +
> + return pcie_link_speed[speed];
> +}
> +EXPORT_SYMBOL_GPL(pcie_get_link_speed);
> +
> const char *pci_speed_string(enum pci_bus_speed speed)
> {
> /* Indexed by the pci_bus_speed enum */
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access
2026-03-13 16:55 ` [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access Hans Zhang
2026-03-26 17:40 ` Manivannan Sadhasivam
2026-03-26 18:09 ` Bjorn Helgaas
@ 2026-03-26 18:16 ` Bjorn Helgaas
2026-03-26 18:32 ` Manivannan Sadhasivam
2 siblings, 1 reply; 13+ messages in thread
From: Bjorn Helgaas @ 2026-03-26 18:16 UTC (permalink / raw)
To: Hans Zhang
Cc: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas,
florian.fainelli, jim2101024, robh, ilpo.jarvinen, linux-arm-msm,
linux-arm-kernel, linux-renesas-soc, claudiu.beznea.uj,
linux-mediatek, linux-tegra, linux-omap, bcm-kernel-feedback-list,
linux-pci, linux-kernel, shawn.lin
On Sat, Mar 14, 2026 at 12:55:18AM +0800, Hans Zhang wrote:
> The pcie_link_speed[] array is indexed by PCIe generation numbers
> (1 = 2.5 GT/s, 2 = 5 GT/s, ...). Several drivers use it directly,
> which can lead to out-of-bounds accesses if an invalid generation
> number is used.
>
> Introduce a helper function pcie_get_link_speed() that returns the
> corresponding enum pci_bus_speed value for a given generation number,
> or PCI_SPEED_UNKNOWN if the generation is out of range. This will
> allow us to safely handle invalid values after the range check is
> removed from of_pci_get_max_link_speed().
>
> Signed-off-by: Hans Zhang <18255117159@163.com>
> ---
> drivers/pci/pci.h | 2 ++
> drivers/pci/probe.c | 16 ++++++++++++++++
> 2 files changed, 18 insertions(+)
>
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 13d998fbacce..409aca7d737a 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -108,6 +108,8 @@ struct pcie_tlp_log;
> PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
>
> extern const unsigned char pcie_link_speed[];
> +unsigned char pcie_get_link_speed(unsigned int speed);
> +
> extern bool pci_early_dump;
>
> extern struct mutex pci_rescan_remove_lock;
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index bccc7a4bdd79..d6592898330c 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -783,6 +783,22 @@ const unsigned char pcie_link_speed[] = {
> };
> EXPORT_SYMBOL_GPL(pcie_link_speed);
>
> +/**
> + * pcie_link_speed_value - Get speed value from PCIe generation number
Wrong name here (pcie_link_speed_value vs pcie_get_link_speed)
(pointed out by Sashiko).
> + * @speed: PCIe speed (1-based: 1 = 2.5GT, 2 = 5GT, ...)
> + *
> + * Returns the speed value (e.g., PCIE_SPEED_2_5GT) if @speed is valid,
> + * otherwise returns PCI_SPEED_UNKNOWN.
> + */
> +unsigned char pcie_get_link_speed(unsigned int speed)
Sashiko also pointed out that the commit log says this returns "enum
pci_bus_speed", while here we return unsigned char (which is also the
type of pcie_link_speed[x]).
https://sashiko.dev/#/patchset/20260313165522.123518-1-18255117159%40163.com
> +{
> + if (speed >= ARRAY_SIZE(pcie_link_speed))
> + return PCI_SPEED_UNKNOWN;
> +
> + return pcie_link_speed[speed];
> +}
> +EXPORT_SYMBOL_GPL(pcie_get_link_speed);
> +
> const char *pci_speed_string(enum pci_bus_speed speed)
> {
> /* Indexed by the pci_bus_speed enum */
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation
2026-03-13 16:55 [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
` (4 preceding siblings ...)
2026-03-13 16:55 ` [PATCH v9 5/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
@ 2026-03-26 18:29 ` Manivannan Sadhasivam
2026-03-27 16:42 ` Bjorn Helgaas
6 siblings, 0 replies; 13+ messages in thread
From: Manivannan Sadhasivam @ 2026-03-26 18:29 UTC (permalink / raw)
To: lpieralisi, jingoohan1, kwilczynski, bhelgaas, helgaas,
florian.fainelli, jim2101024, Hans Zhang
Cc: robh, ilpo.jarvinen, linux-arm-msm, linux-arm-kernel,
linux-renesas-soc, claudiu.beznea.uj, linux-mediatek, linux-tegra,
linux-omap, bcm-kernel-feedback-list, linux-pci, linux-kernel,
shawn.lin
On Sat, 14 Mar 2026 00:55:17 +0800, Hans Zhang wrote:
> 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.
>
> [...]
Applied, thanks!
[1/5] PCI: Add pcie_get_link_speed() helper for safe array access
commit: df61f4732adf9de5ad1f5e71b7670710c1597d18
[2/5] PCI: dwc: Use pcie_get_link_speed() helper for safe array access
commit: d884b0e51459175f17ddc52759ea4533bb752130
[3/5] PCI: j721e: Validate max-link-speed from DT
commit: 1542ac6d83d0b5706f45e2937de7b4f7b8c4831d
[4/5] PCI: controller: Validate max-link-speed
commit: d0cc5918a1d539344190cbb19fa3ae0e7b0dca1e
[5/5] PCI: of: Remove max-link-speed generation validation
commit: 15217c7015c0e1804925693c55d721aad8987e32
Best regards,
--
Manivannan Sadhasivam <mani@kernel.org>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access
2026-03-26 18:16 ` Bjorn Helgaas
@ 2026-03-26 18:32 ` Manivannan Sadhasivam
0 siblings, 0 replies; 13+ messages in thread
From: Manivannan Sadhasivam @ 2026-03-26 18:32 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Hans Zhang, lpieralisi, jingoohan1, kwilczynski, bhelgaas,
florian.fainelli, jim2101024, robh, ilpo.jarvinen, linux-arm-msm,
linux-arm-kernel, linux-renesas-soc, claudiu.beznea.uj,
linux-mediatek, linux-tegra, linux-omap, bcm-kernel-feedback-list,
linux-pci, linux-kernel, shawn.lin
On Thu, Mar 26, 2026 at 01:16:24PM -0500, Bjorn Helgaas wrote:
> On Sat, Mar 14, 2026 at 12:55:18AM +0800, Hans Zhang wrote:
> > The pcie_link_speed[] array is indexed by PCIe generation numbers
> > (1 = 2.5 GT/s, 2 = 5 GT/s, ...). Several drivers use it directly,
> > which can lead to out-of-bounds accesses if an invalid generation
> > number is used.
> >
> > Introduce a helper function pcie_get_link_speed() that returns the
> > corresponding enum pci_bus_speed value for a given generation number,
> > or PCI_SPEED_UNKNOWN if the generation is out of range. This will
> > allow us to safely handle invalid values after the range check is
> > removed from of_pci_get_max_link_speed().
> >
> > Signed-off-by: Hans Zhang <18255117159@163.com>
> > ---
> > drivers/pci/pci.h | 2 ++
> > drivers/pci/probe.c | 16 ++++++++++++++++
> > 2 files changed, 18 insertions(+)
> >
> > diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> > index 13d998fbacce..409aca7d737a 100644
> > --- a/drivers/pci/pci.h
> > +++ b/drivers/pci/pci.h
> > @@ -108,6 +108,8 @@ struct pcie_tlp_log;
> > PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
> >
> > extern const unsigned char pcie_link_speed[];
> > +unsigned char pcie_get_link_speed(unsigned int speed);
> > +
> > extern bool pci_early_dump;
> >
> > extern struct mutex pci_rescan_remove_lock;
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > index bccc7a4bdd79..d6592898330c 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -783,6 +783,22 @@ const unsigned char pcie_link_speed[] = {
> > };
> > EXPORT_SYMBOL_GPL(pcie_link_speed);
> >
> > +/**
> > + * pcie_link_speed_value - Get speed value from PCIe generation number
>
> Wrong name here (pcie_link_speed_value vs pcie_get_link_speed)
> (pointed out by Sashiko).
>
Noticed this one while applying.
> > + * @speed: PCIe speed (1-based: 1 = 2.5GT, 2 = 5GT, ...)
> > + *
> > + * Returns the speed value (e.g., PCIE_SPEED_2_5GT) if @speed is valid,
> > + * otherwise returns PCI_SPEED_UNKNOWN.
> > + */
> > +unsigned char pcie_get_link_speed(unsigned int speed)
>
> Sashiko also pointed out that the commit log says this returns "enum
> pci_bus_speed", while here we return unsigned char (which is also the
> type of pcie_link_speed[x]).
>
> https://sashiko.dev/#/patchset/20260313165522.123518-1-18255117159%40163.com
>
This one I didn't, but fixed now, thanks!
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation
2026-03-13 16:55 [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
` (5 preceding siblings ...)
2026-03-26 18:29 ` [PATCH v9 0/5] " Manivannan Sadhasivam
@ 2026-03-27 16:42 ` Bjorn Helgaas
2026-03-29 14:47 ` Hans Zhang
6 siblings, 1 reply; 13+ messages in thread
From: Bjorn Helgaas @ 2026-03-27 16:42 UTC (permalink / raw)
To: Hans Zhang
Cc: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas,
florian.fainelli, jim2101024, robh, ilpo.jarvinen, linux-arm-msm,
linux-arm-kernel, linux-renesas-soc, claudiu.beznea.uj,
linux-mediatek, linux-tegra, linux-omap, bcm-kernel-feedback-list,
linux-pci, linux-kernel, shawn.lin
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];
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation
2026-03-27 16:42 ` Bjorn Helgaas
@ 2026-03-29 14:47 ` Hans Zhang
0 siblings, 0 replies; 13+ messages in thread
From: Hans Zhang @ 2026-03-29 14:47 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas,
florian.fainelli, jim2101024, robh, ilpo.jarvinen, linux-arm-msm,
linux-arm-kernel, linux-renesas-soc, claudiu.beznea.uj,
linux-mediatek, linux-tegra, linux-omap, bcm-kernel-feedback-list,
linux-pci, linux-kernel, shawn.lin
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
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-03-29 14:48 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-13 16:55 [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
2026-03-13 16:55 ` [PATCH v9 1/5] PCI: Add pcie_get_link_speed() helper for safe array access Hans Zhang
2026-03-26 17:40 ` Manivannan Sadhasivam
2026-03-26 18:09 ` Bjorn Helgaas
2026-03-26 18:16 ` Bjorn Helgaas
2026-03-26 18:32 ` Manivannan Sadhasivam
2026-03-13 16:55 ` [PATCH v9 2/5] PCI: dwc: Use " Hans Zhang
2026-03-13 16:55 ` [PATCH v9 3/5] PCI: j721e: Validate max-link-speed from DT Hans Zhang
2026-03-13 16:55 ` [PATCH v9 4/5] PCI: controller: Validate max-link-speed Hans Zhang
2026-03-13 16:55 ` [PATCH v9 5/5] PCI: of: Remove max-link-speed generation validation Hans Zhang
2026-03-26 18:29 ` [PATCH v9 0/5] " Manivannan Sadhasivam
2026-03-27 16:42 ` Bjorn Helgaas
2026-03-29 14:47 ` Hans Zhang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox