]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
fdt: Align the start of the livetree
authorSimon Glass <sjg@chromium.org>
Thu, 1 Jun 2023 16:22:40 +0000 (10:22 -0600)
committerTom Rini <trini@konsulko.com>
Fri, 14 Jul 2023 16:54:51 +0000 (12:54 -0400)
Ensure that the block of memory used by live tree is aligned according to
the default for structures. This ensures that the root node appears at
the start of the block, so it can be used with free(), rather than being
4 bytes later in some cases.

This corrects a rather obscure bug in unflatten_device_tree().

Fixes: 8b50d526ea5 ("dm: Add a function to create a 'live' device tree")
Signed-off-by: Simon Glass <sjg@chromium.org>
include/dm/of.h
lib/of_live.c
test/dm/ofnode.c

index fce7cef0ff69babf10ae55377c3b2ab497c1c5c9..b1c934f610d35233f21039d12d580313f3396a18 100644 (file)
@@ -63,6 +63,8 @@ struct device_node {
        struct device_node *sibling;
 };
 
+#define BAD_OF_ROOT    0xdead11e3
+
 #define OF_MAX_PHANDLE_ARGS 16
 
 /**
index 1b5964d09a9dc137b1915adf3b981479183d8803..05588d5ed282dda430dc3af89637ad5f73b1f9d5 100644 (file)
@@ -287,9 +287,12 @@ int unflatten_device_tree(const void *blob, struct device_node **mynodes)
        debug("  size is %lx, allocating...\n", size);
 
        /* Allocate memory for the expanded device tree */
-       mem = malloc(size + 4);
+       mem = memalign(__alignof__(struct device_node), size + 4);
        memset(mem, '\0', size);
 
+       /* Set up value for dm_test_livetree_align() */
+       *(u32 *)mem = BAD_OF_ROOT;
+
        *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
 
        debug("  unflattening %p...\n", mem);
index 473a8cef5780a0a82c98fc31c85c72353bac368e..64baaf68db3ae83fa462ef7d39d03fd59c7e3bfa 100644 (file)
@@ -1240,3 +1240,29 @@ static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts)
        return 0;
 }
 DM_TEST(dm_test_ofnode_copy_props_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
+
+/* check that the livetree is aligned to a structure boundary */
+static int dm_test_livetree_align(struct unit_test_state *uts)
+{
+       const int align = __alignof__(struct unit_test_state);
+       struct device_node *node;
+       u32 *sentinel;
+       ulong start;
+
+       start = (ulong)gd_of_root();
+       ut_asserteq(start, ALIGN(start, align));
+
+       node = gd_of_root();
+       sentinel = (void *)node - sizeof(u32);
+
+       /*
+        * The sentinel should be overwritten with the root node. If it isn't,
+        * then the root node is not at the very start of the livetree memory
+        * area, and free(root) will fail to free the memory used by the
+        * livetree.
+        */
+       ut_assert(*sentinel != BAD_OF_ROOT);
+
+       return 0;
+}
+DM_TEST(dm_test_livetree_align, UT_TESTF_LIVE_TREE);