Hi,
This patch set allocates the restricted DMA-bufs via the TEE subsystem.
This a big update compared to the previous patch set [1].
The TEE subsystem handles the DMA-buf allocations since it is the TEE
(OP-TEE, AMD-TEE, TS-TEE, or perhaps a future QTEE) which sets up the
restrictions for the memory used for the DMA-bufs.
I've added a new IOCTL, TEE_IOC_RSTMEM_ALLOC, to allocate the restricted
DMA-bufs. This IOCTL reaches the backend TEE driver, allowing it to choose
how to allocate the restricted physical memory.
TEE_IOC_RSTMEM_ALLOC takes in addition to a size and flags parameters also
a use-case parameter. This is used by the backend TEE driver to decide on
allocation policy and which devices should be able to access the memory.
Three use-cases (Secure Video Playback, Trusted UI, and Secure Video
Recording) has been identified so far to serve as examples of what can be
expected. More use-cases can be added in userspace ABI, but it's up to the
backend TEE drivers to provide the implementation.
Each use-case has it's own restricted memory pool since different use-cases
requires isolation from different parts of the system. A restricted memory
pool can be based on a static carveout instantiated while probing the TEE
backend driver, or dynamically allocated from CMA and made restricted as
needed by the TEE.
This can be tested on QEMU with the following steps:
repo init -u https://github.com/jenswi-linaro/manifest.git -m qemu_v8.xml \
-b prototype/sdp-v3
repo sync -j8
cd build
make toolchains -j$(nproc)
make SPMC_AT_EL=1 all -j$(nproc)
make SPMC_AT_EL=1 run-only
# login and at the prompt:
xtest --sdp-basic
The SPMC_AT_EL=1 parameter configures the build with FF-A and an SPMC at
S-EL1 inside OP-TEE. The parameter can be changed into SPMC_AT_EL=n to test
without FF-A using the original SMC ABI instead. Please remember to do
%rm -rf ../trusted-firmware-a/build/qemu
for TF-A to be rebuilt properly using the new configuration.
https://optee.readthedocs.io/en/latest/building/prerequisites.html
list dependencies needed to build the above.
The tests are pretty basic, mostly checking that a Trusted Application in
the secure world can access and manipulate the memory. There are also some
negative tests for out of bounds buffers etc.
Thanks,
Jens
[1] https://lore.kernel.org/lkml/20241015101716.740829-1-jens.wiklander@linaro.…
Changes since the V2 RFC:
* Based on v6.12
* Replaced the flags for SVP and Trusted UID memory with a u32 field with
unique id for each use case
* Added dynamic allocation of restricted memory pools
* Added OP-TEE ABI both with and without FF-A for dynamic restricted memory
* Added support for FF-A with FFA_LEND
Changes since the V1 RFC:
* Based on v6.11
* Complete rewrite, replacing the restricted heap with TEE_IOC_RSTMEM_ALLOC
Changes since Olivier's post [2]:
* Based on Yong Wu's post [1] where much of dma-buf handling is done in
the generic restricted heap
* Simplifications and cleanup
* New commit message for "dma-buf: heaps: add Linaro restricted dmabuf heap
support"
* Replaced the word "secure" with "restricted" where applicable
Jens Wiklander (4):
tee: add restricted memory allocation
optee: account for direction while converting parameters
optee: sync secure world ABI headers
optee: support restricted memory allocation
drivers/tee/Makefile | 1 +
drivers/tee/optee/Makefile | 1 +
drivers/tee/optee/call.c | 10 +-
drivers/tee/optee/core.c | 1 +
drivers/tee/optee/ffa_abi.c | 178 +++++++++++++-
drivers/tee/optee/optee_ffa.h | 27 ++-
drivers/tee/optee/optee_msg.h | 65 ++++-
drivers/tee/optee/optee_private.h | 75 ++++--
drivers/tee/optee/optee_smc.h | 71 +++++-
drivers/tee/optee/rpc.c | 31 ++-
drivers/tee/optee/rstmem.c | 380 ++++++++++++++++++++++++++++++
drivers/tee/optee/smc_abi.c | 214 +++++++++++++++--
drivers/tee/tee_core.c | 37 ++-
drivers/tee/tee_private.h | 2 +
drivers/tee/tee_rstmem.c | 201 ++++++++++++++++
drivers/tee/tee_shm.c | 2 +
drivers/tee/tee_shm_pool.c | 69 +++++-
include/linux/tee_core.h | 15 ++
include/linux/tee_drv.h | 4 +-
include/uapi/linux/tee.h | 37 ++-
20 files changed, 1344 insertions(+), 77 deletions(-)
create mode 100644 drivers/tee/optee/rstmem.c
create mode 100644 drivers/tee/tee_rstmem.c
--
2.43.0
There has been a recent change in OP-TEE to print 8 and 16 character
commit id for 32bit and 64bit architecture respectively.
In case if commit id is starting with 0 like 04d1c612ec7beaede073b8c
it is printing revision as below removing leading 0
"optee: revision 4.4 (4d1c612ec7beaed)"
Signed-off-by: Sahil Malhotra <sahil.malhotra(a)nxp.com>
---
drivers/tee/optee/smc_abi.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index e9456e3e74cc..eb51dc18f32d 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -1272,8 +1272,9 @@ static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn)
&res.smccc);
if (res.result.build_id)
- pr_info("revision %lu.%lu (%08lx)", res.result.major,
- res.result.minor, res.result.build_id);
+ pr_info("revision %lu.%lu (%0*lx)", res.result.major,
+ res.result.minor, (int)sizeof(res.result.build_id) * 2,
+ res.result.build_id);
else
pr_info("revision %lu.%lu", res.result.major, res.result.minor);
}
--
2.34.1
The TEE subsystem manages three main structures: tee_device, the device
that represents the TEE; tee_context, the context that represents the
TEE client; and tee_shm, which represents the shared memory with the
TEE. When a tee_device is opened, it creates a tee_context instance. The
tee_shm is created for the tee_device when allocating shared memory with
the TEE but is linked to a context. The lifespan of the device is
determined by the presence of context and shared memory, while the
lifespan of a context depends on the client closing the device.
This behavior has been modified, making the lifespan of context
dependent on shared memory. If a client closes the device but doesn’t
release the shared memory, the linked context will remain active,
preventing the release callback from freeing resources in the TEE. This
could lead to a deadlock if the TEE holds a reference to the shared
memory and relies on the release callback to remove the reference.
In this pachset we introduce orphan tee_shm and default tee_context.
When a shared memory becomes orphan because its associated context is
released, it no longer has a tee_context. One method to differentiate
between orphaned and regular shared memory is to use NULL as the linked
context. However, this can cause issues if releasing the shared memory
triggers additional calls, like those to the supplicant, which require a
valid context. Instead of using NULL, an internal tee_context for the
driver can be used.
The driver relies on tee_device_unregister which is a blocking calls
waiting for all context to be released and all shared memory to be freed
before unloading the driver. This means that all contexts, including
internal context, should be closed before tee_device_unregister can
proceed. This can introduce a short window where there is no valid
context to use when releasing the shared memory. The default tee_context
has lifespan similar to the device.
For an orphan tee_shm, default context is used.
This has not been tested. Looking for feedback if this is a reasonable
change.
Signed-off-by: Amirreza Zarrabi <quic_azarrabi(a)quicinc.com>
---
Amirreza Zarrabi (3):
tee: revert removal of redundant teedev in struct tee_shm
tee: revert removal of linked list of struct tee_shm
tee: introduce orphan tee_shm and default context
drivers/tee/optee/core.c | 2 +-
drivers/tee/optee/ffa_abi.c | 2 +-
drivers/tee/optee/smc_abi.c | 2 +-
drivers/tee/tee_core.c | 84 +++++++++++++++++++++++++++++----------------
drivers/tee/tee_private.h | 3 --
drivers/tee/tee_shm.c | 41 ++++++++++++----------
include/linux/tee_core.h | 15 ++++++++
include/linux/tee_drv.h | 13 ++++---
8 files changed, 100 insertions(+), 62 deletions(-)
---
base-commit: ae58226b89ac0cffa05ba7357733776542e40216
change-id: 20241120-fix-tee_shm-refcount-upstream-c671b89fbe67
Best regards,
--
Amirreza Zarrabi <quic_azarrabi(a)quicinc.com>
Main updates from version V12[1]:
Fix warning build by fixing the inline declaration in
remoteproc_tee.h (when CONFIG_REMOTEPROC_TEE is not set).
Reported-by: kernel test robot <lkp(a)intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202410262040.PWNrKv2Q-lkp@intel.com/
Main updates from version V11[2]:
- rename structures, functions, and variables from "tee_rproc_xxx" to
"rproc_tee_xxx",
- update rproc_tee_register to return an error instead of
"struct rproc_tee *" pointer
[1] https://lore.kernel.org/lkml/20241025205924.2087768-1-arnaud.pouliquen@foss…
[2] https://lore.kernel.org/lkml/ZxZ4cBilIlpf3IPw@p14s/T/
Tested-on: commit 42f7652d3eb5 ("Linux 6.12-rc4")
Description of the feature:
--------------------------
This series proposes the implementation of a remoteproc tee driver to
communicate with a TEE trusted application responsible for authenticating
and loading the remoteproc firmware image in an Arm secure context.
1) Principle:
The remoteproc tee driver provides services to communicate with the OP-TEE
trusted application running on the Trusted Execution Context (TEE).
The trusted application in TEE manages the remote processor lifecycle:
- authenticating and loading firmware images,
- isolating and securing the remote processor memories,
- supporting multi-firmware (e.g., TF-M + Zephyr on a Cortex-M33),
- managing the start and stop of the firmware by the TEE.
2) Format of the signed image:
Refer to:
https://github.com/OP-TEE/optee_os/blob/master/ta/remoteproc/src/remoteproc…
3) OP-TEE trusted application API:
Refer to:
https://github.com/OP-TEE/optee_os/blob/master/ta/remoteproc/include/ta_rem…
4) OP-TEE signature script
Refer to:
https://github.com/OP-TEE/optee_os/blob/master/scripts/sign_rproc_fw.py
Example of usage:
sign_rproc_fw.py --in <fw1.elf> --in <fw2.elf> --out <signed_fw.sign> --key ${OP-TEE_PATH}/keys/default.pem
5) Impact on User space Application
No sysfs impact. The user only needs to provide the signed firmware image
instead of the ELF image.
For more information about the implementation, a presentation is available here
(note that the format of the signed image has evolved between the presentation
and the integration in OP-TEE).
https://resources.linaro.org/en/resource/6c5bGvZwUAjX56fvxthxds
Arnaud Pouliquen (7):
remoteproc: core: Introduce rproc_pa_to_va helper
remoteproc: Add TEE support
remoteproc: core: Refactor resource table cleanup into
rproc_release_fw
remoteproc: Introduce release_fw optional operation
dt-bindings: remoteproc: Add compatibility for TEE support
remoteproc: stm32: Create sub-functions to request shutdown and
release
remoteproc: stm32: Add support of an OP-TEE TA to load the firmware
.../bindings/remoteproc/st,stm32-rproc.yaml | 58 +-
drivers/remoteproc/Kconfig | 10 +
drivers/remoteproc/Makefile | 1 +
drivers/remoteproc/remoteproc_core.c | 72 ++-
drivers/remoteproc/remoteproc_tee.c | 510 ++++++++++++++++++
drivers/remoteproc/stm32_rproc.c | 139 +++--
include/linux/remoteproc.h | 8 +
include/linux/remoteproc_tee.h | 105 ++++
8 files changed, 848 insertions(+), 55 deletions(-)
create mode 100644 drivers/remoteproc/remoteproc_tee.c
create mode 100644 include/linux/remoteproc_tee.h
base-commit: 42f7652d3eb527d03665b09edac47f85fb600924
--
2.25.1
Hello,
I've been currently looking at the possibility of storing u-boot
environment variables in RPMB and I've stumbled upon this article:
https://www.linaro.org/blog/protected-uefi-variables-with-u-boot/
which briefly describes what needs to be done in order to achieve
this.
Unfortunately there is no comment section in this article so I cannot
ask the author so I decided to try here.
The article mentions that for that purpose, my board should support
dynamic shared memory, therefore the OP-TEE port for my board should
register that memory in platform main using the "register_ddr"
function. For my platform (ls1028ardb) I do not see anything like
this, thus I assume it's not supported. However, I'm wondering - is it
my platform's hardware limitation or missing software implementation?
Making this question more generic - does dynamic shared memory depend
on hardware, meaning that there is no way to register dynamic shared
memory if hardware does not support some particular features?
I would be grateful for some hints.
Best regards
Patryk
Hi,
I have a doubt about the correct priority that tee-supplicant should have
in the system.
In detail, we have 2 user-space applications (user-pkcs11-0, user-pkcs11-1)
that use the same PKCS11 services from OPTEE-OS (access to RPDB partition
for private key).
For project reason we use the following nice priority values:
user-pkcs11-0, nice=-5
user-pkcs11-1, nice=-10
....
tee-supplcant, nice=0
...
a lot of other services with nice=0
...
Unfortunately, in some strange case when CPU is overload (booting)....
appear a strange problem in user-pkcs11-1: occasionally the time for the
certificate's signature check explode to 400ms.
Due to the problem to replicate this defect, I have try to investigate in
theory if could be verify a starvation/race-condition between
tee-supplicant and user-pkcs11-1 or other-services.
In this scenario, what is the correct priority value that tee-supplicant
should have?
I suspect that we should change the priority of tee-supplcant =
user-pkcs11-1 = -10
Is it make sense for you, or maybe better to search the problem from an
other side :-) ?
Thanks in advance for your attention
BR
Matteo Facchinetti
Hi all,
I'm looking for any advice/clue to help me to progress on enabling
TEE-base EFI Runtime Variable Service on TI a j784s4 platforms.
I basically followed the steps described in u-boot documentation [1],
I enabled some debugging messages but I think I'm at the point that
the problem might be in the StandaloneMM application, and I'm not sure
how to debug it.
What I see is that when I run the tee-supplicant daemon, it looks like
the tee_client_open_session() call loops forever and the tee_stmm_efi
driver never ends to probe.
With debug enabled I got the following messages.
# tee-supplicant
D/TC:? 0 tee_ta_init_session_with_context:557 Re-open trusted service
7011a688-ddde-4053-a5a9-7b3c4ddf13b8
D/TC:? 0 load_stmm:297 stmm load address 0x40004000
D/TC:? 0 spm_handle_scall:859 Received FFA version
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
D/TC:? 0 spm_handle_scall:867 Received FFA direct request
And tracing the function calls gives me that:
tee_stmm_efi_probe() {
tee_client_open_context() {
optee_get_version() {
tee_get_drvdata(); (ret=0xffff000002e55800)
} (ret=0xd)
tee_ctx_match(); (ret=0x1)
optee_smc_open() {
tee_get_drvdata(); (ret=0xffff000002e55800)
optee_open() {
tee_get_drvdata(); (ret=0xffff000002e55800)
} (ret=0x0)
} (ret=0x0)
} (ret=0xffff000004e71c80)
tee_client_open_session() {
optee_open_session() {
tee_get_drvdata(); (ret=0xffff000002e55800)
optee_get_msg_arg() {
tee_get_drvdata(); (ret=0xffff000002e55800)
tee_shm_get_va(); (ret=0xffff000002909000)
} (ret=0xffff000002909000)
tee_session_calc_client_uuid(); (ret=0x0)
optee_to_msg_param(); (ret=0x0)
optee_smc_do_call_with_arg() {
tee_get_drvdata(); (ret=0xffff000002e55800)
tee_shm_get_va(); (ret=0xffff000002909000)
tee_shm_get_va(); (ret=0xffff000002909060)
optee_cq_wait_init(); (ret=0xffff000002e55910)
optee_smccc_smc(); (ret=0xffff0004)
tee_get_drvdata(); (ret=0xffff000002e55800)
optee_smccc_smc(); (ret=0xffff0004)
tee_get_drvdata(); (ret=0xffff000002e55800)
optee_smccc_smc(); (ret=0xffff0004)
tee_get_drvdata(); (ret=0xffff000002e55800)
optee_smccc_smc(); (ret=0xffff0004)
tee_get_drvdata(); (ret=0xffff000002e55800)
optee_smccc_smc(); (ret=0xffff0004)
... continues sending this forever ...
... Hit ^C to stop recording ...
tee_get_drvdata(); (ret=0xffff000002e55800)
optee_smccc_smc() {
[1] https://docs.u-boot.org/en/latest/develop/uefi/uefi.html#using-op-tee-for-e…
Thanks in advance,
Enric
Hello,
I am Jork Loeser from Microsoft, and we are looking into providing the OP-TEE internal core API from Linux user-level, as well as hosting a derivative of OP-TEE OS in Linux user-level. Can you say is something like this has been attempted in the past, and perhaps provide pointers?
How interesting would it be for OP-TEE to have such an implementation - e.g., for early/rapid-development purposes?
Best,
Jork