OP-TEE supplicant is a user-space daemon and it's possible for it
be hung or crashed or killed in the middle of processing an OP-TEE
RPC call. It becomes more complicated when there is incorrect shutdown
ordering of the supplicant process vs the OP-TEE client application which
can eventually lead to system hang-up waiting for the closure of the
client application.
Allow the client process waiting in kernel for supplicant response to
be killed rather than indefinitely waiting in an unkillable state. Also,
a normal uninterruptible wait should not have resulted in the hung-task
watchdog getting triggered, but the endless loop would.
This fixes issues observed during system reboot/shutdown when supplicant
got hung for some reason or gets crashed/killed which lead to client
getting hung in an unkillable state. It in turn lead to system being in
hung up state requiring hard power off/on to recover.
Fixes: 4fb0a5eb364d ("tee: add OP-TEE driver")
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Sumit Garg <sumit.garg(a)linaro.org>
---
Changes in v3:
- Use mutex_lock() instead of mutex_lock_killable().
- Update commit message to incorporate Arnd's feedback.
Changes in v2:
- Switch to killable wait instead as suggested by Arnd instead
of supplicant timeout. It atleast allow the client to wait for
supplicant in killable state which in turn allows system to reboot
or shutdown gracefully.
drivers/tee/optee/supp.c | 35 ++++++++---------------------------
1 file changed, 8 insertions(+), 27 deletions(-)
diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c
index 322a543b8c27..d0f397c90242 100644
--- a/drivers/tee/optee/supp.c
+++ b/drivers/tee/optee/supp.c
@@ -80,7 +80,6 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
struct optee *optee = tee_get_drvdata(ctx->teedev);
struct optee_supp *supp = &optee->supp;
struct optee_supp_req *req;
- bool interruptable;
u32 ret;
/*
@@ -111,36 +110,18 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
/*
* Wait for supplicant to process and return result, once we've
* returned from wait_for_completion(&req->c) successfully we have
- * exclusive access again.
+ * exclusive access again. Allow the wait to be killable such that
+ * the wait doesn't turn into an indefinite state if the supplicant
+ * gets hung for some reason.
*/
- while (wait_for_completion_interruptible(&req->c)) {
+ if (wait_for_completion_killable(&req->c)) {
mutex_lock(&supp->mutex);
- interruptable = !supp->ctx;
- if (interruptable) {
- /*
- * There's no supplicant available and since the
- * supp->mutex currently is held none can
- * become available until the mutex released
- * again.
- *
- * Interrupting an RPC to supplicant is only
- * allowed as a way of slightly improving the user
- * experience in case the supplicant hasn't been
- * started yet. During normal operation the supplicant
- * will serve all requests in a timely manner and
- * interrupting then wouldn't make sense.
- */
- if (req->in_queue) {
- list_del(&req->link);
- req->in_queue = false;
- }
+ if (req->in_queue) {
+ list_del(&req->link);
+ req->in_queue = false;
}
mutex_unlock(&supp->mutex);
-
- if (interruptable) {
- req->ret = TEEC_ERROR_COMMUNICATION;
- break;
- }
+ req->ret = TEEC_ERROR_COMMUNICATION;
}
ret = req->ret;
--
2.43.0
OP-TEE supplicant is a user-space daemon and it's possible for it
being hung or crashed or killed in the middle of processing an OP-TEE
RPC call. It becomes more complicated when there is incorrect shutdown
ordering of the supplicant process vs the OP-TEE client application which
can eventually lead to system hang-up waiting for the closure of the
client application.
Allow the client process waiting in kernel for supplicant response to
be killed rather than indefinitetly waiting in an unkillable state. This
fixes issues observed during system reboot/shutdown when supplicant got
hung for some reason or gets crashed/killed which lead to client getting
hung in an unkillable state. It in turn lead to system being in hung up
state requiring hard power off/on to recover.
Fixes: 4fb0a5eb364d ("tee: add OP-TEE driver")
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Sumit Garg <sumit.garg(a)linaro.org>
---
Changes in v2:
- Switch to killable wait instead as suggested by Arnd instead
of supplicant timeout. It atleast allow the client to wait for
supplicant in killable state which in turn allows system to reboot
or shutdown gracefully.
drivers/tee/optee/supp.c | 32 +++++++-------------------------
1 file changed, 7 insertions(+), 25 deletions(-)
diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c
index 322a543b8c27..3fbfa9751931 100644
--- a/drivers/tee/optee/supp.c
+++ b/drivers/tee/optee/supp.c
@@ -80,7 +80,6 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
struct optee *optee = tee_get_drvdata(ctx->teedev);
struct optee_supp *supp = &optee->supp;
struct optee_supp_req *req;
- bool interruptable;
u32 ret;
/*
@@ -111,36 +110,19 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
/*
* Wait for supplicant to process and return result, once we've
* returned from wait_for_completion(&req->c) successfully we have
- * exclusive access again.
+ * exclusive access again. Allow the wait to be killable such that
+ * the wait doesn't turn into an indefinite state if the supplicant
+ * gets hung for some reason.
*/
- while (wait_for_completion_interruptible(&req->c)) {
- mutex_lock(&supp->mutex);
- interruptable = !supp->ctx;
- if (interruptable) {
- /*
- * There's no supplicant available and since the
- * supp->mutex currently is held none can
- * become available until the mutex released
- * again.
- *
- * Interrupting an RPC to supplicant is only
- * allowed as a way of slightly improving the user
- * experience in case the supplicant hasn't been
- * started yet. During normal operation the supplicant
- * will serve all requests in a timely manner and
- * interrupting then wouldn't make sense.
- */
+ if (wait_for_completion_killable(&req->c)) {
+ if (!mutex_lock_killable(&supp->mutex)) {
if (req->in_queue) {
list_del(&req->link);
req->in_queue = false;
}
+ mutex_unlock(&supp->mutex);
}
- mutex_unlock(&supp->mutex);
-
- if (interruptable) {
- req->ret = TEEC_ERROR_COMMUNICATION;
- break;
- }
+ req->ret = TEEC_ERROR_COMMUNICATION;
}
ret = req->ret;
--
2.43.0
OP-TEE supplicant is a user-space daemon and it's possible for it
being crashed or killed in the middle of processing an OP-TEE RPC call.
It becomes more complicated when there is incorrect shutdown ordering
of the supplicant process vs the OP-TEE client application which can
eventually lead to system hang-up waiting for the closure of the client
application.
In order to gracefully handle this scenario, let's add a long enough
timeout to wait for supplicant to process requests. In case there is a
timeout then we return a proper error code for the RPC request.
Signed-off-by: Sumit Garg <sumit.garg(a)linaro.org>
---
drivers/tee/optee/supp.c | 58 +++++++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 22 deletions(-)
diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c
index 322a543b8c27..92e86ac4cdd4 100644
--- a/drivers/tee/optee/supp.c
+++ b/drivers/tee/optee/supp.c
@@ -7,6 +7,15 @@
#include <linux/uaccess.h>
#include "optee_private.h"
+/*
+ * OP-TEE supplicant timeout, the user-space supplicant may get
+ * crashed or killed while servicing an RPC call. This will just lead
+ * to OP-TEE client hung indefinitely just waiting for supplicant to
+ * serve requests which isn't expected. It is rather expected to fail
+ * gracefully with a timeout which is long enough.
+ */
+#define SUPP_TIMEOUT (msecs_to_jiffies(10000))
+
struct optee_supp_req {
struct list_head link;
@@ -52,8 +61,10 @@ void optee_supp_release(struct optee_supp *supp)
/* Abort all queued requests */
list_for_each_entry_safe(req, req_tmp, &supp->reqs, link) {
- list_del(&req->link);
- req->in_queue = false;
+ if (req->in_queue) {
+ list_del(&req->link);
+ req->in_queue = false;
+ }
req->ret = TEEC_ERROR_COMMUNICATION;
complete(&req->c);
}
@@ -82,6 +93,7 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
struct optee_supp_req *req;
bool interruptable;
u32 ret;
+ int res = 1;
/*
* Return in case there is no supplicant available and
@@ -108,28 +120,28 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
/* Tell an eventual waiter there's a new request */
complete(&supp->reqs_c);
- /*
- * Wait for supplicant to process and return result, once we've
- * returned from wait_for_completion(&req->c) successfully we have
- * exclusive access again.
- */
- while (wait_for_completion_interruptible(&req->c)) {
+ /* Wait for supplicant to process and return result */
+ while (res) {
+ res = wait_for_completion_interruptible_timeout(&req->c,
+ SUPP_TIMEOUT);
+ /* Check if supplicant served the request */
+ if (res > 0)
+ break;
+
mutex_lock(&supp->mutex);
+ /*
+ * There's no supplicant available and since the supp->mutex
+ * currently is held none can become available until the mutex
+ * released again.
+ *
+ * Interrupting an RPC to supplicant is only allowed as a way
+ * of slightly improving the user experience in case the
+ * supplicant hasn't been started yet. During normal operation
+ * the supplicant will serve all requests in a timely manner and
+ * interrupting then wouldn't make sense.
+ */
interruptable = !supp->ctx;
- if (interruptable) {
- /*
- * There's no supplicant available and since the
- * supp->mutex currently is held none can
- * become available until the mutex released
- * again.
- *
- * Interrupting an RPC to supplicant is only
- * allowed as a way of slightly improving the user
- * experience in case the supplicant hasn't been
- * started yet. During normal operation the supplicant
- * will serve all requests in a timely manner and
- * interrupting then wouldn't make sense.
- */
+ if (interruptable || (res == 0)) {
if (req->in_queue) {
list_del(&req->link);
req->in_queue = false;
@@ -141,6 +153,8 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
req->ret = TEEC_ERROR_COMMUNICATION;
break;
}
+ if (res == 0)
+ req->ret = TEE_ERROR_TIMEOUT;
}
ret = req->ret;
--
2.43.0
Hi,
I have some problems configuring dynamic shared memory on my platform,
and thought that perhaps somebody could give me a hint.
My SoC (LS1028A, board: LS1028A-RDB), according to reference manual
has two DRAM regions:
- DRAM region 0 : start address: 0x80000000, size: 0x80000000
- DRAM region 2: start address: 0x2080000000, size: 0x1F80000000
I tried two approaches:
1) In optee-os, in a part of code that handles my SoC I added a call
to register DDR only for the first region:
register_addr(0x80000000, 2G - some size for TZ DRAM) (similarly like
in case of other SoCs)
However when the system boots up, the optee driver logs the following
information:
[ 5.703831] optee: dynamic shared memory is enabled
E/TC:0 0 std_entry_with_parg:234 Bad arg address 0x208100e000
It seems that there is some problem with an address that the driver wants to use
2) Apart from registering first region I also added a call that
registers the second region so I ended up with two calls:
register_addr(0x80000000, 2G - some size for TZ DRAM)
register_ddr(0x2080000000, 0x1F80000000);
Now the problem is different since the platform no longer boots, due
to the panic with the following output:
D/TC:0 0 discover_nsec_memory:1117 No non-secure memory found in external DT
D/TC:0 0 carve_out_phys_mem:362 No need to carve out 0xfc000000 size 0x3e00000
D/TC:0 0 carve_out_phys_mem:362 No need to carve out 0xffe00000 size 0x200000
E/TC:0 0 Panic at
/usr/src/debug/optee-os-qoriq/4.2.0+git/core/mm/core_mmu.c:490
<core_mmu_set_discovered_nsec_ddr>
I'm wondering, what am I missing?
Do I need to register both regions? If so, why does the optee panic
when the second region gets registered?
I would be grateful for some ideas.
Best regards
Patryk
Hi,
Tomorrow, Tuesday, it's time for another LOC monthly meeting. For time
and connection details see the calendar at
https://www.trustedfirmware.org/meetings/
The TA-specific parts of fTPM have now been included in the first
OP-TEE release in the optee_ftpm and we run fTPM in the OP-TEE OS CI
loop at Github. Much of what we set out to do over half a year ago has
been done, but there are some issues with the quality of the code. It
doesn't compile without warnings and the coding style is inconsistent
with the normal OP-TEE coding style (or anything else). Let's discuss
how we can improve the status.
Are there any other topics?
Thanks,
Jens
(Please provide a better way of reporting should this ML not be a good forum for bug-reports/fixes)
Hello all,
While experimenting with OP-TEE OS on a non-ARM platform (x86, to be precise), I noticed xtest regression_4003 and regression_4017 to be failing. It appears that for AES-CTR encrypt/decrypt, optee_os/core/lib/libtomcrypt/src/modes/ctr/ctr_encrypt.c:s_ctr_encrypt()<https://github.com/OP-TEE/optee_os/blob/37de1791d97d0df56db0709b5d001f82159…> fails to increment the counter on block boundaries when passed data covers a whole block. I suppose that it is a non-problem for architectures having crypto acceleration hooked up, since ctr_encrypt() bypasses s_ctr_encrypt() in that case.
The below fixes the behavior for my setup - xtest regression_4003 and regression_4017 pass as a result:
diff --git a/core/lib/libtomcrypt/src/modes/ctr/ctr_encrypt.c b/core/lib/libtomcrypt/src/modes/ctr/ctr_encrypt.c
index a23e33c05..2019de2b6 100644
--- a/core/lib/libtomcrypt/src/modes/ctr/ctr_encrypt.c
+++ b/core/lib/libtomcrypt/src/modes/ctr/ctr_encrypt.c
@@ -61,6 +61,7 @@ static int s_ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned lo
ct += ctr->blocklen;
len -= ctr->blocklen;
ctr->padlen = ctr->blocklen;
+ s_ctr_increment_counter(ctr);
continue;
}
#endif
I understand that you might prefer a full PR instead. Please accept my apologies for not providing such at this time; perhaps one of the maintainers (Jerome Forissier?) can take the above into consideration instead. If in doubt, consider above change as BSD-2-Clause'd.
Best,
Jork Loeser,
Microsoft
Hi,
I'm pleased to announce that I've just completed the release work and made
OP-TEE version 4.5.0 available. The list of changes can be found in the
changelog [1]. A summary of this release will be published shortly. The
stable branch is available here [2] and the tested platforms for this
release are listed here [3].
Many thanks to everyone who has contributed in any form to this release.
[1] https://github.com/OP-TEE/optee_os/blob/master/CHANGELOG.md
[2] https://github.com/OP-TEE/manifest/tree/4.5.0
[3]
https://github.com/OP-TEE/optee_os/commit/0919de0f7c79ad35ad3c8ace5f823ad13…
--
Regards,
Joakim Bech
| Distinguished Engineer | Linaro |
| Mobile: +46 73 697 37 14 | Address: Scheelevägen 17, 223 63 Lund, Sweden |
[BCC all OP-TEE maintainers]
Hi OP-TEE maintainers & contributors,
OP-TEE v4.5.0 is scheduled to be released on 2025-01-17. So, now is
a good time to start testing the master branch on the various platforms
and report/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/7211.
As usual, we will create a release candidate tag one week before the
release date for final testing (Friday this week, i.e., tomorrow).
In addition to that you can find some additional information related to
releases here: https://optee.readthedocs.io/en/latest/general/releases.html
--
Regards,
Joakim Bech
| Distinguished Engineer | Linaro |
| Mobile: +46 73 697 37 14 | Address: Scheelevägen 17, 223 63 Lund, Sweden |
Hello arm-soc maintainers,
Please pull this small patch fixing a version print in the optee driver.
Thanks,
Jens
The following changes since commit fac04efc5c793dccbd07e2d59af9f90b7fc0dca4:
Linux 6.13-rc2 (2024-12-08 14:03:39 -0800)
are available in the Git repository at:
https://git.linaro.org/people/jens.wiklander/linux-tee.git/ tags/optee-for-v6.14
for you to fetch changes up to 1ff7d092dce0b2273dce4b8d33fa5856679dd25b:
optee: fix format string for printing optee build_id (2024-12-17 11:22:46 +0100)
----------------------------------------------------------------
Fix format string for printing optee build_id
----------------------------------------------------------------
Sahil Malhotra (1):
optee: fix format string for printing optee build_id
drivers/tee/optee/smc_abi.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
This patch series introduces a Trusted Execution Environment (TEE)
driver for Qualcomm TEE (QTEE). QTEE enables Trusted Applications (TAs)
and services to run securely. It uses an object-based interface, where
each service is an object with sets of operations. Clients can invoke
these operations on objects, which can generate results, including other
objects. For example, an object can load a TA and return another object
that represents the loaded TA, allowing access to its services.
Kernel and userspace services are also available to QTEE through a
similar approach. QTEE makes callback requests that are converted into
object invocations. These objects can represent services within the
kernel or userspace process.
Note: This patch series focuses on QTEE objects and userspace services.
Linux already provides a TEE subsystem, which is described in [1]. The
tee subsystem provides a generic ioctl interface, TEE_IOC_INVOKE, which
can be used by userspace to talk to a TEE backend driver. We extend the
Linux TEE subsystem to understand object parameters and an ioctl call so
client can invoke objects in QTEE:
- TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_*
- TEE_IOC_OBJECT_INVOKE
The existing ioctl calls TEE_IOC_SUPPL_RECV and TEE_IOC_SUPPL_SEND are
used for invoking services in the userspace process by QTEE.
The TEE backend driver uses the QTEE Transport Message to communicate
with QTEE. Interactions through the object INVOKE interface are
translated into QTEE messages. Likewise, object invocations from QTEE
for userspace objects are converted into SEND/RECV ioctl calls to
supplicants.
The details of QTEE Transport Message to communicate with QTEE is
available in [PATCH 10/10] Documentation: tee: Add Qualcomm TEE driver.
This patch series has been tested for basic QTEE object invocations and
callback requests, including loading a TA and requesting services form
the TA. However, the test platform is currently being prepared for
upstream availability and will soon be accessible to the community for
further validation. I will share updates as the platform become
available.
[1] https://www.kernel.org/doc/Documentation/tee.txt
Signed-off-by: Amirreza Zarrabi <quic_azarrabi(a)quicinc.com>
---
Amirreza Zarrabi (10):
tee: allow a driver to allocate a tee_device without a pool
tee: add TEE_IOCTL_PARAM_ATTR_TYPE_MEMBUF
tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
firmware: qcom: scm: add support for object invocation
qcomtee: implement object invoke support
qcomtee: add primordial object
dt-bindings: arm: qcomtee: add QTEE driver devicetree binding for TEE subsystem
tee: add Qualcomm TEE driver
arm64: dts: qcom: sm8650: add support for QTEE
Documentation: tee: Add Qualcomm TEE driver
.../devicetree/bindings/arm/firmware/qcom,tee.yaml | 34 +
Documentation/tee/index.rst | 1 +
Documentation/tee/qtee.rst | 143 ++++
arch/arm64/boot/dts/qcom/sm8650.dtsi | 4 +
drivers/firmware/qcom/qcom_scm.c | 60 ++
drivers/firmware/qcom/qcom_scm.h | 7 +
drivers/tee/Kconfig | 1 +
drivers/tee/Makefile | 1 +
drivers/tee/qcomtee/Kconfig | 10 +
drivers/tee/qcomtee/Makefile | 9 +
drivers/tee/qcomtee/async.c | 153 ++++
drivers/tee/qcomtee/call.c | 707 ++++++++++++++++
drivers/tee/qcomtee/core.c | 942 +++++++++++++++++++++
drivers/tee/qcomtee/primordial_obj.c | 63 ++
drivers/tee/qcomtee/qcom_scm.c | 36 +
drivers/tee/qcomtee/qcomtee_msg.h | 217 +++++
drivers/tee/qcomtee/qcomtee_private.h | 218 +++++
drivers/tee/qcomtee/release.c | 66 ++
drivers/tee/qcomtee/user_obj.c | 625 ++++++++++++++
drivers/tee/tee_core.c | 113 ++-
include/linux/firmware/qcom/qcom_scm.h | 9 +
include/linux/firmware/qcom/qcom_tee.h | 284 +++++++
include/linux/tee_core.h | 4 +
include/linux/tee_drv.h | 12 +
include/uapi/linux/tee.h | 54 +-
25 files changed, 3765 insertions(+), 8 deletions(-)
---
base-commit: f486c8aa16b8172f63bddc70116a0c897a7f3f02
change-id: 20241202-qcom-tee-using-tee-ss-without-mem-obj-362c66340527
Best regards,
--
Amirreza Zarrabi <quic_azarrabi(a)quicinc.com>