Skip to content

Commit ba6dea4

Browse files
rmurphy-armRussell King
authored andcommitted
ARM: 8616/1: dt: Respect property size when parsing CPUs
Whilst MPIDR values themselves are less than 32 bits, it is still perfectly valid for a DT to have #address-cells > 1 in the CPUs node, resulting in the "reg" property having leading zero cell(s). In that situation, the big-endian nature of the data conspires with the current behaviour of only reading the first cell to cause the kernel to think all CPUs have ID 0, and become resoundingly unhappy as a consequence. Take the full property length into account when parsing CPUs so as to be correct under any circumstances. Cc: Russell King <[email protected]> Signed-off-by: Robin Murphy <[email protected]> Signed-off-by: Russell King <[email protected]>
1 parent 1a57c28 commit ba6dea4

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

arch/arm/kernel/devtree.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ void __init arm_dt_init_cpu_maps(void)
8888
return;
8989

9090
for_each_child_of_node(cpus, cpu) {
91+
const __be32 *cell;
92+
int prop_bytes;
9193
u32 hwid;
9294

9395
if (of_node_cmp(cpu->type, "cpu"))
@@ -99,18 +101,24 @@ void __init arm_dt_init_cpu_maps(void)
99101
* properties is considered invalid to build the
100102
* cpu_logical_map.
101103
*/
102-
if (of_property_read_u32(cpu, "reg", &hwid)) {
104+
cell = of_get_property(cpu, "reg", &prop_bytes);
105+
if (!cell || prop_bytes < sizeof(*cell)) {
103106
pr_debug(" * %s missing reg property\n",
104107
cpu->full_name);
105108
of_node_put(cpu);
106109
return;
107110
}
108111

109112
/*
110-
* 8 MSBs must be set to 0 in the DT since the reg property
113+
* Bits n:24 must be set to 0 in the DT since the reg property
111114
* defines the MPIDR[23:0].
112115
*/
113-
if (hwid & ~MPIDR_HWID_BITMASK) {
116+
do {
117+
hwid = be32_to_cpu(*cell++);
118+
prop_bytes -= sizeof(*cell);
119+
} while (!hwid && prop_bytes > 0);
120+
121+
if (prop_bytes || (hwid & ~MPIDR_HWID_BITMASK)) {
114122
of_node_put(cpu);
115123
return;
116124
}

0 commit comments

Comments
 (0)