Skip to content

Commit de0df44

Browse files
pierregondoissudeep-holla
authored andcommitted
cacheinfo: Check 'cache-unified' property to count cache leaves
The DeviceTree Specification v0.3 specifies that the cache node '[d-|i-|]cache-size' property is required. The 'cache-unified' property is specifies whether the cache level is separate or unified. If the cache-size property is missing, no cache leaves is accounted. This can lead to a 'BUG: KASAN: slab-out-of-bounds' [1] bug. Check 'cache-unified' property and always account for at least one cache leaf when parsing the device tree. [1] https://lore.kernel.org/all/[email protected]/ Reported-by: Krzysztof Kozlowski <[email protected]> Signed-off-by: Pierre Gondois <[email protected]> Tested-by: Krzysztof Kozlowski <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sudeep Holla <[email protected]>
1 parent 8844c3d commit de0df44

File tree

1 file changed

+26
-11
lines changed

1 file changed

+26
-11
lines changed

drivers/base/cacheinfo.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -230,19 +230,38 @@ static int cache_setup_of_node(unsigned int cpu)
230230
return 0;
231231
}
232232

233-
int init_of_cache_level(unsigned int cpu)
233+
static int of_count_cache_leaves(struct device_node *np)
234234
{
235-
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
236-
struct device_node *np = of_cpu_device_node_get(cpu);
237-
struct device_node *prev = NULL;
238-
unsigned int levels = 0, leaves = 0, level;
235+
unsigned int leaves = 0;
239236

240237
if (of_property_read_bool(np, "cache-size"))
241238
++leaves;
242239
if (of_property_read_bool(np, "i-cache-size"))
243240
++leaves;
244241
if (of_property_read_bool(np, "d-cache-size"))
245242
++leaves;
243+
244+
if (!leaves) {
245+
/* The '[i-|d-|]cache-size' property is required, but
246+
* if absent, fallback on the 'cache-unified' property.
247+
*/
248+
if (of_property_read_bool(np, "cache-unified"))
249+
return 1;
250+
else
251+
return 2;
252+
}
253+
254+
return leaves;
255+
}
256+
257+
int init_of_cache_level(unsigned int cpu)
258+
{
259+
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
260+
struct device_node *np = of_cpu_device_node_get(cpu);
261+
struct device_node *prev = NULL;
262+
unsigned int levels = 0, leaves, level;
263+
264+
leaves = of_count_cache_leaves(np);
246265
if (leaves > 0)
247266
levels = 1;
248267

@@ -256,12 +275,8 @@ int init_of_cache_level(unsigned int cpu)
256275
goto err_out;
257276
if (level <= levels)
258277
goto err_out;
259-
if (of_property_read_bool(np, "cache-size"))
260-
++leaves;
261-
if (of_property_read_bool(np, "i-cache-size"))
262-
++leaves;
263-
if (of_property_read_bool(np, "d-cache-size"))
264-
++leaves;
278+
279+
leaves += of_count_cache_leaves(np);
265280
levels = level;
266281
}
267282

0 commit comments

Comments
 (0)