diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 30a81376ac4..0b43407b9e9 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -701,11 +701,6 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
#define MAX_RAND_SIZE 8
int ft_board_setup(void *blob, struct bd_info *bd)
{
- size_t n = MAX_RAND_SIZE;
- struct udevice *dev;
- u8 buf[MAX_RAND_SIZE];
- int nodeoffset, ret;
-
static const struct node_info nodes[] = {
{ "arm,pl353-nand-r2p1", MTD_DEV_TYPE_NAND, },
};
@@ -713,41 +708,6 @@ int ft_board_setup(void *blob, struct bd_info *bd)
if (IS_ENABLED(CONFIG_FDT_FIXUP_PARTITIONS) && IS_ENABLED(CONFIG_NAND_ZYNQ))
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
- if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
- debug("No RNG device\n");
- return 0;
- }
-
- if (dm_rng_read(dev, buf, n)) {
- debug("Reading RNG failed\n");
- return 0;
- }
-
- if (!blob) {
- debug("No FDT memory address configured. Please configure\n"
- "the FDT address via \"fdt addr
\" command.\n"
- "Aborting!\n");
- return 0;
- }
-
- ret = fdt_check_header(blob);
- if (ret < 0) {
- debug("fdt_chosen: %s\n", fdt_strerror(ret));
- return ret;
- }
-
- nodeoffset = fdt_find_or_add_subnode(blob, 0, "chosen");
- if (nodeoffset < 0) {
- debug("Reading chosen node failed\n");
- return nodeoffset;
- }
-
- ret = fdt_setprop(blob, nodeoffset, "kaslr-seed", buf, sizeof(buf));
- if (ret < 0) {
- debug("Unable to set kaslr-seed on chosen node: %s\n", fdt_strerror(ret));
- return ret;
- }
-
return 0;
}
#endif
diff --git a/boot/fdt_support.c b/boot/fdt_support.c
index 874ca4d6f5a..2392027d40b 100644
--- a/boot/fdt_support.c
+++ b/boot/fdt_support.c
@@ -6,12 +6,15 @@
* Copyright 2010-2011 Freescale Semiconductor, Inc.
*/
+#include
#include
#include
#include
#include
#include
+#include
#include
+#include
#include
#include
#include
@@ -273,6 +276,47 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end)
return 0;
}
+int fdt_kaslrseed(void *fdt, bool overwrite)
+{
+ int len, err, nodeoffset;
+ struct udevice *dev;
+ const u64 *orig;
+ u64 data = 0;
+
+ err = fdt_check_header(fdt);
+ if (err < 0)
+ return err;
+
+ /* find or create "/chosen" node. */
+ nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
+ if (nodeoffset < 0)
+ return nodeoffset;
+
+ /* return without error if we are not overwriting and existing non-zero node */
+ orig = fdt_getprop(fdt, nodeoffset, "kaslr-seed", &len);
+ if (orig && len == sizeof(*orig))
+ data = fdt64_to_cpu(*orig);
+ if (data && !overwrite) {
+ debug("not overwriting existing kaslr-seed\n");
+ return 0;
+ }
+ err = uclass_get_device(UCLASS_RNG, 0, &dev);
+ if (err) {
+ printf("No RNG device\n");
+ return err;
+ }
+ err = dm_rng_read(dev, &data, sizeof(data));
+ if (err) {
+ dev_err(dev, "dm_rng_read failed: %d\n", err);
+ return err;
+ }
+ err = fdt_setprop(fdt, nodeoffset, "kaslr-seed", &data, sizeof(data));
+ if (err < 0)
+ printf("WARNING: could not set kaslr-seed %s.\n", fdt_strerror(err));
+
+ return err;
+}
+
/**
* board_fdt_chosen_bootargs - boards may override this function to use
* alternative kernel command line arguments
@@ -300,6 +344,15 @@ int fdt_chosen(void *fdt)
if (nodeoffset < 0)
return nodeoffset;
+ /* if DM_RNG enabled automatically inject kaslr-seed node unless:
+ * CONFIG_MEASURED_BOOT enabled: as dt modifications break measured boot
+ * CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT enabled: as that implementation does not use dm yet
+ */
+ if (IS_ENABLED(CONFIG_DM_RNG) &&
+ !IS_ENABLED(CONFIG_MEASURED_BOOT) &&
+ !IS_ENABLED(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT))
+ fdt_kaslrseed(fdt, false);
+
if (IS_ENABLED(CONFIG_BOARD_RNG_SEED) && !board_rng_seed(&buf)) {
err = fdt_setprop(fdt, nodeoffset, "rng-seed",
abuf_data(&buf), abuf_size(&buf));
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 53ddb16be73..53d6cf700b2 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -325,10 +325,6 @@ static void label_boot_kaslrseed(void)
#if CONFIG_IS_ENABLED(DM_RNG)
ulong fdt_addr;
struct fdt_header *working_fdt;
- size_t n = 0x8;
- struct udevice *dev;
- u64 *buf;
- int nodeoffset;
int err;
/* Get the main fdt and map it */
@@ -344,35 +340,7 @@ static void label_boot_kaslrseed(void)
if (err <= 0)
return;
- if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
- printf("No RNG device\n");
- return;
- }
-
- nodeoffset = fdt_find_or_add_subnode(working_fdt, 0, "chosen");
- if (nodeoffset < 0) {
- printf("Reading chosen node failed\n");
- return;
- }
-
- buf = malloc(n);
- if (!buf) {
- printf("Out of memory\n");
- return;
- }
-
- if (dm_rng_read(dev, buf, n)) {
- printf("Reading RNG failed\n");
- goto err;
- }
-
- err = fdt_setprop(working_fdt, nodeoffset, "kaslr-seed", buf, sizeof(buf));
- if (err < 0) {
- printf("Unable to set kaslr-seed on chosen node: %s\n", fdt_strerror(err));
- goto err;
- }
-err:
- free(buf);
+ fdt_kaslrseed(working_fdt, true);
#endif
return;
}
diff --git a/cmd/kaslrseed.c b/cmd/kaslrseed.c
index e0d3c7fe748..0712097ed05 100644
--- a/cmd/kaslrseed.c
+++ b/cmd/kaslrseed.c
@@ -15,56 +15,21 @@
static int do_kaslr_seed(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- size_t n = 0x8;
- struct udevice *dev;
- u64 *buf;
- int nodeoffset;
- int ret = CMD_RET_SUCCESS;
+ int err = CMD_RET_SUCCESS;
- if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
- printf("No RNG device\n");
- return CMD_RET_FAILURE;
- }
-
- buf = malloc(n);
- if (!buf) {
- printf("Out of memory\n");
- return CMD_RET_FAILURE;
- }
-
- if (dm_rng_read(dev, buf, n)) {
- printf("Reading RNG failed\n");
- return CMD_RET_FAILURE;
- }
+ printf("Notice: a /chosen/kaslr-seed is automatically added to the device-tree when booted via booti/bootm/bootz therefore using this command is likely no longer needed\n");
if (!working_fdt) {
printf("No FDT memory address configured. Please configure\n"
"the FDT address via \"fdt addr \" command.\n"
"Aborting!\n");
- return CMD_RET_FAILURE;
+ err = CMD_RET_FAILURE;
+ } else {
+ if (fdt_kaslrseed(working_fdt, true) < 0)
+ err = CMD_RET_FAILURE;
}
- ret = fdt_check_header(working_fdt);
- if (ret < 0) {
- printf("fdt_chosen: %s\n", fdt_strerror(ret));
- return CMD_RET_FAILURE;
- }
-
- nodeoffset = fdt_find_or_add_subnode(working_fdt, 0, "chosen");
- if (nodeoffset < 0) {
- printf("Reading chosen node failed\n");
- return CMD_RET_FAILURE;
- }
-
- ret = fdt_setprop(working_fdt, nodeoffset, "kaslr-seed", buf, sizeof(buf));
- if (ret < 0) {
- printf("Unable to set kaslr-seed on chosen node: %s\n", fdt_strerror(ret));
- return CMD_RET_FAILURE;
- }
-
- free(buf);
-
- return ret;
+ return cmd_process_error(cmdtp, err);
}
U_BOOT_LONGHELP(kaslrseed,
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 4b71b8948d9..741e2360c22 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -463,4 +463,14 @@ void fdt_fixup_board_enet(void *blob);
#ifdef CONFIG_CMD_PSTORE
void fdt_fixup_pstore(void *blob);
#endif
+
+/**
+ * fdt_kaslrseed() - create a 'kaslr-seed' node in chosen
+ *
+ * @blob: fdt blob
+ * @overwrite: do not overwrite existing non-zero node unless true
+ * Return: 0 if OK, -ve on error
+ */
+int fdt_kaslrseed(void *blob, bool overwrite);
+
#endif /* ifndef __FDT_SUPPORT_H */
diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c
index a0faf5aca90..e09a929a5e4 100644
--- a/test/cmd/fdt.c
+++ b/test/cmd/fdt.c
@@ -1346,6 +1346,10 @@ static int fdt_test_chosen(struct unit_test_state *uts)
ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
if (env_bootargs)
ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
+ if (IS_ENABLED(CONFIG_DM_RNG) &&
+ !IS_ENABLED(CONFIG_MEASURED_BOOT) &&
+ !IS_ENABLED(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT))
+ ut_assert_nextlinen("\tkaslr-seed = ");
ut_assert_nextline("};");
ut_assertok(ut_check_console_end(uts));
@@ -1362,6 +1366,10 @@ static int fdt_test_chosen(struct unit_test_state *uts)
ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
if (env_bootargs)
ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
+ if (IS_ENABLED(CONFIG_DM_RNG) &&
+ !IS_ENABLED(CONFIG_MEASURED_BOOT) &&
+ !IS_ENABLED(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT))
+ ut_assert_nextlinen("\tkaslr-seed = ");
ut_assert_nextline("};");
ut_assertok(ut_check_console_end(uts));