Re: [PATCH v15 2/8] remoteproc: Add TEE support
From: Arnaud POULIQUEN
Date: Tue Mar 25 2025 - 07:08:35 EST
On 12/6/24 23:07, Bjorn Andersson wrote:
> On Thu, Nov 28, 2024 at 09:42:09AM GMT, Arnaud Pouliquen wrote:
>> Add a remoteproc TEE (Trusted Execution Environment) driver
>> that will be probed by the TEE bus. If the associated Trusted
>> application is supported on secure part this driver offers a client
>> interface to load a firmware by the secure part.
>
> If...else?
>
>> This firmware could be authenticated by the secure trusted application.
>>
>
> I would like for this to fully describe how this fits with the bus and
> how it is expected to be used by a specific remoteproc driver.
>
>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@xxxxxxxxxxx>
>> ---
>> Updates vs version v13:
>> - define REMOTEPROC_TEE as bool instead of tristate,
>> - remove the load of the firmware in rproc_tee_parse_fw as we will ensure
>> that the firmware is loaded using the load_fw() operation.
>> ---
>> drivers/remoteproc/Kconfig | 10 +
>> drivers/remoteproc/Makefile | 1 +
>> drivers/remoteproc/remoteproc_tee.c | 508 ++++++++++++++++++++++++++++
>> include/linux/remoteproc.h | 4 +
>> include/linux/remoteproc_tee.h | 105 ++++++
>> 5 files changed, 628 insertions(+)
>> create mode 100644 drivers/remoteproc/remoteproc_tee.c
>> create mode 100644 include/linux/remoteproc_tee.h
[...]
>> +
>> +MODULE_DEVICE_TABLE(tee, rproc_tee_id_table);
>> +
>> +static struct tee_client_driver rproc_tee_fw_driver = {
>> + .id_table = rproc_tee_id_table,
>> + .driver = {
>> + .name = KBUILD_MODNAME,
>> + .bus = &tee_bus_type,
>> + .probe = rproc_tee_probe,
>> + .remove = rproc_tee_remove,
>> + },
>> +};
>> +
>> +static int __init rproc_tee_fw_mod_init(void)
>> +{
>> + return driver_register(&rproc_tee_fw_driver.driver);
>> +}
>> +
>> +static void __exit rproc_tee_fw_mod_exit(void)
>> +{
>> + driver_unregister(&rproc_tee_fw_driver.driver);
>> +}
>> +
>> +module_init(rproc_tee_fw_mod_init);
>> +module_exit(rproc_tee_fw_mod_exit);
>
> Please add an equivalent of the module_platform_driver() macro to tee
> framework instead of open-coding this.
>
It is not possible to use equivalent of the module_platform_driver() macro
as the device is on the TEE bus.
I followed recommendation provided in Documentation/driver-api/tee.rst[1]
Or do you have an alternative in mind?
Thanks,
Arnaud
[1]https://elixir.bootlin.com/linux/v6.14-rc6/source/Documentation/driver-api/tee.rst
>> +
>> +MODULE_DESCRIPTION(" remote processor TEE module");
>> +MODULE_LICENSE("GPL");
>> diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
>> index 8fd0d7f63c8e..2e0ddcb2d792 100644
>> --- a/include/linux/remoteproc.h
>> +++ b/include/linux/remoteproc.h
>> @@ -503,6 +503,8 @@ enum rproc_features {
>> RPROC_MAX_FEATURES,
>> };
>>
>> +struct rproc_tee;
>> +
>> /**
>> * struct rproc - represents a physical remote processor device
>> * @node: list node of this rproc object
>> @@ -545,6 +547,7 @@ enum rproc_features {
>> * @cdev: character device of the rproc
>> * @cdev_put_on_release: flag to indicate if remoteproc should be shutdown on @char_dev release
>> * @features: indicate remoteproc features
>> + * @rproc_tee_itf: pointer to the remoteproc tee context
>> */
>> struct rproc {
>> struct list_head node;
>> @@ -586,6 +589,7 @@ struct rproc {
>> struct cdev cdev;
>> bool cdev_put_on_release;
>> DECLARE_BITMAP(features, RPROC_MAX_FEATURES);
>> + struct rproc_tee *rproc_tee_itf;
>
> TEE is just one specific remoteproc implementation, why does it need to
> infest the core data structure? Do you want a stm32_rproc here as well?
>
>> };
>>
>> /**
>> diff --git a/include/linux/remoteproc_tee.h b/include/linux/remoteproc_tee.h
>> new file mode 100644
>> index 000000000000..9b498a8eff4d
>> --- /dev/null
>> +++ b/include/linux/remoteproc_tee.h
>> @@ -0,0 +1,105 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * Copyright(c) 2024 STMicroelectronics
>> + */
>> +
>> +#ifndef REMOTEPROC_TEE_H
>> +#define REMOTEPROC_TEE_H
>> +
>> +#include <linux/tee_drv.h>
>> +#include <linux/firmware.h>
>> +#include <linux/remoteproc.h>
>> +
>> +struct rproc;
>> +
>> +/**
>> + * struct rproc_tee - TEE remoteproc structure
>> + * @node: Reference in list
>> + * @rproc: Remoteproc reference
>> + * @parent: Parent device
>
> Isn't that rproc->dev->parent?
>
>> + * @rproc_id: Identifier of the target firmware
>> + * @session_id: TEE session identifier
>> + */
>> +struct rproc_tee {
>
> As far as I can tell this isn't dereferenced outside remoteproc_tee.c,
> can we hide it therein?
>
>> + struct list_head node;
>> + struct rproc *rproc;
>> + struct device *parent;
>> + u32 rproc_id;
>> + u32 session_id;
>> +};
>> +
>> +#if IS_REACHABLE(CONFIG_REMOTEPROC_TEE)
>> +
>> +int rproc_tee_register(struct device *dev, struct rproc *rproc, unsigned int rproc_id);
>> +int rproc_tee_unregister(struct rproc *rproc);
>> +int rproc_tee_parse_fw(struct rproc *rproc, const struct firmware *fw);
>> +int rproc_tee_load_fw(struct rproc *rproc, const struct firmware *fw);
>> +void rproc_tee_release_fw(struct rproc *rproc);
>> +struct resource_table *rproc_tee_find_loaded_rsc_table(struct rproc *rproc,
>> + const struct firmware *fw);
>> +int rproc_tee_start(struct rproc *rproc);
>> +int rproc_tee_stop(struct rproc *rproc);
>> +
>> +#else
>> +
>
> Do we really need yet another bunch of stubs? Can't we just leave
> CONFIG_REMOTEPROC_TEE non-user-selectable and have the drivers that rely
> on it do "select REMOTEPROC_TEE"?
>
> If my measurements are correct, it's 3.1kB of code...
>
> Regards,
> Bjorn
>
>> +static inline int rproc_tee_register(struct device *dev, struct rproc *rproc, unsigned int rproc_id)
>> +{
>> + return -ENODEV;
>> +}
>> +
>> +static inline int rproc_tee_parse_fw(struct rproc *rproc, const struct firmware *fw)
>> +{
>> + /* This shouldn't be possible */
>> + WARN_ON(1);
>> +
>> + return 0;
>> +}
>> +
>> +static inline int rproc_tee_unregister(struct rproc *rproc)
>> +{
>> + /* This shouldn't be possible */
>> + WARN_ON(1);
>> +
>> + return 0;
>> +}
>> +
>> +static inline int rproc_tee_load_fw(struct rproc *rproc, const struct firmware *fw)
>> +{
>> + /* This shouldn't be possible */
>> + WARN_ON(1);
>> +
>> + return 0;
>> +}
>> +
>> +static inline int rproc_tee_start(struct rproc *rproc)
>> +{
>> + /* This shouldn't be possible */
>> + WARN_ON(1);
>> +
>> + return 0;
>> +}
>> +
>> +static inline int rproc_tee_stop(struct rproc *rproc)
>> +{
>> + /* This shouldn't be possible */
>> + WARN_ON(1);
>> +
>> + return 0;
>> +}
>> +
>> +static inline void rproc_tee_release_fw(struct rproc *rproc)
>> +{
>> + /* This shouldn't be possible */
>> + WARN_ON(1);
>> +}
>> +
>> +static inline struct resource_table *
>> +rproc_tee_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
>> +{
>> + /* This shouldn't be possible */
>> + WARN_ON(1);
>> +
>> + return NULL;
>> +}
>> +#endif /* CONFIG_REMOTEPROC_TEE */
>> +#endif /* REMOTEPROC_TEE_H */
>> --
>> 2.25.1
>>
>