From: Harshal Dev via OP-TEE <op-tee@lists.trustedfirmware.org>
To: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>
Cc: Basant Kumar <basantk@qti.qualcomm.com>,
Apurupa Pattapu <apurupa@qti.qualcomm.com>,
Arun Kumar Neelakantam <aneelaka@qti.qualcomm.com>,
op-tee@lists.trustedfirmware.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org,
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>,
Konrad Dybcio <konradybcio@kernel.org>,
Jens Wiklander <jens.wiklander@oss.qualcomm.com>,
Sumit Garg <sumit.garg@kernel.org>,
Bjorn Andersson <andersson@kernel.org>
Subject: Re: [PATCH v2 5/6] tee: qcomtee: Add support for registering QTEE services on TEE bus
Date: Fri, 31 Jul 2026 14:05:27 +0530 [thread overview]
Message-ID: <2e41d146-c641-444f-b406-875534c1cd98@oss.qualcomm.com> (raw)
In-Reply-To: <886466f0-0df2-4ee0-90f7-bd7e7bd731d9@oss.qualcomm.com>
Hi Amir,
On 29-07-2026 12:35 pm, Amirreza Zarrabi wrote:
> Hi Harshal,
>
> On 7/22/2026 4:59 PM, Harshal Dev wrote:
>> QTEE exposes certain secure services implemented either within the QTEE
>> kernel or via pre-loaded Trusted Applications (TAs). Such always-available
>> services can be readily accessed by TEE client drivers via QTEE's
>> object-IPC protocol if the service is registered as a device on the TEE
>> bus.
>>
>> One such service is the EFI-variables service, implemented by the
>> uefisecapp TA which enables kernel clients to access EFI variables at
>> runtime.
>>
>> Maintain a static list of such always-available secure services and add
>> support for the QCOMTEE driver to register these services as devices on
>> the TEE bus during probe.
>>
>> Signed-off-by: Harshal Dev <harshal.dev@oss.qualcomm.com>
>> ---
>> drivers/tee/qcomtee/call.c | 160 ++++++++++++++++++++++++++++++++++-
>> 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 | 3 +-
>> 5 files changed, 177 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/tee/qcomtee/call.c b/drivers/tee/qcomtee/call.c
>> index c1bba5fbfa3e..e909955e6b21 100644
>> --- a/drivers/tee/qcomtee/call.c
>> +++ b/drivers/tee/qcomtee/call.c
>> @@ -662,7 +662,7 @@ static void qcomtee_get_qtee_feature_list(struct tee_context *ctx, u32 id,
>> {
>> struct qcomtee_object *client_env, *service;
>> struct qcomtee_arg u[3] = { 0 };
>> - int result;
>> + int result, error = 0;
>>
>> struct qcomtee_object_invoke_ctx *oic __free(kfree) =
>> qcomtee_object_invoke_ctx_alloc(ctx, true);
>> @@ -675,9 +675,13 @@ static void qcomtee_get_qtee_feature_list(struct tee_context *ctx, u32 id,
>>
>> /* Get ''FeatureVersions Service'' object. */
>> service = qcomtee_object_get_service(oic, client_env,
>> - QCOMTEE_FEATURE_VER_UID);
>> - if (service == NULL_QCOMTEE_OBJECT)
>> + QCOMTEE_FEATURE_VER_UID,
>> + &error);
>> + if (service == NULL_QCOMTEE_OBJECT) {
>> + if (error)
>> + pr_err("Failed to get service! error: %d\n", error);
>> goto out_failed;
>> + }
>
> no need to check for !error (why new variable reuse result),
Ack. will use 'result' everywhere where I am calling this. Makes sense.
> just print "FeatureVersions Service unavailable (%d)", result
> The message "Failed to get service! error: %d\n" is not helpful.
Ack.
>
>>
>> /* IB: Feature to query. */
>> u[0].b.addr = &id;
>> @@ -697,6 +701,153 @@ static void qcomtee_get_qtee_feature_list(struct tee_context *ctx, u32 id,
>> qcomtee_object_put(client_env);
>> }
>>
>> +/**
>> + * is_qcomtee_service_available() - Check if the QTEE service identified by the UID
>> + * is available
>> + * @ctx: TEE context.
>> + * @uid: 32-bit UID of the service.
>> + *
>> + * Returns true if the service exists and is available.
>> + * Returns false if a service is not exposed by QTEE.
>> + */
>> +static bool is_qcomtee_service_available(struct tee_context *ctx, u32 uid)
>> +{
>> + struct qcomtee_object *client_env;
>> + struct qcomtee_object *service;
>> + int error = 0;
>> + bool ret = false;
>> +
>> + struct qcomtee_object_invoke_ctx *oic __free(kfree) =
>> + qcomtee_object_invoke_ctx_alloc(ctx, true);
>> + if (!oic)
>> + return ret;
>> +
>> + client_env = qcomtee_object_get_client_env(oic);
>> + if (client_env == NULL_QCOMTEE_OBJECT)
>> + return ret;
>> +
>> + /* Get service object corresponding to the uid. */
>> + service = qcomtee_object_get_service(oic, client_env, uid, &error);
>> + if (service != NULL_QCOMTEE_OBJECT) {
>> + qcomtee_object_put(service);
>> + ret = true;
>> + }
>> +
>> + /* When we fail to get the service, QTEE provides the reason. */
>> + if (error)
>> + pr_err("Failed to get service! error: %d\n", error);
>> +
>
> This is not a useful message. We need to know which static service is missing:
> e.g. print "%s is unavailable (%d)", qcom.tz.uefisecapp, error.
Ack.
> Also it is possible to re-org to avoid qcomtee_object_invoke_ctx_alloc() and
> qcomtee_object_get_client_env() on each iteration? oic is reusable.
>
Agreed, since this is called in a loop, it results in unnecessary re-allocation
on every iteration and call to QTEE for getting client_env().
Ack.
>> + qcomtee_object_put(client_env);
>> + return ret;
>> +}
>> +
>> +/*
>> + * QTEE Service UUID name space identifier
>> + *
>> + * A random UUID that is allocated as a name space identifier for forming UUID's
>> + * representing secure services exposed by QTEE.
>> + */
>> +static const uuid_t qtee_service_uuid_ns = UUID_INIT(0xe1b48857, 0x6154, 0x49f9,
>> + 0x93, 0x4e, 0xa2, 0xf2,
>> + 0x0a, 0xba, 0x98, 0x42);
>> +
>> +static const struct qtee_service qtee_services[] = {
>> + { "qcom.tz.uefisecapp",
>> + QCOMTEE_UEFI_SEC_UID }
>> +};
>> +
>> +static void qtee_release_service(struct device *dev)
>> +{
>> + struct tee_client_device *qtee_service = to_tee_client_device(dev);
>> +
>> + kfree(qtee_service);
>> +}
>> +
>> +/**
>> + * qtee_enumerate_service() - Enumerate a given QTEE service and register
>> + * it on the TEE bus as a TEE client device
>> + * @ctx: TEE context.
>> + * @service_uuid: UUID of the service to be registered on the TEE bus.
>> + * @uid: 32-bit UID used by QTEE to identify the service.
>> + *
>> + * Returns 0 on success and < 0 on failure.
>> + */
>> +static int qtee_enumerate_service(struct tee_context *ctx, const char *service_name,
>> + const u32 uid)
>> +{
>> + struct tee_client_device *qtee_service;
>> + uuid_t service_uuid;
>> + int rc;
>> +
>> + if (!is_qcomtee_service_available(ctx, uid))
>> + return -ENXIO;
>
> -EOPNOTSUPP?
Ack.
>
>> +
>> + tee_generate_uuid_v5(&service_uuid, &qtee_service_uuid_ns, service_name,
>> + strlen(service_name));
>> +
>> + qtee_service = kzalloc_obj(*qtee_service);
>> + if (!qtee_service)
>> + return -ENOMEM;
>> +
>> + qtee_service->dev.bus = &tee_bus_type;
>> + qtee_service->dev.release = qtee_release_service;
>> + if (dev_set_name(&qtee_service->dev, "qtee-svc-%pUb", &service_uuid)) {
>> + kfree(qtee_service);
>> + return -ENOMEM;
>> + }
>> + uuid_copy(&qtee_service->id.uuid, &service_uuid);
>> +
>> + rc = device_register(&qtee_service->dev);
>> + if (rc) {
>> + pr_err("QTEE service registration failed, err: %d\n", rc);
>> + put_device(&qtee_service->dev);
>> + kfree(qtee_service);
>
> It is double free!? is not put_device enough?
>
Thank you for catching this, I did not realize that put_device frees the entire
struct.
Ack.
>> + return rc;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + * qtee_enumerate_services() - Enumerate all the secure services exposed by QTEE
>> + * from the static 'qtee_services' list and register them on the TEE bus as
>> + * TEE client devices.
>> + *
>> + * Not all versions of QTEE support a given service. Hence, we try to
>> + * enumerate as many services from the 'qtee_services' list as possible.
>> + * Not being able to enumerate a service shouldn't cause the driver probe
>> + * to fail since none of the services in the list are mandatory for
>> + * establishing communication with QTEE.
>> + * @ctx: TEE context.
>> + */
>> +static void qtee_enumerate_services(struct tee_context *ctx)
>> +{
>> + int rc;
>> + u32 idx;
>> +
>> + for (idx = 0; idx < ARRAY_SIZE(qtee_services); idx++) {
>> + rc = qtee_enumerate_service(ctx, qtee_services[idx].name,
>> + qtee_services[idx].uid);
>> + if (rc == -ENXIO)
>> + pr_err("QTEE does not implement service %d.\n",
>> + qtee_services[idx].uid);
>
> If you print in is_qcomtee_service_available(), why here again?
>
Ack, will remove from here.
Regards,
Harshal
> - Amir
>
>> + }
>> +}
>> +
>> +static int qtee_unregister_service(struct device *dev, void *data)
>> +{
>> + if (!strncmp(dev_name(dev), "qtee-svc", strlen("qtee-svc")))
>> + device_unregister(dev);
>> +
>> + return 0;
>> +}
>> +
>> +static void qtee_unregister_services(void)
>> +{
>> + bus_for_each_dev(&tee_bus_type, NULL, NULL,
>> + qtee_unregister_service);
>> +}
>> +
>> static const struct tee_driver_ops qcomtee_ops = {
>> .get_version = qcomtee_get_version,
>> .open = qcomtee_open,
>> @@ -778,6 +929,8 @@ static int qcomtee_probe(struct platform_device *pdev)
>> QTEE_VERSION_GET_MINOR(qcomtee->qtee_version),
>> QTEE_VERSION_GET_PATCH(qcomtee->qtee_version));
>>
>> + qtee_enumerate_services(qcomtee->ctx);
>> +
>> return 0;
>>
>> err_dest_wq:
>> @@ -807,6 +960,7 @@ static void qcomtee_remove(struct platform_device *pdev)
>> {
>> struct qcomtee *qcomtee = platform_get_drvdata(pdev);
>>
>> + qtee_unregister_services();
>> teedev_close_context(qcomtee->ctx);
>> /* Wait for RELEASE operations to be processed for QTEE objects. */
>> tee_device_unregister(qcomtee->teedev);
>> diff --git a/drivers/tee/qcomtee/core.c b/drivers/tee/qcomtee/core.c
>> index b1cb50e434f0..4e39e867c3e9 100644
>> --- a/drivers/tee/qcomtee/core.c
>> +++ b/drivers/tee/qcomtee/core.c
>> @@ -896,19 +896,20 @@ qcomtee_object_get_client_env(struct qcomtee_object_invoke_ctx *oic)
>>
>> struct qcomtee_object *
>> qcomtee_object_get_service(struct qcomtee_object_invoke_ctx *oic,
>> - struct qcomtee_object *client_env, u32 uid)
>> + struct qcomtee_object *client_env, u32 uid,
>> + int *result)
>> {
>> struct qcomtee_arg u[3] = { 0 };
>> - int ret, result;
>> + int ret;
>>
>> u[0].b.addr = &uid;
>> u[0].b.size = sizeof(uid);
>> u[0].type = QCOMTEE_ARG_TYPE_IB;
>> u[1].type = QCOMTEE_ARG_TYPE_OO;
>> ret = qcomtee_object_do_invoke(oic, client_env, QCOMTEE_CLIENT_ENV_OPEN,
>> - u, &result);
>> + u, result);
>>
>> - if (ret || result)
>> + if (ret || *result)
>> return NULL_QCOMTEE_OBJECT;
>>
>> return u[1].o;
>> diff --git a/drivers/tee/qcomtee/qcomtee.h b/drivers/tee/qcomtee/qcomtee.h
>> index f39bf63fd1c2..66d305a46c0a 100644
>> --- a/drivers/tee/qcomtee/qcomtee.h
>> +++ b/drivers/tee/qcomtee/qcomtee.h
>> @@ -17,6 +17,8 @@
>> #define QCOMTEE_OBJREF_FLAG_USER BIT(1)
>> #define QCOMTEE_OBJREF_FLAG_MEM BIT(2)
>>
>> +#define QTEE_UUID_NS_NAME_SIZE 128
>> +
>> /**
>> * struct qcomtee - Main service struct.
>> * @teedev: client device.
>> @@ -39,6 +41,16 @@ struct qcomtee {
>> u32 qtee_version;
>> };
>>
>> +/**
>> + * struct qtee_service - A secure service exposed by QTEE identified by a 32-bit UID.
>> + * @name: Name of the QTEE service.
>> + * @uid: 32-bit UID used by QTEE to identify the service.
>> + */
>> +struct qtee_service {
>> + const char *name;
>> + const u32 uid;
>> +};
>> +
>> void qcomtee_fetch_async_reqs(struct qcomtee_object_invoke_ctx *oic);
>> struct qcomtee_object *qcomtee_idx_erase(struct qcomtee_object_invoke_ctx *oic,
>> u32 idx);
>> diff --git a/drivers/tee/qcomtee/qcomtee_msg.h b/drivers/tee/qcomtee/qcomtee_msg.h
>> index 878f70178a5b..ecaf8db67d45 100644
>> --- a/drivers/tee/qcomtee/qcomtee_msg.h
>> +++ b/drivers/tee/qcomtee/qcomtee_msg.h
>> @@ -105,6 +105,7 @@ union qcomtee_msg_arg {
>> #define QTEE_VERSION_GET_MINOR(x) (((x) >> 12) & 0xffU)
>> #define QTEE_VERSION_GET_PATCH(x) ((x) >> 0 & 0xfffU)
>>
>> +#define QCOMTEE_UEFI_SEC_UID 413
>> /* Response types as returned from qcomtee_object_invoke_ctx_invoke(). */
>>
>> /* The message contains a callback request. */
>> diff --git a/drivers/tee/qcomtee/qcomtee_object.h b/drivers/tee/qcomtee/qcomtee_object.h
>> index 7bd6e23b038c..f4cb9b8fcbd4 100644
>> --- a/drivers/tee/qcomtee/qcomtee_object.h
>> +++ b/drivers/tee/qcomtee/qcomtee_object.h
>> @@ -316,6 +316,7 @@ qcomtee_object_get_client_env(struct qcomtee_object_invoke_ctx *oic);
>>
>> struct qcomtee_object *
>> qcomtee_object_get_service(struct qcomtee_object_invoke_ctx *oic,
>> - struct qcomtee_object *client_env, u32 uid);
>> + struct qcomtee_object *client_env, u32 uid,
>> + int *result);
>>
>> #endif /* QCOMTEE_OBJECT_H */
>>
>
WARNING: multiple messages have this Message-ID (diff)
From: Harshal Dev <harshal.dev@oss.qualcomm.com>
To: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>
Cc: Basant Kumar <basantk@qti.qualcomm.com>,
Apurupa Pattapu <apurupa@qti.qualcomm.com>,
Arun Kumar Neelakantam <aneelaka@qti.qualcomm.com>,
op-tee@lists.trustedfirmware.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org,
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>,
Konrad Dybcio <konradybcio@kernel.org>,
Jens Wiklander <jens.wiklander@oss.qualcomm.com>,
Sumit Garg <sumit.garg@kernel.org>,
Bjorn Andersson <andersson@kernel.org>
Subject: Re: [PATCH v2 5/6] tee: qcomtee: Add support for registering QTEE services on TEE bus
Date: Fri, 31 Jul 2026 14:05:27 +0530 [thread overview]
Message-ID: <2e41d146-c641-444f-b406-875534c1cd98@oss.qualcomm.com> (raw)
In-Reply-To: <886466f0-0df2-4ee0-90f7-bd7e7bd731d9@oss.qualcomm.com>
Hi Amir,
On 29-07-2026 12:35 pm, Amirreza Zarrabi wrote:
> Hi Harshal,
>
> On 7/22/2026 4:59 PM, Harshal Dev wrote:
>> QTEE exposes certain secure services implemented either within the QTEE
>> kernel or via pre-loaded Trusted Applications (TAs). Such always-available
>> services can be readily accessed by TEE client drivers via QTEE's
>> object-IPC protocol if the service is registered as a device on the TEE
>> bus.
>>
>> One such service is the EFI-variables service, implemented by the
>> uefisecapp TA which enables kernel clients to access EFI variables at
>> runtime.
>>
>> Maintain a static list of such always-available secure services and add
>> support for the QCOMTEE driver to register these services as devices on
>> the TEE bus during probe.
>>
>> Signed-off-by: Harshal Dev <harshal.dev@oss.qualcomm.com>
>> ---
>> drivers/tee/qcomtee/call.c | 160 ++++++++++++++++++++++++++++++++++-
>> 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 | 3 +-
>> 5 files changed, 177 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/tee/qcomtee/call.c b/drivers/tee/qcomtee/call.c
>> index c1bba5fbfa3e..e909955e6b21 100644
>> --- a/drivers/tee/qcomtee/call.c
>> +++ b/drivers/tee/qcomtee/call.c
>> @@ -662,7 +662,7 @@ static void qcomtee_get_qtee_feature_list(struct tee_context *ctx, u32 id,
>> {
>> struct qcomtee_object *client_env, *service;
>> struct qcomtee_arg u[3] = { 0 };
>> - int result;
>> + int result, error = 0;
>>
>> struct qcomtee_object_invoke_ctx *oic __free(kfree) =
>> qcomtee_object_invoke_ctx_alloc(ctx, true);
>> @@ -675,9 +675,13 @@ static void qcomtee_get_qtee_feature_list(struct tee_context *ctx, u32 id,
>>
>> /* Get ''FeatureVersions Service'' object. */
>> service = qcomtee_object_get_service(oic, client_env,
>> - QCOMTEE_FEATURE_VER_UID);
>> - if (service == NULL_QCOMTEE_OBJECT)
>> + QCOMTEE_FEATURE_VER_UID,
>> + &error);
>> + if (service == NULL_QCOMTEE_OBJECT) {
>> + if (error)
>> + pr_err("Failed to get service! error: %d\n", error);
>> goto out_failed;
>> + }
>
> no need to check for !error (why new variable reuse result),
Ack. will use 'result' everywhere where I am calling this. Makes sense.
> just print "FeatureVersions Service unavailable (%d)", result
> The message "Failed to get service! error: %d\n" is not helpful.
Ack.
>
>>
>> /* IB: Feature to query. */
>> u[0].b.addr = &id;
>> @@ -697,6 +701,153 @@ static void qcomtee_get_qtee_feature_list(struct tee_context *ctx, u32 id,
>> qcomtee_object_put(client_env);
>> }
>>
>> +/**
>> + * is_qcomtee_service_available() - Check if the QTEE service identified by the UID
>> + * is available
>> + * @ctx: TEE context.
>> + * @uid: 32-bit UID of the service.
>> + *
>> + * Returns true if the service exists and is available.
>> + * Returns false if a service is not exposed by QTEE.
>> + */
>> +static bool is_qcomtee_service_available(struct tee_context *ctx, u32 uid)
>> +{
>> + struct qcomtee_object *client_env;
>> + struct qcomtee_object *service;
>> + int error = 0;
>> + bool ret = false;
>> +
>> + struct qcomtee_object_invoke_ctx *oic __free(kfree) =
>> + qcomtee_object_invoke_ctx_alloc(ctx, true);
>> + if (!oic)
>> + return ret;
>> +
>> + client_env = qcomtee_object_get_client_env(oic);
>> + if (client_env == NULL_QCOMTEE_OBJECT)
>> + return ret;
>> +
>> + /* Get service object corresponding to the uid. */
>> + service = qcomtee_object_get_service(oic, client_env, uid, &error);
>> + if (service != NULL_QCOMTEE_OBJECT) {
>> + qcomtee_object_put(service);
>> + ret = true;
>> + }
>> +
>> + /* When we fail to get the service, QTEE provides the reason. */
>> + if (error)
>> + pr_err("Failed to get service! error: %d\n", error);
>> +
>
> This is not a useful message. We need to know which static service is missing:
> e.g. print "%s is unavailable (%d)", qcom.tz.uefisecapp, error.
Ack.
> Also it is possible to re-org to avoid qcomtee_object_invoke_ctx_alloc() and
> qcomtee_object_get_client_env() on each iteration? oic is reusable.
>
Agreed, since this is called in a loop, it results in unnecessary re-allocation
on every iteration and call to QTEE for getting client_env().
Ack.
>> + qcomtee_object_put(client_env);
>> + return ret;
>> +}
>> +
>> +/*
>> + * QTEE Service UUID name space identifier
>> + *
>> + * A random UUID that is allocated as a name space identifier for forming UUID's
>> + * representing secure services exposed by QTEE.
>> + */
>> +static const uuid_t qtee_service_uuid_ns = UUID_INIT(0xe1b48857, 0x6154, 0x49f9,
>> + 0x93, 0x4e, 0xa2, 0xf2,
>> + 0x0a, 0xba, 0x98, 0x42);
>> +
>> +static const struct qtee_service qtee_services[] = {
>> + { "qcom.tz.uefisecapp",
>> + QCOMTEE_UEFI_SEC_UID }
>> +};
>> +
>> +static void qtee_release_service(struct device *dev)
>> +{
>> + struct tee_client_device *qtee_service = to_tee_client_device(dev);
>> +
>> + kfree(qtee_service);
>> +}
>> +
>> +/**
>> + * qtee_enumerate_service() - Enumerate a given QTEE service and register
>> + * it on the TEE bus as a TEE client device
>> + * @ctx: TEE context.
>> + * @service_uuid: UUID of the service to be registered on the TEE bus.
>> + * @uid: 32-bit UID used by QTEE to identify the service.
>> + *
>> + * Returns 0 on success and < 0 on failure.
>> + */
>> +static int qtee_enumerate_service(struct tee_context *ctx, const char *service_name,
>> + const u32 uid)
>> +{
>> + struct tee_client_device *qtee_service;
>> + uuid_t service_uuid;
>> + int rc;
>> +
>> + if (!is_qcomtee_service_available(ctx, uid))
>> + return -ENXIO;
>
> -EOPNOTSUPP?
Ack.
>
>> +
>> + tee_generate_uuid_v5(&service_uuid, &qtee_service_uuid_ns, service_name,
>> + strlen(service_name));
>> +
>> + qtee_service = kzalloc_obj(*qtee_service);
>> + if (!qtee_service)
>> + return -ENOMEM;
>> +
>> + qtee_service->dev.bus = &tee_bus_type;
>> + qtee_service->dev.release = qtee_release_service;
>> + if (dev_set_name(&qtee_service->dev, "qtee-svc-%pUb", &service_uuid)) {
>> + kfree(qtee_service);
>> + return -ENOMEM;
>> + }
>> + uuid_copy(&qtee_service->id.uuid, &service_uuid);
>> +
>> + rc = device_register(&qtee_service->dev);
>> + if (rc) {
>> + pr_err("QTEE service registration failed, err: %d\n", rc);
>> + put_device(&qtee_service->dev);
>> + kfree(qtee_service);
>
> It is double free!? is not put_device enough?
>
Thank you for catching this, I did not realize that put_device frees the entire
struct.
Ack.
>> + return rc;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + * qtee_enumerate_services() - Enumerate all the secure services exposed by QTEE
>> + * from the static 'qtee_services' list and register them on the TEE bus as
>> + * TEE client devices.
>> + *
>> + * Not all versions of QTEE support a given service. Hence, we try to
>> + * enumerate as many services from the 'qtee_services' list as possible.
>> + * Not being able to enumerate a service shouldn't cause the driver probe
>> + * to fail since none of the services in the list are mandatory for
>> + * establishing communication with QTEE.
>> + * @ctx: TEE context.
>> + */
>> +static void qtee_enumerate_services(struct tee_context *ctx)
>> +{
>> + int rc;
>> + u32 idx;
>> +
>> + for (idx = 0; idx < ARRAY_SIZE(qtee_services); idx++) {
>> + rc = qtee_enumerate_service(ctx, qtee_services[idx].name,
>> + qtee_services[idx].uid);
>> + if (rc == -ENXIO)
>> + pr_err("QTEE does not implement service %d.\n",
>> + qtee_services[idx].uid);
>
> If you print in is_qcomtee_service_available(), why here again?
>
Ack, will remove from here.
Regards,
Harshal
> - Amir
>
>> + }
>> +}
>> +
>> +static int qtee_unregister_service(struct device *dev, void *data)
>> +{
>> + if (!strncmp(dev_name(dev), "qtee-svc", strlen("qtee-svc")))
>> + device_unregister(dev);
>> +
>> + return 0;
>> +}
>> +
>> +static void qtee_unregister_services(void)
>> +{
>> + bus_for_each_dev(&tee_bus_type, NULL, NULL,
>> + qtee_unregister_service);
>> +}
>> +
>> static const struct tee_driver_ops qcomtee_ops = {
>> .get_version = qcomtee_get_version,
>> .open = qcomtee_open,
>> @@ -778,6 +929,8 @@ static int qcomtee_probe(struct platform_device *pdev)
>> QTEE_VERSION_GET_MINOR(qcomtee->qtee_version),
>> QTEE_VERSION_GET_PATCH(qcomtee->qtee_version));
>>
>> + qtee_enumerate_services(qcomtee->ctx);
>> +
>> return 0;
>>
>> err_dest_wq:
>> @@ -807,6 +960,7 @@ static void qcomtee_remove(struct platform_device *pdev)
>> {
>> struct qcomtee *qcomtee = platform_get_drvdata(pdev);
>>
>> + qtee_unregister_services();
>> teedev_close_context(qcomtee->ctx);
>> /* Wait for RELEASE operations to be processed for QTEE objects. */
>> tee_device_unregister(qcomtee->teedev);
>> diff --git a/drivers/tee/qcomtee/core.c b/drivers/tee/qcomtee/core.c
>> index b1cb50e434f0..4e39e867c3e9 100644
>> --- a/drivers/tee/qcomtee/core.c
>> +++ b/drivers/tee/qcomtee/core.c
>> @@ -896,19 +896,20 @@ qcomtee_object_get_client_env(struct qcomtee_object_invoke_ctx *oic)
>>
>> struct qcomtee_object *
>> qcomtee_object_get_service(struct qcomtee_object_invoke_ctx *oic,
>> - struct qcomtee_object *client_env, u32 uid)
>> + struct qcomtee_object *client_env, u32 uid,
>> + int *result)
>> {
>> struct qcomtee_arg u[3] = { 0 };
>> - int ret, result;
>> + int ret;
>>
>> u[0].b.addr = &uid;
>> u[0].b.size = sizeof(uid);
>> u[0].type = QCOMTEE_ARG_TYPE_IB;
>> u[1].type = QCOMTEE_ARG_TYPE_OO;
>> ret = qcomtee_object_do_invoke(oic, client_env, QCOMTEE_CLIENT_ENV_OPEN,
>> - u, &result);
>> + u, result);
>>
>> - if (ret || result)
>> + if (ret || *result)
>> return NULL_QCOMTEE_OBJECT;
>>
>> return u[1].o;
>> diff --git a/drivers/tee/qcomtee/qcomtee.h b/drivers/tee/qcomtee/qcomtee.h
>> index f39bf63fd1c2..66d305a46c0a 100644
>> --- a/drivers/tee/qcomtee/qcomtee.h
>> +++ b/drivers/tee/qcomtee/qcomtee.h
>> @@ -17,6 +17,8 @@
>> #define QCOMTEE_OBJREF_FLAG_USER BIT(1)
>> #define QCOMTEE_OBJREF_FLAG_MEM BIT(2)
>>
>> +#define QTEE_UUID_NS_NAME_SIZE 128
>> +
>> /**
>> * struct qcomtee - Main service struct.
>> * @teedev: client device.
>> @@ -39,6 +41,16 @@ struct qcomtee {
>> u32 qtee_version;
>> };
>>
>> +/**
>> + * struct qtee_service - A secure service exposed by QTEE identified by a 32-bit UID.
>> + * @name: Name of the QTEE service.
>> + * @uid: 32-bit UID used by QTEE to identify the service.
>> + */
>> +struct qtee_service {
>> + const char *name;
>> + const u32 uid;
>> +};
>> +
>> void qcomtee_fetch_async_reqs(struct qcomtee_object_invoke_ctx *oic);
>> struct qcomtee_object *qcomtee_idx_erase(struct qcomtee_object_invoke_ctx *oic,
>> u32 idx);
>> diff --git a/drivers/tee/qcomtee/qcomtee_msg.h b/drivers/tee/qcomtee/qcomtee_msg.h
>> index 878f70178a5b..ecaf8db67d45 100644
>> --- a/drivers/tee/qcomtee/qcomtee_msg.h
>> +++ b/drivers/tee/qcomtee/qcomtee_msg.h
>> @@ -105,6 +105,7 @@ union qcomtee_msg_arg {
>> #define QTEE_VERSION_GET_MINOR(x) (((x) >> 12) & 0xffU)
>> #define QTEE_VERSION_GET_PATCH(x) ((x) >> 0 & 0xfffU)
>>
>> +#define QCOMTEE_UEFI_SEC_UID 413
>> /* Response types as returned from qcomtee_object_invoke_ctx_invoke(). */
>>
>> /* The message contains a callback request. */
>> diff --git a/drivers/tee/qcomtee/qcomtee_object.h b/drivers/tee/qcomtee/qcomtee_object.h
>> index 7bd6e23b038c..f4cb9b8fcbd4 100644
>> --- a/drivers/tee/qcomtee/qcomtee_object.h
>> +++ b/drivers/tee/qcomtee/qcomtee_object.h
>> @@ -316,6 +316,7 @@ qcomtee_object_get_client_env(struct qcomtee_object_invoke_ctx *oic);
>>
>> struct qcomtee_object *
>> qcomtee_object_get_service(struct qcomtee_object_invoke_ctx *oic,
>> - struct qcomtee_object *client_env, u32 uid);
>> + struct qcomtee_object *client_env, u32 uid,
>> + int *result);
>>
>> #endif /* QCOMTEE_OBJECT_H */
>>
>
next prev parent reply other threads:[~2026-07-31 8:35 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-22 6:59 [PATCH v2 0/6] Add TEE based client driver for UEFI Secure Application Harshal Dev via OP-TEE
2026-07-22 6:59 ` Harshal Dev
2026-07-22 6:59 ` [PATCH v2 1/6] tee: qcomtee: Track the object invocation context Harshal Dev
2026-07-22 6:59 ` Harshal Dev via OP-TEE
2026-07-22 6:59 ` [PATCH v2 2/6] tee: Add kernel client object invoke helper Harshal Dev
2026-07-22 6:59 ` Harshal Dev via OP-TEE
2026-07-22 6:59 ` [PATCH v2 3/6] tee: qcomtee: Allow object invokes from kernel clients Harshal Dev
2026-07-22 6:59 ` Harshal Dev via OP-TEE
2026-07-29 7:06 ` Amirreza Zarrabi via OP-TEE
2026-07-29 7:06 ` Amirreza Zarrabi
2026-07-31 7:38 ` Harshal Dev via OP-TEE
2026-07-31 7:38 ` Harshal Dev
2026-07-22 6:59 ` [PATCH v2 4/6] tee: Export uuidv5 generation for TEE backends Harshal Dev
2026-07-22 6:59 ` Harshal Dev via OP-TEE
2026-07-22 6:59 ` [PATCH v2 5/6] tee: qcomtee: Add support for registering QTEE services on TEE bus Harshal Dev
2026-07-22 6:59 ` Harshal Dev via OP-TEE
2026-07-22 8:29 ` Dmitry Baryshkov
2026-07-22 8:29 ` Dmitry Baryshkov via OP-TEE
2026-07-24 9:13 ` Harshal Dev via OP-TEE
2026-07-24 9:13 ` Harshal Dev
2026-07-29 7:05 ` Amirreza Zarrabi via OP-TEE
2026-07-29 7:05 ` Amirreza Zarrabi
2026-07-31 8:35 ` Harshal Dev via OP-TEE [this message]
2026-07-31 8:35 ` Harshal Dev
2026-07-22 6:59 ` [PATCH v2 6/6] firmware: qcom: Add support for TEE based EFI-var client driver Harshal Dev
2026-07-22 6:59 ` Harshal Dev via OP-TEE
2026-07-22 8:37 ` Dmitry Baryshkov
2026-07-22 8:37 ` Dmitry Baryshkov via OP-TEE
2026-07-24 9:14 ` Harshal Dev via OP-TEE
2026-07-24 9:14 ` Harshal Dev
2026-07-24 10:09 ` Harshal Dev
2026-07-24 10:09 ` Harshal Dev via OP-TEE
2026-07-22 8:26 ` [PATCH v2 0/6] Add TEE based client driver for UEFI Secure Application Dmitry Baryshkov
2026-07-22 8:26 ` Dmitry Baryshkov via OP-TEE
2026-07-24 9:13 ` Harshal Dev via OP-TEE
2026-07-24 9:13 ` Harshal Dev
2026-08-03 14:52 ` Harshal Dev via OP-TEE
2026-08-03 14:52 ` Harshal Dev
2026-08-10 5:41 ` Harshal Dev via OP-TEE
2026-08-10 5:41 ` Harshal Dev
2026-08-10 7:07 ` Dmitry Baryshkov via OP-TEE
2026-08-10 7:07 ` Dmitry Baryshkov
2026-08-12 11:30 ` Harshal Dev via OP-TEE
2026-08-12 11:30 ` Harshal Dev
2026-08-17 6:24 ` Harshal Dev via OP-TEE
2026-08-17 6:24 ` Harshal Dev
2026-08-21 8:34 ` Harshal Dev
2026-08-21 8:34 ` Harshal Dev via OP-TEE
2026-08-26 6:43 ` Harshal Dev via OP-TEE
2026-08-26 6:43 ` Harshal Dev
2026-08-29 14:49 ` Dmitry Baryshkov 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=2e41d146-c641-444f-b406-875534c1cd98@oss.qualcomm.com \
--to=op-tee@lists.trustedfirmware.org \
--cc=amirreza.zarrabi@oss.qualcomm.com \
--cc=andersson@kernel.org \
--cc=aneelaka@qti.qualcomm.com \
--cc=apurupa@qti.qualcomm.com \
--cc=basantk@qti.qualcomm.com \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=harshal.dev@oss.qualcomm.com \
--cc=jens.wiklander@oss.qualcomm.com \
--cc=konradybcio@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=sumit.garg@kernel.org \
/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.