aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2023-06-01 10:22:40 -0600
committerTom Rini <trini@konsulko.com>2023-07-14 12:20:24 -0400
commitbb19d37423cfc76328f5bdd5d4cff3ef20f41f48 (patch)
tree7e3023750dabd1ce14bf1301fe55a2418082f688
parent092e765c4c08265ea346a1adae9194836a956e82 (diff)
downloadu-boot-bb19d37423cfc76328f5bdd5d4cff3ef20f41f48.zip
u-boot-bb19d37423cfc76328f5bdd5d4cff3ef20f41f48.tar.gz
u-boot-bb19d37423cfc76328f5bdd5d4cff3ef20f41f48.tar.bz2
fdt: Align the start of the livetree
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>
-rw-r--r--include/dm/of.h2
-rw-r--r--lib/of_live.c5
-rw-r--r--test/dm/ofnode.c26
3 files changed, 32 insertions, 1 deletions
diff --git a/include/dm/of.h b/include/dm/of.h
index fce7cef..b1c934f 100644
--- a/include/dm/of.h
+++ b/include/dm/of.h
@@ -63,6 +63,8 @@ struct device_node {
struct device_node *sibling;
};
+#define BAD_OF_ROOT 0xdead11e3
+
#define OF_MAX_PHANDLE_ARGS 16
/**
diff --git a/lib/of_live.c b/lib/of_live.c
index 1b5964d..05588d5 100644
--- a/lib/of_live.c
+++ b/lib/of_live.c
@@ -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);
diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c
index 473a8ce..64baaf6 100644
--- a/test/dm/ofnode.c
+++ b/test/dm/ofnode.c
@@ -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);