On Qualcomm SoC based platforms, UEFI stores EFI variables within the
Replay Protected Memory Block (RPMB) located within either the UFS,
eMMC or SPI-NOR storage. The RPMB key which is one-time programmed into
the storage controller to allow authentication of the RPMB frames is
generated by and only available to the Qualcomm Trusted Execution
Environment (QTEE). Thus, only QTEE can prepare the RPMB frames which
will be accepted by the storage controller.
The legacy QSEECOM protocol used for communicating with the QTEE is
deprecated and replaced with the use-case agnostic SMCInvoke protocol
starting with the Qualcomm SM8x50 series. On platforms where the QSEECOM
protocol still works (the QSEECOM driver probes) the driver does not
support a listener interface with QTEE to enable writing of non-volatile
EFI variables (via listener requests to Linux from QTEE) to the RPMB
for UFS and eMMC storage. (Qualcomm Compute platforms with SPI-NOR storage
are an exception to this and work with QSEECOM, see the NOTE below)
Therefore on such platforms, a TEE client driver (which communicates with
QTEE via the SMCInvoke protocol implemented by the QCOMTEE driver
registered with the TEE subsystem) must be used to update such EFI variables
through the RPMB service hosted in the QTEE supplicant user-space daemon
[1] which forwards RPMB packets to the RPMB device.
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 access to the uefisecapp service via the SMCInvoke
protocol.
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.
NOTE: Since Compute platforms do not have a firmware running on their SPI-NOR
storage controller which must be programmed with a RPMB key, QTEE has a
SPI-NOR driver which holds the key, and so the QSEECOM driver can be used
for updating EFI variables on these platforms because QTEE never makes a
listener request to Linux (QTEE doesn't need the Linux SPI-NOR driver).
Such platforms are outlined in the following static list [5].
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…
[5] https://elixir.bootlin.com/linux/v7.3-rc5/source/drivers/firmware/qcom/qcom…
Signed-off-by: Harshal Dev <harshal.dev(a)oss.qualcomm.com>
---
Changes in v3:
- Updated the cover letter and commit messages to highlight the following:
1. Only QTEE has the ability to prepare RPMB frames since it generates and
holds the RPMB key.
2. The QSEECOM protocol is deprecated on new platforms and so this series
migrates the uefisecapp to SMCInvoke which is a use-case agnostic, transport
focused and easier to maintain protocol.
- Use single if statement to update both flags and addr/uaddr.
- Remove redundant use of new error variable in qcomtee_get_qtee_feature_list().
- Minor fixes such as concise error prints and use of better error codes.
- Fix a double free in qtee_enumerate_service().
- Re-org the qcomtee_enumerate_services() function to re-use the same oic and
client_env object.
- Remove depends on !QCOM_QSEECOM_UEFISECAPP from Kconfig since both drivers
can co-exist even on platforms that support both QSEECOM and SMCInvoke protocols.
- Update the Kconfig description to better help the user understand when to enable
the TEE based uefisecapp driver.
- Removed qcom_tee_uefisecapp.h file and inline the header in qcom_tee_uefisecapp.c
- Rebased patch series onto the latest linux next tag: next-20260930.
- Link to v2: https://lore.kernel.org/r/20260722-qcom_uefisecapp_migrate_qcomtee-v2-0-b8a…
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 | 6 +
arch/arm64/configs/defconfig | 1 +
drivers/firmware/qcom/Kconfig | 31 ++
drivers/firmware/qcom/Makefile | 1 +
drivers/firmware/qcom/qcom_tee_uefisecapp.c | 636 ++++++++++++++++++++++++++++
drivers/tee/qcomtee/call.c | 206 ++++++++-
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(+), 32 deletions(-)
---
base-commit: 6c2cb8b8b843d216ab549b678a0d8831c43153e0
change-id: 20260408-qcom_uefisecapp_migrate_qcomtee-13869d45e014
Best regards,
--
Harshal Dev <harshal.dev(a)oss.qualcomm.com>
Hello soc maintainers,
Please pull this small kernel-doc fix for the QTEE driver in the TEE
subsystem.
Thanks,
Jens
The following changes since commit 8d3ae59288f1e7d58d76558a6ee96d533bc5019f:
Linux 7.2 (2026-08-16 14:32:26 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee.git tags/qcomtee-fix-for-v7.3
for you to fetch changes up to 93847823b6761e1791a7db10f55bbd4f79fa0dbc:
tee: qcomtee: fix kernel-doc warnings (2026-08-24 14:49:01 +0200)
----------------------------------------------------------------
Fix kernel-doc warnings
----------------------------------------------------------------
Babanpreet Singh (1):
tee: qcomtee: fix kernel-doc warnings
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(-)
Hello soc maintainers,
Please pull this small patch for the QTEE driver in TEE subsystem.
Thanks,
Jens
The following changes since commit 8d3ae59288f1e7d58d76558a6ee96d533bc5019f:
Linux 7.2 (2026-08-16 14:32:26 -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.4
for you to fetch changes up to 615970476444bdf853c7c3ecdbe809dbdca06c16:
tee: qcomtee: Drop unused assignment of platform_device_id driver data (2026-09-16 10:38:46 +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 patch for the TEE subsystem.
Thanks,
Jens
The following changes since commit 8d3ae59288f1e7d58d76558a6ee96d533bc5019f:
Linux 7.2 (2026-08-16 14:32:26 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee.git tags/tee-for-v7.4
for you to fetch changes up to 6229fda9a88656ea7c727c3e2401080c5d3efbc6:
tee: move tee_ioctl_shm_register_data to above IOCTL definition (2026-09-16 07:52:31 +0200)
----------------------------------------------------------------
Move tee_ioctl_shm_register_data to above IOCTL definition
----------------------------------------------------------------
Andrew Davis (1):
tee: move tee_ioctl_shm_register_data to above IOCTL definition
include/uapi/linux/tee.h | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
Hello soc maintainers,
Please pull these fixes for the OP-TEE driver in the TEE subsystem.
Thanks,
Jens
The following changes since commit 8d3ae59288f1e7d58d76558a6ee96d533bc5019f:
Linux 7.2 (2026-08-16 14:32:26 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee.git tags/optee-fixes-for-v7.3
for you to fetch changes up to 3c0d2f1f431c51a11253f28763be723ac782fd7a:
tee: optee: ffa: support shared memory offsets on large-page kernels (2026-10-02 16:08:05 +0200)
----------------------------------------------------------------
OP-TEE fixes for v7.3
- Register the TEE devices only once fully initialized
- Support FF-A shared memory offsets on large-page kernels
----------------------------------------------------------------
Mahantesh Salimath (1):
tee: optee: ffa: support shared memory offsets on large-page kernels
Shao-Fu Chen (1):
optee: register TEE devices only once fully initialized
drivers/tee/optee/ffa_abi.c | 38 ++++++++++++++++++++++++++------------
drivers/tee/optee/optee_msg.h | 4 ++--
drivers/tee/optee/smc_abi.c | 17 ++++++++---------
3 files changed, 36 insertions(+), 23 deletions(-)
[BCC all OP-TEE maintainers]
Hi OP-TEE maintainers & contributors,
OP-TEE version 4.11.0 is now scheduled for release on 2026-10-16. So,
now is a good time to start testing the master branch across various
platforms and report or fix any bugs.
The GitHub pull request for collecting Tested-by tags or any other
comments is https://github.com/OP-TEE/optee_os/pull/8054.
We will create the release candidate tag 4.11.0-rc1 next Friday, October 2.
You can find more information related to releases here:
https://optee.readthedocs.io/en/latest/general/releases.html
Thanks,
Jens
OP-TEE FF-A memory objects use 4 KiB pages, while the kernel page
size may be larger. Consequently, tee_shm->offset can be greater than
or equal to FFA_PAGE_SIZE, but OP-TEE rejects such a value in
internal_offs.
Do not encode the excess page offset in offs_low/offs_high. Those
fields describe the logical memref offset and are copied back into
tee_param->shm_offs on return. Folding the page offset into them breaks
parameter round trips when a memref is reused. They are also ignored by
the OPTEE_RPC_CMD_SHM_ALLOC response path, which uses only global_id and
internal_offs to construct the shared-memory mobj.
Instead, start the FF-A descriptor at the 4 KiB page containing the
shared buffer, the same approach as optee_fill_pages_list() in the SMC
ABI. Store the remaining in-page offset in internal_offs and preserve
shm_offs in offs_low/offs_high. This keeps internal_offs within the
FF-A page size, maps RPC allocations at the correct address, and
preserves normal memref offsets across repeated invocations.
Tested on ARMv8-A with 64 KiB PAGE_SIZE. OP-TEE OS ran as a secure
partition under Hafnium (SPMC) over FF-A. Verified registered shared
memory with tee_shm->offset >= 4 KiB, memref reuse on the same
TEEC_Operation, and RPC OPTEE_RPC_CMD_SHM_ALLOC (xtest regression
6007-6009). optee_hello_world, optee_aes, and xtest regression 1005,
1007, 1008, 4001-4003 and 6001-6003 also passed.
Fixes: 4615e5a34b95 ("optee: add FF-A support")
Acked-by: Liming Sun <limings(a)nvidia.com>
Acked-by: James Hurley <jahurley(a)nvidia.com>
Acked-by: Dave Thompson <davthompson(a)nvidia.com>
Signed-off-by: Mahantesh Salimath <mahantesh(a)nvidia.com>
---
drivers/tee/optee/ffa_abi.c | 66 +++++++++++++++++++++++++++++------
drivers/tee/optee/optee_msg.h | 4 +--
2 files changed, 57 insertions(+), 13 deletions(-)
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index 633715b98625..2a37e4899dc6 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -187,6 +187,40 @@ static int optee_ffa_from_msg_param(struct optee *optee,
return 0;
}
+/*
+ * OP-TEE FF-A memory objects use 4 KiB pages while the kernel page size may
+ * be larger, for example 64 KiB on arm64. The FF-A descriptor is registered
+ * from the 4 KiB page containing the start of the shared buffer, so
+ * internal_offs is the offset into that page.
+ */
+static void optee_ffa_set_internal_offs(struct optee_msg_param_fmem *fmem,
+ struct tee_shm *shm)
+{
+ size_t page_offs = tee_shm_get_page_offset(shm);
+
+ BUILD_BUG_ON(PAGE_SIZE < FFA_PAGE_SIZE);
+
+ fmem->internal_offs = page_offs & (FFA_PAGE_SIZE - 1);
+}
+
+/*
+ * Keep shm_offs unchanged in offs_low/offs_high: it is returned to callers
+ * and may be reused for a subsequent invocation.
+ */
+static int optee_ffa_set_fmem_offsets(struct optee_msg_param_fmem *fmem,
+ struct tee_shm *shm, u64 shm_offs)
+{
+ optee_ffa_set_internal_offs(fmem, shm);
+
+ fmem->offs_low = shm_offs;
+ fmem->offs_high = shm_offs >> 32;
+ /* Check that the entire offset could be stored. */
+ if (fmem->offs_high != shm_offs >> 32)
+ return -EINVAL;
+
+ return 0;
+}
+
static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
const struct tee_param *p)
{
@@ -196,14 +230,8 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
if (shm) {
- u64 shm_offs = p->u.memref.shm_offs;
-
- mp->u.fmem.internal_offs = shm->offset;
-
- mp->u.fmem.offs_low = shm_offs;
- mp->u.fmem.offs_high = shm_offs >> 32;
- /* Check that the entire offset could be stored. */
- if (mp->u.fmem.offs_high != shm_offs >> 32)
+ if (optee_ffa_set_fmem_offsets(&mp->u.fmem, shm,
+ p->u.memref.shm_offs))
return -EINVAL;
mp->u.fmem.global_id = shm->sec_world_id;
@@ -284,14 +312,30 @@ static int optee_ffa_shm_register(struct tee_context *ctx, struct tee_shm *shm,
.nattrs = 1,
};
struct sg_table sgt;
+ size_t page_offs;
+ size_t ffa_offs;
+ size_t ffa_size;
int rc;
+ if (!num_pages)
+ return -EINVAL;
+
rc = optee_check_mem_type(start, num_pages);
if (rc)
return rc;
- rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
- num_pages * PAGE_SIZE, GFP_KERNEL);
+ page_offs = tee_shm_get_page_offset(shm);
+ ffa_offs = round_down(page_offs, FFA_PAGE_SIZE);
+ ffa_size = num_pages * PAGE_SIZE - ffa_offs;
+
+ /*
+ * Start the FF-A descriptor at the 4 KiB page containing the shared
+ * buffer, skipping unused leading 4 KiB pages when PAGE_SIZE is
+ * larger. Same approach as optee_fill_pages_list() in the SMC ABI.
+ * This leaves only page_offs & (FFA_PAGE_SIZE - 1) for internal_offs.
+ */
+ rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, ffa_offs,
+ ffa_size, GFP_KERNEL);
if (rc)
return rc;
args.sg = sgt.sgl;
@@ -458,8 +502,8 @@ static void handle_ffa_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
.attr = OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT,
.u.fmem.size = tee_shm_get_size(shm),
.u.fmem.global_id = shm->sec_world_id,
- .u.fmem.internal_offs = shm->offset,
};
+ optee_ffa_set_internal_offs(&arg->params[0].u.fmem, shm);
arg->ret = TEEC_SUCCESS;
}
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index 7d9b12e71c03..6c3043f8da33 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -136,8 +136,8 @@ struct optee_msg_param_rmem {
* struct optee_msg_param_fmem - FF-A memory reference parameter
* @offs_low: lower bits of offset into shared memory reference
* @offs_high: higher bits of offset into shared memory reference
- * @internal_offs: internal offset into the first page of shared memory
- * reference
+ * @internal_offs: offset into the first 4 KiB page of the FF-A shared
+ * memory region
* @size: size of the buffer
* @global_id: global identifier of the shared memory
*/
--
2.43.0
tee_dyn_shm_alloc_helper() derives nr_pages from a caller-supplied size
and passes it to alloc_pages_exact() without checking it. For size == 0
nr_pages is 0, and alloc_pages_exact(0) calls get_order(0), which is
documented as undefined and returns BITS_PER_LONG - PAGE_SHIFT. The page
allocator then trips its order > MAX_PAGE_ORDER warning and fails the
allocation; on a panic_on_warn kernel that ends the boot.
This can be triggered by TEE_IOC_SHM_ALLOC with struct
tee_ioctl_shm_alloc_data where size is 0.
Reject a zero page count, as register_shm_helper() already does for the
register path.
Fixes: cf4441503e20 ("tee: optee: Move pool_op helper functions")
Cc: stable(a)vger.kernel.org
Cc: lvc-project(a)linuxtesting.org
Signed-off-by: Georgiy Osokin <g.osokin(a)auroraos.dev>
---
drivers/tee/tee_shm.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
index 6742b3579..daa4af1e0 100644
--- a/drivers/tee/tee_shm.c
+++ b/drivers/tee/tee_shm.c
@@ -343,6 +343,10 @@ int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align,
unsigned int i;
int rc = 0;
+ /* get_order(0) is undefined and exceeds MAX_PAGE_ORDER. */
+ if (!nr_pages)
+ return -EINVAL;
+
/*
* Ignore alignment since this is already going to be page aligned
* and there's no need for any larger alignment.
base-commit: 72d3fcf802c45d00b300f25b848a93c3a2bd7c7e
--
2.54.0
From: Marouene Boubakri <marouene.boubakri(a)oss.nxp.com>
The OP-TEE driver reaches OP-TEE through the SMC ABI or the FF-A ABI,
both specific to Arm, yet builds both unconditionally together with the
SMC Calling Convention definitions they rely on: ffa_abi.c is always
compiled and only its registration is conditioned on
IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT), and optee_private.h includes
<linux/arm-smccc.h> and defines the SMC and FF-A specific types for
every file of the driver. This is fine as long as the driver depends on
HAVE_ARM_SMCCC, but it keeps the driver from being built for an
architecture without SMCCC, such as RISC-V.
Build smc_abi.c only when HAVE_ARM_SMCCC is set and ffa_abi.c only when
the FF-A transport is enabled, and provide stubs for their registration
otherwise, so that it fails with -EOPNOTSUPP as the FF-A ABI already
does when the FF-A transport is not reachable. Keep the SMCCC header,
the SMC invoke function type, the SMC and FF-A specific structures and
the SMC RPC register parameters in optee_private.h under the same
conditions, and drop the unused <linux/arm-smccc.h> include from
notif.c.
Make OPTEE depend on ARM_FFA_TRANSPORT || !ARM_FFA_TRANSPORT, as it
already does for RPMB, so that the driver is limited to a module when
the FF-A transport is one, rather than built in without FF-A support.
ffa_abi.c is thus built exactly when the FF-A transport is reachable
from the driver, and the IS_REACHABLE() checks in
optee_ffa_abi_register() and optee_ffa_abi_unregister() are always
true, so drop them.
OPTEE still depends on HAVE_ARM_SMCCC, so smc_abi.c is still always
built. The only visible change is that OPTEE=y can no longer be
combined with ARM_FFA_TRANSPORT=m: such a configuration now resolves to
OPTEE=m, with the FF-A ABI available.
Signed-off-by: Marouene Boubakri <marouene.boubakri(a)oss.nxp.com>
---
Changes in v4:
- Make OPTEE depend on ARM_FFA_TRANSPORT || !ARM_FFA_TRANSPORT so that
the driver is limited to =m when the FF-A transport is =m (Jens).
- Update the commit message accordingly.
v3: https://lore.kernel.org/all/20260922131735.524635-1-marouene.boubakri@oss.n…
Changes in v3:
- Dropped the RPMI ABI placeholder and the RISC-V enablement patches,
this is now a single patch (Jens).
- Key the FF-A parts of optee_private.h on IS_REACHABLE() instead of
IS_ENABLED(): with OPTEE=y and ARM_FFA_TRANSPORT=m kbuild drops
ffa_abi.o from the built-in optee.o while optee_ffa_abi_register()
was still declared, which does not link.
- Drop the now always true IS_REACHABLE() checks in
optee_ffa_abi_register() and optee_ffa_abi_unregister().
- Describe the current FF-A conditional compilation accurately in the
commit message.
- Posted as a new thread with a proper subject prefix.
v2: https://lore.kernel.org/op-tee/20260915020235.507302-2-marouene.boubakri@os…
Changes in v2:
- No code change, the testing section of the cover letter was completed.
v1: https://lore.kernel.org/op-tee/20260914175435.118303-2-marouene.boubakri@os…
drivers/tee/optee/Kconfig | 1 +
drivers/tee/optee/Makefile | 4 ++--
drivers/tee/optee/ffa_abi.c | 8 ++-----
drivers/tee/optee/notif.c | 1 -
drivers/tee/optee/optee_private.h | 39 ++++++++++++++++++++++++++++++-
5 files changed, 43 insertions(+), 10 deletions(-)
diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
index 50d2051..891dac6 100644
--- a/drivers/tee/optee/Kconfig
+++ b/drivers/tee/optee/Kconfig
@@ -5,6 +5,7 @@ config OPTEE
depends on HAVE_ARM_SMCCC
depends on MMU
depends on RPMB || !RPMB
+ depends on ARM_FFA_TRANSPORT || !ARM_FFA_TRANSPORT
help
This implements the OP-TEE Trusted Execution Environment (TEE)
driver.
diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index ad7049c..183cdde 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -7,8 +7,8 @@ optee-objs += rpc.o
optee-objs += protmem.o
optee-objs += supp.o
optee-objs += device.o
-optee-objs += smc_abi.o
-optee-objs += ffa_abi.o
+optee-$(CONFIG_HAVE_ARM_SMCCC) += smc_abi.o
+optee-$(CONFIG_ARM_FFA_TRANSPORT) += ffa_abi.o
# for tracing framework to find optee_trace.h
CFLAGS_smc_abi.o := -I$(src)
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index 633715b..08236d8 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -1212,14 +1212,10 @@ static struct ffa_driver optee_ffa_driver = {
int optee_ffa_abi_register(void)
{
- if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT))
- return ffa_register(&optee_ffa_driver);
- else
- return -EOPNOTSUPP;
+ return ffa_register(&optee_ffa_driver);
}
void optee_ffa_abi_unregister(void)
{
- if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT))
- ffa_unregister(&optee_ffa_driver);
+ ffa_unregister(&optee_ffa_driver);
}
diff --git a/drivers/tee/optee/notif.c b/drivers/tee/optee/notif.c
index 6e85f2f..6801422 100644
--- a/drivers/tee/optee/notif.c
+++ b/drivers/tee/optee/notif.c
@@ -5,7 +5,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/arm-smccc.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index aefe1e6..02d6f79 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -6,7 +6,6 @@
#ifndef OPTEE_PRIVATE_H
#define OPTEE_PRIVATE_H
-#include <linux/arm-smccc.h>
#include <linux/notifier.h>
#include <linux/rhashtable.h>
#include <linux/rpmb.h>
@@ -15,6 +14,10 @@
#include <linux/types.h>
#include "optee_msg.h"
+#ifdef CONFIG_HAVE_ARM_SMCCC
+#include <linux/arm-smccc.h>
+#endif
+
#define DRIVER_NAME "optee"
#define OPTEE_MAX_ARG_SIZE 1024
@@ -42,10 +45,12 @@
*/
#define OPTEE_DEFAULT_MAX_NOTIF_VALUE 255
+#ifdef CONFIG_HAVE_ARM_SMCCC
typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long,
struct arm_smccc_res *);
+#endif
/**
* struct optee_call_waiter - TEE entry may need to wait for a free TEE thread
@@ -119,6 +124,7 @@ struct optee_supp {
struct completion reqs_c;
};
+#ifdef CONFIG_HAVE_ARM_SMCCC
/**
* struct optee_pcpu - per cpu notif private struct passed to work functions
* @optee: optee device reference
@@ -149,7 +155,9 @@ struct optee_smc {
struct work_struct notif_pcpu_work;
unsigned int notif_cpuhp_state;
};
+#endif
+#if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)
/**
* struct optee_ffa - FFA communication struct
* @ffa_dev: FFA device, contains the destination id, the id of
@@ -170,6 +178,7 @@ struct optee_ffa {
struct workqueue_struct *notif_wq;
struct work_struct notif_work;
};
+#endif
struct optee;
@@ -257,8 +266,12 @@ struct optee {
const struct optee_ops *ops;
struct tee_context *ctx;
union {
+#ifdef CONFIG_HAVE_ARM_SMCCC
struct optee_smc smc;
+#endif
+#if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)
struct optee_ffa ffa;
+#endif
};
struct optee_shm_arg_cache shm_arg_cache;
struct optee_call_queue call_queue;
@@ -290,6 +303,7 @@ struct optee_context_data {
struct list_head sess_list;
};
+#ifdef CONFIG_HAVE_ARM_SMCCC
struct optee_rpc_param {
u32 a0;
u32 a1;
@@ -300,6 +314,7 @@ struct optee_rpc_param {
u32 a6;
u32 a7;
};
+#endif
/* Holds context that is preserved during one STD call */
struct optee_call_ctx {
@@ -422,9 +437,31 @@ static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
}
/* Registration of the ABIs */
+#ifdef CONFIG_HAVE_ARM_SMCCC
int optee_smc_abi_register(void);
void optee_smc_abi_unregister(void);
+#else
+static inline int optee_smc_abi_register(void)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void optee_smc_abi_unregister(void)
+{
+}
+#endif
+#if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)
int optee_ffa_abi_register(void);
void optee_ffa_abi_unregister(void);
+#else
+static inline int optee_ffa_abi_register(void)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void optee_ffa_abi_unregister(void)
+{
+}
+#endif
#endif /*OPTEE_PRIVATE_H*/
base-commit: 827751b699b79a6e569983359c02dce67f81b94c
--
2.43.0
This RFC series adds the RISC-V RPMI TEE service group transport [1],
which provides RISC-V systems a mechanism for Linux to communicate
with TEE endpoints. Linux and a TEE act as endpoints of the RPMI TEE
service group, while the RPMI framework in machine-mode firmware
mediates communication between them over an SBI MPXY [2] mailbox
channel.
The series is layered as follows:
- Two mailbox patches add a direct synchronous send mode
(mbox_send_message_sync()) and its implementation for RPMI MPXY
channels, needed because RPMI TEE requests must complete
synchronously in the calling context.
- The RPMI TEE bus registers one device per discovered TEE endpoint
and service UUID pair, following the device-per-service model,
so individual service drivers can bind independently.
- The RPMI TEE transport core binds to the mailbox channel and
validates the RPMI and TEE service-group versions before any
discovery or service traffic is attempted.
- System-information parsing and discovery walk the firmware-provided
descriptor tables to find physical TEE endpoints and the services
they expose, registering a bus device for each.
- Memory parcel operations (lend, share, reclaim) let a consumer
driver share memory with a TEE endpoint. Linux creates a parcel and
the parcel identifier is then used by the consumer's own protocol to
refer to that memory.
- Signal buses let a consumer driver exchange asynchronous
notifications with its TEE endpoint in both directions.
This series only establishes the transport, bus, and discovery layer.
A consumer driver - an OP-TEE backend mapped onto these services,
analogous to drivers/tee/optee/ffa_abi.c — is intended to follow in a
later series once this transport is reviewed.
Feedback on the overall architecture, the bus/device model, and the
memory-parcel and signal-bus abstractions is especially welcome at
this stage in this RFC series.
[1] https://github.com/riscv-non-isa/riscv-rpmi/commits/main/src/srvgrp-tee.adoc
[2] https://github.com/riscv-non-isa/riscv-sbi-doc/releases
Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi(a)oss.qualcomm.com>
---
Amirreza Zarrabi (10):
mailbox: add direct synchronous send support
mailbox: mpxy: add direct synchronous send
firmware: add RPMI TEE bus support
dt-bindings: firmware: add RISC-V RPMI TEE transport
firmware: add RPMI TEE transport core
firmware: riscv: rpmi-tee: parse system information tables
firmware: riscv: rpmi-tee: discover TEE services
firmware: riscv: rpmi-tee: cache TEE capabilities
firmware: riscv: rpmi-tee: add memory parcel operations
firmware: riscv: rpmi-tee: add signal bus support
.../bindings/firmware/riscv,rpmi-tee.yaml | 35 +
drivers/firmware/Kconfig | 2 +
drivers/firmware/Makefile | 1 +
drivers/firmware/riscv_rpmi_tee/Kconfig | 8 +
drivers/firmware/riscv_rpmi_tee/Makefile | 8 +
drivers/firmware/riscv_rpmi_tee/bus.c | 202 +++
drivers/firmware/riscv_rpmi_tee/driver.c | 1816 ++++++++++++++++++++
drivers/firmware/riscv_rpmi_tee/sysinfo.c | 385 +++++
drivers/firmware/riscv_rpmi_tee/sysinfo.h | 244 +++
drivers/mailbox/mailbox.c | 72 +-
drivers/mailbox/riscv-sbi-mpxy-mbox.c | 196 ++-
include/linux/mailbox/riscv-rpmi-message.h | 13 +
include/linux/mailbox_client.h | 3 +
include/linux/mailbox_controller.h | 10 +
include/linux/rpmi_tee.h | 175 ++
15 files changed, 3098 insertions(+), 72 deletions(-)
---
base-commit: 6375e61c01e93e35ee7acd336a689ac1fae4b509
change-id: 20260928-riscv-rpmi-tee-abi-603e9a3b4399
Best regards,
--
Amirreza Zarrabi <amirreza.zarrabi(a)oss.qualcomm.com>