With the removal of hardcoded upper bound in of_pci_get_max_link_speed(),
the DWC driver must now validate the retrieved speed value before using
it as an index into the pcie_link_speed array. Invalid values (missing,
out of range, or mapping to PCI_SPEED_UNKNOWN) could lead to out-of-bounds
access or incorrect link configuration.
Introduce dw_pcie_get_link_speed() to handle the property retrieval and
validation. If the property is missing or invalid, fall back to Gen1 (1)
and issue a warning. This ensures safe operation while allowing future
PCIe generations to be supported without code changes in the validation
logic.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/dwc/pcie-designware.c | 29 +++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 5741c09dde7f..e10cd7a0fee1 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -110,6 +110,33 @@ static int dw_pcie_get_resets(struct dw_pcie *pci)
return 0;
}
+static void dw_pcie_get_link_speed(struct dw_pcie *pci)
+{
+ struct device_node *np = dev_of_node(pci->dev);
+ int max_speed;
+
+ max_speed = of_pci_get_max_link_speed(np);
+ if (max_speed < 0) {
+ dev_warn(pci->dev,
+ "Failed to get max-link-speed, using default (Gen1)\n");
+ pci->max_link_speed = 1;
+ return;
+ }
+
+ /* Validate against known speeds in pcie_link_speed */
+ if (max_speed == 0 ||
+ max_speed >= ARRAY_SIZE(pcie_link_speed) ||
+ pcie_link_speed[max_speed] == PCI_SPEED_UNKNOWN) {
+ dev_warn(pci->dev,
+ "Invalid max-link-speed %d, using default (Gen1)\n",
+ max_speed);
+ pci->max_link_speed = 1;
+ return;
+ }
+
+ pci->max_link_speed = max_speed;
+}
+
int dw_pcie_get_resources(struct dw_pcie *pci)
{
struct platform_device *pdev = to_platform_device(pci->dev);
@@ -189,7 +216,7 @@ int dw_pcie_get_resources(struct dw_pcie *pci)
}
if (pci->max_link_speed < 1)
- pci->max_link_speed = of_pci_get_max_link_speed(np);
+ dw_pcie_get_link_speed(pci);
of_property_read_u32(np, "num-lanes", &pci->num_lanes);
--
2.34.1
Hi Hans,
kernel test robot noticed the following build errors:
[auto build test ERROR on c23719abc3308df7ed3ad35650ad211fb2d2003d]
url: https://github.com/intel-lab-lkp/linux/commits/Hans-Zhang/PCI-of-Remove-max-link-speed-generation-validation/20260308-223128
base: c23719abc3308df7ed3ad35650ad211fb2d2003d
patch link: https://lore.kernel.org/r/20260308142629.75392-3-18255117159%40163.com
patch subject: [PATCH v7 2/2] PCI: dwc: Validate max-link-speed property
config: i386-randconfig-004-20260308 (https://download.01.org/0day-ci/archive/20260309/202603092301.uROFb9mn-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260309/202603092301.uROFb9mn-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603092301.uROFb9mn-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/pci/controller/dwc/pcie-designware.c:128:19: error: invalid application of 'sizeof' to an incomplete type 'const unsigned char[]'
128 | max_speed >= ARRAY_SIZE(pcie_link_speed) ||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/array_size.h:11:32: note: expanded from macro 'ARRAY_SIZE'
11 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
| ^~~~~
drivers/pci/controller/dwc/pcie-designware.c:255:9: warning: indirection of non-volatile null pointer will be deleted, not trap [-Wnull-dereference]
255 | return PCI_FIND_NEXT_CAP(dw_pcie_read_cfg, PCI_CAPABILITY_LIST, cap,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
256 | NULL, pci);
| ~~~~~~~~~~
drivers/pci/controller/dwc/../../pci.h:159:5: note: expanded from macro 'PCI_FIND_NEXT_CAP'
159 | *(u8 *)prev_ptr = __prev_pos; \
| ^~~~~~~~~~~~~~~
drivers/pci/controller/dwc/pcie-designware.c:255:9: note: consider using __builtin_trap() or qualifying pointer with 'volatile'
drivers/pci/controller/dwc/../../pci.h:159:5: note: expanded from macro 'PCI_FIND_NEXT_CAP'
159 | *(u8 *)prev_ptr = __prev_pos; \
| ^
drivers/pci/controller/dwc/pcie-designware.c:262:9: warning: indirection of non-volatile null pointer will be deleted, not trap [-Wnull-dereference]
262 | return PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, 0, cap, NULL, pci);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/pci/controller/dwc/../../pci.h:207:5: note: expanded from macro 'PCI_FIND_NEXT_EXT_CAP'
207 | *(u16 *)prev_ptr = __prev_pos; \
| ^~~~~~~~~~~~~~~~
drivers/pci/controller/dwc/pcie-designware.c:262:9: note: consider using __builtin_trap() or qualifying pointer with 'volatile'
drivers/pci/controller/dwc/../../pci.h:207:5: note: expanded from macro 'PCI_FIND_NEXT_EXT_CAP'
207 | *(u16 *)prev_ptr = __prev_pos; \
| ^
drivers/pci/controller/dwc/pcie-designware.c:329:17: warning: indirection of non-volatile null pointer will be deleted, not trap [-Wnull-dereference]
329 | while ((vsec = PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, vsec,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
330 | PCI_EXT_CAP_ID_VNDR, NULL, pci))) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/pci/controller/dwc/../../pci.h:207:5: note: expanded from macro 'PCI_FIND_NEXT_EXT_CAP'
207 | *(u16 *)prev_ptr = __prev_pos; \
| ^~~~~~~~~~~~~~~~
drivers/pci/controller/dwc/pcie-designware.c:329:17: note: consider using __builtin_trap() or qualifying pointer with 'volatile'
drivers/pci/controller/dwc/../../pci.h:207:5: note: expanded from macro 'PCI_FIND_NEXT_EXT_CAP'
207 | *(u16 *)prev_ptr = __prev_pos; \
| ^
3 warnings and 1 error generated.
vim +128 drivers/pci/controller/dwc/pcie-designware.c
112
113 static void dw_pcie_get_link_speed(struct dw_pcie *pci)
114 {
115 struct device_node *np = dev_of_node(pci->dev);
116 int max_speed;
117
118 max_speed = of_pci_get_max_link_speed(np);
119 if (max_speed < 0) {
120 dev_warn(pci->dev,
121 "Failed to get max-link-speed, using default (Gen1)\n");
122 pci->max_link_speed = 1;
123 return;
124 }
125
126 /* Validate against known speeds in pcie_link_speed */
127 if (max_speed == 0 ||
> 128 max_speed >= ARRAY_SIZE(pcie_link_speed) ||
129 pcie_link_speed[max_speed] == PCI_SPEED_UNKNOWN) {
130 dev_warn(pci->dev,
131 "Invalid max-link-speed %d, using default (Gen1)\n",
132 max_speed);
133 pci->max_link_speed = 1;
134 return;
135 }
136
137 pci->max_link_speed = max_speed;
138 }
139
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Hans,
kernel test robot noticed the following build warnings:
[auto build test WARNING on c23719abc3308df7ed3ad35650ad211fb2d2003d]
url: https://github.com/intel-lab-lkp/linux/commits/Hans-Zhang/PCI-of-Remove-max-link-speed-generation-validation/20260308-223128
base: c23719abc3308df7ed3ad35650ad211fb2d2003d
patch link: https://lore.kernel.org/r/20260308142629.75392-3-18255117159%40163.com
patch subject: [PATCH v7 2/2] PCI: dwc: Validate max-link-speed property
config: i386-randconfig-004-20260308 (https://download.01.org/0day-ci/archive/20260309/202603091845.8xKRO6rW-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260309/202603091845.8xKRO6rW-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603091845.8xKRO6rW-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/pci/controller/dwc/pcie-designware.c:128:19: error: invalid application of 'sizeof' to an incomplete type 'const unsigned char[]'
128 | max_speed >= ARRAY_SIZE(pcie_link_speed) ||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/array_size.h:11:32: note: expanded from macro 'ARRAY_SIZE'
11 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
| ^~~~~
>> drivers/pci/controller/dwc/pcie-designware.c:255:9: warning: indirection of non-volatile null pointer will be deleted, not trap [-Wnull-dereference]
255 | return PCI_FIND_NEXT_CAP(dw_pcie_read_cfg, PCI_CAPABILITY_LIST, cap,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
256 | NULL, pci);
| ~~~~~~~~~~
drivers/pci/controller/dwc/../../pci.h:159:5: note: expanded from macro 'PCI_FIND_NEXT_CAP'
159 | *(u8 *)prev_ptr = __prev_pos; \
| ^~~~~~~~~~~~~~~
drivers/pci/controller/dwc/pcie-designware.c:255:9: note: consider using __builtin_trap() or qualifying pointer with 'volatile'
drivers/pci/controller/dwc/../../pci.h:159:5: note: expanded from macro 'PCI_FIND_NEXT_CAP'
159 | *(u8 *)prev_ptr = __prev_pos; \
| ^
drivers/pci/controller/dwc/pcie-designware.c:262:9: warning: indirection of non-volatile null pointer will be deleted, not trap [-Wnull-dereference]
262 | return PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, 0, cap, NULL, pci);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/pci/controller/dwc/../../pci.h:207:5: note: expanded from macro 'PCI_FIND_NEXT_EXT_CAP'
207 | *(u16 *)prev_ptr = __prev_pos; \
| ^~~~~~~~~~~~~~~~
drivers/pci/controller/dwc/pcie-designware.c:262:9: note: consider using __builtin_trap() or qualifying pointer with 'volatile'
drivers/pci/controller/dwc/../../pci.h:207:5: note: expanded from macro 'PCI_FIND_NEXT_EXT_CAP'
207 | *(u16 *)prev_ptr = __prev_pos; \
| ^
drivers/pci/controller/dwc/pcie-designware.c:329:17: warning: indirection of non-volatile null pointer will be deleted, not trap [-Wnull-dereference]
329 | while ((vsec = PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, vsec,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
330 | PCI_EXT_CAP_ID_VNDR, NULL, pci))) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/pci/controller/dwc/../../pci.h:207:5: note: expanded from macro 'PCI_FIND_NEXT_EXT_CAP'
207 | *(u16 *)prev_ptr = __prev_pos; \
| ^~~~~~~~~~~~~~~~
drivers/pci/controller/dwc/pcie-designware.c:329:17: note: consider using __builtin_trap() or qualifying pointer with 'volatile'
drivers/pci/controller/dwc/../../pci.h:207:5: note: expanded from macro 'PCI_FIND_NEXT_EXT_CAP'
207 | *(u16 *)prev_ptr = __prev_pos; \
| ^
3 warnings and 1 error generated.
vim +255 drivers/pci/controller/dwc/pcie-designware.c
13e9d3900c2024 Serge Semin 2022-06-24 252
7a6854f6874ff4 Vidya Sagar 2019-08-13 253 u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap)
7a6854f6874ff4 Vidya Sagar 2019-08-13 254 {
8ffc9f234fdf33 Hans Zhang 2025-08-13 @255 return PCI_FIND_NEXT_CAP(dw_pcie_read_cfg, PCI_CAPABILITY_LIST, cap,
a2582e05e39adf Qiang Yu 2025-11-09 256 NULL, pci);
7a6854f6874ff4 Vidya Sagar 2019-08-13 257 }
7a6854f6874ff4 Vidya Sagar 2019-08-13 258 EXPORT_SYMBOL_GPL(dw_pcie_find_capability);
7a6854f6874ff4 Vidya Sagar 2019-08-13 259
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Hans,
kernel test robot noticed the following build errors:
[auto build test ERROR on c23719abc3308df7ed3ad35650ad211fb2d2003d]
url: https://github.com/intel-lab-lkp/linux/commits/Hans-Zhang/PCI-of-Remove-max-link-speed-generation-validation/20260308-223128
base: c23719abc3308df7ed3ad35650ad211fb2d2003d
patch link: https://lore.kernel.org/r/20260308142629.75392-3-18255117159%40163.com
patch subject: [PATCH v7 2/2] PCI: dwc: Validate max-link-speed property
config: csky-randconfig-r071-20260308 (https://download.01.org/0day-ci/archive/20260309/202603090252.S3qQ67Kh-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 10.5.0
smatch: v0.5.0-9004-gb810ac53
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260309/202603090252.S3qQ67Kh-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603090252.S3qQ67Kh-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from include/linux/kernel.h:16,
from include/linux/clk.h:13,
from drivers/pci/controller/dwc/pcie-designware.c:13:
drivers/pci/controller/dwc/pcie-designware.c: In function 'dw_pcie_get_link_speed':
>> include/linux/array_size.h:11:32: error: invalid application of 'sizeof' to incomplete type 'const unsigned char[]'
11 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
| ^
drivers/pci/controller/dwc/pcie-designware.c:128:19: note: in expansion of macro 'ARRAY_SIZE'
128 | max_speed >= ARRAY_SIZE(pcie_link_speed) ||
| ^~~~~~~~~~
vim +11 include/linux/array_size.h
3cd39bc3b11b8d Alejandro Colomar 2023-10-03 6
3cd39bc3b11b8d Alejandro Colomar 2023-10-03 7 /**
3cd39bc3b11b8d Alejandro Colomar 2023-10-03 8 * ARRAY_SIZE - get the number of elements in array @arr
3cd39bc3b11b8d Alejandro Colomar 2023-10-03 9 * @arr: array to be sized
3cd39bc3b11b8d Alejandro Colomar 2023-10-03 10 */
3cd39bc3b11b8d Alejandro Colomar 2023-10-03 @11 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
3cd39bc3b11b8d Alejandro Colomar 2023-10-03 12
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On 2026/3/9 02:10, kernel test robot wrote: > Hi Hans, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on c23719abc3308df7ed3ad35650ad211fb2d2003d] > > url: https://github.com/intel-lab-lkp/linux/commits/Hans-Zhang/PCI-of-Remove-max-link-speed-generation-validation/20260308-223128 > base: c23719abc3308df7ed3ad35650ad211fb2d2003d > patch link: https://lore.kernel.org/r/20260308142629.75392-3-18255117159%40163.com > patch subject: [PATCH v7 2/2] PCI: dwc: Validate max-link-speed property > config: csky-randconfig-r071-20260308 (https://download.01.org/0day-ci/archive/20260309/202603090252.S3qQ67Kh-lkp@intel.com/config) > compiler: csky-linux-gcc (GCC) 10.5.0 > smatch: v0.5.0-9004-gb810ac53 > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260309/202603090252.S3qQ67Kh-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202603090252.S3qQ67Kh-lkp@intel.com/ > > All errors (new ones prefixed by >>): > > In file included from include/linux/kernel.h:16, > from include/linux/clk.h:13, > from drivers/pci/controller/dwc/pcie-designware.c:13: > drivers/pci/controller/dwc/pcie-designware.c: In function 'dw_pcie_get_link_speed': >>> include/linux/array_size.h:11:32: error: invalid application of 'sizeof' to incomplete type 'const unsigned char[]' > 11 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) > | ^ > drivers/pci/controller/dwc/pcie-designware.c:128:19: note: in expansion of macro 'ARRAY_SIZE' > 128 | max_speed >= ARRAY_SIZE(pcie_link_speed) || > | ^~~~~~~~~~ > Hi Bjorn and Mani, I am currently working on a patch series aimed at removing the range check in the of_pci_get_max_link_speed() function and adding validation functionality in the DWC driver. In patch 2 of v7, I used ARRAY_SIZE(pcie_link_speed) in the DWC driver to validate the "max-link-speed" attribute. However, the kernel test robot reported a build error [2] because pcie_link_speed is an incomplete type (only an external declaration) in the pcie-designware.c file, so ARRAY_SIZE cannot be used. To solve this problem, I suggest adding a macro named "#define PCIE_LINK_SPEED_COUNT 16" in the <linux/pci.h> file to represent the fixed size of the pcie_link_speed array (with 16 entries according to the 4-bit field of the PCIe standard). Then use this macro in the DWC driver instead of using ARRAY_SIZE. The reason for adding the macro instead of using the fixed value "16" is to make the code more self-explanatory and this array size can be used for many years in 16 cases. Do you agree with this approach? Please let me know. Perhaps there are any other better methods? Best regards, Hans > > vim +11 include/linux/array_size.h > > 3cd39bc3b11b8d Alejandro Colomar 2023-10-03 6 > 3cd39bc3b11b8d Alejandro Colomar 2023-10-03 7 /** > 3cd39bc3b11b8d Alejandro Colomar 2023-10-03 8 * ARRAY_SIZE - get the number of elements in array @arr > 3cd39bc3b11b8d Alejandro Colomar 2023-10-03 9 * @arr: array to be sized > 3cd39bc3b11b8d Alejandro Colomar 2023-10-03 10 */ > 3cd39bc3b11b8d Alejandro Colomar 2023-10-03 @11 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) > 3cd39bc3b11b8d Alejandro Colomar 2023-10-03 12 >
© 2016 - 2026 Red Hat, Inc.