All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Amirreza Zarrabi" <amirreza.zarrabi@oss.qualcomm.com>
Cc: devicetree@vger.kernel.org, conor+dt@kernel.org, robh@kernel.org
Subject: Re: [PATCH RFC v2 6/8] tee: optee: execute yielding RPMI calls
Date: Tue, 06 Oct 2026 00:55:48 +0000	[thread overview]
Message-ID: <20261006005548.EA0BD1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20261005-rpmi-tee-service-grp-dev-v2-6-72f222e23ec1@oss.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] optee: unhandled unknown RPC result causes infinite loop in yielding call
- [High] optee: deadlock on RPMI_ERR_BUSY when no local threads are active
- [High] optee: uninitialized req.flags leaks stack memory to Secure World
- [Medium] optee: zero resume_token from suspended call causes infinite retry loop
--

commit e5243042ee3a40ae18df933976be9641326c5d08
Author: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>
Date:   Tue Oct 6 00:39:50 2026 +0000

    tee: optee: execute yielding RPMI calls
    
    OP-TEE commands can span multiple exchanges with normal world. A call
    may yield to request an RPC service or allow interrupt processing
    before continuing execution in secure world.
    
    Add the RPMI yielding-call path used by the common OP-TEE session
    operations. Submit the command and RPC argument buffers as ranges
    within a shared memory parcel.
    
    Handle RPC requests while the call is suspended and resume execution
    using the token returned by OP-TEE until the command completes.
    
    Use the common OP-TEE call queue to wait when an initial request is
    rejected with RPMI_ERR_BUSY, allowing another active call to complete
    before retrying.
    
    Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>

> diff --git a/drivers/tee/optee/rpmi_abi.c b/drivers/tee/optee/rpmi_abi.c
> index 58d82678be98f..6e76316794c18 100644
> --- a/drivers/tee/optee/rpmi_abi.c
> +++ b/drivers/tee/optee/rpmi_abi.c

[ ... ]

> +/* Handle RPC command or interrupt returns from a yielding call. */
> +static void optee_rpmi_handle_rpc(struct tee_context *ctx, struct optee *optee,
> +				  u32 result, struct optee_msg_arg *arg)
> +{
> +	switch (result) {
> +	case OPTEE_RPMI_YIELDING_CALL_RETURN_RPC_CMD:
> +		optee_rpmi_handle_rpc_cmd(ctx, optee, arg);
> +		break;
> +	case OPTEE_RPMI_YIELDING_CALL_RETURN_INTERRUPT:
> +		break;
> +	default:
> +		pr_warn("Unknown RPC func 0x%x\n", result);
> +		break;
> +	}
> +}

[Severity: High]
Does this code risk entering an infinite loop? If the result is unknown,
optee_rpmi_handle_rpc() logs a warning but doesn't return an error code to
the caller.

The loop in optee_rpmi_yielding_call() below will then blindly update the
token and continue infinitely polling the TEE.

