From nobody Fri Oct 10 04:08:14 2025 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B38491E493C; Mon, 16 Jun 2025 07:58:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060723; cv=none; b=PDXKY0ARpr2QVUcYSpmSvoOdJe/+DFsymp1QxLM1yttgNnV5wuMcHmRieMyjsPiU8H4Ic/Oi4Z0a91Q53B6mzgjAoAADhw2kDvRjiDAm9uUQ6CIXsCPtnK+1fQD1pDBnYEB7Hd21bK8mSkhHutXq+oTtEEaOod44eOO79hkMq4w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060723; c=relaxed/simple; bh=jCWWkrmEJfZ25so82ytPFoQiKJzvNYkyN981ikbuWHI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=f8qGedEdWBmcYLz+IjUg7nClEFRsdhjg50j61R/lSck8hB2FvdHX1rxtZTTns0h4H7AliOY4wd/De/kEsUpn5flIjoERHCeJz9w0+yfuKPu4mkpN8QsD/oXhBP2y+Wnq03cE+66S7e12Rc7m+mCbAvDGMTxR4SckZyZpvizSI1M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=qcNBDwSC; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="qcNBDwSC" Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55G3RlrK001745; Mon, 16 Jun 2025 09:58:17 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=selector1; bh= Qukd4stYOCYEBe2KGcf2tpYpRWJZmwskg2vfqUfUsKY=; b=qcNBDwSCZyTIGiuz 9lawJymhFNS80QgpYOdmnVRptUI+anTbvbIUSzrujY0OhOswOz0lgbul6MJOMhj8 P+Qwo3+frh2swX2f2xjuHmG4CDuUbbebpGIsbpFo59aS9iD5uTI5DNq40xqWBZqE xaMlunIJ8DqMGbyFX0ffKJMdvTkgaKJnVfZJBO3oW1d5cElIRt7Wuvy7169ljX5e TrGC5bb/CD1n7P2VydM9E1RN88uJu3eo1CD5gFRACZQyOk2U/Xojfgs4Ax/Y1a4s q5TmSBxplOayoc1wxc/8mWn2RSqI4YeotXzAxXXxXPNWN6jvSbhXv7L+l2mAH5Af jicFpA== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 4790e1yc76-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 16 Jun 2025 09:58:17 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 9DE8F4006F; Mon, 16 Jun 2025 09:57:08 +0200 (CEST) Received: from Webmail-eu.st.com (eqndag1node5.st.com [10.75.129.134]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 6E43F4CB02D; Mon, 16 Jun 2025 09:56:20 +0200 (CEST) Received: from SAFDAG1NODE1.st.com (10.75.90.17) by EQNDAG1NODE5.st.com (10.75.129.134) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:20 +0200 Received: from localhost (10.48.86.121) by SAFDAG1NODE1.st.com (10.75.90.17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:19 +0200 From: Arnaud Pouliquen To: Bjorn Andersson , Mathieu Poirier , Jens Wiklander , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" CC: , , , , , , Arnaud Pouliquen Subject: [PATCH v18 1/6] remoteproc: core: Introduce rproc_pa_to_va helper Date: Mon, 16 Jun 2025 09:55:25 +0200 Message-ID: <20250616075530.4106090-2-arnaud.pouliquen@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> References: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SHFCAS1NODE2.st.com (10.75.129.73) To SAFDAG1NODE1.st.com (10.75.90.17) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-16_03,2025-06-13_01,2025-03-28_01 Content-Type: text/plain; charset="utf-8" When a resource table is loaded by an external entity such as U-boot or OP-TEE, we do not necessarily get the device address(da) but the physical address(pa). This helper performs similar translation than the rproc_da_to_va() but based on a physical address. Signed-off-by: Arnaud Pouliquen --- drivers/remoteproc/remoteproc_core.c | 46 ++++++++++++++++++++++++++++ include/linux/remoteproc.h | 1 + 2 files changed, 47 insertions(+) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remo= teproc_core.c index 81b2ccf988e8..d06eef1fa424 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -230,6 +230,52 @@ void *rproc_da_to_va(struct rproc *rproc, u64 da, size= _t len, bool *is_iomem) } EXPORT_SYMBOL(rproc_da_to_va); =20 +/** + * rproc_pa_to_va() - lookup the kernel virtual address for a physical add= ress of a remoteproc + * memory + * + * @rproc: handle of a remote processor + * @pa: remoteproc physical address + * @len: length of the memory region @pa is pointing to + * @is_iomem: optional pointer filled in to indicate if @da is iomapped me= mory + * + * This function is a helper function similar to rproc_da_to_va() but it d= eals with physical + * addresses instead of device addresses. + * + * Return: a valid kernel address on success or NULL on failure + */ +void *rproc_pa_to_va(struct rproc *rproc, phys_addr_t pa, size_t len, bool= *is_iomem) +{ + struct rproc_mem_entry *carveout; + void *ptr =3D NULL; + + list_for_each_entry(carveout, &rproc->carveouts, node) { + int offset =3D pa - carveout->dma; + + /* Verify that carveout is allocated */ + if (!carveout->va) + continue; + + /* try next carveout if da is too small */ + if (offset < 0) + continue; + + /* try next carveout if da is too large */ + if (offset + len > carveout->len) + continue; + + ptr =3D carveout->va + offset; + + if (is_iomem) + *is_iomem =3D carveout->is_iomem; + + break; + } + + return ptr; +} +EXPORT_SYMBOL(rproc_pa_to_va); + /** * rproc_find_carveout_by_name() - lookup the carveout region by a name * @rproc: handle of a remote processor diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index b4795698d8c2..8fd0d7f63c8e 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -690,6 +690,7 @@ int rproc_detach(struct rproc *rproc); int rproc_set_firmware(struct rproc *rproc, const char *fw_name); void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iom= em); +void *rproc_pa_to_va(struct rproc *rproc, phys_addr_t pa, size_t len, bool= *is_iomem); =20 /* from remoteproc_coredump.c */ void rproc_coredump_cleanup(struct rproc *rproc); --=20 2.25.1 From nobody Fri Oct 10 04:08:14 2025 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C98361F4CAE; Mon, 16 Jun 2025 07:58:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060725; cv=none; b=kb4DXEe6tG5JEhf9aky0roUKEafgahaxM5coUPscQvDIagF8T7oiUwM7JaA9L2q3oGgiWkMSA1fMNXxoKnIxo0ZW9+N2FV8PrwZqscCWiJxKXZ01TYO0SOYZ7k1rU5uqT0u8iPRQp2E77cHYqhNVV12WQDnU7b5FIyueDukMxZM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060725; c=relaxed/simple; bh=Z8Cc1cqg1Y6mQIXa84OggAcV43tneCQVxeNOqc+7glg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=AGFBy1gnOvLARg1CPHDTEnqWi0OUWq8TRC0OSoD+9WE6JYZJXcrWWkQfXClRAtbs8Q+WpI1tqMc3NMtHDscS5ZzTIaMzpf/61FXzkiu1gLpIvbAREPAfpaWnrr5Yv4YtLsWd/2++WWVwzVk7Vuuq2oLPsRtG0xuAdc8V3z0orgg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=0c9dIwqu; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="0c9dIwqu" Received: from pps.filterd (m0369458.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55G7CeYR023399; Mon, 16 Jun 2025 09:58:24 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=selector1; bh= +i+lHnX/EVN6vrUR/l0h3RKfh8qCpnxHX7P/NPNW0MI=; b=0c9dIwquGTCJzkh5 kaVkI/G/WS1MF/3J+l+qvKcMlBgasLXNergy+PuWRE6Dpj+raFdyGym3csrLhVQG aAAUQb2HlED9J56P2wQKBqErZUI3kFQHvCvg3zELbgMBU+3zYzdod39CGprdW04W 2ZMGwEaDcPND/CZbfCWOus9Je76h3hIiMVc2dJ38Ru0iTSzapS6Nm2IuqFUHZ2qc EZsEJDJ8BMxGh6lNyxxP1DQB5l+KmxUvm3UIVWMvW5xfi9VF6UlnmI/baZhGFrpD eZkOYK9IkddYsPz6NU5QhHIZgb+7NkpeevHXdZL4bqnG1ZCR/xbs9lTiLjuBpXGg VQ+Erg== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 479jn4m31j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 16 Jun 2025 09:58:24 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 863D34005A; Mon, 16 Jun 2025 09:57:12 +0200 (CEST) Received: from Webmail-eu.st.com (eqndag1node4.st.com [10.75.129.133]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 391264CB032; Mon, 16 Jun 2025 09:56:21 +0200 (CEST) Received: from SAFDAG1NODE1.st.com (10.75.90.17) by EQNDAG1NODE4.st.com (10.75.129.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:21 +0200 Received: from localhost (10.48.86.121) by SAFDAG1NODE1.st.com (10.75.90.17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:20 +0200 From: Arnaud Pouliquen To: Bjorn Andersson , Mathieu Poirier , Jens Wiklander , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" CC: , , , , , , Arnaud Pouliquen Subject: [PATCH v18 2/6] remoteproc: Add TEE support Date: Mon, 16 Jun 2025 09:55:26 +0200 Message-ID: <20250616075530.4106090-3-arnaud.pouliquen@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> References: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SHFCAS1NODE2.st.com (10.75.129.73) To SAFDAG1NODE1.st.com (10.75.90.17) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-16_03,2025-06-13_01,2025-03-28_01 Content-Type: text/plain; charset="utf-8" Add a remoteproc TEE (Trusted Execution Environment) driver that will be probed by the TEE bus. If the associated Trusted application is supported on the secure part, this driver offers a client interface to load firmware by the secure part. This firmware could be authenticated by the secure trusted application. A specificity of the implementation is that the firmware has to be authenticated and optionally decrypted to access the resource table. Consequently, the boot sequence is: 1) rproc_parse_fw --> rproc_tee_parse_fw remoteproc TEE: - Requests the TEE application to authenticate and load the firmware in the remote processor memories. - Requests the TEE application for the address of the resource table. - Creates a copy of the resource table stored in rproc->cached_table. 2) rproc_load_segments --> rproc_tee_load_fw remoteproc TEE: - Requests the TEE application to load the firmware. Nothing is done at the TEE application as the firmware is already loaded. - In case of recovery, the TEE application has to reload the firmware. 3) rproc_tee_get_loaded_rsc_table remoteproc TEE requests the TEE application for the address of the resource table. 4) rproc_start --> rproc_tee_start - Requests the TEE application to start the remote processor. The shutdown sequence is: 5) rproc_stop --> rproc_tee_stop - Requests the TEE application to stop the remote processor. 6) rproc_tee_release_fw This function is used to request the TEE application to perform actions to return to the initial state on stop or on error during the boot sequence. Signed-off-by: Arnaud Pouliquen --- Updates vs previous version: Fix warning: EXPORT_SYMBOL() is used, but #include is miss= ing --- drivers/remoteproc/Kconfig | 10 + drivers/remoteproc/Makefile | 1 + drivers/remoteproc/remoteproc_tee.c | 620 ++++++++++++++++++++++++++++ include/linux/remoteproc_tee.h | 90 ++++ 4 files changed, 721 insertions(+) create mode 100644 drivers/remoteproc/remoteproc_tee.c create mode 100644 include/linux/remoteproc_tee.h diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 83962a114dc9..e39265d249d9 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -23,6 +23,16 @@ config REMOTEPROC_CDEV =20 It's safe to say N if you don't want to use this interface. =20 +config REMOTEPROC_TEE + bool "Remoteproc support by a TEE application" + depends on OPTEE + help + Support a remote processor that is managed by an application running in= a Trusted + Execution Environment (TEE). This application is responsible for loadin= g the remote + processor firmware image and managing its lifecycle. + + It's safe to say N if the remote processor is not managed by a TEE. + config IMX_REMOTEPROC tristate "i.MX remoteproc support" depends on ARCH_MXC diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index 1c7598b8475d..a1a5201982d4 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -11,6 +11,7 @@ remoteproc-y +=3D remoteproc_sysfs.o remoteproc-y +=3D remoteproc_virtio.o remoteproc-y +=3D remoteproc_elf_loader.o obj-$(CONFIG_REMOTEPROC_CDEV) +=3D remoteproc_cdev.o +obj-$(CONFIG_REMOTEPROC_TEE) +=3D remoteproc_tee.o obj-$(CONFIG_IMX_REMOTEPROC) +=3D imx_rproc.o obj-$(CONFIG_IMX_DSP_REMOTEPROC) +=3D imx_dsp_rproc.o obj-$(CONFIG_INGENIC_VPU_RPROC) +=3D ingenic_rproc.o diff --git a/drivers/remoteproc/remoteproc_tee.c b/drivers/remoteproc/remot= eproc_tee.c new file mode 100644 index 000000000000..6b610dfa1ee1 --- /dev/null +++ b/drivers/remoteproc/remoteproc_tee.c @@ -0,0 +1,620 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) STMicroelectronics 2024 + * Author: Arnaud Pouliquen + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_TEE_PARAM_ARRAY_MEMBER 4 + +/* + * Authentication and load of the firmware image in the remote processor m= emories by the TEE. + * After this step the firmware is loaded in destination memories, which c= an then be locked to + * prevent access by Linux. + * + * [in] params[0].value.a: remote processor identifier + * [in] params[1].memref: buffer containing a temporary copy of the signe= d image to load. + */ +#define TA_RPROC_FW_CMD_LOAD_FW 1 + +/* + * Start the remote processor by the TEE + * + * [in] params[0].value.a: remote processor identifier + */ +#define TA_RPROC_FW_CMD_START 2 + +/* + * Stop the remote processor by the TEE + * + * [in] params[0].value.a: remote processor identifier + */ +#define TA_RPROC_FW_CMD_STOP 3 + +/* + * Return the address of the resource table, or 0 if not found. + * + * [in] params[0].value.a: remote processor identifier + * [out] params[1].value.a: 32bit LSB resource table memory address + * [out] params[1].value.b: 32bit MSB resource table memory address + * [out] params[2].value.a: 32bit LSB resource table memory size + * [out] params[2].value.b: 32bit MSB resource table memory size + */ +#define TA_RPROC_FW_CMD_GET_RSC_TABLE 4 + +/* + * Release remote processor firmware images and associated resources. + * This command should be used in case an error occurs between the loading= of + * the firmware images (TA_RPROC_CMD_LOAD_FW) and the starting of the remo= te + * processor (TA_RPROC_CMD_START_FW) or after stopping the remote processor + * to release associated resources (TA_RPROC_CMD_STOP_FW). + * + * [in] params[0].value.a: Unique 32-bit remote processor identifier + */ +#define TA_RPROC_CMD_RELEASE_FW 6 + +struct rproc_tee_context { + struct list_head sessions; + struct tee_context *tee_ctx; + struct device *dev; +}; + +/** + * struct rproc_tee - TEE remoteproc structure + * @node: Reference in list + * @rproc: Remoteproc reference + * @rproc_id: Identifier of the target firmware + * @session_id: TEE session identifier + */ +struct rproc_tee { + struct list_head node; + struct rproc *rproc; + u32 rproc_id; + u32 session_id; +}; + +static struct rproc_tee_context rproc_tee_ctx; +static DEFINE_SPINLOCK(ctx_lock); + +static struct rproc_tee *rproc_to_trproc(struct rproc *rproc) +{ + struct rproc_tee *trproc; + + list_for_each_entry(trproc, &rproc_tee_ctx.sessions, node) + if (trproc->rproc =3D=3D rproc) + return trproc; + + return NULL; +} + +static void rproc_tee_prepare_args(struct rproc_tee *trproc, int cmd, + struct tee_ioctl_invoke_arg *arg, + struct tee_param *param, + unsigned int num_params) +{ + memset(arg, 0, sizeof(*arg)); + memset(param, 0, MAX_TEE_PARAM_ARRAY_MEMBER * sizeof(*param)); + + arg->func =3D cmd; + arg->session =3D trproc->session_id; + arg->num_params =3D num_params + 1; + + param[0] =3D (struct tee_param) { + .attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT, + .u.value.a =3D trproc->rproc_id, + }; +} + +/** + * rproc_tee_release_fw - Release the firmware for a TEE-based remote proc= essor + * + * This function invokes the TA_RPROC_CMD_RELEASE_FW TEE client function t= o release the firmware. + * It should only be called when the remoteproc state is RPROC_OFFLINE or = RPROC_DETACHED. + * The function requests the TEE remoteproc application to release the fir= mware loaded by + * rproc_tee_load_fw(). The request is ignored if the rproc state is RPROC= _DETACHED as the + * remote processor is still running. + * + * @rproc: Pointer to the struct rproc representing the remote processor + */ +void rproc_tee_release_fw(struct rproc *rproc) +{ + struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER]; + struct rproc_tee *trproc =3D rproc_to_trproc(rproc); + struct tee_ioctl_invoke_arg arg; + int ret; + + if (!rproc_tee_ctx.dev) + return; + + if (!trproc) + return; + + /* + * If the remote processor state is RPROC_DETACHED, just ignore the + * request, as the remote processor is still running. + */ + if (rproc->state =3D=3D RPROC_DETACHED) + return; + + if (rproc->state !=3D RPROC_OFFLINE) { + dev_err(rproc_tee_ctx.dev, "unexpected rproc state: %d\n", rproc->state); + return; + } + + rproc_tee_prepare_args(trproc, TA_RPROC_CMD_RELEASE_FW, &arg, param, 0); + + ret =3D tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param); + if (ret < 0 || arg.ret !=3D 0) { + dev_err(rproc_tee_ctx.dev, + "TA_RPROC_CMD_RELEASE_FW invoke failed TEE err: %#x, ret:%d\n", + arg.ret, ret); + ret =3D -EIO; + } +} +EXPORT_SYMBOL_GPL(rproc_tee_release_fw); + +/** + * rproc_tee_load_fw - Load firmware from TEE application + * @rproc: Pointer to the struct rproc representing the remote processor + * @fw: Pointer to the firmware structure containing the firmware data and= size + * + * This function invokes the TA_RPROC_FW_CMD_LOAD_FW TEE client function t= o load the firmware. + * It registers the fw->data as a shared memory region with the TEE, and r= equest the TEE to load + * the firmware. This function can be called twice during the remote proce= ssor boot, considering + * that the TEE application ignores the command if the firmware is already= loaded. + * + * @rproc: Pointer to the struct rproc representing the remote processor + * @fw: Pointer to the firmware structure containing the firmware data and= size + * + * Return: 0 on success, or an error code on failure + */ +int rproc_tee_load_fw(struct rproc *rproc, const struct firmware *fw) +{ + struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER]; + struct rproc_tee *trproc =3D rproc_to_trproc(rproc); + struct tee_ioctl_invoke_arg arg; + struct tee_shm *fw_shm; + int ret; + + if (!rproc_tee_ctx.dev) + return -ENODEV; + + if (!trproc) + return -EINVAL; + + fw_shm =3D tee_shm_register_kernel_buf(rproc_tee_ctx.tee_ctx, (void *)fw-= >data, fw->size); + if (IS_ERR(fw_shm)) + return PTR_ERR(fw_shm); + + rproc_tee_prepare_args(trproc, TA_RPROC_FW_CMD_LOAD_FW, &arg, param, 1); + + /* Provide the address of the firmware image */ + param[1] =3D (struct tee_param) { + .attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT, + .u.memref =3D { + .shm =3D fw_shm, + .size =3D fw->size, + .shm_offs =3D 0, + }, + }; + + ret =3D tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param); + if (ret < 0 || arg.ret !=3D 0) { + dev_err(rproc_tee_ctx.dev, + "TA_RPROC_FW_CMD_LOAD_FW invoke failed TEE err: %#x, ret:%d\n", + arg.ret, ret); + if (!ret) + ret =3D -EIO; + } + + tee_shm_free(fw_shm); + + return ret; +} +EXPORT_SYMBOL_GPL(rproc_tee_load_fw); + +static int rproc_tee_get_loaded_rsc_table(struct rproc *rproc, phys_addr_t= *rsc_pa, + size_t *table_sz) +{ + struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER]; + struct rproc_tee *trproc =3D rproc_to_trproc(rproc); + struct tee_ioctl_invoke_arg arg; + int ret; + + if (!rproc_tee_ctx.dev) + return -ENODEV; + + if (!trproc) + return -EINVAL; + + rproc_tee_prepare_args(trproc, TA_RPROC_FW_CMD_GET_RSC_TABLE, &arg, param= , 2); + + param[1].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; + param[2].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; + + ret =3D tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param); + if (ret < 0 || arg.ret !=3D 0) { + dev_err(rproc_tee_ctx.dev, + "TA_RPROC_FW_CMD_GET_RSC_TABLE invoke failed TEE err: %#x, ret:%d\n", + arg.ret, ret); + return -EIO; + } + + *table_sz =3D param[2].u.value.a; + + if (*table_sz) + *rsc_pa =3D param[1].u.value.a; + else + *rsc_pa =3D 0; + + return 0; +} + +/** + * rproc_tee_parse_fw - Get the resource table from TEE application + * @rproc: Pointer to the struct rproc representing the remote processor + * @fw: Pointer to the firmware structure containing the firmware data and= size + * + * This function retrieves the loaded resource table and creates a cached_= table copy. Since the + * firmware image is signed and potentially encrypted, the firmware must b= e loaded first to + * access the loaded resource table. + * + * @rproc: Pointer to the struct rproc representing the remote processor + * @fw: Pointer to the firmware structure containing the firmware data and= size + * + * Return: 0 on success, or an error code on failure + */ +int rproc_tee_parse_fw(struct rproc *rproc, const struct firmware *fw) +{ + phys_addr_t rsc_table; + void __iomem *rsc_va; + size_t table_sz; + int ret; + + if (!rproc) + return -EINVAL; + + /* We need first to Load the firmware, to be able to get the resource tab= le. */ + ret =3D rproc_tee_load_fw(rproc, fw); + if (ret) + return ret; + + ret =3D rproc_tee_get_loaded_rsc_table(rproc, &rsc_table, &table_sz); + if (ret) + goto release_fw; + + /* + * We assume here that the memory mapping is the same between the TEE and= Linux kernel + * contexts. Else a new TEE remoteproc service could be needed to get a c= opy of the + * resource table + */ + rsc_va =3D ioremap_wc(rsc_table, table_sz); + if (!rsc_va) { + dev_err(rproc_tee_ctx.dev, "Unable to map memory region: %pa+%zx\n", + &rsc_table, table_sz); + ret =3D -ENOMEM; + goto release_fw; + } + + /* + * Create a copy of the resource table to have the same behavior as the E= LF loader. + * This cached table will be used by the remoteproc core after the remote= proc stops + * to free resources and for crash recovery to reapply the settings. + * The cached table will be freed by the remoteproc core. + */ + rproc->cached_table =3D kmemdup((__force void *)rsc_va, table_sz, GFP_KER= NEL); + iounmap(rsc_va); + + if (!rproc->cached_table) { + ret =3D -ENOMEM; + goto release_fw; + } + + rproc->table_ptr =3D rproc->cached_table; + rproc->table_sz =3D table_sz; + + return 0; + +release_fw: + rproc_tee_release_fw(rproc); + return ret; +} +EXPORT_SYMBOL_GPL(rproc_tee_parse_fw); + +/** + * rproc_tee_find_loaded_rsc_table - Find the loaded resource table loaded= by the TEE application + * @rproc: Pointer to the struct rproc representing the remote processor + * @fw: Pointer to the firmware structure containing the firmware data and= size + * + * This function retrieves the physical address and size of the resource t= able loaded by the TEE + * application. + * + * @rproc: Pointer to the struct rproc representing the remote processor + * @fw: Pointer to the firmware structure containing the firmware data and= size + * + * Return: pointer to the resource table if found, or NULL if not found o= r size is 0 + */ +struct resource_table *rproc_tee_find_loaded_rsc_table(struct rproc *rproc, + const struct firmware *fw) +{ + phys_addr_t rsc_table; + size_t table_sz; + int ret; + + ret =3D rproc_tee_get_loaded_rsc_table(rproc, &rsc_table, &table_sz); + if (ret) + return NULL; + + rproc->table_sz =3D table_sz; + if (!table_sz) + return NULL; + + /* + * At this step the memory area that contains the resource table should h= ave been registered + * by the remote proc platform driver and allocated by rproc_alloc_regist= ered_carveouts(). + */ + return (struct resource_table *)rproc_pa_to_va(rproc, rsc_table, table_sz= , NULL); +} +EXPORT_SYMBOL_GPL(rproc_tee_find_loaded_rsc_table); + +/** + * rproc_tee_start - Request the TEE application to start the remote proce= ssor + * + * This function invokes the TA_RPROC_FW_CMD_START command to start the re= mote processor. + * + * @rproc: Pointer to the struct rproc representing the remote processor + * + * Return: Returns 0 on success, -EINVAL or -EIO on failure + */ +int rproc_tee_start(struct rproc *rproc) +{ + struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER]; + struct rproc_tee *trproc =3D rproc_to_trproc(rproc); + struct tee_ioctl_invoke_arg arg; + int ret =3D 0; + + if (!trproc) + return -EINVAL; + + rproc_tee_prepare_args(trproc, TA_RPROC_FW_CMD_START, &arg, param, 0); + + ret =3D tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param); + if (ret < 0 || arg.ret !=3D 0) { + dev_err(rproc_tee_ctx.dev, + "TA_RPROC_FW_CMD_START invoke failed TEE err: %#x, ret:%d\n", arg.ret, = ret); + if (!ret) + return -EIO; + } + + return 0; +} +EXPORT_SYMBOL_GPL(rproc_tee_start); + +/** + * rproc_tee_stop - Request the TEE application to start the remote proces= sor + * + * This function invokes the TA_RPROC_FW_CMD_STOP command to stop the remo= te processor. + * + * @rproc: Pointer to the struct rproc representing the remote processor + * + * Return: Returns 0 on success, -EINVAL or -EIO on failure + */ +int rproc_tee_stop(struct rproc *rproc) +{ + struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER]; + struct rproc_tee *trproc =3D rproc_to_trproc(rproc); + struct tee_ioctl_invoke_arg arg; + int ret; + + if (!trproc) + return -EINVAL; + + rproc_tee_prepare_args(trproc, TA_RPROC_FW_CMD_STOP, &arg, param, 0); + + ret =3D tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param); + if (ret < 0 || arg.ret !=3D 0) { + dev_err(rproc_tee_ctx.dev, + "TA_RPROC_FW_CMD_STOP invoke failed TEE err: %#x, ret:%d\n", arg.ret, r= et); + if (!ret) + ret =3D -EIO; + } + + return ret; +} +EXPORT_SYMBOL_GPL(rproc_tee_stop); + +static const struct tee_client_device_id rproc_tee_id_table[] =3D { + {UUID_INIT(0x80a4c275, 0x0a47, 0x4905, 0x82, 0x85, 0x14, 0x86, 0xa9, 0x77= , 0x1a, 0x08)}, + {} +}; + +/** + * rproc_tee_register - Register a remote processor controlled by a TEE ap= plication. + * + * This function registers a remote processor that will be managed by a TE= E application,by opening + * a session with the TEE client. + * + * @dev: Pointer to client rproc device + * @rproc: Pointer to the struct rproc representing the remote processor + * @rproc_id: ID of the remote processor + * + * Return: Returns 0 on success, or an error code on failure + */ +int rproc_tee_register(struct device *dev, struct rproc *rproc, unsigned i= nt rproc_id) +{ + struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER]; + struct tee_ioctl_open_session_arg sess_arg; + struct tee_client_device *tee_device; + struct rproc_tee *trproc; + struct device_link *link; + int ret; + + spin_lock(&ctx_lock); + /* + * Test if the device has been probed by the TEE bus. In case of failure,= we ignore the + * reason. The bus could be not yet probed or the service not available i= n the secure + * firmware.The assumption in such a case is that the TEE remoteproc is n= ot probed. + */ + if (!rproc_tee_ctx.dev) { + ret =3D -EPROBE_DEFER; + goto out; + } + + trproc =3D kzalloc(sizeof(*trproc), GFP_KERNEL); + if (!trproc) { + ret =3D -ENOMEM; + goto out; + } + + tee_device =3D to_tee_client_device(rproc_tee_ctx.dev); + memset(&sess_arg, 0, sizeof(sess_arg)); + + memcpy(sess_arg.uuid, tee_device->id.uuid.b, TEE_IOCTL_UUID_LEN); + + sess_arg.clnt_login =3D TEE_IOCTL_LOGIN_REE_KERNEL; + sess_arg.num_params =3D 1; + + param[0] =3D (struct tee_param) { + .attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT, + .u.value.a =3D rproc_id, + }; + + ret =3D tee_client_open_session(rproc_tee_ctx.tee_ctx, &sess_arg, param); + if (ret < 0 || sess_arg.ret !=3D 0) { + dev_err(dev, "tee_client_open_session failed, err: %#x\n", sess_arg.ret); + ret =3D -EINVAL; + goto free_tproc; + } + + trproc->rproc_id =3D rproc_id; + trproc->session_id =3D sess_arg.session; + + trproc->rproc =3D rproc; + + /* Create device link between the rproc device and the TEE device */ + link =3D device_link_add(dev, rproc_tee_ctx.dev, DL_FLAG_AUTOREMOVE_CONSU= MER); + if (!link) { + ret =3D -ENOMEM; + goto close_tee; + } + list_add_tail(&trproc->node, &rproc_tee_ctx.sessions); + + goto out; + +close_tee: + if (tee_client_close_session(rproc_tee_ctx.tee_ctx, trproc->session_id)) + dev_err(rproc_tee_ctx.dev, "tee_client_close_session failed\n"); +free_tproc: + kfree(trproc); +out: + spin_unlock(&ctx_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(rproc_tee_register); + +/** + * rproc_tee_unregister - Register a remote processor controlled by a TEE = application. + * + * This function unregisters a remote processor previously registered by t= he rproc_tee_register() + * function. + * + * @dev: Pointer to client rproc device + * @rproc: Pointer to the struct rproc representing the remote processor + * + * Return: Returns 0 on success, or an error code on failure + */ +int rproc_tee_unregister(struct device *dev, struct rproc *rproc) +{ + struct rproc_tee *trproc =3D rproc_to_trproc(rproc); + int ret; + + if (!trproc) + return -EINVAL; + + spin_lock(&ctx_lock); + + ret =3D tee_client_close_session(rproc_tee_ctx.tee_ctx, trproc->session_i= d); + if (ret < 0) + dev_err(rproc_tee_ctx.dev, "tee_client_close_session failed, err: %#x\n"= , ret); + + spin_unlock(&ctx_lock); + + list_del(&trproc->node); + kfree(trproc); + + return ret; +} +EXPORT_SYMBOL_GPL(rproc_tee_unregister); + +static int rproc_tee_ctx_match(struct tee_ioctl_version_data *ver, const v= oid *data) +{ + /* Today we support only the OP-TEE, could be extend to other tees */ + return (ver->impl_id =3D=3D TEE_IMPL_ID_OPTEE); +} + +static int rproc_tee_probe(struct device *dev) +{ + struct tee_context *tee_ctx; + + /* Open context with TEE driver */ + tee_ctx =3D tee_client_open_context(NULL, rproc_tee_ctx_match, NULL, NULL= ); + if (IS_ERR(tee_ctx)) + return PTR_ERR(tee_ctx); + + spin_lock(&ctx_lock); + rproc_tee_ctx.dev =3D dev; + rproc_tee_ctx.tee_ctx =3D tee_ctx; + INIT_LIST_HEAD(&rproc_tee_ctx.sessions); + spin_unlock(&ctx_lock); + + return 0; +} + +static int rproc_tee_remove(struct device *dev) +{ + spin_lock(&ctx_lock); + tee_client_close_context(rproc_tee_ctx.tee_ctx); + rproc_tee_ctx.dev =3D NULL; + rproc_tee_ctx.tee_ctx =3D NULL; + spin_unlock(&ctx_lock); + + return 0; +} + +MODULE_DEVICE_TABLE(tee, rproc_tee_id_table); + +static struct tee_client_driver rproc_tee_fw_driver =3D { + .id_table =3D rproc_tee_id_table, + .driver =3D { + .name =3D KBUILD_MODNAME, + .bus =3D &tee_bus_type, + .probe =3D rproc_tee_probe, + .remove =3D 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); + +MODULE_DESCRIPTION(" remote processor TEE module"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/remoteproc_tee.h b/include/linux/remoteproc_tee.h new file mode 100644 index 000000000000..659bd77a4f12 --- /dev/null +++ b/include/linux/remoteproc_tee.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 STMicroelectronics + */ + +#ifndef REMOTEPROC_TEE_H +#define REMOTEPROC_TEE_H + +#include +#include +#include + +struct rproc; +struct rproc_tee; + +#if IS_ENABLED(CONFIG_REMOTEPROC_TEE) + +int rproc_tee_register(struct device *dev, struct rproc *rproc, unsigned i= nt rproc_id); +int rproc_tee_unregister(struct device *dev, 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 + +static inline int rproc_tee_register(struct device *dev, struct rproc *rpr= oc, unsigned int rproc_id) +{ + return -ENODEV; +} + +static inline int rproc_tee_parse_fw(struct rproc *rproc, const struct fir= mware *fw) +{ + /* This shouldn't be possible */ + WARN_ON(1); + + return 0; +} + +static inline int rproc_tee_unregister(struct device *dev, struct rproc *r= proc) +{ + /* This shouldn't be possible */ + WARN_ON(1); + + return 0; +} + +static inline int rproc_tee_load_fw(struct rproc *rproc, const struct fir= mware *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 */ --=20 2.25.1 From nobody Fri Oct 10 04:08:14 2025 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B390D1F4CA9; Mon, 16 Jun 2025 07:58:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060724; cv=none; b=bhClx2225+jhk+ErbNzesKkA3tLh3jbCR3GvlvPlC+eQXV9K7OBZBl3pM/ZApDlnvXAuaOuNsxpDmbZcp1czJwEyJwngBuhSn5QZE1j/yVOSHAmHcy5rzqhEotm2G0MaFRQZ6wmFbk+udNePDtjJKjEE/xV9L5qsPE5buaMOQ+s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060724; c=relaxed/simple; bh=48+tfPB30Wj9CBXzoXpunqcMTSdG6Xe8h087sTMo7VI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CPMkJ0qjIZgMbWd9lSJfyf3dKv8Q1hvQZhPB+XBK6ioC2LtVuDeIwRUVQStZe0qUjp9EKmSBR9guc0Avtk4bJjtFFYVYudBdH9JYFtQYZX3rD1uIMEh7CmtVn82yGS0Bi6VL1Svnxf7eR8VU8NtmPXdI9RuFhKPFQ5q1oQkt2hQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=RcP/Yl9F; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="RcP/Yl9F" Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55G7pBJa031098; Mon, 16 Jun 2025 09:58:15 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=selector1; bh= B0CIe4Em+6SiyZ1yvMPHjJzRbLfZtQOApicnI4RfN3o=; b=RcP/Yl9F4c/AUTU3 Tx+qF9yEn8H19kU0EsPnsnmoVg5lDEvtUrI0a1yMWX88Vd05YbeZrpv0qHrMFlmv mAbrKWDTKDtU08ezToLooD3vBiDszdH/KeYxADAoh0fCKhEST6dCEHYu11uHkQRr jSgdFKZr0/YY0X+vuSP4U1LmEJNJNKnHKbGt13czJIOtY/5H3JjhVb3pH9MTbTt1 +SXP7pvxkvH8TFVT9KB0PZP1ExoBgL8YLzXwN7dkSZPFPd1E78lqwCZ/ntWZpGJF HzIrDsOKG/eg+mqdst1Xd3ntr7vGINh9rHXsOU4mE85nsG275wNGpHI6dIaL/yUA Kko9tg== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 4790e1yc71-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 16 Jun 2025 09:58:14 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id B49104002D; Mon, 16 Jun 2025 09:57:11 +0200 (CEST) Received: from Webmail-eu.st.com (eqndag1node6.st.com [10.75.129.135]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id D05764CB02E; Mon, 16 Jun 2025 09:56:21 +0200 (CEST) Received: from SAFDAG1NODE1.st.com (10.75.90.17) by EQNDAG1NODE6.st.com (10.75.129.135) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:21 +0200 Received: from localhost (10.48.86.121) by SAFDAG1NODE1.st.com (10.75.90.17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:21 +0200 From: Arnaud Pouliquen To: Bjorn Andersson , Mathieu Poirier , Jens Wiklander , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" CC: , , , , , , Arnaud Pouliquen Subject: [PATCH v18 3/6] remoteproc: Introduce release_fw optional operation Date: Mon, 16 Jun 2025 09:55:27 +0200 Message-ID: <20250616075530.4106090-4-arnaud.pouliquen@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> References: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SHFCAS1NODE2.st.com (10.75.129.73) To SAFDAG1NODE1.st.com (10.75.90.17) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-16_03,2025-06-13_01,2025-03-28_01 Content-Type: text/plain; charset="utf-8" The release_fw operation is the inverse operation of the load, responsible for releasing the remote processor resources configured from the loading of the remoteproc firmware (e.g., memories). The operation is called in the following cases: - An error occurs on boot of the remote processor. - An error occurs on recovery start of the remote processor. - After stopping the remote processor. This operation is needed for the remoteproc_tee implementation after stop and on error. Indeed, as the remoteproc image is loaded when we parse the resource table, there are many situations where something can go wrong before the start of the remote processor(resource handling, carveout allocation, ...). Signed-off-by: Arnaud Pouliquen --- drivers/remoteproc/remoteproc_core.c | 6 ++++++ drivers/remoteproc/remoteproc_internal.h | 6 ++++++ include/linux/remoteproc.h | 3 +++ 3 files changed, 15 insertions(+) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remo= teproc_core.c index d06eef1fa424..4c1a4bc9e7b7 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1857,6 +1857,8 @@ static int rproc_boot_recovery(struct rproc *rproc) =20 /* boot the remote processor up again */ ret =3D rproc_start(rproc, firmware_p); + if (ret) + rproc_release_fw(rproc); =20 release_firmware(firmware_p); =20 @@ -1998,6 +2000,8 @@ int rproc_boot(struct rproc *rproc) } =20 ret =3D rproc_fw_boot(rproc, firmware_p); + if (ret) + rproc_release_fw(rproc); =20 release_firmware(firmware_p); } @@ -2067,6 +2071,8 @@ int rproc_shutdown(struct rproc *rproc) =20 rproc_disable_iommu(rproc); =20 + rproc_release_fw(rproc); + /* Free the copy of the resource table */ kfree(rproc->cached_table); rproc->cached_table =3D NULL; diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/= remoteproc_internal.h index 0cd09e67ac14..c7fb908f8652 100644 --- a/drivers/remoteproc/remoteproc_internal.h +++ b/drivers/remoteproc/remoteproc_internal.h @@ -221,4 +221,10 @@ bool rproc_u64_fit_in_size_t(u64 val) return (val <=3D (size_t) -1); } =20 +static inline void rproc_release_fw(struct rproc *rproc) +{ + if (rproc->ops->release_fw) + rproc->ops->release_fw(rproc); +} + #endif /* REMOTEPROC_INTERNAL_H */ diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 8fd0d7f63c8e..80128461972b 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -381,6 +381,8 @@ enum rsc_handling_status { * @panic: optional callback to react to system panic, core will delay * panic at least the returned number of milliseconds * @coredump: collect firmware dump after the subsystem is shutdown + * @release_fw: optional function to release the loaded firmware, called a= fter + * stopping the remote processor or in case of error */ struct rproc_ops { int (*prepare)(struct rproc *rproc); @@ -403,6 +405,7 @@ struct rproc_ops { u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw); unsigned long (*panic)(struct rproc *rproc); void (*coredump)(struct rproc *rproc); + void (*release_fw)(struct rproc *rproc); }; =20 /** --=20 2.25.1 From nobody Fri Oct 10 04:08:14 2025 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3E7320E01A; Mon, 16 Jun 2025 07:58:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060727; cv=none; b=O92iSHgRty/lwxBnRi9xRjeSDJrSSqphb+teUKq/M2IS0eCHigq0V1O961LU3S3a3CRDC0lzjekCAgpWqCnuy5nC5tcnRxzawOpGvh8CguD/+V7x8OIlDuYUkyHJZQ7DnTYu+A0uyVrAWQDxg5voG43S7DgsHH6nC1B2VbYPkAI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060727; c=relaxed/simple; bh=La9eOSM7+OYSzG5Ov7Ay/TzOIDr77S7Jp4sDgKB46mA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=beH3lJYAEJkfj7YTD6lL33s7oF2keKkK/Nuq+tOLifhEyhaUZGioDCU7mMKpCmkJQKSjjpUqom4g3yumJZey95JsadNaCzyGUNQGC8i+AHiTppi+UeZdiulZSil8btLFKqaXYjVPPCcZsPnN/nlNX2nWAn1NFdRq7oqx0E5ujtA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=zr82XDFI; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="zr82XDFI" Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55G7Xpxd029583; Mon, 16 Jun 2025 09:58:27 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=selector1; bh= Jeq5JI4lCT6ZEy/eg01EjyjLaJrHnzpFREfAtoOf8ec=; b=zr82XDFIJemNGefZ scZbCyNeYiLbmKJZFI+0cN+rkV3vdE7GyMh46T6kpU2FR920zOYl5NOnNF2AW6pl iwSWlSTBv+4yGgwxBn1GeQp0z093MumsJqCPgVGoguEZQWsfKAid6ULOpFNcYZGo 5gjQ84JGzJ2u9Bw8gojcnv3ep3huhkl8fjVr6eqAegap482t/aaB/c5j7ycM3f2J xbh/suHmB/7pojzHBc1Q1kLnuGMt81mMa0s6eDH1hjesIF2cgRVuGurH87+sLxve Nj6YBx6802mwBlQHf5wE+Ks6toHo3Qci9vlU7Bxd+R6N0vBs/XesoSR850CMifxx kOQ9IQ== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 4790e1yc80-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 16 Jun 2025 09:58:27 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 2E91640046; Mon, 16 Jun 2025 09:57:12 +0200 (CEST) Received: from Webmail-eu.st.com (eqndag1node5.st.com [10.75.129.134]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 95EBF4CB033; Mon, 16 Jun 2025 09:56:22 +0200 (CEST) Received: from SAFDAG1NODE1.st.com (10.75.90.17) by EQNDAG1NODE5.st.com (10.75.129.134) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:22 +0200 Received: from localhost (10.48.86.121) by SAFDAG1NODE1.st.com (10.75.90.17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:22 +0200 From: Arnaud Pouliquen To: Bjorn Andersson , Mathieu Poirier , Jens Wiklander , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" CC: , , , , , , Arnaud Pouliquen Subject: [PATCH v18 4/6] dt-bindings: remoteproc: Add compatibility for TEE support Date: Mon, 16 Jun 2025 09:55:28 +0200 Message-ID: <20250616075530.4106090-5-arnaud.pouliquen@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> References: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SHFCAS1NODE2.st.com (10.75.129.73) To SAFDAG1NODE1.st.com (10.75.90.17) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-16_03,2025-06-13_01,2025-03-28_01 Content-Type: text/plain; charset="utf-8" The "st,stm32mp1-m4-tee" compatible is utilized in a system configuration where the Cortex-M4 firmware is loaded by the Trusted Execution Environment (TEE). For instance, this compatible is used in both the Linux and OP-TEE device trees: - In OP-TEE, a node is defined in the device tree with the "st,stm32mp1-m4-tee" compatible to support signed remoteproc firmware. Based on DT properties, the OP-TEE remoteproc framework is initiated to expose a trusted application service to authenticate and load the remote processor firmware provided by the Linux remoteproc framework, as well as to start and stop the remote processor. - In Linux, when the compatibility is set, the Cortex-M resets should not be declared in the device tree. In such a configuration, the reset is managed by the OP-TEE remoteproc driver and is no longer accessible from the Linux kernel. Associated with this new compatible, add the "st,proc-id" property to identify the remote processor. This ID is used to define a unique ID, common between Linux, U-Boot, and OP-TEE, to identify a coprocessor. This ID will be used in requests to the OP-TEE remoteproc Trusted Application to specify the remote processor. Signed-off-by: Arnaud Pouliquen Reviewed-by: Rob Herring (Arm) --- .../bindings/remoteproc/st,stm32-rproc.yaml | 58 ++++++++++++++++--- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.ya= ml b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml index 843679c557e7..58da07e536fc 100644 --- a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml @@ -16,7 +16,12 @@ maintainers: =20 properties: compatible: - const: st,stm32mp1-m4 + enum: + - st,stm32mp1-m4 + - st,stm32mp1-m4-tee + description: + Use "st,stm32mp1-m4" for the Cortex-M4 coprocessor management by non= -secure context + Use "st,stm32mp1-m4-tee" for the Cortex-M4 coprocessor management by= secure context =20 reg: description: @@ -43,6 +48,10 @@ properties: - description: The offset of the hold boot setting register - description: The field mask of the hold boot =20 + st,proc-id: + description: remote processor identifier + $ref: /schemas/types.yaml#/definitions/uint32 + st,syscfg-tz: deprecated: true description: @@ -146,21 +155,43 @@ properties: required: - compatible - reg - - resets =20 allOf: - if: properties: - reset-names: - not: - contains: - const: hold_boot + compatible: + contains: + const: st,stm32mp1-m4 then: + if: + properties: + reset-names: + not: + contains: + const: hold_boot + then: + required: + - st,syscfg-holdboot + else: + properties: + st,syscfg-holdboot: false + required: + - reset-names required: - - st,syscfg-holdboot - else: + - resets + + - if: + properties: + compatible: + contains: + const: st,stm32mp1-m4-tee + then: properties: st,syscfg-holdboot: false + reset-names: false + resets: false + required: + - st,proc-id =20 additionalProperties: false =20 @@ -192,5 +223,16 @@ examples: st,syscfg-rsc-tbl =3D <&tamp 0x144 0xFFFFFFFF>; st,syscfg-m4-state =3D <&tamp 0x148 0xFFFFFFFF>; }; + - | + #include + m4@10000000 { + compatible =3D "st,stm32mp1-m4-tee"; + reg =3D <0x10000000 0x40000>, + <0x30000000 0x40000>, + <0x38000000 0x10000>; + st,proc-id =3D <0>; + st,syscfg-rsc-tbl =3D <&tamp 0x144 0xFFFFFFFF>; + st,syscfg-m4-state =3D <&tamp 0x148 0xFFFFFFFF>; + }; =20 ... --=20 2.25.1 From nobody Fri Oct 10 04:08:14 2025 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B38B71F0E2F; Mon, 16 Jun 2025 07:58:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060723; cv=none; b=WZndrms7TqLWbjZVuEnBNve52oEgZaS4LUDMd9A7J6LZl2pm2xUAj5xMn/vHkBY/djh2Gpj58/vmU3swgXkQTStRog4VVECL7tMhPF+n0E2r8XsnT1USV67w2Q5cWoRvLhCvaioj3ItWIuFkcmMcQpPMlC39LtBWxSNV6k/UaVA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060723; c=relaxed/simple; bh=/UaD7L2Vb27H17GtHN5VEE3MuD/tl/8GVoHJYXhqnsI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UF6tcZuyu4NJyOUu4ZXuzznXbKHpghmkStunDYygH1Wj8pORVsKiclv51d5CDj0GsApkeNGDg/n60A3VnI59KkiqHzzKXooAPq5pjO9OfPo3Xyg7dWERxjUQ+mJ3i8/MnTkQ36S+aj04EzxhGzIl+AliErBjTtx7v16Xse7+SMw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=E5FwRaex; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="E5FwRaex" Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55G7pBJd031098; Mon, 16 Jun 2025 09:58:24 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=selector1; bh= oRoK+To3ECSWyMsKvQou69OpviNdWWWWDeXdSq5d7yw=; b=E5FwRaexgoRuIF8o uFNgFXyRMqotviy0+jA3cRLtsJpsokZwAVdeFUjl9xJ9WuwZ1D85kvWBcCbGw/pg wDCebVAUk3nJri1O7c4n4FdiYiiUXrEq9K0wQ/Cpp3e5NrhJ1R9FEtq0UcDK6EAm QfVt7MRChwI1h/LmOlyL7UgnBIjfEM04F23qNUmmOujz2ullceMacdbfiIYzMKva UU2awaauh8FivqOkWxBR0w4M5w553rAUH9PjUJAK+En35N2m73SxHaBr+pxaHg+j Z4FLZmtP3a+oR+IDrN7VtyOAAzQxlSO0c/M9FhD5Q6j1iMplts+4S4hbe1GEVIwB YA4vZQ== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 4790e1yc7u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 16 Jun 2025 09:58:24 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 3FA454004B; Mon, 16 Jun 2025 09:57:12 +0200 (CEST) Received: from Webmail-eu.st.com (eqndag1node4.st.com [10.75.129.133]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 545254CB03C; Mon, 16 Jun 2025 09:56:23 +0200 (CEST) Received: from SAFDAG1NODE1.st.com (10.75.90.17) by EQNDAG1NODE4.st.com (10.75.129.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:23 +0200 Received: from localhost (10.48.86.121) by SAFDAG1NODE1.st.com (10.75.90.17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:22 +0200 From: Arnaud Pouliquen To: Bjorn Andersson , Mathieu Poirier , Jens Wiklander , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" CC: , , , , , , Arnaud Pouliquen Subject: [PATCH v18 5/6] remoteproc: stm32: Create sub-functions to request shutdown and release Date: Mon, 16 Jun 2025 09:55:29 +0200 Message-ID: <20250616075530.4106090-6-arnaud.pouliquen@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> References: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SHFCAS1NODE2.st.com (10.75.129.73) To SAFDAG1NODE1.st.com (10.75.90.17) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-16_03,2025-06-13_01,2025-03-28_01 Content-Type: text/plain; charset="utf-8" To prepare for the support of TEE remoteproc, create sub-functions that can be used in both cases, with and without remoteproc TEE support. Signed-off-by: Arnaud Pouliquen --- drivers/remoteproc/stm32_rproc.c | 82 +++++++++++++++++++------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rp= roc.c index 431648607d53..db82d4308376 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -209,6 +209,52 @@ static int stm32_rproc_mbox_idx(struct rproc *rproc, c= onst unsigned char *name) return -EINVAL; } =20 +static void stm32_rproc_request_shutdown(struct rproc *rproc) +{ + struct stm32_rproc *ddata =3D rproc->priv; + int err, idx; + + /* Request shutdown of the remote processor */ + if (rproc->state !=3D RPROC_OFFLINE && rproc->state !=3D RPROC_CRASHED) { + idx =3D stm32_rproc_mbox_idx(rproc, STM32_MBX_SHUTDOWN); + if (idx >=3D 0 && ddata->mb[idx].chan) { + err =3D mbox_send_message(ddata->mb[idx].chan, "detach"); + if (err < 0) + dev_warn(&rproc->dev, "warning: remote FW shutdown without ack\n"); + } + } +} + +static int stm32_rproc_release(struct rproc *rproc) +{ + struct stm32_rproc *ddata =3D rproc->priv; + unsigned int err =3D 0; + + /* To allow platform Standby power mode, set remote proc Deep Sleep */ + if (ddata->pdds.map) { + err =3D regmap_update_bits(ddata->pdds.map, ddata->pdds.reg, + ddata->pdds.mask, 1); + if (err) { + dev_err(&rproc->dev, "failed to set pdds\n"); + return err; + } + } + + /* Update coprocessor state to OFF if available */ + if (ddata->m4_state.map) { + err =3D regmap_update_bits(ddata->m4_state.map, + ddata->m4_state.reg, + ddata->m4_state.mask, + M4_STATE_OFF); + if (err) { + dev_err(&rproc->dev, "failed to set copro state\n"); + return err; + } + } + + return 0; +} + static int stm32_rproc_prepare(struct rproc *rproc) { struct device *dev =3D rproc->dev.parent; @@ -519,17 +565,9 @@ static int stm32_rproc_detach(struct rproc *rproc) static int stm32_rproc_stop(struct rproc *rproc) { struct stm32_rproc *ddata =3D rproc->priv; - int err, idx; + int err; =20 - /* request shutdown of the remote processor */ - if (rproc->state !=3D RPROC_OFFLINE && rproc->state !=3D RPROC_CRASHED) { - idx =3D stm32_rproc_mbox_idx(rproc, STM32_MBX_SHUTDOWN); - if (idx >=3D 0 && ddata->mb[idx].chan) { - err =3D mbox_send_message(ddata->mb[idx].chan, "detach"); - if (err < 0) - dev_warn(&rproc->dev, "warning: remote FW shutdown without ack\n"); - } - } + stm32_rproc_request_shutdown(rproc); =20 err =3D stm32_rproc_set_hold_boot(rproc, true); if (err) @@ -541,29 +579,7 @@ static int stm32_rproc_stop(struct rproc *rproc) return err; } =20 - /* to allow platform Standby power mode, set remote proc Deep Sleep */ - if (ddata->pdds.map) { - err =3D regmap_update_bits(ddata->pdds.map, ddata->pdds.reg, - ddata->pdds.mask, 1); - if (err) { - dev_err(&rproc->dev, "failed to set pdds\n"); - return err; - } - } - - /* update coprocessor state to OFF if available */ - if (ddata->m4_state.map) { - err =3D regmap_update_bits(ddata->m4_state.map, - ddata->m4_state.reg, - ddata->m4_state.mask, - M4_STATE_OFF); - if (err) { - dev_err(&rproc->dev, "failed to set copro state\n"); - return err; - } - } - - return 0; + return stm32_rproc_release(rproc); } =20 static void stm32_rproc_kick(struct rproc *rproc, int vqid) --=20 2.25.1 From nobody Fri Oct 10 04:08:14 2025 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9501D20F085; Mon, 16 Jun 2025 07:58:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060726; cv=none; b=jU+BQssFg5wbCpqxISi6imW7vfnO/lr9cV0KZ3lT6JFw8P9YhgVl8GZfqRE09C6cHCxzaxsN/pYYyKyRdyB+Vo3Oy61R6foUfTE9gF02zt1KJ4jdZa/juVXfKcQLX7GT4un11PBR7kfORksvH4jjQjNEIUECoMX3VebiHH82qZQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750060726; c=relaxed/simple; bh=jPK4wtVtgowQBi+UmxZnj54EDsYP4uXpHHgPQcBnK9Y=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pllbGIT65DLjZP3e1KGV3DtWB77H5GcBOPymgC+YLQwhRdCYc2SIFmia4AwYgDwF5mC/79bkXZqjrateIRq7zZVmCOLflzJwiUbJHdsl+ccSsZYa0Tk8ts6jwSPTIIPww3sdoDALL296vTDtSZ0sB41CoKFfoNEiTeLx5kHk+rM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=tvb1wGB0; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="tvb1wGB0" Received: from pps.filterd (m0369458.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55G6VltD029998; Mon, 16 Jun 2025 09:58:27 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=selector1; bh= XnJtiwxef0NlsIA0iJK2TmfZ9WiB+Rmg7cFo4i5Ph/o=; b=tvb1wGB0lVwOwiRr Z7bMY1fiIFQ9Ji1hnw5hcBxVKjKd4vYwI8tg3zEXrirjw3VSxkYVLtEqUgQaItk/ YIAkI3/DsnUCHDUNPCcIFom519v8Ne+uUdjfjSHXVr3cw2xEjyDvPQQkMwV25xWk VvjqBe7k6Ojnt1BbaGygHYfsxhvzOQZet0mf5BTlFiDd58e5fyp94lQ5Qplyru5o cCWqq5dmK2MXRkuOrcetm3ANimlt+TiVxJxTGJcxhk9711KGQvJ7jHqPlzvjjg9Y 0bNojv/bQW7aEkrYYQ0UJX7JWXC+qg/fUVZNZPweKXUVW6YS2xd8zjApRFqKWc7w FiFVUg== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 479jn4m31q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 16 Jun 2025 09:58:27 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 7076C40047; Mon, 16 Jun 2025 09:57:12 +0200 (CEST) Received: from Webmail-eu.st.com (eqndag1node6.st.com [10.75.129.135]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 1754E4CB020; Mon, 16 Jun 2025 09:56:24 +0200 (CEST) Received: from SAFDAG1NODE1.st.com (10.75.90.17) by EQNDAG1NODE6.st.com (10.75.129.135) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:23 +0200 Received: from localhost (10.48.86.121) by SAFDAG1NODE1.st.com (10.75.90.17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 16 Jun 2025 09:56:23 +0200 From: Arnaud Pouliquen To: Bjorn Andersson , Mathieu Poirier , Jens Wiklander , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" CC: , , , , , , Arnaud Pouliquen Subject: [PATCH v18 6/6] remoteproc: stm32: Add support of an OP-TEE TA to load the firmware Date: Mon, 16 Jun 2025 09:55:30 +0200 Message-ID: <20250616075530.4106090-7-arnaud.pouliquen@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> References: <20250616075530.4106090-1-arnaud.pouliquen@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SHFCAS1NODE2.st.com (10.75.129.73) To SAFDAG1NODE1.st.com (10.75.90.17) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-16_03,2025-06-13_01,2025-03-28_01 Content-Type: text/plain; charset="utf-8" The new TEE remoteproc driver 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 --- drivers/remoteproc/stm32_rproc.c | 57 ++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rp= roc.c index db82d4308376..a3613c337264 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -255,6 +256,19 @@ static int stm32_rproc_release(struct rproc *rproc) return 0; } =20 +static int stm32_rproc_tee_stop(struct rproc *rproc) +{ + int err; + + stm32_rproc_request_shutdown(rproc); + + err =3D rproc_tee_stop(rproc); + if (err) + return err; + + return stm32_rproc_release(rproc); +} + static int stm32_rproc_prepare(struct rproc *rproc) { struct device *dev =3D rproc->dev.parent; @@ -691,8 +705,20 @@ static const struct rproc_ops st_rproc_ops =3D { .get_boot_addr =3D rproc_elf_get_boot_addr, }; =20 +static const struct rproc_ops st_rproc_tee_ops =3D { + .prepare =3D stm32_rproc_prepare, + .start =3D rproc_tee_start, + .stop =3D stm32_rproc_tee_stop, + .kick =3D stm32_rproc_kick, + .load =3D rproc_tee_load_fw, + .parse_fw =3D rproc_tee_parse_fw, + .find_loaded_rsc_table =3D rproc_tee_find_loaded_rsc_table, + .release_fw =3D rproc_tee_release_fw, +}; + static const struct of_device_id stm32_rproc_match[] =3D { { .compatible =3D "st,stm32mp1-m4" }, + { .compatible =3D "st,stm32mp1-m4-tee" }, {}, }; MODULE_DEVICE_TABLE(of, stm32_rproc_match); @@ -854,6 +880,7 @@ static int stm32_rproc_probe(struct platform_device *pd= ev) const char *fw_name; struct rproc *rproc; unsigned int state; + u32 proc_id; int ret; =20 ret =3D dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); @@ -865,9 +892,29 @@ static int stm32_rproc_probe(struct platform_device *p= dev) if (ret < 0 && ret !=3D -EINVAL) return ret; =20 - rproc =3D devm_rproc_alloc(dev, np->name, &st_rproc_ops, fw_name, sizeof(= *ddata)); - if (!rproc) - return -ENOMEM; + if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) { + /* + * Delegate the firmware management to the secure context. + * The firmware loaded has to be signed. + */ + ret =3D of_property_read_u32(np, "st,proc-id", &proc_id); + if (ret) { + dev_err(dev, "failed to read st,rproc-id property\n"); + return ret; + } + + rproc =3D devm_rproc_alloc(dev, np->name, &st_rproc_tee_ops, fw_name, si= zeof(*ddata)); + if (!rproc) + return -ENOMEM; + + ret =3D rproc_tee_register(dev, rproc, proc_id); + if (ret) + return dev_err_probe(dev, ret, "signed firmware not supported by TEE\n= "); + } else { + rproc =3D devm_rproc_alloc(dev, np->name, &st_rproc_ops, fw_name, sizeof= (*ddata)); + if (!rproc) + return -ENOMEM; + } =20 ddata =3D rproc->priv; =20 @@ -919,6 +966,8 @@ static int stm32_rproc_probe(struct platform_device *pd= ev) dev_pm_clear_wake_irq(dev); device_init_wakeup(dev, false); } + rproc_tee_unregister(dev, rproc); + return ret; } =20 @@ -939,6 +988,8 @@ static void stm32_rproc_remove(struct platform_device *= pdev) dev_pm_clear_wake_irq(dev); device_init_wakeup(dev, false); } + + rproc_tee_unregister(dev, rproc); } =20 static int stm32_rproc_suspend(struct device *dev) --=20 2.25.1