]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
of: fix incorrect device creation for reserved memory nodes
authorKenny Cheng <chao.shun.cheng.tw@gmail.com>
Sun, 22 Feb 2026 23:47:15 +0000 (07:47 +0800)
committerRob Herring (Arm) <robh@kernel.org>
Fri, 27 Feb 2026 23:49:31 +0000 (17:49 -0600)
The current global search for nodes in reserved_mem_matches can find
nodes outside "/reserved-memory". These nodes might not have actual
memory reserved (via memblock), leading to drivers (e.g., ramoops)
accessing unreserved memory and causing memory corruption.

Restrict the scan to the "/reserved-memory" node to ensure created
devices are correctly backed by reserved memory. This enforces
specification compliance and avoids dangerous probing.

Signed-off-by: Kenny Cheng <chao.shun.cheng.tw@gmail.com>
Link: https://patch.msgid.link/20260222234715.1748302-1-chao.shun.cheng.tw@gmail.com
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
drivers/of/platform.c

index ba591fbceb56954bd8301e8ab479af6a2ba28ecc..2a7111e8354d7efe0fed1f687b0f472db5a12487 100644 (file)
@@ -500,7 +500,7 @@ static const struct of_device_id reserved_mem_matches[] = {
 
 static int __init of_platform_default_populate_init(void)
 {
-       struct device_node *node;
+       struct device_node *node, *reserved;
 
        device_links_supplier_sync_state_pause();
 
@@ -563,8 +563,14 @@ static int __init of_platform_default_populate_init(void)
                 * platform_devices for every node in /reserved-memory with a
                 * "compatible",
                 */
-               for_each_matching_node(node, reserved_mem_matches)
-                       of_platform_device_create(node, NULL, NULL);
+               reserved = of_find_node_by_path("/reserved-memory");
+               if (reserved) {
+                       for_each_child_of_node(reserved, node) {
+                               if (of_match_node(reserved_mem_matches, node))
+                                       of_platform_device_create(node, NULL, NULL);
+                       }
+                       of_node_put(reserved);
+               }
 
                node = of_find_node_by_path("/firmware");
                if (node) {