I have been reviewing how OP‑TEE is implemented and how secure‑world
invocations behave. The goal was to determine whether an OP‑TEE call can
delay the Linux side and introduce latency depending on the time spent
in the secure world.
Similar latency effects are already known for EFI runtime services, but
this was not documented. To mitigate the impact, EFI runtime invocations
can be restricted to specific CPUs so that real‑time workloads on other
CPUs remain unaffected. This mechanism, however, is only described in
the commit that introduced it.
This change adds a firmware section that documents these behaviours
explicitly. It highlights cases where firmware can delay the kernel,
information that may be unfamiliar to some users and surprising-or
concerning-to others.
Assisted-by: Microsoft-Copilot
Signed-off-by: Sebastian Andrzej Siewior <bigeasy(a)linutronix.de>
---
v1…v2: https://lore.kernel.org/all/20260701091226.7SWW4TrT@linutronix.de
- Rewrote the OP-TEE bits after some feedback from Ilias and Jens.
Added a link to the TF-A/OP-TEE documentation. The main difference is
that in contrast to my initial belief, OP-TEE can disable
normal-world's interrupts and it is not guaranteed that normal world
can always preempt the secure world.
Documentation/core-api/real-time/hardware.rst | 104 ++++++++++++++++++
1 file changed, 104 insertions(+)
diff --git a/Documentation/core-api/real-time/hardware.rst b/Documentation/core-api/real-time/hardware.rst
index 19f9bb3786e03..9f95e75e6aa18 100644
--- a/Documentation/core-api/real-time/hardware.rst
+++ b/Documentation/core-api/real-time/hardware.rst
@@ -130,3 +130,107 @@ https://github.com/Linutronix/RTC-Testbench.
The goal of this project is to validate real-time network communication. It can
be thought of as a "cyclictest" for networking and also serves as a starting
point for application development.
+
+Firmware
+--------
+
+The firmware often plays a significant role in system operation because it can
+perform tasks that the kernel cannot directly access, and in some cases it can
+even preempt or intercept the kernel.
+
+A common example of firmware assisting the kernel is when it provides a generic
+interface to a resource. Instead of accessing an RTC chip through an I2C host
+controller, the kernel may query the firmware for the current time, and the
+firmware then accesses the RTC behind the scenes.
+
+Firmware can also intercept kernel execution by providing services that
+temporarily take control of the system. One example is memory scrubbing, where
+the firmware periodically pauses the kernel, reads back portions of system
+memory, and then returns control. During this time, the kernel is effectively
+interrupted.
+In contrast, some systems provide hardware-based memory scrubbing, which
+operates independently of firmware or software. See
+Documentation/edac/scrub.rst for details.
+
+If the kernel is intercepted for longer periods then these periods can be made
+visible with the hardware latency detector. See
+Documentation/trace/hwlat_detector.rst.
+
+The kernel can also be intercepted in response to specific events, such as
+overheating. In this case, the firmware may throttle the CPU or shut it down
+immediately to prevent hardware damage.
+
+Unless the firmware is well documented, it should be thoroughly tested to
+uncover any unexpected behaviour.
+
+EFI
+~~~~
+
+EFI provides runtime services that act as a communication interface between the
+firmware and the operating system. One such service is reading and writing EFI
+variables, which are used, for example, to determine the boot source.
+
+Invoking a runtime service may require the architecture to disable kernel
+preemption or interrupts during the call. This means the duration of a service
+invocation directly affects the system’s observable latency. There is also
+nothing that prevents a service call from disabling interrupts internally while
+it runs.
+
+For these reasons, EFI runtime services are disabled by default on a PREEMPT_RT
+kernel. They can still be enabled at boot time or via a Kconfig option if
+required.
+The native EFI runtime service implementation (where both the EFI service and
+the kernel are either 32-bit or 64-bit executables) uses a wrapper mechanism
+that invokes the service through a dedicated workqueue. This workqueue is named
+efi_runtime, and it can be restricted to a housekeeping CPU using the
+``/sys/devices/virtual/workqueue/efi_runtime/cpumask`` sysfs file. Assigning it
+to a housekeeping CPU ensures that potentially long service invocations do not
+impact the real-time workload which is restricted to other CPUs.
+
+It must also be verified that the runtime services behave as expected. Some
+implementations on the x86 architecture pause all other CPUs while one CPU
+performs the service call. In such cases, the interruption affects all CPUs,
+and restricting the workqueue to a single CPU provides no benefit.
+
+OP-TEE (ARM)
+~~~~~~~~~~~~
+
+Execution flows from the normal world (Linux) into the secure world (OP-TEE)
+through the secure monitor at EL3. The transition is initiated by the `smc`
+(Secure Monitor Call) opcode or the `hvc` (Hypervisor Call) opcode together
+with a function identifier. The calling convention defines two types of calls:
+**yielding calls** and **fast calls**:
+
+- A **yielding call** unmasks interrupts before handling the requested service,
+ allowing normal world interrupts to occur.
+- A **fast call** handles the requested service atomically, without allowing
+ interrupts from either the normal world or the secure world.
+
+In addition, the secure world (EL3 and OP-TEE) can receive interrupts routed to
+the secure world. While a secure world interrupt is being serviced,
+normal world interrupts are masked and cannot preempt the operation.
+
+The transition from normal world to secure monitor to OP-TEE and back introduces
+additional latency due to world switching and context save/restore. This
+overhead is typically a few microseconds and usually remains within the noise
+floor.
+
+It is worth noting that the normal world cannot mask secure interrupts, while
+the secure world can mask normal-world interrupts during execution. How OP-TEE
+affects real-time workloads depends on whether secure interrupts are enabled
+and which OP-TEE services are invoked.
+
+A practical concern is any fast call that runs longer than expected, for
+example a function that occasionally performs a long-running cryptographic
+computation. Another example that may block in an unexpected way are OP-TEE
+drivers that issue RPC requests. An OP-TEE service in the secure world (RPMB
+for instance) may need to issue a request back to the normal world (the Linux
+driver) in order to complete the operation. While Linux remains preemptible,
+the thread that issued the request stays blocked until the RPC completes and
+the secure function call returns.
+
+The TF-A project provides documentation on interrupt management:
+https://trustedfirmware-a.readthedocs.io/en/latest/design/interrupt-framework-design.html#interrupt-management-framework
+
+The OP-TEE project provides documentation on how interrupts are handled:
+https://optee.readthedocs.io/en/latest/architecture/core.html#interrupt-handling
--
2.53.0
On Qualcomm SoC based platforms, UEFI stores EFI variables within the
Replay Protected Memory Block (RPMB) which is only accessible by the
Qualcomm Trusted Execution Environment (QTEE).
For Qualcomm platforms without emulated RPMB support, specifically
platforms where RPMB is not located within SPI-NOR storage and instead
located on UFS/EMMC storage, non-volatile EFI variables can only be set via
a callback request from the UEFI Secure Application to the RPMB service
running in user-space (within the QTEE supplicant [1]).
Unlike the QCOM-TEE driver, the QSEECOM driver (used by the current
QSEECOM based uefisecapp) does not support callback requests. And on
certain Qualcomm platforms such as the RB3Gen2, attempts to access the
QSEECOM interface fail due to lack of support within Qualcomm TEE.
On these platforms, a TEE based uefisecapp client driver is required to:
1. Access cached & volatile EFI variables stored in uefisecapp's memory.
2. Ensure persistence of non-volatile EFI variables via writes through
the RPMB service hosted in the QTEE supplicant.
This series introduces such a uefisecapp TEE client driver for the
aforementioned Qualcomm platforms which installs efi-var operations _if_
the QCOMTEE driver registers support for an object-IPC based uefisecapp
service on the TEE bus during its probe. Only new QTEE firmware versions
available at [2] provide this support.
Thus, QCOMTEE now maintains a static list of always-available object-IPC
based secure services exposed by QTEE. These services are implemented either
within the QTEE kernel or within a pre-loaded Trusted Application (TA)
usually loaded by the bootloader. The uefisecapp TA is an example of a
preloaded TA loaded by UEFI. A static list is required since QTEE does not
yet expose any way to dynamically query and enumerate the services exposed by
it.
To facilitate object-IPC interactions from the kernel-space, this
series also introduces a tee_client_object_invoke_func() to allow
invocation of TEE objects similar to the existing tee_client_invoke_func()
API exported by the TEE subsystem which allows invocation of TEE functions.
Some suporting changes are also introduced to track and handle operations
for TEE contexts opened from the kernel-space in the back-end QCOM-TEE
driver.
Finally and as previously mentioned, access to the object-IPC based uefisecapp
service is restricted on older QTEE firmware versions. A new QTEE firmware
release must be picked up from QArtifactory [2] for all upstream supported
Qualcomm SoCs to enable access to uefisecapp service via the TEE client
driver.
This patch series has been validated on Kodiak RB3Gen2 platform with UFS
storage by attempting to read/write EFI variables via the efivar tool [3]
after mounting the efivarfs filesystem. See [4] for an example.
Merge Strategy:
This patch series could either be taken from the OP-TEE tree or the
QCOM soc tree. I would prefer it to be picked by the OP-TEE tree since
all except the uefisecapp TEE client driver patch in this series make
changes relevant to the TEE subsystem. It would be great if the QCOM soc
tree maintainers can Ack the uefisecapp driver patch.
[1] https://github.com/qualcomm/minkipc
[2] https://shorturl.at/zQU07
[3] https://github.com/rhboot/efivar
[4] https://docs.qualcomm.com/doc/80-70020-27/topic/manage_uefi_environment_var…
Signed-off-by: Harshal Dev <harshal.dev(a)oss.qualcomm.com>
---
Changes in v2:
- Drop using MSB of the object_id to distingush kernel and user object invoke contexts.
- Introduce enum tee_object_invoke_origin to check the context of object invocation.
- Link to v1: https://lore.kernel.org/r/20260707-qcom_uefisecapp_migrate_qcomtee-v1-0-f65…
---
Amirreza Zarrabi (2):
tee: Add kernel client object invoke helper
tee: qcomtee: Allow object invokes from kernel clients
Harshal Dev (4):
tee: qcomtee: Track the object invocation context
tee: Export uuidv5 generation for TEE backends
tee: qcomtee: Add support for registering QTEE services on TEE bus
firmware: qcom: Add support for TEE based EFI-var client driver
MAINTAINERS | 7 +
drivers/firmware/qcom/Kconfig | 24 ++
drivers/firmware/qcom/Makefile | 1 +
drivers/firmware/qcom/qcom_tee_uefisecapp.c | 525 ++++++++++++++++++++++++++++
drivers/firmware/qcom/qcom_tee_uefisecapp.h | 120 +++++++
drivers/tee/qcomtee/call.c | 205 ++++++++++-
drivers/tee/qcomtee/core.c | 9 +-
drivers/tee/qcomtee/qcomtee.h | 12 +
drivers/tee/qcomtee/qcomtee_msg.h | 1 +
drivers/tee/qcomtee/qcomtee_object.h | 16 +-
drivers/tee/tee_core.c | 24 +-
include/linux/tee_core.h | 23 +-
include/linux/tee_drv.h | 18 +-
13 files changed, 952 insertions(+), 33 deletions(-)
---
base-commit: f3e6330d7fe42b204af05a2dbc68b379e0ad179e
change-id: 20260408-qcom_uefisecapp_migrate_qcomtee-13869d45e014
Best regards,
--
Harshal Dev <harshal.dev(a)oss.qualcomm.com>
'select' does not work on config options in a 'choice', so currently it is
possible to enable QCOMTEE without QCOM_TZMEM_MODE_SHMBRIDGE, even though
this is needed at runtime.
There are no users of the generic allocator option,
QCOM_TZMEM_MODE_GENERIC, so let's remove it. Then, we can remove the
containing choice..endchoice, which allows the 'select' to work as
intended.
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
Signed-off-by: Julian Braha <julianbraha(a)gmail.com>
---
Changes since v2:
- add back stubs for when CONFIG_QCOM_TZMEM_MODE_GENERIC=n
- updated help text accordingly
Link:
https://lore.kernel.org/all/20260729203845.387239-1-julianbraha@gmail.com/
Changes since v1:
- remove TZMEM_MODE_GENERIC instead of removing the dead select
Link:
https://lore.kernel.org/all/20260715092539.18384-1-julianbraha@gmail.com/
---
drivers/firmware/qcom/Kconfig | 26 +++++---------------------
drivers/firmware/qcom/qcom_tzmem.c | 4 ++--
2 files changed, 7 insertions(+), 23 deletions(-)
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index c7f8413ab996..95b968d88dc3 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -34,33 +34,17 @@ config QCOM_TZMEM
tristate
select GENERIC_ALLOCATOR
-choice
- prompt "TrustZone interface memory allocator mode"
- depends on QCOM_TZMEM
- default QCOM_TZMEM_MODE_GENERIC
- help
- Selects the mode of the memory allocator providing memory buffers of
- suitable format for sharing with the TrustZone. If in doubt, select
- 'Generic'.
-
-config QCOM_TZMEM_MODE_GENERIC
- bool "Generic"
- help
- Use the generic allocator mode. The memory is page-aligned, non-cachable
- and physically contiguous.
-
config QCOM_TZMEM_MODE_SHMBRIDGE
- bool "SHM Bridge"
+ bool "TrustZone interface memory allocator: SHM Bridge"
+ depends on QCOM_TZMEM
help
- Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
- in the 'Generic' allocator but is also explicitly marked as an SHM Bridge
- buffer.
+ Use Qualcomm Shared Memory Bridge as memory allocator. The memory has the
+ same alignment as in the 'Generic' allocator, which is used when this option
+ is disabled, but is also explicitly marked as an SHM Bridge buffer.
With this selected, all buffers passed to the TrustZone must be allocated
using the TZMem allocator or else the TrustZone will refuse to use them.
-endchoice
-
config QCOM_QSEECOM
bool "Qualcomm QSEECOM interface driver"
depends on QCOM_SCM=y
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
index 0fd9581275f1..510474902c3a 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -50,7 +50,7 @@ static struct device *qcom_tzmem_dev;
static RADIX_TREE(qcom_tzmem_chunks, GFP_ATOMIC);
static DEFINE_SPINLOCK(qcom_tzmem_chunks_lock);
-#if IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_GENERIC)
+#ifndef CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE
static int qcom_tzmem_init(void)
{
@@ -67,7 +67,7 @@ static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
}
-#elif IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE)
+#else
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/of.h>
--
2.55.0
Hello soc maintainers,
Please pull this small update for the QCOMTEE driver.
Thanks,
Jens
The following changes since commit dc59e4fea9d83f03bad6bddf3fa2e52491777482:
Linux 7.2-rc1 (2026-06-28 12:01:31 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee.git tags/qcomtee-for-v7.3
for you to fetch changes up to d92f87f3e7c79f58cc6d6edad4bf1c96f795aa7b:
tee: qcomtee: Drop unused assignment of platform_device_id driver data (2026-06-29 07:53:26 +0200)
----------------------------------------------------------------
Drop unused assignment of platform_device_id driver data
----------------------------------------------------------------
Uwe Kleine-König (The Capable Hub) (1):
tee: qcomtee: Drop unused assignment of platform_device_id driver data
drivers/tee/qcomtee/call.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
Hello soc maintainers,
Please pull this small OP-TEE fix for the OP-TEE drivers.
Thanks,
Jens
The following changes since commit dc59e4fea9d83f03bad6bddf3fa2e52491777482:
Linux 7.2-rc1 (2026-06-28 12:01:31 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee.git tags/optee-fix-for-v7.2
for you to fetch changes up to 650c88738ae8976f46ba71b24dd8aa311adc6fde:
optee: ffa: Add NULL check in optee_ffa_lend_protmem (2026-06-29 08:04:45 +0200)
----------------------------------------------------------------
Add NULL check in optee_ffa_lend_protmem()
----------------------------------------------------------------
Mostafa Saleh (1):
optee: ffa: Add NULL check in optee_ffa_lend_protmem
drivers/tee/optee/ffa_abi.c | 3 +++
1 file changed, 3 insertions(+)
param_from_user_memref() obtains a temporary reference to the dma-buf
tee_shm wrapper by ID. If closing the shared-memory file descriptor races
with the ioctl, this temporary reference can be the wrapper's last one.
tee_shm_put() then frees the enclosing tee_shm_dmabuf_ref, but the function
still reads ref->parent_shm and ref->offset afterwards.
Save the parent pointer and offset before dropping the wrapper reference.
The additional parent reference keeps the parent shared memory alive for
the parameter list as before.
Fixes: 146bf4e75eca ("tee: new ioctl to a register tee_shm from a dmabuf file descriptor")
Cc: stable(a)vger.kernel.org
Signed-off-by: Hongyan Xu <getshell(a)seu.edu.cn>
---
drivers/tee/tee_core.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index 1aac50c7c1de..489c39d5b35f 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -397,6 +397,7 @@ static int param_from_user_memref(struct tee_context *ctx,
}
if (shm->flags & TEE_SHM_DMA_BUF) {
+ struct tee_shm *parent_shm;
struct tee_shm_dmabuf_ref *ref;
ref = container_of(shm, struct tee_shm_dmabuf_ref, shm);
@@ -409,10 +410,11 @@ static int param_from_user_memref(struct tee_context *ctx,
* list instead of the shm we got with
* tee_shm_get_from_id() above.
*/
- refcount_inc(&ref->parent_shm->refcount);
- tee_shm_put(shm);
- shm = ref->parent_shm;
+ parent_shm = ref->parent_shm;
offs = ref->offset;
+ refcount_inc(&parent_shm->refcount);
+ tee_shm_put(shm);
+ shm = parent_shm;
}
}
} else if (ctx->cap_memref_null) {
--
2.50.1.windows.1
This series makes UFS RPMB work out of the box with an OP-TEE that
implements the standard eMMC RPMB key-derivation flow, without requiring
any fundamental changes on the OP-TEE side.
RPMB provides an authenticated, replay-protected storage area whose
security relies on a secret authentication key. In our setup that key is
never exposed to the kernel: OP-TEE derives it in the secure world from
its hardware-unique key and a device identifier (dev_id) that the RPMB
core hands down. OP-TEE's implementation targets eMMC, where dev_id is
the 16-byte eMMC CID, and both the fixed length and the raw-CID layout
are baked into its key derivation.
Two things stand in the way of reusing that same, unmodified OP-TEE flow
for UFS RPMB:
1. On a cold boot the very first frame sent to the RPMB well-known LU
comes back with a power-on UNIT ATTENTION (ASC 0x29), which the SCSI
core reports rather than retries. RPMB has no earlier guaranteed
access that could clear the condition first, so RPMB fails on every
power cycle. Patch 1 asks the SCSI core to retry the power-on UNIT
ATTENTION on the RPMB WLUN.
2. The UFS RPMB id is "<device_id>-R<region>", which is variable length
and longer than 16 bytes. Passing it verbatim would tie the derived
key to a length OP-TEE does not expect and diverge from the fixed
eMMC CID ABI. Patch 2 hashes it into a fixed 16-byte dev_id with
blake2s, keeping the key stable and unique per region while matching
the eMMC CID layout OP-TEE relies on. The hash algorithm and input
string are thus part of the key-derivation ABI and must stay stable.
With both patches, UFS RPMB is functional from the first access after a
cold boot and derives keys through the existing eMMC-style OP-TEE flow,
(requires minimal OP-TEE changes).
Jorge Ramirez-Ortiz (2):
ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN
ufs: rpmb: use a fixed-length RPMB dev_id
drivers/ufs/Kconfig | 1 +
drivers/ufs/core/ufs-rpmb.c | 41 ++++++++++++++++++++++++++++++++++---
2 files changed, 39 insertions(+), 3 deletions(-)
'select' does not work on config options in a 'choice', so currently it is
possible to enable QCOMTEE without QCOM_TZMEM_MODE_SHMBRIDGE, even though
this is needed at runtime.
There are no users of the generic allocator option,
QCOM_TZMEM_MODE_GENERIC, so let's remove it. Then, we can remove the
containing choice..endchoice, which allows the 'select' to work as
intended.
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
Signed-off-by: Julian Braha <julianbraha(a)gmail.com>
---
Changes since v1:
- remove TZMEM_MODE_GENERIC instead of removing the dead select
Link:
https://lore.kernel.org/all/20260715092539.18384-1-julianbraha@gmail.com/
---
drivers/firmware/qcom/Kconfig | 26 +++++---------------------
drivers/firmware/qcom/qcom_tzmem.c | 21 ---------------------
2 files changed, 5 insertions(+), 42 deletions(-)
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index c7f8413ab996..d99e09c5fa18 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -34,33 +34,17 @@ config QCOM_TZMEM
tristate
select GENERIC_ALLOCATOR
-choice
- prompt "TrustZone interface memory allocator mode"
- depends on QCOM_TZMEM
- default QCOM_TZMEM_MODE_GENERIC
- help
- Selects the mode of the memory allocator providing memory buffers of
- suitable format for sharing with the TrustZone. If in doubt, select
- 'Generic'.
-
-config QCOM_TZMEM_MODE_GENERIC
- bool "Generic"
- help
- Use the generic allocator mode. The memory is page-aligned, non-cachable
- and physically contiguous.
-
config QCOM_TZMEM_MODE_SHMBRIDGE
- bool "SHM Bridge"
+ bool "TrustZone interface memory allocator: SHM Bridge"
+ depends on QCOM_TZMEM
help
- Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
- in the 'Generic' allocator but is also explicitly marked as an SHM Bridge
- buffer.
+ Use Qualcomm Shared Memory Bridge as memory allocator. The memory has the
+ same alignment as in the 'Generic' allocator but is also explicitly marked
+ as an SHM Bridge buffer.
With this selected, all buffers passed to the TrustZone must be allocated
using the TZMem allocator or else the TrustZone will refuse to use them.
-endchoice
-
config QCOM_QSEECOM
bool "Qualcomm QSEECOM interface driver"
depends on QCOM_SCM=y
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
index 0635cbeacfc8..5b3e5a3ad1ae 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -49,25 +49,6 @@ static struct device *qcom_tzmem_dev;
static RADIX_TREE(qcom_tzmem_chunks, GFP_ATOMIC);
static DEFINE_SPINLOCK(qcom_tzmem_chunks_lock);
-#if IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_GENERIC)
-
-static int qcom_tzmem_init(void)
-{
- return 0;
-}
-
-static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)
-{
- return 0;
-}
-
-static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
-{
-
-}
-
-#elif IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE)
-
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/of.h>
@@ -189,8 +170,6 @@ static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
kfree(handle);
}
-#endif /* CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE */
-
static int qcom_tzmem_pool_add_memory(struct qcom_tzmem_pool *pool,
size_t size, gfp_t gfp)
{
--
2.55.0
Fix kernel-doc issues present since the driver was added in commit
d6e290837e50 ("tee: add Qualcomm TEE driver"):
- async_release() documents its second parameter as @msg, but the
parameter is named async_msg (msg is a local variable);
- struct qcomtee_msg_object_invoke documents member @ctx, but the
member is named cxt;
- enum qcomtee_arg_type leaves QCOMTEE_ARG_TYPE_NR undescribed.
The cxt spelling is part of the QTEE message format and is used
throughout the driver; struct qcomtee_msg_callback in the same header
already documents it as @cxt, so the comment is corrected rather than
the member.
No functional changes.
Assisted-by: Claude:claude-opus-5 [kernel-doc]
Signed-off-by: Babanpreet Singh <bbnpreetsingh(a)gmail.com>
---
drivers/tee/qcomtee/async.c | 4 ++--
drivers/tee/qcomtee/qcomtee_msg.h | 2 +-
drivers/tee/qcomtee/qcomtee_object.h | 1 +
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/tee/qcomtee/async.c b/drivers/tee/qcomtee/async.c
index 31bff4309e672..5849e51612033 100644
--- a/drivers/tee/qcomtee/async.c
+++ b/drivers/tee/qcomtee/async.c
@@ -97,10 +97,10 @@ static void qcomtee_get_async_buffer(struct qcomtee_object_invoke_ctx *oic,
/**
* async_release() - Process QTEE async release requests.
* @oic: context used for the current invocation.
- * @msg: async message for object release.
+ * @async_msg: async message for object release.
* @size: size of the async buffer available.
*
- * Return: Size of the outbound buffer used when processing @msg.
+ * Return: Size of the outbound buffer used when processing @async_msg.
*/
static size_t async_release(struct qcomtee_object_invoke_ctx *oic,
struct qcomtee_async_msg_hdr *async_msg,
diff --git a/drivers/tee/qcomtee/qcomtee_msg.h b/drivers/tee/qcomtee/qcomtee_msg.h
index 878f70178a5b6..5d7b21fdd3688 100644
--- a/drivers/tee/qcomtee/qcomtee_msg.h
+++ b/drivers/tee/qcomtee/qcomtee_msg.h
@@ -112,7 +112,7 @@ union qcomtee_msg_arg {
/**
* struct qcomtee_msg_object_invoke - Direct object invocation message.
- * @ctx: object ID hosted in QTEE.
+ * @cxt: object ID hosted in QTEE.
* @op: operation for the object.
* @counts: number of different types of arguments in @args.
* @args: array of arguments.
diff --git a/drivers/tee/qcomtee/qcomtee_object.h b/drivers/tee/qcomtee/qcomtee_object.h
index 8b4401ecad48c..d5de02dcef3b9 100644
--- a/drivers/tee/qcomtee/qcomtee_object.h
+++ b/drivers/tee/qcomtee/qcomtee_object.h
@@ -74,6 +74,7 @@ enum qcomtee_object_type {
* @QCOMTEE_ARG_TYPE_OO: output object (OO).
* @QCOMTEE_ARG_TYPE_IB: input buffer (IB).
* @QCOMTEE_ARG_TYPE_IO: input object (IO).
+ * @QCOMTEE_ARG_TYPE_NR: number of argument types.
*
* Use the invalid type to specify the end of the argument array.
*/
--
2.43.0
The qcomtee_cb_params_to_args() walks the argument array QTEE asked for and
indexes the parameter array the supplicant supplied, but it never looks at
num_params. A supplicant that answers TEE_IOC_SUPPL_SEND with fewer
parameters than the request needs makes that walk read past the end of the
allocation.
To fix this, reject a response that is too short, the way ureq_select()
already does for the receive direction.
Fixes: d6e290837e50 ("tee: add Qualcomm TEE driver")
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311(a)gmail.com>
---
drivers/tee/qcomtee/user_obj.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/tee/qcomtee/user_obj.c b/drivers/tee/qcomtee/user_obj.c
index 10452fcc7ccb..2a594ae299da 100644
--- a/drivers/tee/qcomtee/user_obj.c
+++ b/drivers/tee/qcomtee/user_obj.c
@@ -507,6 +507,10 @@ static int qcomtee_cb_params_to_args(struct qcomtee_arg *u,
{
int i;
+ /* Supplicant can not send fewer parameters than requested. */
+ if (num_params < qcomtee_args_len(u))
+ return -EINVAL;
+
qcomtee_arg_for_each(i, u) {
switch (u[i].type) {
case QCOMTEE_ARG_TYPE_IB:
--
2.43.0