[PATCH 1/5] common: machine_id: support /chosen/barebox, machine-id-path override

Ahmad Fatoum a.fatoum at pengutronix.de
Mon Jun 28 03:11:09 PDT 2021


Hello Basti,

On 28.06.21 11:35, Bastian Krause wrote:
> 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?

For barebox, I usually fold smaller changes into the commit that depends on them.
Sascha was ok with it so far. When the changes get bigger, I split them up,
but here I didn't deem this necessary.

> 
> 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