[PATCH v2] lib: optee: forbid OP-TEE OS loading without adding OP-TEE OS reserved-memory nodes

Quentin Schulz foss+uboot at 0leil.net
Tue Nov 11 12:52:34 CET 2025


From: Quentin Schulz <quentin.schulz at cherry.de>

I've spent time trying to figure out why my board (Rockchip PX30-based)
suddenly boot loops when running a specific program in Linux userspace
after working on a U-Boot upgrade. I actually inadvertently had the TEE
environment variable set for a device which doesn't actually need to run
any TEE OS (so had OPTEE_LIB disabled).

It is currently possible to build an image with an OP-TEE OS (via the
TEE environment variable) without OPTEE_LIB. U-Boot will happily load
the TEE OS and the next OS (e.g. the Linux kernel).

This is an issue because on FDT-enabled devices, OP-TEE OS adds nodes to
the reserved-memory FDT node for the memory regions it just reserved for
itself. This updated FDT is then passed to U-Boot proper which should
know better not to use memory from there. The actual issue is that
without OPTEE_LIB and OF_LIBFDT enabled, U-Boot proper will not copy
those nodes over to the next OS's FDT before starting it. This results
in the next OS's (e.g. Linux kernel) to not be aware of reserved memory,
incurring random crashes or device reboots when it tries to access
secure reserved memory area.

On Rockchip, the U-Boot FIT image which contains both the TEE OS and
U-Boot proper is generated by binman. Unfortunately, binman doesn't seem
to have access to Kconfig symbols (grep CONFIG_ doesn't return anything
meaningful and binman is either configured through FDT nodes or via CLI
arguments, c.f. cmd_binman in the root Makefile) so we cannot try to be
smart and guide the user to the correct Kconfig option to select if TEE
is set. We could add a property based on the presence of OPTEE_LIB in
rockchip-u-boot.dtsi for example and have a custom message based on
that, the issue is that I assume all FDT-based platforms do actually
need to do this dance, and not only Rockchip.

Another option could be to add a CLI argument to binman through which
we would pass the state of OPTEE_LIB and error out the build in that
case, but that feels like opening the door to other various dirty hacks.

Another option is to propagate the TEE environment variable to the
preprocessor of the FDT (via dtc_cpp_flags) and then we can do

  #if defined(TEE) && !IS_ENABLED(CONFIG_OPTEE_LIB)
  #error "CONFIG_OPTEE_LIB must be enabled!"
  #endif

but we have the same issue as above, it is then Rockchip-specific and
doesn't feel right to me.

Yet another option is to remove the @tee-SEQ node from the binman FIT
description when OPTEE_LIB isn't set but then we would lose the
following nice message when no TEE is provided:

Image 'simple-bin' is missing optional external blobs but is still functional: tee-os

and even worse, build without any TEE OS even though we could provide
one via the TEE environment variable.

Finally, another option could be to move this hack under
arch/arm/mach-rockchip/Kconfig to make it Rockchip-specific or add a
depends on ARCH_ROCKCHIP. However OP-TEE OS on Aarch32 Rockchip boards
doesn't actually need any of that if SPL_OPTEE_IMAGE is set because
arch/arm/mach-rockchip/sdram.c then marks some hardcoded memory regions
in RAM as holes in DRAM, which has the same effect as reserved memory
regions I guess. I assume other platforms may use something different,
so it may be casting too wide of a net.

This commit is what I could come up with as a stopgap measure to avoid
building images that simply cannot reliably work and fail randomly.

Signed-off-by: Quentin Schulz <quentin.schulz at cherry.de>
---
Changes in v2:
- removed RFC tag as requested by Tom,
- merged v1 commit log with v1 cover letter into the commit log of v2,
---
 lib/optee/Kconfig | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/lib/optee/Kconfig b/lib/optee/Kconfig
index e6834d4d3e1..34b9d8afe67 100644
--- a/lib/optee/Kconfig
+++ b/lib/optee/Kconfig
@@ -4,6 +4,25 @@ config OPTEE_LIB
 	help
 	  Selecting this option will enable the shared OPTEE library code.
 
+config HAS_TEE_IN_BUILD_ENV
+	def_bool $(success, test -n "$(TEE)")
+	select OPTEE_LIB if OF_CONTROL
+	select OF_LIBFDT if OF_CONTROL
+	help
+	  It is typical whenever OP-TEE OS is loaded before U-Boot proper that
+	  it modifies the FDT passed to U-Boot proper to add reserved-memory
+	  nodes for the RAM it just reserved for itself.
+
+	  U-Boot must copy those reserved-nodes in the FDT for the next OS to
+	  boot.
+
+	  Failing to do so will incur random crashes or device reboots once the
+	  next OS is running.
+
+	  This makes sure that whenever TEE is present in the environment,
+	  meaning a TEE OS will be part of the boot flow, the copy made by the
+	  OP-TEE lib will happen.
+
 config OPTEE_IMAGE
 	bool "Support OPTEE images"
 	help

---
base-commit: 365a7079fb918643da0f0709660a7d8ea76dd6f3
change-id: 20250919-tee-env-needs-optee-lib-32e0a3cec838

Best regards,
-- 
Quentin Schulz <quentin.schulz at cherry.de>



More information about the U-Boot mailing list