> +
> +/**
> + * optee_rpmi_yielding_call() - submit and resume a yielding RPMI command
> + * @ctx: calling context
> + * @req: initial command request
> + * @rpc_arg: shared RPC argument buffer
> + * @system_thread: caller requests TEE system thread support
> + *
> + * Only RPMI_ERR_BUSY rejection of the initial command permits retry.
> + *
> + * Return: zero on completion, or a negative error.
> + */
> +static int optee_rpmi_yielding_call(struct tee_context *ctx,
> +				    const struct optee_rpmi_call_req *req,
> +				    struct optee_msg_arg *rpc_arg,
> +				    bool system_thread)
> +{
> +	struct optee *optee = tee_get_drvdata(ctx->teedev);
> +	struct optee_rpmi_resume_req resume = {
> +		.op = cpu_to_le32(OPTEE_RPMI_YIELDING_CALL_RESUME),
> +		/* resume_token is nonzero after OP-TEE suspends the call. */
> +		.resume_token = 0,
> +	};
> +	struct optee_rpmi_call_resp resp;
> +	struct optee_call_waiter waiter;
> +	u32 result;
> +	s32 status;
> +	int ret;
> +
> +	optee_cq_wait_init(&optee->call_queue, &waiter, system_thread);
> +	while (true) {
> +		if (resume.resume_token)
> +			ret = optee_rpmi_call_with_status(optee, &resume,
> +							  sizeof(resume), &resp,
> +							  sizeof(resp), &status);
> +		else
> +			ret = optee_rpmi_call_with_status(optee, req, sizeof(*req),
> +							  &resp, sizeof(resp),
> +							  &status);

[Severity: Medium]
Will this correctly handle a zero resume_token from a suspended call?

If the firmware suspends the call but incorrectly provides a resume_token
of 0, resume.resume_token will be 0 on the next iteration. This if
statement will evaluate to false, falling back to resending the initial
request instead of the resume command, which could cause an infinite retry
loop.

> +		if (ret)
> +			goto done;
> +
> +		switch (status) {
> +		case RPMI_SUCCESS:
> +			break;
> +		case RPMI_ERR_BUSY:
> +			if (!resume.resume_token) {
> +				optee_cq_wait_for_completion(&optee->call_queue,
> +							     &waiter);
> +				continue;
> +			}

[Severity: High]
Can this cause a deadlock if the BUSY state was triggered by an external
client?

If RPMI_ERR_BUSY is returned on the initial command, the task blocks
indefinitely in optee_cq_wait_for_completion() waiting for a local
completion. If the shared mailbox or service is busy processing requests
from another VM and the local kernel has no other active threads, no thread
will ever call optee_cq_wait_final() to wake up this task.

> +
> +			fallthrough;

[ ... ]

> +/* The caller supplies SHM with room for command and RPC args. */
> +static int optee_rpmi_do_call_with_arg(struct tee_context *ctx,
> +				       struct tee_shm *shm, u_int offs,
> +				       bool system_thread)
> +{
> +	struct optee *optee = tee_get_drvdata(ctx->teedev);
> +	struct optee_msg_arg *arg, *rpc_arg;
> +	struct optee_rpmi_call_req req;

[Severity: High]
Does this leak uninitialized kernel stack memory to the Secure World?

The struct optee_rpmi_call_req req is allocated on the stack here but is
not zero-initialized.

> +	size_t arg_size, rpc_size, rpc_offset;
> +	u32 parcel_id, nonce;
> +
> +	arg = tee_shm_get_va(shm, offs);
> +	if (IS_ERR(arg))
> +		return PTR_ERR(arg);
> +
> +	arg_size = OPTEE_MSG_GET_ARG_SIZE(arg->num_params);
> +	rpc_size = OPTEE_MSG_GET_ARG_SIZE(optee->rpc_param_count);
> +	rpc_offset = offs + arg_size;
> +	rpc_arg = tee_shm_get_va(shm, rpc_offset);
> +	if (IS_ERR(rpc_arg))
> +		return PTR_ERR(rpc_arg);
> +
> +	optee_rpmi_shm_get_identity(shm, &parcel_id, &nonce);
> +
> +	req.op = cpu_to_le32(OPTEE_RPMI_YIELDING_CALL_WITH_ARG);
> +	req.parcel_id = cpu_to_le32(parcel_id);
> +	req.nonce = cpu_to_le32(nonce);
> +	req.arg_offset = cpu_to_le64((u64)shm->offset + offs);
> +	req.rpc_offset = cpu_to_le64((u64)shm->offset + rpc_offset);
> +	req.arg_size = cpu_to_le32(arg_size);
> +	req.rpc_size = cpu_to_le32(rpc_size);

[Severity: High]
The code explicitly initializes most fields but misses req.flags. This
leaves req.flags containing uninitialized stack memory when req is passed
to optee_rpmi_yielding_call() and sent over the RPMI mailbox.

Could we initialize the whole struct to zero?

> +
> +	return optee_rpmi_yielding_call(ctx, &req, rpc_arg, system_thread);
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261005-rpmi-tee-service-grp-dev-v2-0-72f222e23ec1@oss.qualcomm.com?part=6

  reply	other threads:[~2026-10-06  0:55 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-06  0:39 [PATCH RFC v2 0/8] tee: optee: add RPMI backend support on RISC-V Amirreza Zarrabi
2026-10-06  0:39 ` Amirreza Zarrabi
2026-10-06  0:39 ` Amirreza Zarrabi via OP-TEE
2026-10-06  0:39 ` [PATCH RFC v2 1/8] tee: optee: allow RPMI transport builds " Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi via OP-TEE
2026-10-06  0:52   ` sashiko-bot
2026-10-06  0:39 ` [PATCH RFC v2 2/8] tee: optee: define the RPMI control and parcel-reference ABI Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi via OP-TEE
2026-10-08  6:51   ` Jens Wiklander
2026-10-08  6:51     ` Jens Wiklander
2026-10-08  6:51     ` Jens Wiklander via OP-TEE
2026-10-08 22:02     ` Amirreza Zarrabi
2026-10-08 22:02       ` Amirreza Zarrabi via OP-TEE
2026-10-08 22:02       ` Amirreza Zarrabi
2026-10-09 13:54       ` Jens Wiklander
2026-10-09 13:54         ` Jens Wiklander
2026-10-09 13:54         ` Jens Wiklander via OP-TEE
2026-10-06  0:39 ` [PATCH RFC v2 3/8] tee: optee: add RPMI shared-memory and parameter support Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi via OP-TEE
2026-10-08  7:10   ` Jens Wiklander
2026-10-08  7:10     ` Jens Wiklander
2026-10-08  7:10     ` Jens Wiklander via OP-TEE
2026-10-08 22:27     ` Amirreza Zarrabi
2026-10-08 22:27       ` Amirreza Zarrabi via OP-TEE
2026-10-08 22:27       ` Amirreza Zarrabi
2026-10-06  0:39 ` [PATCH RFC v2 4/8] tee: optee: add RPMI dynamic shared-memory pool Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi via OP-TEE
2026-10-06  0:55   ` sashiko-bot
2026-10-06  0:39 ` [PATCH RFC v2 5/8] tee: optee: add RPMI RPC handling Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi via OP-TEE
2026-10-06  0:39 ` [PATCH RFC v2 6/8] tee: optee: execute yielding RPMI calls Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi via OP-TEE
2026-10-06  0:55   ` sashiko-bot [this message]
2026-10-08  8:11   ` Jens Wiklander
2026-10-08  8:11     ` Jens Wiklander
2026-10-08  8:11     ` Jens Wiklander via OP-TEE
2026-10-08 22:56     ` Amirreza Zarrabi
2026-10-08 22:56       ` Amirreza Zarrabi
2026-10-08 22:56       ` Amirreza Zarrabi via OP-TEE
2026-10-06  0:39 ` [PATCH RFC v2 7/8] tee: optee: bind RPMI services and negotiate backend capabilities Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi via OP-TEE
2026-10-06  0:53   ` sashiko-bot
2026-10-08  8:20   ` Jens Wiklander
2026-10-08  8:20     ` Jens Wiklander
2026-10-08  8:20     ` Jens Wiklander via OP-TEE
2026-10-08 23:10     ` Amirreza Zarrabi
2026-10-08 23:10       ` Amirreza Zarrabi via OP-TEE
2026-10-08 23:10       ` Amirreza Zarrabi
2026-10-09 14:43       ` Jens Wiklander
2026-10-09 14:43         ` Jens Wiklander
2026-10-09 14:43         ` Jens Wiklander via OP-TEE
2026-10-06  0:39 ` [PATCH RFC v2 8/8] tee: optee: support RPMI asynchronous notification doorbells Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi
2026-10-06  0:39   ` Amirreza Zarrabi via OP-TEE
2026-10-06  0:47   ` sashiko-bot
2026-10-08  6:15 ` [PATCH RFC v2 0/8] tee: optee: add RPMI backend support on RISC-V Jens Wiklander
2026-10-08  6:15   ` Jens Wiklander
2026-10-08  6:15   ` Jens Wiklander via OP-TEE
2026-10-08 23:21   ` Amirreza Zarrabi
2026-10-08 23:21     ` Amirreza Zarrabi
2026-10-08 23:21     ` Amirreza Zarrabi via OP-TEE

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261006005548.EA0BD1F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=amirreza.zarrabi@oss.qualcomm.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.