The len value is in bytes, while `dt_root_addr_cells + dt_root_size_cells`
is in cells (4 bytes per cell). Modulo calculation between them is
incorrect, the units must be converted first.
Use helper functions to simplify the code and fix this issue.
Fixes: fb319e77a0e7 ("of: fdt: Add memory for devices by DT property "linux,usable-memory-range"")
Fixes: 2af2b50acf9b9c38 ("of: fdt: Add generic support for handling usable memory range property")
Fixes: 8f579b1c4e347b23 ("arm64: limit memory regions based on DT property, usable-memory-range")
Signed-off-by: Yuntao Wang <yuntao.wang@linux.dev>
---
drivers/of/fdt.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 80b7236efdc6..d0caaab42aa7 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -884,7 +884,7 @@ static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND;
void __init early_init_dt_check_for_usable_mem_range(void)
{
struct memblock_region rgn[MAX_USABLE_RANGES] = {0};
- const __be32 *prop, *endp;
+ const __be32 *prop;
int len, i;
unsigned long node = chosen_node_offset;
@@ -893,14 +893,14 @@ void __init early_init_dt_check_for_usable_mem_range(void)
pr_debug("Looking for usable-memory-range property... ");
- prop = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len);
- if (!prop || (len % (dt_root_addr_cells + dt_root_size_cells)))
+ prop = of_fdt_get_addr_size_prop(node, "linux,usable-memory-range", &len);
+ if (!prop)
return;
- endp = prop + (len / sizeof(__be32));
- for (i = 0; i < MAX_USABLE_RANGES && prop < endp; i++) {
- rgn[i].base = dt_mem_next_cell(dt_root_addr_cells, &prop);
- rgn[i].size = dt_mem_next_cell(dt_root_size_cells, &prop);
+ len = min(len, MAX_USABLE_RANGES);
+
+ for (i = 0; i < len; i++) {
+ of_fdt_read_addr_size(prop, &rgn[i].base, &rgn[i].size);
pr_debug("cap_mem_regions[%d]: base=%pa, size=%pa\n",
i, &rgn[i].base, &rgn[i].size);
--
2.51.0
Hi Yuntao,
kernel test robot noticed the following build errors:
[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.18-rc5 next-20251113]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Yuntao-Wang/of-fdt-Consolidate-duplicate-code-into-helper-functions/20251114-004121
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link: https://lore.kernel.org/r/20251113155104.226617-4-yuntao.wang%40linux.dev
patch subject: [PATCH v2 3/7] of/fdt: Fix the len check in early_init_dt_check_for_usable_mem_range()
config: arc-allnoconfig (https://download.01.org/0day-ci/archive/20251114/202511140206.XDGIw3J1-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251114/202511140206.XDGIw3J1-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/202511140206.XDGIw3J1-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/of/fdt.c: In function 'early_init_dt_check_for_usable_mem_range':
>> drivers/of/fdt.c:903:45: error: passing argument 2 of 'of_fdt_read_addr_size' from incompatible pointer type [-Wincompatible-pointer-types]
903 | of_fdt_read_addr_size(prop, &rgn[i].base, &rgn[i].size);
| ^~~~~~~~~~~~
| |
| phys_addr_t * {aka unsigned int *}
drivers/of/fdt.c:663:60: note: expected 'u64 *' {aka 'long long unsigned int *'} but argument is of type 'phys_addr_t *' {aka 'unsigned int *'}
663 | void __init of_fdt_read_addr_size(const __be32 *prop, u64 *addr, u64 *size)
| ~~~~~^~~~
drivers/of/fdt.c:903:59: error: passing argument 3 of 'of_fdt_read_addr_size' from incompatible pointer type [-Wincompatible-pointer-types]
903 | of_fdt_read_addr_size(prop, &rgn[i].base, &rgn[i].size);
| ^~~~~~~~~~~~
| |
| phys_addr_t * {aka unsigned int *}
drivers/of/fdt.c:663:71: note: expected 'u64 *' {aka 'long long unsigned int *'} but argument is of type 'phys_addr_t *' {aka 'unsigned int *'}
663 | void __init of_fdt_read_addr_size(const __be32 *prop, u64 *addr, u64 *size)
| ~~~~~^~~~
vim +/of_fdt_read_addr_size +903 drivers/of/fdt.c
879
880 /**
881 * early_init_dt_check_for_usable_mem_range - Decode usable memory range
882 * location from flat tree
883 */
884 void __init early_init_dt_check_for_usable_mem_range(void)
885 {
886 struct memblock_region rgn[MAX_USABLE_RANGES] = {0};
887 const __be32 *prop;
888 int len, i;
889 unsigned long node = chosen_node_offset;
890
891 if ((long)node < 0)
892 return;
893
894 pr_debug("Looking for usable-memory-range property... ");
895
896 prop = of_fdt_get_addr_size_prop(node, "linux,usable-memory-range", &len);
897 if (!prop)
898 return;
899
900 len = min(len, MAX_USABLE_RANGES);
901
902 for (i = 0; i < len; i++) {
> 903 of_fdt_read_addr_size(prop, &rgn[i].base, &rgn[i].size);
904
905 pr_debug("cap_mem_regions[%d]: base=%pa, size=%pa\n",
906 i, &rgn[i].base, &rgn[i].size);
907 }
908
909 memblock_cap_memory_range(rgn[0].base, rgn[0].size);
910 for (i = 1; i < MAX_USABLE_RANGES && rgn[i].size; i++)
911 memblock_add(rgn[i].base, rgn[i].size);
912 }
913
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Yuntao,
kernel test robot noticed the following build errors:
[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.18-rc5 next-20251113]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Yuntao-Wang/of-fdt-Consolidate-duplicate-code-into-helper-functions/20251114-004121
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link: https://lore.kernel.org/r/20251113155104.226617-4-yuntao.wang%40linux.dev
patch subject: [PATCH v2 3/7] of/fdt: Fix the len check in early_init_dt_check_for_usable_mem_range()
config: arm-allnoconfig (https://download.01.org/0day-ci/archive/20251114/202511140236.zLyckeBA-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 0bba1e76581bad04e7d7f09f5115ae5e2989e0d9)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251114/202511140236.zLyckeBA-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/202511140236.zLyckeBA-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/of/fdt.c:903:31: error: incompatible pointer types passing 'phys_addr_t *' (aka 'unsigned int *') to parameter of type 'u64 *' (aka 'unsigned long long *') [-Wincompatible-pointer-types]
903 | of_fdt_read_addr_size(prop, &rgn[i].base, &rgn[i].size);
| ^~~~~~~~~~~~
drivers/of/fdt.c:663:60: note: passing argument to parameter 'addr' here
663 | void __init of_fdt_read_addr_size(const __be32 *prop, u64 *addr, u64 *size)
| ^
drivers/of/fdt.c:903:45: error: incompatible pointer types passing 'phys_addr_t *' (aka 'unsigned int *') to parameter of type 'u64 *' (aka 'unsigned long long *') [-Wincompatible-pointer-types]
903 | of_fdt_read_addr_size(prop, &rgn[i].base, &rgn[i].size);
| ^~~~~~~~~~~~
drivers/of/fdt.c:663:71: note: passing argument to parameter 'size' here
663 | void __init of_fdt_read_addr_size(const __be32 *prop, u64 *addr, u64 *size)
| ^
2 errors generated.
vim +903 drivers/of/fdt.c
879
880 /**
881 * early_init_dt_check_for_usable_mem_range - Decode usable memory range
882 * location from flat tree
883 */
884 void __init early_init_dt_check_for_usable_mem_range(void)
885 {
886 struct memblock_region rgn[MAX_USABLE_RANGES] = {0};
887 const __be32 *prop;
888 int len, i;
889 unsigned long node = chosen_node_offset;
890
891 if ((long)node < 0)
892 return;
893
894 pr_debug("Looking for usable-memory-range property... ");
895
896 prop = of_fdt_get_addr_size_prop(node, "linux,usable-memory-range", &len);
897 if (!prop)
898 return;
899
900 len = min(len, MAX_USABLE_RANGES);
901
902 for (i = 0; i < len; i++) {
> 903 of_fdt_read_addr_size(prop, &rgn[i].base, &rgn[i].size);
904
905 pr_debug("cap_mem_regions[%d]: base=%pa, size=%pa\n",
906 i, &rgn[i].base, &rgn[i].size);
907 }
908
909 memblock_cap_memory_range(rgn[0].base, rgn[0].size);
910 for (i = 1; i < MAX_USABLE_RANGES && rgn[i].size; i++)
911 memblock_add(rgn[i].base, rgn[i].size);
912 }
913
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.