[PATCH 1/5] common: machine_id: support /chosen/barebox, machine-id-path override
Bastian Krause
bst at pengutronix.de
Mon Jun 28 02:35:56 PDT 2021
On 6/28/21 8:40 AM, Ahmad Fatoum wrote:
> The Kconfig option already warns that the current behavior of
> machine_id_set_hashable() overriding previous calls can lead to the
> machine-id changing over updates. We don't yet have this problem in
> practice, because the only two upstream users are for bsec and ocotp,
> which are efuse drivers for different SoCs. On the other hand, users
> may want to get the unique ID from an EEPROM and with deep probe
> support, the initcall ordering will be independent of the actual probe
> order.
>
> Work around this issue by introducing a way for each board to explicitly
> reference a nvmem cell that should be hashed to produce the machine-id.
>
> If no such device tree property is supplied, the last call to
> machine_id_set_hashable() will be used as before.
>
> Cc: Bastian Krause <bst at pengutronix.de>
> Cc: Uwe Kleine-König <ukl at pengutronix.de>
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
> common/Kconfig | 13 ++++++----
> common/machine_id.c | 41 ++++++++++++++++++++++++++++---
> drivers/nvmem/core.c | 44 ++++++++++++++++++++++++----------
> drivers/of/base.c | 11 +++++++++
> include/linux/nvmem-consumer.h | 5 ++++
> include/of.h | 6 +++++
> 6 files changed, 99 insertions(+), 21 deletions(-)
>
> diff --git a/common/Kconfig b/common/Kconfig
> index 54f1eb633a32..a4a109f04f08 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -1066,13 +1066,16 @@ config MACHINE_ID
> bool "compute unique machine-id"
> depends on FLEXIBLE_BOOTARGS
> depends on SHA1
> + select NVMEM
> help
> Compute a persistent machine-specific id and store it to $global.machine_id.
> - The id is a hash of device-specific information added via
> - machine_id_set_hashable(). If multiple sources are available, the
> - information provided by the last call prior to the late initcall
> - set_machine_id() is used to generate the machine id from. Thus when
> - updating barebox the machine id might change.
> + The id is a hash of device-specific information added either via
> + machine_id_set_hashable() or by hashing the nvmem cell referenced by the
> + /chosen/barebox,machine-id device tree property.
> +
> + With machine_id_set_hashable(), the last call prior to the late initcall
> + set_machine_id() willl be used to generate the machine id. This means
> + updating barebox may change the machine id!
>
> global.bootm.provide_machine_id may be used to automatically set
> the linux.bootargs.machine_id global variable with a value of
> diff --git a/common/machine_id.c b/common/machine_id.c
> index 6480806cd287..fd2f0888a6cd 100644
> --- a/common/machine_id.c
> +++ b/common/machine_id.c
> @@ -10,6 +10,9 @@
> #include <magicvar.h>
> #include <crypto/sha.h>
> #include <machine_id.h>
> +#include <linux/err.h>
> +#include <linux/nvmem-consumer.h>
> +#include <of.h>
>
> #define MACHINE_ID_LENGTH 32
>
> @@ -24,16 +27,49 @@ void machine_id_set_hashable(const void *hashable, size_t len)
> __machine_id_hashable_length = len;
> }
>
> +static const void *machine_id_get_hashable(size_t *len)
> +{
> + struct device_node *np = of_get_machineidpath();
> + struct nvmem_cell *cell;
> + void *ret;
> +
> + if (!np)
> + goto no_cell;
> +
> + cell = of_nvmem_cell_get_from_node(np);
> + if (IS_ERR(cell)) {
> + pr_err("Invalid barebox,machine-id-path: %pe\n", cell);
> + goto no_cell;
> + }
> +
> + ret = nvmem_cell_read(cell, len);
> + nvmem_cell_put(cell);
> + if (IS_ERR(ret)) {
> + pr_err("Couldn't read from barebox,machine-id-path: %pe\n", ret);
> + goto no_cell;
> + }
> +
> + return ret;
> +
> +no_cell:
> + *len = __machine_id_hashable_length;
> + return __machine_id_hashable;
> +}
> +
> static int machine_id_set_globalvar(void)
> {
> struct digest *digest = NULL;
> unsigned char machine_id[SHA1_DIGEST_SIZE];
> char hex_machine_id[MACHINE_ID_LENGTH];
> char *env_machine_id;
> + const void *hashable;
> + size_t length;
> int ret = 0;
>
> + hashable = machine_id_get_hashable(&length);
> +
> /* nothing to do if no hashable information provided */
> - if (!__machine_id_hashable)
> + if (!hashable)
> goto out;
>
> digest = digest_alloc_by_algo(HASH_ALGO_SHA1);
> @@ -41,8 +77,7 @@ static int machine_id_set_globalvar(void)
> if (ret)
> goto out;
>
> - ret = digest_update(digest, __machine_id_hashable,
> - __machine_id_hashable_length);
> + ret = digest_update(digest, hashable, length);
> if (ret)
> goto out;
>
> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
> index 4e558e165063..980304a8078b 100644
> --- a/drivers/nvmem/core.c
> +++ b/drivers/nvmem/core.c
> @@ -361,29 +361,21 @@ static struct nvmem_cell *nvmem_cell_get_from_list(const char *cell_id)
>
> #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OFTREE)
> /**
> - * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
> + * of_nvmem_cell_get_from_node() - Get a nvmem cell from cell device node
> *
> - * @dev node: Device tree node that uses the nvmem cell
> - * @id: nvmem cell name from nvmem-cell-names property.
> + * @cell_np: Device tree node of the nvmem cell
> *
> * Return: Will be an ERR_PTR() on error or a valid pointer
> * to a struct nvmem_cell. The nvmem_cell will be freed by the
> * nvmem_cell_put().
> */
> -struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
> - const char *name)
> +struct nvmem_cell *of_nvmem_cell_get_from_node(struct device_node *cell_np)
> {
> - struct device_node *cell_np, *nvmem_np;
> + struct device_node *nvmem_np;
> struct nvmem_cell *cell;
> struct nvmem_device *nvmem;
> const __be32 *addr;
> - int rval, len, index;
> -
> - index = of_property_match_string(np, "nvmem-cell-names", name);
> -
> - cell_np = of_parse_phandle(np, "nvmem-cells", index);
> - if (!cell_np)
> - return ERR_PTR(-EINVAL);
> + int rval, len;
>
> nvmem_np = of_get_parent(cell_np);
> if (!nvmem_np)
> @@ -445,6 +437,32 @@ err_mem:
>
> return ERR_PTR(rval);
> }
> +EXPORT_SYMBOL_GPL(of_nvmem_cell_get_from_node);
> +
> +/**
> + * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
> + *
> + * @dev node: Device tree node that uses the nvmem cell
> + * @id: nvmem cell name from nvmem-cell-names property.
> + *
> + * Return: Will be an ERR_PTR() on error or a valid pointer
> + * to a struct nvmem_cell. The nvmem_cell will be freed by the
> + * nvmem_cell_put().
> + */
> +struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
> + const char *name)
> +{
> + struct device_node *cell_np;
> + int index;
> +
> + index = of_property_match_string(np, "nvmem-cell-names", name);
> +
> + cell_np = of_parse_phandle(np, "nvmem-cells", index);
> + if (!cell_np)
> + return ERR_PTR(-EINVAL);
> +
> + return of_nvmem_cell_get_from_node(cell_np);
> +}
> EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
> #endif
Shouldn't these changes be part of a separate patch?
Regards,
Bastian
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 4104d7589305..a5b74707fc4f 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -2525,6 +2525,17 @@ int of_device_is_stdout_path(struct device_d *dev, unsigned int *baudrate)
> return true;
> }
>
> +struct device_node *of_get_machineidpath(void)
> +{
> + const char *name;
> +
> + name = of_get_property(of_chosen, "barebox,machine-id-path", NULL);
> + if (!name)
> + return NULL;
> +
> + return of_find_node_by_path_or_alias(NULL, name);
> +}
> +
> /**
> * of_add_initrd - add initrd properties to the devicetree
> * @root - the root node of the tree
> diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
> index b979f23372a6..639a7ebbabae 100644
> --- a/include/linux/nvmem-consumer.h
> +++ b/include/linux/nvmem-consumer.h
> @@ -122,11 +122,16 @@ static inline int nvmem_device_write(struct nvmem_device *nvmem,
> #endif /* CONFIG_NVMEM */
>
> #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OFTREE)
> +struct nvmem_cell *of_nvmem_cell_get_from_node(struct device_node *cell_np);
> struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
> const char *name);
> struct nvmem_device *of_nvmem_device_get(struct device_node *np,
> const char *name);
> #else
> +static inline struct nvmem_cell *of_nvmem_cell_get_from_node(struct device_node *cell_np)
> +{
> + return ERR_PTR(-ENOSYS);
> +}
> static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
> const char *name)
> {
> diff --git a/include/of.h b/include/of.h
> index d82790c0523e..677f48d0aba1 100644
> --- a/include/of.h
> +++ b/include/of.h
> @@ -290,6 +290,7 @@ int of_fixup_partitions(struct device_node *np, struct cdev *cdev);
> int of_partitions_register_fixup(struct cdev *cdev);
> struct device_node *of_get_stdoutpath(unsigned int *);
> int of_device_is_stdout_path(struct device_d *dev, unsigned int *baudrate);
> +struct device_node *of_get_machineidpath(void);
> const char *of_get_model(void);
> void *of_flatten_dtb(struct device_node *node);
> int of_add_memory(struct device_node *node, bool dump);
> @@ -336,6 +337,11 @@ static inline int of_device_is_stdout_path(struct device_d *dev, unsigned int *b
> return 0;
> }
>
> +static inline struct device_node *of_get_machineidpath(void)
> +{
> + return NULL;
> +}
> +
> static inline const char *of_get_model(void)
> {
> return NULL;
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the barebox
mailing list