diff --git a/boot/fdt_support.c b/boot/fdt_support.c index 2bd80a9dfb1..b1b2679dea0 100644 --- a/boot/fdt_support.c +++ b/boot/fdt_support.c @@ -7,12 +7,15 @@ */ #include +#include #include #include #include #include #include +#include #include +#include #include #include #include @@ -274,6 +277,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 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 */