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 4/6] tee: optee: Register TEE devices on the platform bus
Date: Wed, 11 Nov 2026 15:30:17 +0000 [thread overview]
Message-ID: <sashiko-outbox-209224@kernel.org> (raw)
In-Reply-To: <20261111-ice-migrate-tee-svc-v2-4-29d19f6c92ab@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 7 potential
issues to consider:
- [High] firmware: qcom: duplicate module_init() and module_exit() in
qcom_ice_tee.c
- [High] tee: missing EXPORT_SYMBOL_GPL() for
tee_platform_device_register()
- [High] soc: qcom: Kconfig dependency and module cycle selecting
QCOM_ICE_TEE
- [High] tee: optee: platform device name collision with optee_driver
- [High] soc: qcom: ice: qcom_ice_tz_is_available() requires both SCM
and OP-TEE
- [Medium] tee: unchecked devm_add_action_or_reset() in
tee_platform_device_register()
- [Medium] firmware: qcom: missing remove callback in
qcom_ice_plat_driver
--
commit c9fd96220ba8e5c6eeef8806d3112f1e39c17581
Author: Harshal Dev <harshal.dev@oss.qualcomm.com>
tee: optee: Register TEE devices on the platform bus
This commit adds tee_platform_device_register() to register OP-TEE devices on
the platform bus and updates the Qualcomm ICE driver and its TEE backend to
check whether OP-TEE has probed.
> diff --git a/drivers/firmware/qcom/qcom_ice_tee.c b/drivers/firmware/qcom/qcom_ice_tee.c
> index 694aa05847f0e..39f7094439d99 100644
> --- a/drivers/firmware/qcom/qcom_ice_tee.c
> +++ b/drivers/firmware/qcom/qcom_ice_tee.c
[ ... ]
> @@ -398,5 +414,30 @@ static struct tee_client_driver qcom_ice_tee_driver = {
>
> module_tee_client_driver(qcom_ice_tee_driver);
>
> +static int qcom_ice_plat_probe(struct platform_device *pdev)
> +{
> + /* Paired with smp_load_acquire() in qcom_ice_tee_is_available() */
> + smp_store_release(&__teedev, &pdev->dev);
> + return 0;
> +}
> +
> +static const struct platform_device_id qcom_ice_plat_id_table[] = {
> + {
> + .name = "optee",
> + },
> + { }
> +};
> +MODULE_DEVICE_TABLE(platform, qcom_ice_plat_id_table);
> +
> +static struct platform_driver qcom_ice_plat_driver = {
> + .probe = qcom_ice_plat_probe,
> + .id_table = qcom_ice_plat_id_table,
> + .driver = {
> + .name = "qcom-ice-plat",
> + },
> +};
[Severity: Medium]
Should qcom_ice_plat_driver also provide a .remove callback to clear
__teedev? When the parent tee_device is unregistered or qcom-ice-plat is
unbound, plat_tee_free() unregisters and frees pdev, leaving __teedev as a
dangling pointer and causing qcom_ice_tee_is_available() to keep returning
true.
> +
> +module_platform_driver(qcom_ice_plat_driver);
[Severity: High]
Does adding module_platform_driver(qcom_ice_plat_driver) in the same file as
module_tee_client_driver(qcom_ice_tee_driver) break modular builds? Both
macros expand to module_driver(), which defines __inittest(), init_module(),
__exittest(), and cleanup_module(), causing duplicate symbol definitions when
built as a module.
A single module_init() and module_exit() pair is needed to register
qcom_ice_tee_driver before qcom_ice_plat_driver, unwind on registration
failure, and unregister both in reverse order.
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index 535c8619197b3..8dc75c252f52b 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
> @@ -296,6 +296,7 @@ endif
> config QCOM_INLINE_CRYPTO_ENGINE
> tristate
> select QCOM_SCM
> + select QCOM_ICE_TEE
[Severity: High]
Can QCOM_INLINE_CRYPTO_ENGINE unconditionally select QCOM_ICE_TEE here?
QCOM_ICE_TEE depends on TEE and !CPU_BIG_ENDIAN in
drivers/firmware/qcom/Kconfig, whereas QCOM_INLINE_CRYPTO_ENGINE is selected
by MMC_SDHCI_MSM and SCSI_UFS_QCOM without those dependencies. Selecting
QCOM_ICE_TEE when TEE is disabled (or when QCOM_INLINE_CRYPTO_ENGINE is
built-in and TEE is modular) causes unmet direct dependency warnings and link
failures for tee_client_* symbols, and include/linux/firmware/qcom/qcom_ice_tee.h
has no fallback stub for qcom_ice_tee_is_available() (nor an include of
linux/types.h for bool).
In addition, qcom_ice.c now calls qcom_ice_tee_is_available() from
qcom_ice_tee.c while qcom_ice_tee.c calls qcom_ice_tz_ops_register() and
qcom_ice_tz_ops_unregister() from qcom_ice.c, creating a circular dependency
between the two modules.
> diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c
> index 452896b1858f1..4844621b74970 100644
> --- a/drivers/soc/qcom/ice.c
> +++ b/drivers/soc/qcom/ice.c
> @@ -18,6 +18,7 @@
> #include <linux/platform_device.h>
> #include <linux/xarray.h>
>
> +#include <linux/firmware/qcom/qcom_ice_tee.h>
> #include <linux/firmware/qcom/qcom_scm.h>
>
> #include <soc/qcom/ice.h>
> @@ -132,7 +133,13 @@ static bool qcom_ice_tz_ops_registered(void)
>
> static bool qcom_ice_tz_is_available(void)
> {
> - return qcom_scm_is_available();
> + /*
> + * Both back-ends should be available before we check for
> + * qcom_ice_tz_ops_registered(), otherwise we could pre-maturely
> + * assume that TZ does not provide any ICE secure interface.
> + */
> + return (qcom_scm_is_available() & qcom_ice_tee_is_available());
> +
> }
[Severity: High]
Does requiring both qcom_scm_is_available() and qcom_ice_tee_is_available()
break all QTEE-based platforms where OP-TEE is not present?
__teedev is only set when OP-TEE probes and registers its platform device.
On platforms using QTEE via SCM (or when OP-TEE is not enabled),
qcom_ice_tee_is_available() remains false forever, so once qcom_ice_create()
checks qcom_ice_tz_is_available() in the next patch it will defer probe
indefinitely and prevent UFS/SDHC storage from coming online.
Also, this uses bitwise & on booleans instead of &&, and at this commit
qcom_ice_tz_is_available() is an unused static function, triggering a
-Wunused-function warning during bisection.
> diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
> index 51624443359bf..85ee761739826 100644
> --- a/drivers/tee/optee/smc_abi.c
> +++ b/drivers/tee/optee/smc_abi.c
> @@ -1920,6 +1920,14 @@ static int optee_probe(struct platform_device *pdev)
> if (rc)
> goto err_disable_shm_cache;
>
> + /*
> + * Device should only be visible on the platform bus once the
> + * child devices have already been enumerated on the TEE bus.
> + */
> + rc = tee_platform_device_register(optee->teedev, "optee");
> + if (rc)
> + goto err_disable_shm_cache;
[Severity: High]
Does registering a platform device named "optee" here (and in
optee_ffa_probe()) collide with optee_driver on the platform bus?
drivers/tee/optee/smc_abi.c defines optee_driver with:
drivers/tee/optee/smc_abi.c:
static struct platform_driver optee_driver = {
.probe = optee_probe,
.remove = optee_smc_remove,
.shutdown = optee_shutdown,
.driver = {
.name = "optee",
.of_match_table = optee_dt_match,
},
};
Because optee_driver has .driver.name = "optee" and no .id_table,
platform_match() falls back to strcmp(pdev->name, drv->name) == 0 and matches
this new child platform device against optee_driver, recursively calling
optee_probe() (which logs errors and fails with -ENXIO). On non-DT systems
that already have a platform device named "optee" with PLATFORM_DEVID_NONE,
registering a second one also fails with -EEXIST, and only a single platform
driver can bind to the device at a time.
> diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
> index 1aac50c7c1de7..0d3c266b29c7b 100644
> --- a/drivers/tee/tee_core.c
> +++ b/drivers/tee/tee_core.c
[ ... ]
> @@ -1225,6 +1226,26 @@ int tee_device_register(struct tee_device *teedev)
> }
> EXPORT_SYMBOL_GPL(tee_device_register);
>
> +static void plat_tee_free(void *data)
> +{
> + struct platform_device *plat_dev = data;
> +
> + platform_device_unregister(plat_dev);
> +}
> +
> +int tee_platform_device_register(struct tee_device *teedev, const char *teename)
> +{
> + struct platform_device *plat_dev;
> +
> + plat_dev = platform_device_register_data(&teedev->dev, teename,
> + PLATFORM_DEVID_NONE, NULL, 0);
> + if (IS_ERR(plat_dev))
> + return PTR_ERR(plat_dev);
> +
> + devm_add_action_or_reset(&teedev->dev, plat_tee_free, plat_dev);
> + return 0;
[Severity: Medium]
Should tee_platform_device_register() return the result of
devm_add_action_or_reset()? __devm_add_action_or_reset() is marked
__must_check and on allocation failure it runs plat_tee_free() to unregister
plat_dev, while this function still returns 0 to the caller.
> +}
[Severity: High]
Does tee_platform_device_register() need EXPORT_SYMBOL_GPL()? It is defined
in tee.ko and called from optee_probe() and optee_ffa_probe() in optee.ko, so
building OP-TEE as a module fails at modpost with an undefined symbol.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261111-ice-migrate-tee-svc-v2-0-29d19f6c92ab@oss.qualcomm.com?part=4
next prev parent reply other threads:[~2026-11-11 15:30 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 [this message]
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
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-209224@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 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.