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>
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>
optee_probe() called tee_device_register() on both the client and the
supplicant device before the rest of struct optee had been initialized.
tee_device_register() calls cdev_device_add(), which does two things at
once: it creates /dev/tee0 and /dev/teepriv0, and it links the device
into the tee class so that class_find_device() can find it. From that
moment on the device is reachable both from user space via tee_open()
and from kernel space via tee_client_open_context(). The only gate in
teedev_open() is tee_device_get(), which merely checks that
teedev->desc is non-NULL, which was already set by tee_device_alloc().
Therefore, there is effectively no gate at all.
A context opened in that window can run against a struct optee where
- optee->call_queue.mutex is not initialized by optee_cq_init()
- optee->supp mutex and completions is not initialized by
optee_supp_init()
- optee->rpmb_dev_mutex is not initialized yet,
- the message argument cache is not initialized by
optee_shm_arg_cache_init()
- optee->ctx is still NULL
Any open session or invoke during this window takes uninitialized
mutexes and dereferences a NULL pointer.
Fix it by moving both tee_device_register() calls down to the point
where all of struct optee is set up.
Signed-off-by: Shao-Fu Chen <shf.chen(a)mediatek.com>
---
drivers/tee/optee/ffa_abi.c | 16 ++++++++--------
drivers/tee/optee/smc_abi.c | 17 ++++++++---------
2 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index 633715b98625..d3cc7c5fc1e9 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -1123,14 +1123,6 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
optee_set_dev_group(optee);
- rc = tee_device_register(optee->teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
- rc = tee_device_register(optee->supp_teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
rc = rhashtable_init(&optee->ffa.global_ids, &shm_rhash_params);
if (rc)
goto err_unreg_supp_teedev;
@@ -1159,6 +1151,14 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
if (optee_ffa_protmem_pool_init(optee, sec_caps))
pr_info("Protected memory service not available\n");
+ rc = tee_device_register(optee->teedev);
+ if (rc)
+ goto err_unregister_devices;
+
+ rc = tee_device_register(optee->supp_teedev);
+ if (rc)
+ goto err_unregister_devices;
+
rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
if (rc)
goto err_unregister_devices;
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index b8a2bdac3208..51624443359b 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -1849,14 +1849,6 @@ static int optee_probe(struct platform_device *pdev)
optee_set_dev_group(optee);
- rc = tee_device_register(optee->teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
- rc = tee_device_register(optee->supp_teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
optee_cq_init(&optee->call_queue, thread_count);
optee_supp_init(&optee->supp);
optee->smc.memremaped_shm = memremaped_shm;
@@ -1916,6 +1908,14 @@ static int optee_probe(struct platform_device *pdev)
if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
pr_info("dynamic shared memory is enabled\n");
+ rc = tee_device_register(optee->teedev);
+ if (rc)
+ goto err_disable_shm_cache;
+
+ rc = tee_device_register(optee->supp_teedev);
+ if (rc)
+ goto err_disable_shm_cache;
+
rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
if (rc)
goto err_disable_shm_cache;
@@ -1942,7 +1942,6 @@ static int optee_probe(struct platform_device *pdev)
optee_shm_arg_cache_uninit(optee);
optee_supp_uninit(&optee->supp);
mutex_destroy(&optee->call_queue.mutex);
-err_unreg_supp_teedev:
tee_device_unregister(optee->supp_teedev);
err_unreg_teedev:
tee_device_unregister(optee->teedev);
--
2.45.2
The SCM driver still funnels every call through a process-wide
__scm singleton.
This series threads struct qcom_scm through the driver and the
exported API, then drops the global.
Series summary
--------------
Patch 1: Internal helpers take the instance. Callbacks that only
have a struct device or reset_controller_dev recover it
with drvdata / container_of. Exported signatures stay
unchanged so this patch is bisectable on its own.
Patch 2: Exported calls take struct qcom_scm * as the first
argument. The type stays opaque in qcom_scm.h.
Children of the SCM device (qseecom, tzmem, qcomtee)
use dev_get_drvdata() on the parent. Other consumers
call qcom_scm_get(), which finds the bound platform
device and returns NULL until probe has marked the
instance ready. Callers that need SCM return
-EPROBE_DEFER; callers that only use it for an optional
path (rmtfs VMIDs, fastrpc vmids, PAS region assign,
Venus CP, HDMI HDCP, Adreno fuse poke) skip the lookup
or tolerate NULL. qcom_pas_* is unchanged: PAS has a
TEE backend, so those ops keep struct device * and the
SCM backend uses drvdata.
Patch 3: Drop __scm. Readiness is scm->available with the same
release/acquire pairing as today. Module-parameter
stores reuse qcom_scm_get(); shutdown uses
platform_get_drvdata().
No intended change in SCM calling convention or wait-queue
behaviour.
Testing
-------
Booted to a shell on Qualcomm SA8775P Ride4 with current series.
qcom_scm bound as firmware:qcom_scm; probe logged SMC ARM 64 and
the tz-ffi reserved-memory assignment. Consumers were not exercised.
Suggested-by: Maxime Ripard <mripard(a)kernel.org>
Signed-off-by: Albert Esteve <aesteve(a)redhat.com>
---
Albert Esteve (3):
firmware: qcom: scm: pass qcom_scm to internal helpers
firmware: qcom: scm: pass qcom_scm through the exported API
firmware: qcom: scm: drop the __scm global
arch/arm/mach-qcom/platsmp.c | 3 +-
drivers/cpuidle/cpuidle-qcom-spm.c | 28 +-
drivers/firmware/qcom/qcom_qseecom.c | 3 +-
drivers/firmware/qcom/qcom_scm-smc.c | 2 +-
drivers/firmware/qcom/qcom_scm.c | 518 +++++++++++++----------
drivers/firmware/qcom/qcom_scm.h | 2 +-
drivers/firmware/qcom/qcom_tzmem.c | 6 +-
drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 +-
drivers/gpu/drm/msm/adreno/adreno_gpu.c | 8 +-
drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c | 6 +-
drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c | 9 +-
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 8 +-
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 3 +
drivers/iommu/arm/arm-smmu/qcom_iommu.c | 18 +-
drivers/irqchip/qcom-pdc.c | 6 +-
drivers/media/platform/qcom/venus/firmware.c | 10 +-
drivers/misc/fastrpc.c | 31 +-
drivers/net/wireless/ath/ath10k/qmi.c | 12 +-
drivers/net/wireless/ath/ath10k/qmi.h | 3 +
drivers/nvmem/sec-qfprom.c | 6 +-
drivers/pinctrl/qcom/pinctrl-msm.c | 11 +-
drivers/remoteproc/qcom_q6v5_mss.c | 6 +-
drivers/remoteproc/qcom_q6v5_pas.c | 12 +-
drivers/soc/qcom/ice.c | 23 +-
drivers/soc/qcom/ocmem.c | 22 +-
drivers/soc/qcom/rmtfs_mem.c | 8 +-
drivers/tee/qcomtee/call.c | 7 +
drivers/tee/qcomtee/core.c | 6 +-
drivers/tee/qcomtee/qcomtee.h | 2 +
drivers/thermal/qcom/lmh.c | 22 +-
include/linux/firmware/qcom/qcom_qseecom.h | 5 +-
include/linux/firmware/qcom/qcom_scm.h | 117 ++---
32 files changed, 566 insertions(+), 363 deletions(-)
---
base-commit: bc35965f6940a9bf834d54187b6088b8eb09206d
change-id: 20260908-scm-device-api-634ac7a7f377
Best regards,
--
Albert Esteve <aesteve(a)redhat.com>
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 reachable, 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.
The FF-A parts are keyed on IS_REACHABLE() rather than IS_ENABLED() to
preserve the behaviour of a built-in driver with a modular FF-A
transport: kbuild does not link the optee-m objects into a built-in
optee.o, so ffa_abi.c is left out exactly when the transport is not
reachable and the stubs are used instead. The IS_REACHABLE() checks in
optee_ffa_abi_register() and optee_ffa_abi_unregister() are always true
once ffa_abi.c is only compiled in that case, so drop them.
No functional change: OPTEE still depends on HAVE_ARM_SMCCC, and
ffa_abi.c is still built whenever the FF-A ABI can be registered.
Signed-off-by: Marouene Boubakri <marouene.boubakri(a)oss.nxp.com>
---
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/Makefile | 4 ++--
drivers/tee/optee/ffa_abi.c | 8 ++-----
drivers/tee/optee/notif.c | 1 -
drivers/tee/optee/optee_private.h | 39 ++++++++++++++++++++++++++++++-
4 files changed, 42 insertions(+), 10 deletions(-)
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
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, and the TEE subsystem and the OP-TEE driver
depend on HAVE_ARM_SMCCC. On RISC-V there is no SMC instruction: OP-TEE
runs in a domain isolated by the M-mode firmware and is reached through
the RISC-V Platform Management Interface (RPMI), carried on an SBI
Message Proxy (MPXY) channel, for which Linux already has a mailbox
driver.
This series only puts the build plumbing in place for a third ABI next
to the SMC and FF-A ones:
- patch 1 builds the Arm-specific code of the driver only on Arm:
smc_abi.c when HAVE_ARM_SMCCC is set and ffa_abi.c when
ARM_FFA_TRANSPORT is enabled, with stubs for their registration
otherwise. The SMCCC header, the SMC and FF-A specific types and the
SMC RPC register parameters in optee_private.h are kept under the
same conditions, so that nothing Arm-specific is left in the common
part of the driver;
- patch 2 adds an RPMI ABI placeholder: an OPTEE_RPMI_ABI option built
when the MPXY mailbox driver is enabled, rpmi_abi.c and its
registration from the driver core. The transport is not implemented,
so the registration fails with -EOPNOTSUPP;
- patch 3 lets the TEE subsystem and the OP-TEE driver be enabled on
RISC-V, and teaches the memory type check of the driver about the
RISC-V page attributes, without which the driver does not build
there. It is kept separate as it changes the dependencies of the
subsystem-wide TEE menu.
There is no functional change. On Arm, OPTEE still depends on
HAVE_ARM_SMCCC and the SMC and FF-A ABIs are built whenever they can be
registered. On RISC-V the driver builds without any Arm-specific code
but no ABI registers, so it does not load. The RPMI transport will be
implemented on top of this in a separate series.
Testing: [TODO before posting: riscv64 defconfig plus TEE/OP-TEE,
built-in and as modules, and arm64 defconfig plus OP-TEE with FF-A
built-in, modular and disabled, with W=1 at every step of the series.]
Marouene Boubakri (3):
tee: optee: build the Arm-specific code only on Arm
tee: optee: add an RPMI ABI placeholder
tee: optee: allow enabling the driver on RISC-V
drivers/tee/Kconfig | 2 +-
drivers/tee/optee/Kconfig | 10 +++++-
drivers/tee/optee/Makefile | 5 +--
drivers/tee/optee/call.c | 8 +++++
drivers/tee/optee/core.c | 8 +++--
drivers/tee/optee/notif.c | 1 -
drivers/tee/optee/optee_private.h | 52 ++++++++++++++++++++++++++++++-
drivers/tee/optee/rpmi_abi.c | 23 ++++++++++++++
8 files changed, 101 insertions(+), 8 deletions(-)
create mode 100644 drivers/tee/optee/rpmi_abi.c
base-commit: 827751b699b79a6e569983359c02dce67f81b94c
--
2.43.0
'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