diff mbox series

[4/4] remoteproc: stm32: Add support of an OP-TEE TA to load the firmware

Message ID 20240115135249.296822-5-arnaud.pouliquen@foss.st.com
State New
Headers show
Series Introduction of a remoteproc tee to load signed firmware | expand

Commit Message

Arnaud Pouliquen Jan. 15, 2024, 1:52 p.m. UTC
The new TEE remoteproc device is used to manage remote firmware in a
secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
introduced to delegate the loading of the firmware to the trusted
execution context. In such cases, the firmware should be signed and
adhere to the image format defined by the TEE.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
---
 drivers/remoteproc/Kconfig       |   3 +-
 drivers/remoteproc/stm32_rproc.c | 149 +++++++++++++++++++++++++++++--
 2 files changed, 146 insertions(+), 6 deletions(-)

Comments

kernel test robot Jan. 16, 2024, 6:22 a.m. UTC | #1
Hi Arnaud,

kernel test robot noticed the following build warnings:

[auto build test WARNING on remoteproc/rproc-next]
[also build test WARNING on robh/for-next linus/master v6.7 next-20240112]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Arnaud-Pouliquen/remoteproc-Add-TEE-support/20240115-215613
base:   git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git rproc-next
patch link:    https://lore.kernel.org/r/20240115135249.296822-5-arnaud.pouliquen%40foss.st.com
patch subject: [PATCH 4/4] remoteproc: stm32: Add support of an OP-TEE TA to load the firmware
config: alpha-kismet-CONFIG_TEE_REMOTEPROC-CONFIG_STM32_RPROC-0-0 (https://download.01.org/0day-ci/archive/20240116/202401161447.0AQqNEiO-lkp@intel.com/config)
reproduce: (https://download.01.org/0day-ci/archive/20240116/202401161447.0AQqNEiO-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401161447.0AQqNEiO-lkp@intel.com/

kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for TEE_REMOTEPROC when selected by STM32_RPROC
   
   WARNING: unmet direct dependencies detected for TEE_REMOTEPROC
     Depends on [n]: REMOTEPROC [=y] && OPTEE [=n]
     Selected by [y]:
     - STM32_RPROC [=y] && (ARCH_STM32 || COMPILE_TEST [=y]) && REMOTEPROC [=y]
kernel test robot Jan. 16, 2024, 8:15 a.m. UTC | #2
Hi Arnaud,

kernel test robot noticed the following build warnings:

[auto build test WARNING on remoteproc/rproc-next]
[also build test WARNING on robh/for-next linus/master v6.7 next-20240112]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Arnaud-Pouliquen/remoteproc-Add-TEE-support/20240115-215613
base:   git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git rproc-next
patch link:    https://lore.kernel.org/r/20240115135249.296822-5-arnaud.pouliquen%40foss.st.com
patch subject: [PATCH 4/4] remoteproc: stm32: Add support of an OP-TEE TA to load the firmware
config: um-randconfig-r113-20240116 (https://download.01.org/0day-ci/archive/20240116/202401161552.JWQXL1kD-lkp@intel.com/config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240116/202401161552.JWQXL1kD-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401161552.JWQXL1kD-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/remoteproc/tee_remoteproc.c:82:26: sparse: sparse: symbol 'tee_rproc_ctx' was not declared. Should it be static?
>> drivers/remoteproc/tee_remoteproc.c:166:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected void *rsc_va @@     got void [noderef] __iomem * @@
   drivers/remoteproc/tee_remoteproc.c:166:24: sparse:     expected void *rsc_va
   drivers/remoteproc/tee_remoteproc.c:166:24: sparse:     got void [noderef] __iomem *
>> drivers/remoteproc/tee_remoteproc.c:233:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void volatile [noderef] __iomem *addr @@     got void *rsc_va @@
   drivers/remoteproc/tee_remoteproc.c:233:31: sparse:     expected void volatile [noderef] __iomem *addr
   drivers/remoteproc/tee_remoteproc.c:233:31: sparse:     got void *rsc_va
   drivers/remoteproc/tee_remoteproc.c: note: in included file (through include/linux/preempt.h, include/linux/spinlock.h, include/linux/mmzone.h, ...):
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true

vim +/tee_rproc_ctx +82 drivers/remoteproc/tee_remoteproc.c

6805d1065198e1 Arnaud Pouliquen 2024-01-15   81  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  @82  struct tee_rproc_context *tee_rproc_ctx;
6805d1065198e1 Arnaud Pouliquen 2024-01-15   83  
6805d1065198e1 Arnaud Pouliquen 2024-01-15   84  static void prepare_args(struct tee_rproc *trproc, int cmd, struct tee_ioctl_invoke_arg *arg,
6805d1065198e1 Arnaud Pouliquen 2024-01-15   85  			 struct tee_param *param, unsigned int num_params)
6805d1065198e1 Arnaud Pouliquen 2024-01-15   86  {
6805d1065198e1 Arnaud Pouliquen 2024-01-15   87  	memset(arg, 0, sizeof(*arg));
6805d1065198e1 Arnaud Pouliquen 2024-01-15   88  	memset(param, 0, MAX_TEE_PARAM_ARRY_MEMBER * sizeof(*param));
6805d1065198e1 Arnaud Pouliquen 2024-01-15   89  
6805d1065198e1 Arnaud Pouliquen 2024-01-15   90  	arg->func = cmd;
6805d1065198e1 Arnaud Pouliquen 2024-01-15   91  	arg->session = trproc->session_id;
6805d1065198e1 Arnaud Pouliquen 2024-01-15   92  	arg->num_params = num_params + 1;
6805d1065198e1 Arnaud Pouliquen 2024-01-15   93  
6805d1065198e1 Arnaud Pouliquen 2024-01-15   94  	param[0] = (struct tee_param) {
6805d1065198e1 Arnaud Pouliquen 2024-01-15   95  		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
6805d1065198e1 Arnaud Pouliquen 2024-01-15   96  		.u.value.a = trproc->rproc_id,
6805d1065198e1 Arnaud Pouliquen 2024-01-15   97  	};
6805d1065198e1 Arnaud Pouliquen 2024-01-15   98  }
6805d1065198e1 Arnaud Pouliquen 2024-01-15   99  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  100  int tee_rproc_load_fw(struct tee_rproc *trproc, const struct firmware *fw)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  101  {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  102  	struct tee_ioctl_invoke_arg arg;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  103  	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
6805d1065198e1 Arnaud Pouliquen 2024-01-15  104  	struct tee_shm *fw_shm;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  105  	int ret;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  106  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  107  	fw_shm = tee_shm_register_kernel_buf(tee_rproc_ctx->tee_ctx, (void *)fw->data, fw->size);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  108  	if (IS_ERR(fw_shm))
6805d1065198e1 Arnaud Pouliquen 2024-01-15  109  		return PTR_ERR(fw_shm);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  110  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  111  	prepare_args(trproc, TA_RPROC_FW_CMD_LOAD_FW, &arg, param, 1);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  112  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  113  	/* Provide the address of the firmware image */
6805d1065198e1 Arnaud Pouliquen 2024-01-15  114  	param[1] = (struct tee_param) {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  115  		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
6805d1065198e1 Arnaud Pouliquen 2024-01-15  116  		.u.memref = {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  117  			.shm = fw_shm,
6805d1065198e1 Arnaud Pouliquen 2024-01-15  118  			.size = fw->size,
6805d1065198e1 Arnaud Pouliquen 2024-01-15  119  			.shm_offs = 0,
6805d1065198e1 Arnaud Pouliquen 2024-01-15  120  		},
6805d1065198e1 Arnaud Pouliquen 2024-01-15  121  	};
6805d1065198e1 Arnaud Pouliquen 2024-01-15  122  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  123  	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  124  	if (ret < 0 || arg.ret != 0) {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  125  		dev_err(tee_rproc_ctx->dev,
6805d1065198e1 Arnaud Pouliquen 2024-01-15  126  			"TA_RPROC_FW_CMD_LOAD_FW invoke failed TEE err: %x, ret:%x\n",
6805d1065198e1 Arnaud Pouliquen 2024-01-15  127  			arg.ret, ret);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  128  		if (!ret)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  129  			ret = -EIO;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  130  	}
6805d1065198e1 Arnaud Pouliquen 2024-01-15  131  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  132  	tee_shm_free(fw_shm);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  133  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  134  	return ret;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  135  }
6805d1065198e1 Arnaud Pouliquen 2024-01-15  136  EXPORT_SYMBOL_GPL(tee_rproc_load_fw);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  137  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  138  int rproc_tee_get_rsc_table(struct tee_rproc *trproc)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  139  {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  140  	struct tee_ioctl_invoke_arg arg;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  141  	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
6805d1065198e1 Arnaud Pouliquen 2024-01-15  142  	struct rproc *rproc = trproc->rproc;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  143  	size_t rsc_size;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  144  	int ret;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  145  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  146  	prepare_args(trproc, TA_RPROC_FW_CMD_GET_RSC_TABLE, &arg, param, 2);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  147  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  148  	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  149  	param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  150  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  151  	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  152  	if (ret < 0 || arg.ret != 0) {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  153  		dev_err(tee_rproc_ctx->dev,
6805d1065198e1 Arnaud Pouliquen 2024-01-15  154  			"TA_RPROC_FW_CMD_GET_RSC_TABLE invoke failed TEE err: %x, ret:%x\n",
6805d1065198e1 Arnaud Pouliquen 2024-01-15  155  			arg.ret, ret);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  156  		return -EIO;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  157  	}
6805d1065198e1 Arnaud Pouliquen 2024-01-15  158  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  159  	rsc_size = param[2].u.value.a;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  160  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  161  	/* If the size is null no resource table defined in the image */
6805d1065198e1 Arnaud Pouliquen 2024-01-15  162  	if (!rsc_size)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  163  		return 0;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  164  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  165  	/* Store the resource table address that would be updated by the remote core . */
6805d1065198e1 Arnaud Pouliquen 2024-01-15 @166  	trproc->rsc_va = ioremap_wc(param[1].u.value.a, rsc_size);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  167  	if (IS_ERR_OR_NULL(trproc->rsc_va)) {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  168  		dev_err(tee_rproc_ctx->dev, "Unable to map memory region: %lld+%zx\n",
6805d1065198e1 Arnaud Pouliquen 2024-01-15  169  			param[1].u.value.a, rsc_size);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  170  		trproc->rsc_va = NULL;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  171  		return -ENOMEM;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  172  	}
6805d1065198e1 Arnaud Pouliquen 2024-01-15  173  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  174  	/*
6805d1065198e1 Arnaud Pouliquen 2024-01-15  175  	 * A cached table is requested as the physical address is not mapped yet
6805d1065198e1 Arnaud Pouliquen 2024-01-15  176  	 * but remoteproc needs to parse the table for resources.
6805d1065198e1 Arnaud Pouliquen 2024-01-15  177  	 */
6805d1065198e1 Arnaud Pouliquen 2024-01-15  178  	rproc->cached_table = kmemdup(trproc->rsc_va, rsc_size, GFP_KERNEL);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  179  	if (!rproc->cached_table)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  180  		return -ENOMEM;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  181  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  182  	rproc->table_ptr = rproc->cached_table;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  183  	rproc->table_sz = rsc_size;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  184  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  185  	return 0;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  186  }
6805d1065198e1 Arnaud Pouliquen 2024-01-15  187  EXPORT_SYMBOL_GPL(rproc_tee_get_rsc_table);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  188  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  189  struct resource_table *tee_rproc_get_loaded_rsc_table(struct tee_rproc *trproc)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  190  {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  191  	return (struct resource_table *)trproc->rsc_va;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  192  }
6805d1065198e1 Arnaud Pouliquen 2024-01-15  193  EXPORT_SYMBOL_GPL(tee_rproc_get_loaded_rsc_table);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  194  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  195  int tee_rproc_start(struct tee_rproc *trproc)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  196  {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  197  	struct tee_ioctl_invoke_arg arg;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  198  	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
6805d1065198e1 Arnaud Pouliquen 2024-01-15  199  	int ret;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  200  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  201  	prepare_args(trproc, TA_RPROC_FW_CMD_START_FW, &arg, param, 0);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  202  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  203  	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  204  	if (ret < 0 || arg.ret != 0) {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  205  		dev_err(tee_rproc_ctx->dev,
6805d1065198e1 Arnaud Pouliquen 2024-01-15  206  			"TA_RPROC_FW_CMD_START_FW invoke failed TEE err: %x, ret:%x\n",
6805d1065198e1 Arnaud Pouliquen 2024-01-15  207  			arg.ret, ret);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  208  		if (!ret)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  209  			ret = -EIO;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  210  	}
6805d1065198e1 Arnaud Pouliquen 2024-01-15  211  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  212  	return ret;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  213  }
6805d1065198e1 Arnaud Pouliquen 2024-01-15  214  EXPORT_SYMBOL_GPL(tee_rproc_start);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  215  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  216  int tee_rproc_stop(struct tee_rproc *trproc)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  217  {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  218  	struct tee_ioctl_invoke_arg arg;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  219  	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
6805d1065198e1 Arnaud Pouliquen 2024-01-15  220  	int ret;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  221  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  222  	prepare_args(trproc, TA_RPROC_FW_CMD_STOP_FW, &arg, param, 0);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  223  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  224  	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  225  	if (ret < 0 || arg.ret != 0) {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  226  		dev_err(tee_rproc_ctx->dev,
6805d1065198e1 Arnaud Pouliquen 2024-01-15  227  			"TA_RPROC_FW_CMD_STOP_FW invoke failed TEE err: %x, ret:%x\n",
6805d1065198e1 Arnaud Pouliquen 2024-01-15  228  			arg.ret, ret);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  229  		if (!ret)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  230  			ret = -EIO;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  231  	}
6805d1065198e1 Arnaud Pouliquen 2024-01-15  232  	if (trproc->rsc_va)
6805d1065198e1 Arnaud Pouliquen 2024-01-15 @233  		iounmap(trproc->rsc_va);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  234  	trproc->rsc_va = NULL;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  235  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  236  	return ret;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  237  }
6805d1065198e1 Arnaud Pouliquen 2024-01-15  238  EXPORT_SYMBOL_GPL(tee_rproc_stop);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  239
kernel test robot Jan. 16, 2024, 8:46 a.m. UTC | #3
Hi Arnaud,

kernel test robot noticed the following build warnings:

[auto build test WARNING on remoteproc/rproc-next]
[also build test WARNING on robh/for-next linus/master v6.7 next-20240112]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Arnaud-Pouliquen/remoteproc-Add-TEE-support/20240115-215613
base:   git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git rproc-next
patch link:    https://lore.kernel.org/r/20240115135249.296822-5-arnaud.pouliquen%40foss.st.com
patch subject: [PATCH 4/4] remoteproc: stm32: Add support of an OP-TEE TA to load the firmware
config: arm64-allyesconfig (https://download.01.org/0day-ci/archive/20240116/202401161603.5dloSqiJ-lkp@intel.com/config)
compiler: clang version 18.0.0git (https://github.com/llvm/llvm-project 9bde5becb44ea071f5e1fa1f5d4071dc8788b18c)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240116/202401161603.5dloSqiJ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401161603.5dloSqiJ-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/remoteproc/stm32_rproc.c:977:6: warning: variable 'trproc' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
     977 |         if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
         |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/remoteproc/stm32_rproc.c:991:8: note: uninitialized use occurs here
     991 |                             trproc ? &st_rproc_tee_ops : &st_rproc_ops,
         |                             ^~~~~~
   drivers/remoteproc/stm32_rproc.c:977:2: note: remove the 'if' if its condition is always true
     977 |         if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/remoteproc/stm32_rproc.c:968:26: note: initialize the variable 'trproc' to silence this warning
     968 |         struct tee_rproc *trproc;
         |                                 ^
         |                                  = NULL
   1 warning generated.


vim +977 drivers/remoteproc/stm32_rproc.c

   962	
   963	static int stm32_rproc_probe(struct platform_device *pdev)
   964	{
   965		struct device *dev = &pdev->dev;
   966		struct stm32_rproc *ddata;
   967		struct device_node *np = dev->of_node;
   968		struct tee_rproc *trproc;
   969		struct rproc *rproc;
   970		unsigned int state;
   971		int ret;
   972	
   973		ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
   974		if (ret)
   975			return ret;
   976	
 > 977		if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
   978			trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
   979			if (IS_ERR(trproc)) {
   980				dev_err_probe(dev, PTR_ERR(trproc),
   981					      "signed firmware not supported by TEE\n");
   982				return PTR_ERR(trproc);
   983			}
   984			/*
   985			 * Delegate the firmware management to the secure context.
   986			 * The firmware loaded has to be signed.
   987			 */
   988			dev_info(dev, "Support of signed firmware only\n");
   989		}
   990		rproc = rproc_alloc(dev, np->name,
   991				    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
   992				    NULL, sizeof(*ddata));
   993		if (!rproc) {
   994			ret = -ENOMEM;
   995			goto free_tee;
   996		}
   997	
   998		ddata = rproc->priv;
   999		ddata->trproc = trproc;
  1000		if (trproc)
  1001			trproc->rproc = rproc;
  1002	
  1003		rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
  1004	
  1005		ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot);
  1006		if (ret)
  1007			goto free_rproc;
  1008	
  1009		ret = stm32_rproc_of_memory_translations(pdev, ddata);
  1010		if (ret)
  1011			goto free_rproc;
  1012	
  1013		ret = stm32_rproc_get_m4_status(ddata, &state);
  1014		if (ret)
  1015			goto free_rproc;
  1016	
  1017		if (state == M4_STATE_CRUN)
  1018			rproc->state = RPROC_DETACHED;
  1019	
  1020		rproc->has_iommu = false;
  1021		ddata->workqueue = create_workqueue(dev_name(dev));
  1022		if (!ddata->workqueue) {
  1023			dev_err(dev, "cannot create workqueue\n");
  1024			ret = -ENOMEM;
  1025			goto free_resources;
  1026		}
  1027	
  1028		platform_set_drvdata(pdev, rproc);
  1029	
  1030		ret = stm32_rproc_request_mbox(rproc);
  1031		if (ret)
  1032			goto free_wkq;
  1033	
  1034		ret = rproc_add(rproc);
  1035		if (ret)
  1036			goto free_mb;
  1037	
  1038		return 0;
  1039	
  1040	free_mb:
  1041		stm32_rproc_free_mbox(rproc);
  1042	free_wkq:
  1043		destroy_workqueue(ddata->workqueue);
  1044	free_resources:
  1045		rproc_resource_cleanup(rproc);
  1046	free_rproc:
  1047		if (device_may_wakeup(dev)) {
  1048			dev_pm_clear_wake_irq(dev);
  1049			device_init_wakeup(dev, false);
  1050		}
  1051		rproc_free(rproc);
  1052	free_tee:
  1053		if (trproc)
  1054			tee_rproc_unregister(trproc);
  1055	
  1056		return ret;
  1057	}
  1058
kernel test robot Jan. 17, 2024, 11:49 p.m. UTC | #4
Hi Arnaud,

kernel test robot noticed the following build warnings:

[auto build test WARNING on remoteproc/rproc-next]
[also build test WARNING on robh/for-next linus/master v6.7 next-20240117]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Arnaud-Pouliquen/remoteproc-Add-TEE-support/20240115-215613
base:   git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git rproc-next
patch link:    https://lore.kernel.org/r/20240115135249.296822-5-arnaud.pouliquen%40foss.st.com
patch subject: [PATCH 4/4] remoteproc: stm32: Add support of an OP-TEE TA to load the firmware
config: mips-randconfig-r112-20240117 (https://download.01.org/0day-ci/archive/20240118/202401180740.1ud9PJYn-lkp@intel.com/config)
compiler: clang version 18.0.0git (https://github.com/llvm/llvm-project 9bde5becb44ea071f5e1fa1f5d4071dc8788b18c)
reproduce: (https://download.01.org/0day-ci/archive/20240118/202401180740.1ud9PJYn-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401180740.1ud9PJYn-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   drivers/remoteproc/tee_remoteproc.c:82:26: sparse: sparse: symbol 'tee_rproc_ctx' was not declared. Should it be static?
   drivers/remoteproc/tee_remoteproc.c:166:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected void *rsc_va @@     got void [noderef] __iomem * @@
   drivers/remoteproc/tee_remoteproc.c:166:24: sparse:     expected void *rsc_va
   drivers/remoteproc/tee_remoteproc.c:166:24: sparse:     got void [noderef] __iomem *
>> drivers/remoteproc/tee_remoteproc.c:233:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *rsc_va @@
   drivers/remoteproc/tee_remoteproc.c:233:31: sparse:     expected void const volatile [noderef] __iomem *addr
   drivers/remoteproc/tee_remoteproc.c:233:31: sparse:     got void *rsc_va
   drivers/remoteproc/tee_remoteproc.c: note: in included file (through include/linux/preempt.h, include/linux/spinlock.h, include/linux/mmzone.h, ...):
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true

vim +233 drivers/remoteproc/tee_remoteproc.c

6805d1065198e1 Arnaud Pouliquen 2024-01-15  215  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  216  int tee_rproc_stop(struct tee_rproc *trproc)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  217  {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  218  	struct tee_ioctl_invoke_arg arg;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  219  	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
6805d1065198e1 Arnaud Pouliquen 2024-01-15  220  	int ret;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  221  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  222  	prepare_args(trproc, TA_RPROC_FW_CMD_STOP_FW, &arg, param, 0);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  223  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  224  	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  225  	if (ret < 0 || arg.ret != 0) {
6805d1065198e1 Arnaud Pouliquen 2024-01-15  226  		dev_err(tee_rproc_ctx->dev,
6805d1065198e1 Arnaud Pouliquen 2024-01-15  227  			"TA_RPROC_FW_CMD_STOP_FW invoke failed TEE err: %x, ret:%x\n",
6805d1065198e1 Arnaud Pouliquen 2024-01-15  228  			arg.ret, ret);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  229  		if (!ret)
6805d1065198e1 Arnaud Pouliquen 2024-01-15  230  			ret = -EIO;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  231  	}
6805d1065198e1 Arnaud Pouliquen 2024-01-15  232  	if (trproc->rsc_va)
6805d1065198e1 Arnaud Pouliquen 2024-01-15 @233  		iounmap(trproc->rsc_va);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  234  	trproc->rsc_va = NULL;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  235  
6805d1065198e1 Arnaud Pouliquen 2024-01-15  236  	return ret;
6805d1065198e1 Arnaud Pouliquen 2024-01-15  237  }
6805d1065198e1 Arnaud Pouliquen 2024-01-15  238  EXPORT_SYMBOL_GPL(tee_rproc_stop);
6805d1065198e1 Arnaud Pouliquen 2024-01-15  239
diff mbox series

Patch

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 85299606806c..e5bb675b5fc5 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -316,6 +316,7 @@  config STM32_RPROC
 	depends on ARCH_STM32 || COMPILE_TEST
 	depends on REMOTEPROC
 	select MAILBOX
+	select TEE_REMOTEPROC
 	help
 	  Say y here to support STM32 MCU processors via the
 	  remote processor framework.
@@ -367,7 +368,7 @@  config XLNX_R5_REMOTEPROC
 
 
 config TEE_REMOTEPROC
-	tristate "trusted firmware support by a TEE application"
+	tristate "trusted firmware support by a trusted application"
 	depends on OPTEE
 	help
 	  Support for trusted remote processors firmware. The firmware
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index fcc0001e2657..16dcf36ceeb6 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -20,6 +20,7 @@ 
 #include <linux/remoteproc.h>
 #include <linux/reset.h>
 #include <linux/slab.h>
+#include <linux/tee_remoteproc.h>
 #include <linux/workqueue.h>
 
 #include "remoteproc_internal.h"
@@ -49,6 +50,9 @@ 
 #define M4_STATE_STANDBY	4
 #define M4_STATE_CRASH		5
 
+/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
+#define STM32_MP1_M4_PROC_ID    0
+
 struct stm32_syscon {
 	struct regmap *map;
 	u32 reg;
@@ -90,6 +94,8 @@  struct stm32_rproc {
 	struct stm32_mbox mb[MBOX_NB_MBX];
 	struct workqueue_struct *workqueue;
 	bool hold_boot_smc;
+	bool fw_loaded;
+	struct tee_rproc *trproc;
 	void __iomem *rsc_va;
 };
 
@@ -257,6 +263,91 @@  static int stm32_rproc_release(struct rproc *rproc)
 	return err;
 }
 
+static int stm32_rproc_tee_elf_sanity_check(struct rproc *rproc,
+					    const struct firmware *fw)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+	unsigned int ret = 0;
+
+	if (rproc->state == RPROC_DETACHED)
+		return 0;
+
+	ret = tee_rproc_load_fw(ddata->trproc, fw);
+	if (!ret)
+		ddata->fw_loaded = true;
+
+	return ret;
+}
+
+static int stm32_rproc_tee_elf_load(struct rproc *rproc,
+				    const struct firmware *fw)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+	unsigned int ret;
+
+	/*
+	 * This function can be called by remote proc for recovery
+	 * without the sanity check. In this case we need to load the firmware
+	 * else nothing done here as the firmware has been preloaded for the
+	 * sanity check to be able to parse it for the resource table.
+	 */
+	if (ddata->fw_loaded)
+		return 0;
+
+	ret = tee_rproc_load_fw(ddata->trproc, fw);
+	if (ret)
+		return ret;
+	ddata->fw_loaded = true;
+
+	/* Update the resource table parameters. */
+	if (rproc_tee_get_rsc_table(ddata->trproc)) {
+		/* No resource table: reset the related fields. */
+		rproc->cached_table = NULL;
+		rproc->table_ptr = NULL;
+		rproc->table_sz = 0;
+	}
+
+	return 0;
+}
+
+static struct resource_table *
+stm32_rproc_tee_elf_find_loaded_rsc_table(struct rproc *rproc,
+					  const struct firmware *fw)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+
+	return tee_rproc_get_loaded_rsc_table(ddata->trproc);
+}
+
+static int stm32_rproc_tee_start(struct rproc *rproc)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+
+	return tee_rproc_start(ddata->trproc);
+}
+
+static int stm32_rproc_tee_attach(struct rproc *rproc)
+{
+	/* Nothing to do, remote proc already started by the secured context. */
+	return 0;
+}
+
+static int stm32_rproc_tee_stop(struct rproc *rproc)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+	int err;
+
+	stm32_rproc_request_shutdown(rproc);
+
+	err = tee_rproc_stop(ddata->trproc);
+	if (err)
+		return err;
+
+	ddata->fw_loaded = false;
+
+	return stm32_rproc_release(rproc);
+}
+
 static int stm32_rproc_prepare(struct rproc *rproc)
 {
 	struct device *dev = rproc->dev.parent;
@@ -319,7 +410,14 @@  static int stm32_rproc_prepare(struct rproc *rproc)
 
 static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
 {
-	if (rproc_elf_load_rsc_table(rproc, fw))
+	struct stm32_rproc *ddata = rproc->priv;
+	int ret;
+
+	if (ddata->trproc)
+		ret = rproc_tee_get_rsc_table(ddata->trproc);
+	else
+		ret = rproc_elf_load_rsc_table(rproc, fw);
+	if (ret)
 		dev_warn(&rproc->dev, "no resource table found for this firmware\n");
 
 	return 0;
@@ -693,8 +791,22 @@  static const struct rproc_ops st_rproc_ops = {
 	.get_boot_addr	= rproc_elf_get_boot_addr,
 };
 
+static const struct rproc_ops st_rproc_tee_ops = {
+	.prepare	= stm32_rproc_prepare,
+	.start		= stm32_rproc_tee_start,
+	.stop		= stm32_rproc_tee_stop,
+	.attach		= stm32_rproc_tee_attach,
+	.kick		= stm32_rproc_kick,
+	.parse_fw	= stm32_rproc_parse_fw,
+	.find_loaded_rsc_table = stm32_rproc_tee_elf_find_loaded_rsc_table,
+	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
+	.sanity_check	= stm32_rproc_tee_elf_sanity_check,
+	.load		= stm32_rproc_tee_elf_load,
+};
+
 static const struct of_device_id stm32_rproc_match[] = {
-	{ .compatible = "st,stm32mp1-m4" },
+	{.compatible = "st,stm32mp1-m4",},
+	{.compatible = "st,stm32mp1-m4-tee",},
 	{},
 };
 MODULE_DEVICE_TABLE(of, stm32_rproc_match);
@@ -853,6 +965,7 @@  static int stm32_rproc_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct stm32_rproc *ddata;
 	struct device_node *np = dev->of_node;
+	struct tee_rproc *trproc;
 	struct rproc *rproc;
 	unsigned int state;
 	int ret;
@@ -861,11 +974,31 @@  static int stm32_rproc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
-	if (!rproc)
-		return -ENOMEM;
+	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
+		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
+		if (IS_ERR(trproc)) {
+			dev_err_probe(dev, PTR_ERR(trproc),
+				      "signed firmware not supported by TEE\n");
+			return PTR_ERR(trproc);
+		}
+		/*
+		 * Delegate the firmware management to the secure context.
+		 * The firmware loaded has to be signed.
+		 */
+		dev_info(dev, "Support of signed firmware only\n");
+	}
+	rproc = rproc_alloc(dev, np->name,
+			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
+			    NULL, sizeof(*ddata));
+	if (!rproc) {
+		ret = -ENOMEM;
+		goto free_tee;
+	}
 
 	ddata = rproc->priv;
+	ddata->trproc = trproc;
+	if (trproc)
+		trproc->rproc = rproc;
 
 	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
 
@@ -916,6 +1049,10 @@  static int stm32_rproc_probe(struct platform_device *pdev)
 		device_init_wakeup(dev, false);
 	}
 	rproc_free(rproc);
+free_tee:
+	if (trproc)
+		tee_rproc_unregister(trproc);
+
 	return ret;
 }
 
@@ -937,6 +1074,8 @@  static void stm32_rproc_remove(struct platform_device *pdev)
 		device_init_wakeup(dev, false);
 	}
 	rproc_free(rproc);
+	if (ddata->trproc)
+		tee_rproc_unregister(ddata->trproc);
 }
 
 static int stm32_rproc_suspend(struct device *dev)