Linux cryptographic layer development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Harshal Dev" <harshal.dev@oss.qualcomm.com>,
	"Eric Biggers" <ebiggers@kernel.org>,
	"Bjorn Andersson" <andersson@kernel.org>,
	"Konrad Dybcio" <konradybcio@kernel.org>,
	"Abel Vesa" <abelvesa@kernel.org>,
	"Kuldeep Singh" <kuldeep.singh@oss.qualcomm.com>,
	"Neeraj Soni" <neeraj.soni@oss.qualcomm.com>,
	"Manivannan Sadhasivam" <manivannan.sadhasivam@oss.qualcomm.com>,
	"Sumit Garg" <sumit.garg@oss.qualcomm.com>,
	"Selvam Sathappan Periakaruppan"
	<selvam.periakaruppan@oss.qualcomm.com>
Cc: "Basant Kumar" <basantk@qti.qualcomm.com>, linux-crypto@vger.kernel.org
Subject: Re: [PATCH v2 5/6] soc: qcom: ice: Migrate to the TZ agnostic ICE APIs
Date: Wed, 11 Nov 2026 15:47:34 +0000	[thread overview]
Message-ID: <sashiko-outbox-209231@kernel.org> (raw)
In-Reply-To: <20261111-ice-migrate-tee-svc-v2-5-29d19f6c92ab@oss.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 4 potential
issues to consider:
- [High] soc: qcom: ice: infinite probe deferral in qcom_ice_create()
  without OP-TEE
- [High] soc: qcom: ice: circular module dependency and build failure in
  qcom_ice_create()
- [Medium] soc: qcom: ice: -ENODEV converts to true in
  qcom_ice_tz_has_wrapped_key_support()
- [Medium] soc: qcom: ice: unsynchronized ice_tz_ops access races with
  backend teardown
--

commit 6c35fbb5f17a57538422d90392b9a647da09687a
Author: Harshal Dev <harshal.dev@oss.qualcomm.com>

soc: qcom: ice: Migrate to the TZ agnostic ICE APIs

This commit switches the Qualcomm Inline Crypto Engine driver from calling
qcom_scm_*() directly to using the qcom_ice_tz_*() wrapper functions.

> diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c
> index 4844621b74970..9bab177f7ce55 100644
> --- a/drivers/soc/qcom/ice.c
> +++ b/drivers/soc/qcom/ice.c
> @@ -307,7 +307,7 @@ static bool qcom_ice_check_supported(struct qcom_ice *ice)
>  	 * advertise support for raw keys or wrapped keys, HWKM cannot be used
>  	 * unconditionally.  A module parameter is used to opt into using it.
>  	 */
> -	if (ice->hwkm_version && qcom_scm_has_wrapped_key_support()) {
> +	if (ice->hwkm_version && qcom_ice_tz_has_wrapped_key_support()) {

[Severity: Medium]
Does qcom_ice_tz_has_wrapped_key_support() evaluate to true when ice_tz_ops
is NULL?

drivers/soc/qcom/ice.c:qcom_ice_tz_has_wrapped_key_support() {
	struct qcom_ice_tz_ops *ops;

	ops = ice_tz_ops;
	if (!ops)
		return -ENODEV;

	return ops->ice_has_wrapped_key_support(ops->dev);
}

Because the return type is bool, returning -ENODEV converts to true,
causing qcom_ice_check_supported() to falsely enable ice->use_hwkm when
ice_tz_ops is NULL.

[ ... ]

> @@ -553,9 +553,9 @@ int qcom_ice_program_key(struct qcom_ice *ice, unsigned int slot,
>  	for (i = 0; i < ARRAY_SIZE(key.words); i++)
>  		__cpu_to_be32s(&key.words[i]);
>  
> -	err = qcom_scm_ice_set_key(slot, key.bytes, AES_256_XTS_KEY_SIZE,
> -				   QCOM_SCM_ICE_CIPHER_AES_256_XTS,
> -				   blk_key->crypto_cfg.data_unit_size / 512);
> +	err = qcom_ice_tz_set_key(slot, key.bytes, AES_256_XTS_KEY_SIZE,
> +				  QCOM_ICE_CIPHER_AES_256_XTS,
> +				  blk_key->crypto_cfg.data_unit_size / 512);

[Severity: Medium]
Can qcom_ice_tz_set_key() and the other qcom_ice_tz_*() wrappers race with
qcom_ice_tz_ops_unregister() during backend teardown?

CPU0                              CPU1
qcom_ice_program_key()
  qcom_ice_tz_set_key()
    ops = ice_tz_ops;
    if (!ops)
                                  qcom_ice_tee_remove()
                                    qcom_ice_tz_ops_unregister(...)
                                      smp_store_release(&ice_tz_ops, NULL)
                                    tee_client_close_session(...)
                                    tee_client_close_context(...)
                                    /* devm frees qcom_ice_tee_private */
    ops->ice_set_key(ops->dev, ...)
      ...                         <-- use-after-free on ops->dev data

Each qcom_ice_tz_*() wrapper reads ice_tz_ops without holding a lock or
reference, and qcom_ice_tz_ops_unregister() clears ice_tz_ops without
waiting for in-flight calls to complete before qcom_ice_tee_remove() tears
down the TEE session and frees its devm-managed driver data.

[ ... ]

> @@ -696,11 +696,11 @@ static struct qcom_ice *qcom_ice_create(struct device *dev,
>  {
>  	struct qcom_ice *engine;
>  
> -	if (!qcom_scm_is_available())
> +	if (!qcom_ice_tz_is_available())
>  		return ERR_PTR(-EPROBE_DEFER);

[Severity: High]
Does checking qcom_ice_tz_is_available() here cause qcom_ice_create() to
return -EPROBE_DEFER forever on platforms that do not have both QTEE SCM
and OP-TEE available at the same time?

drivers/soc/qcom/ice.c:qcom_ice_tz_is_available() {
	...
	return (qcom_scm_is_available() & qcom_ice_tee_is_available());
}

qcom_ice_tee_is_available() only becomes true when an OP-TEE platform
device binds to qcom_ice_plat_probe().  On any QTEE/SCM platform without
OP-TEE (or on an OP-TEE platform without qcom_scm),
qcom_ice_tz_is_available() never becomes true even after ice_tz_ops is
registered, so UFS and SDHCI controllers calling devm_of_qcom_ice_get()
defer probe indefinitely and cannot mount the root filesystem.

Conversely, on OP-TEE platforms, qcom_ice_plat_probe() and
qcom_ice_tee_probe() bind on different buses; if qcom_ice_plat_probe() sets
__teedev before qcom_ice_tee_probe() registers qcom_ice_tee_ops,
qcom_ice_tz_is_available() returns true while qcom_ice_tz_ops_registered()
is still false, causing qcom_ice_create() to fail permanently with
-EOPNOTSUPP instead of deferring probe.

>  
> -	if (!qcom_scm_ice_available()) {
> -		dev_warn(dev, "ICE SCM interface not found\n");
> +	if (!qcom_ice_tz_ops_registered()) {
> +		dev_warn(dev, "ICE firmware service interface not found\n");
>  		return ERR_PTR(-EOPNOTSUPP);
>  	}

[Severity: High]
Does calling qcom_ice_tz_is_available() and qcom_ice_tz_ops_registered() in
qcom_ice_create() introduce a circular module dependency and break modular
builds?

Making qcom_ice_tz_is_available() live causes qcom_ice to reference
qcom_ice_tee_is_available() from qcom_ice_tee and qcom_scm_is_available()
from qcom_scm, while both of those modules call qcom_ice_tz_ops_register()
and qcom_ice_tz_ops_unregister() exported by qcom_ice.  This also fails to
link when CONFIG_QCOM_INLINE_CRYPTO_ENGINE=y and CONFIG_QCOM_ICE_TEE is
modular or disabled.

In addition, include/soc/qcom/ice.h guards qcom_ice_tz_ops_register() and
qcom_ice_tz_ops_unregister() with #ifdef CONFIG_QCOM_INLINE_CRYPTO_ENGINE
instead of IS_ENABLED(CONFIG_QCOM_INLINE_CRYPTO_ENGINE):

include/soc/qcom/ice.h:
#ifdef CONFIG_QCOM_INLINE_CRYPTO_ENGINE
int qcom_ice_tz_ops_register(struct qcom_ice_tz_ops *ops);
void qcom_ice_tz_ops_unregister(struct qcom_ice_tz_ops *ops);
#else
static inline int qcom_ice_tz_ops_register(struct qcom_ice_tz_ops *__unused)
{
	return 0;
}

When CONFIG_QCOM_INLINE_CRYPTO_ENGINE=m (such as in arm64 defconfig), the
static inline stubs in include/soc/qcom/ice.h conflict with the definitions
in drivers/soc/qcom/ice.c and turn registration in the backends into a
no-op, leaving qcom_ice_tz_ops_registered() permanently false.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261111-ice-migrate-tee-svc-v2-0-29d19f6c92ab@oss.qualcomm.com?part=5

  reply	other threads:[~2026-11-11 15:47 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11 14:17 [PATCH v2 0/6] Add support for a TEE agnostic Inline Crypto Engine service Harshal Dev
2026-11-11 14:17 ` [PATCH v2 1/6] soc: qcom: ice: Add TZ agnostic re-direction functions Harshal Dev
2026-11-11 14:37   ` sashiko-bot
2026-11-11 14:17 ` [PATCH v2 2/6] firmware: qcom_scm: Transition to ICE TZ agnostic operations Harshal Dev
2026-11-11 14:55   ` sashiko-bot
2026-11-11 14:17 ` [PATCH v2 3/6] firmware: qcom: Add a TEE bus based ICE back-end Harshal Dev
2026-11-11 15:07   ` sashiko-bot
2026-11-11 14:17 ` [PATCH v2 4/6] tee: optee: Register TEE devices on the platform bus Harshal Dev
2026-11-11 14:57   ` Harshal Dev
2026-11-11 15:30   ` sashiko-bot
2026-11-11 14:17 ` [PATCH v2 5/6] soc: qcom: ice: Migrate to the TZ agnostic ICE APIs Harshal Dev
2026-11-11 15:47   ` sashiko-bot [this message]
2026-11-11 14:17 ` [PATCH v2 6/6] firmware: qcom: scm: Drop exported ICE wrapper functions Harshal Dev
2026-11-11 15:54   ` sashiko-bot
2026-11-11 14:21 ` [PATCH v2 0/6] Add support for a TEE agnostic Inline Crypto Engine service Harshal Dev

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=sashiko-outbox-209231@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=abelvesa@kernel.org \
    --cc=andersson@kernel.org \
    --cc=basantk@qti.qualcomm.com \
    --cc=ebiggers@kernel.org \
    --cc=harshal.dev@oss.qualcomm.com \
    --cc=konradybcio@kernel.org \
    --cc=kuldeep.singh@oss.qualcomm.com \
    --cc=linux-crypto@vger.kernel.org \
    --cc=manivannan.sadhasivam@oss.qualcomm.com \
    --cc=neeraj.soni@oss.qualcomm.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=selvam.periakaruppan@oss.qualcomm.com \
    --cc=sumit.garg@oss.qualcomm.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox