All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 1/1] tee: optee: expose OS revision via sysfs
@ 2025-11-21 14:12 ` Wei Ming Chen
  0 siblings, 0 replies; 74+ messages in thread
From: Wei Ming Chen @ 2025-11-21 14:12 UTC (permalink / raw)
  To: linux-kernel; +Cc: sumit.garg, op-tee, Aristo Chen

From: Aristo Chen <aristo.chen@canonical.com>

Today the only way to read the OP-TEE OS version is from dmesg/journal
logs, which can be lost as buffers roll over. Add a minimal
optee_version_info (major/minor/build) and get_optee_revision hook,
collect the OS revision in both SMC and FF-A ABIs, and publish
/sys/class/tee/tee*/optee_os_revision for a stable userspace readout.

Signed-off-by: Aristo Chen <aristo.chen@canonical.com>
---
 drivers/tee/optee/ffa_abi.c       | 27 +++++++++++-
 drivers/tee/optee/optee_private.h |  1 +
 drivers/tee/optee/smc_abi.c       | 27 +++++++++++-
 drivers/tee/tee_core.c            | 73 ++++++++++++++++++++++++++++++-
 include/linux/tee_core.h          |  2 +
 include/linux/tee_drv.h           | 12 +++++
 6 files changed, 137 insertions(+), 5 deletions(-)

diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index bf8390789ecf..291ba3bfde7f 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -776,7 +776,8 @@ static int optee_ffa_reclaim_protmem(struct optee *optee,
  */
 
 static bool optee_ffa_api_is_compatible(struct ffa_device *ffa_dev,
-					const struct ffa_ops *ops)
+					const struct ffa_ops *ops,
+					struct optee_version_info *version_info)
 {
 	const struct ffa_msg_ops *msg_ops = ops->msg_ops;
 	struct ffa_send_direct_data data = {
@@ -806,6 +807,12 @@ static bool optee_ffa_api_is_compatible(struct ffa_device *ffa_dev,
 		pr_err("Unexpected error %d\n", rc);
 		return false;
 	}
+	if (version_info) {
+		version_info->os_major = data.data0;
+		version_info->os_minor = data.data1;
+		version_info->os_build_id = data.data2;
+	}
+
 	if (data.data2)
 		pr_info("revision %lu.%lu (%08lx)",
 			data.data0, data.data1, data.data2);
@@ -893,6 +900,18 @@ static void optee_ffa_get_version(struct tee_device *teedev,
 	*vers = v;
 }
 
+static int optee_ffa_get_optee_revision(struct tee_device *teedev,
+					struct optee_version_info *vers)
+{
+	struct optee *optee = tee_get_drvdata(teedev);
+
+	if (!optee)
+		return -ENODEV;
+
+	*vers = optee->version_info;
+	return 0;
+}
+
 static int optee_ffa_open(struct tee_context *ctx)
 {
 	return optee_open(ctx, true);
@@ -900,6 +919,7 @@ static int optee_ffa_open(struct tee_context *ctx)
 
 static const struct tee_driver_ops optee_ffa_clnt_ops = {
 	.get_version = optee_ffa_get_version,
+	.get_optee_revision = optee_ffa_get_optee_revision,
 	.open = optee_ffa_open,
 	.release = optee_release,
 	.open_session = optee_open_session,
@@ -918,6 +938,7 @@ static const struct tee_desc optee_ffa_clnt_desc = {
 
 static const struct tee_driver_ops optee_ffa_supp_ops = {
 	.get_version = optee_ffa_get_version,
+	.get_optee_revision = optee_ffa_get_optee_revision,
 	.open = optee_ffa_open,
 	.release = optee_release_supp,
 	.supp_recv = optee_supp_recv,
@@ -1034,6 +1055,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
 {
 	const struct ffa_notifier_ops *notif_ops;
 	const struct ffa_ops *ffa_ops;
+	struct optee_version_info version_info = { };
 	unsigned int max_notif_value;
 	unsigned int rpc_param_count;
 	struct tee_shm_pool *pool;
@@ -1047,7 +1069,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
 	ffa_ops = ffa_dev->ops;
 	notif_ops = ffa_ops->notifier_ops;
 
-	if (!optee_ffa_api_is_compatible(ffa_dev, ffa_ops))
+	if (!optee_ffa_api_is_compatible(ffa_dev, ffa_ops, &version_info))
 		return -EINVAL;
 
 	if (!optee_ffa_exchange_caps(ffa_dev, ffa_ops, &sec_caps,
@@ -1059,6 +1081,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
 	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
 	if (!optee)
 		return -ENOMEM;
+	optee->version_info = version_info;
 
 	pool = optee_ffa_shm_pool_alloc_pages();
 	if (IS_ERR(pool)) {
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index db9ea673fbca..967c015e8ffb 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -249,6 +249,7 @@ struct optee {
 	bool in_kernel_rpmb_routing;
 	struct work_struct scan_bus_work;
 	struct work_struct rpmb_scan_bus_work;
+	struct optee_version_info version_info;
 };
 
 struct optee_session {
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index 0be663fcd52b..1e412949898f 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -1232,6 +1232,18 @@ static void optee_get_version(struct tee_device *teedev,
 	*vers = v;
 }
 
+static int optee_get_optee_revision(struct tee_device *teedev,
+				    struct optee_version_info *vers)
+{
+	struct optee *optee = tee_get_drvdata(teedev);
+
+	if (!optee)
+		return -ENODEV;
+
+	*vers = optee->version_info;
+	return 0;
+}
+
 static int optee_smc_open(struct tee_context *ctx)
 {
 	struct optee *optee = tee_get_drvdata(ctx->teedev);
@@ -1242,6 +1254,7 @@ static int optee_smc_open(struct tee_context *ctx)
 
 static const struct tee_driver_ops optee_clnt_ops = {
 	.get_version = optee_get_version,
+	.get_optee_revision = optee_get_optee_revision,
 	.open = optee_smc_open,
 	.release = optee_release,
 	.open_session = optee_open_session,
@@ -1261,6 +1274,7 @@ static const struct tee_desc optee_clnt_desc = {
 
 static const struct tee_driver_ops optee_supp_ops = {
 	.get_version = optee_get_version,
+	.get_optee_revision = optee_get_optee_revision,
 	.open = optee_smc_open,
 	.release = optee_release_supp,
 	.supp_recv = optee_supp_recv,
@@ -1323,7 +1337,8 @@ static bool optee_msg_api_uid_is_optee_image_load(optee_invoke_fn *invoke_fn)
 }
 #endif
 
-static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn)
+static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn,
+				      struct optee_version_info *version_info)
 {
 	union {
 		struct arm_smccc_res smccc;
@@ -1337,6 +1352,12 @@ static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn)
 	invoke_fn(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0,
 		  &res.smccc);
 
+	if (version_info) {
+		version_info->os_major = res.result.major;
+		version_info->os_minor = res.result.minor;
+		version_info->os_build_id = res.result.build_id;
+	}
+
 	if (res.result.build_id)
 		pr_info("revision %lu.%lu (%0*lx)", res.result.major,
 			res.result.minor, (int)sizeof(res.result.build_id) * 2,
@@ -1727,6 +1748,7 @@ static int optee_probe(struct platform_device *pdev)
 	unsigned int thread_count;
 	struct tee_device *teedev;
 	struct tee_context *ctx;
+	struct optee_version_info version_info = { };
 	u32 max_notif_value;
 	u32 arg_cache_flags;
 	u32 sec_caps;
@@ -1745,7 +1767,7 @@ static int optee_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	optee_msg_get_os_revision(invoke_fn);
+	optee_msg_get_os_revision(invoke_fn, &version_info);
 
 	if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
 		pr_warn("api revision mismatch\n");
@@ -1814,6 +1836,7 @@ static int optee_probe(struct platform_device *pdev)
 		rc = -ENOMEM;
 		goto err_free_shm_pool;
 	}
+	optee->version_info = version_info;
 
 	optee->ops = &optee_ops;
 	optee->smc.invoke_fn = invoke_fn;
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index d65d47cc154e..dc23058e7be6 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -1141,12 +1141,83 @@ static ssize_t implementation_id_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(implementation_id);
 
+static int tee_get_optee_revision(struct tee_device *teedev,
+				  struct optee_version_info *ver_info)
+{
+	if (!teedev->desc->ops->get_optee_revision)
+		return -ENODEV;
+
+	return teedev->desc->ops->get_optee_revision(teedev, ver_info);
+}
+
+static bool tee_is_optee(struct tee_device *teedev)
+{
+	struct tee_ioctl_version_data vers;
+
+	teedev->desc->ops->get_version(teedev, &vers);
+
+	return vers.impl_id == TEE_IMPL_ID_OPTEE;
+}
+
+static ssize_t optee_os_revision_show(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct tee_device *teedev = container_of(dev, struct tee_device, dev);
+	struct optee_version_info ver_info;
+	int ret;
+
+	if (!tee_is_optee(teedev))
+		return -ENODEV;
+
+	ret = tee_get_optee_revision(teedev, &ver_info);
+	if (ret)
+		return ret;
+
+	if (ver_info.os_build_id)
+		return sysfs_emit(buf, "%u.%u (%08x)\n", ver_info.os_major,
+				  ver_info.os_minor, ver_info.os_build_id);
+
+	return sysfs_emit(buf, "%u.%u\n", ver_info.os_major,
+			  ver_info.os_minor);
+}
+static DEVICE_ATTR_RO(optee_os_revision);
+
 static struct attribute *tee_dev_attrs[] = {
 	&dev_attr_implementation_id.attr,
 	NULL
 };
 
-ATTRIBUTE_GROUPS(tee_dev);
+static struct attribute *tee_optee_attrs[] = {
+	&dev_attr_optee_os_revision.attr,
+	NULL
+};
+
+static umode_t tee_optee_attr_is_visible(struct kobject *kobj,
+					 struct attribute *attr, int n)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct tee_device *teedev = container_of(dev, struct tee_device, dev);
+
+	if (tee_is_optee(teedev) && teedev->desc->ops->get_optee_revision)
+		return attr->mode;
+
+	return 0;
+}
+
+static const struct attribute_group tee_dev_group = {
+	.attrs = tee_dev_attrs,
+};
+
+static const struct attribute_group tee_optee_group = {
+	.attrs = tee_optee_attrs,
+	.is_visible = tee_optee_attr_is_visible,
+};
+
+static const struct attribute_group *tee_dev_groups[] = {
+	&tee_dev_group,
+	&tee_optee_group,
+	NULL
+};
 
 static const struct class tee_class = {
 	.name = "tee",
diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h
index 1f3e5dad6d0d..4bd9b6b191c9 100644
--- a/include/linux/tee_core.h
+++ b/include/linux/tee_core.h
@@ -98,6 +98,8 @@ struct tee_device {
 struct tee_driver_ops {
 	void (*get_version)(struct tee_device *teedev,
 			    struct tee_ioctl_version_data *vers);
+	int (*get_optee_revision)(struct tee_device *teedev,
+				  struct optee_version_info *vers);
 	int (*open)(struct tee_context *ctx);
 	void (*close_context)(struct tee_context *ctx);
 	void (*release)(struct tee_context *ctx);
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index 88a6f9697c89..64a2fea11cb9 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -20,6 +20,18 @@
 
 struct tee_device;
 
+/**
+ * struct optee_version_info - OP-TEE version information
+ * @os_major:		OS major version
+ * @os_minor:		OS minor version
+ * @os_build_id:	OS build identifier (0 if unspecified)
+ */
+struct optee_version_info {
+	u32 os_major;
+	u32 os_minor;
+	u32 os_build_id;
+};
+
 /**
  * struct tee_context - driver specific context on file pointer data
  * @teedev:	pointer to this drivers struct tee_device
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 74+ messages in thread

end of thread, other threads:[~2026-01-15  6:18 UTC | newest]

Thread overview: 74+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-21 14:12 [PATCH v1 1/1] tee: optee: expose OS revision via sysfs Wei Ming Chen
2025-11-21 14:12 ` Wei Ming Chen
2025-11-22  7:36 ` Harshal Dev via OP-TEE
2025-11-22  7:36   ` Harshal Dev
2025-11-22 14:59 ` [PATCH v2 " Wei Ming Chen
2025-11-22 14:59   ` Wei Ming Chen
2025-11-24  7:15   ` Jens Wiklander
2025-11-24  7:15     ` Jens Wiklander
2025-11-24 14:28     ` Thomas, Rijo-john via OP-TEE
2025-11-25  7:53     ` Sumit Garg via OP-TEE
2025-11-25  7:53       ` Sumit Garg
2025-11-25  7:55       ` Sumit Garg via OP-TEE
2025-11-25  7:55         ` Sumit Garg
2025-12-01 11:47         ` Aristo Chen
2025-12-01 11:47           ` Aristo Chen
2025-12-01 13:06           ` Jens Wiklander
2025-12-02  9:54             ` Aristo Chen
2025-12-03  7:50               ` Jens Wiklander
2025-12-07 14:01                 ` Aristo Chen
2025-12-09  8:30                   ` Jens Wiklander
2025-12-19 15:38                     ` Aristo Chen
2025-12-22  8:34                       ` Jens Wiklander
2025-12-22 10:07                         ` Sumit Garg via OP-TEE
2025-12-22 10:07                           ` Sumit Garg
2025-12-23  3:33                           ` Aristo Chen via OP-TEE
2025-12-26 13:19   ` [PATCH v3 " Aristo Chen
2025-12-26 13:19     ` Aristo Chen
2025-12-29  4:59     ` Sumit Garg via OP-TEE
2025-12-29  4:59       ` Sumit Garg
2025-12-30  5:17     ` [PATCH v4 1/2] tee: add revision sysfs attribute Aristo Chen
2025-12-30  5:17       ` Aristo Chen
2025-12-30  5:17       ` [PATCH v4 2/2] tee: optee: store OS revision for TEE core Aristo Chen
2025-12-30  5:17         ` Aristo Chen
2026-01-05  5:20         ` Sumit Garg via OP-TEE
2026-01-05  5:20           ` Sumit Garg
2026-01-05  8:13           ` Aristo Chen
2026-01-05  8:13             ` Aristo Chen
2026-01-05  8:48             ` Sumit Garg via OP-TEE
2026-01-05  8:48               ` Sumit Garg
2026-01-05  4:53       ` [PATCH v4 1/2] tee: add revision sysfs attribute Sumit Garg via OP-TEE
2026-01-05  4:53         ` Sumit Garg
2026-01-07 15:26       ` [PATCH v5 " Aristo Chen
2026-01-07 15:26         ` Aristo Chen
2026-01-07 15:26         ` [PATCH v5 2/2] tee: optee: store OS revision for TEE core Aristo Chen
2026-01-07 15:26           ` Aristo Chen
2026-01-07 15:28         ` [PATCH v5 1/2] tee: add revision sysfs attribute Mario Limonciello via OP-TEE
2026-01-07 15:28           ` Mario Limonciello
2026-01-08  2:55           ` Aristo Chen
2026-01-08  2:55             ` Aristo Chen
2026-01-08  3:01             ` Mario Limonciello (AMD) (kernel.org) via OP-TEE
2026-01-08  3:01               ` Mario Limonciello (AMD) (kernel.org)
2026-01-08  6:45         ` [PATCH v6 " Aristo Chen
2026-01-08  6:45           ` Aristo Chen
2026-01-08  6:45           ` [PATCH v6 2/2] tee: optee: store OS revision for TEE core Aristo Chen
2026-01-08  6:45             ` Aristo Chen
2026-01-09 11:50             ` Sumit Garg via OP-TEE
2026-01-09 11:50               ` Sumit Garg
2026-01-09 15:07               ` Aristo Chen
2026-01-09 15:07                 ` Aristo Chen
2026-01-12 11:22                 ` Sumit Garg via OP-TEE
2026-01-12 11:22                   ` Sumit Garg
2026-01-12  9:55             ` Jens Wiklander
2026-01-12 10:43               ` Aristo Chen
2026-01-09 11:48           ` [PATCH v6 1/2] tee: add revision sysfs attribute Sumit Garg via OP-TEE
2026-01-09 11:48             ` Sumit Garg
2026-01-12  9:50           ` Jens Wiklander
2026-01-12 15:48           ` [PATCH v7 " Aristo Chen via OP-TEE
2026-01-12 15:48             ` Aristo Chen
2026-01-12 15:48             ` [PATCH v7 2/2] tee: optee: store OS revision for TEE core Aristo Chen via OP-TEE
2026-01-12 15:48               ` Aristo Chen
2026-01-14 15:43               ` Jens Wiklander
2026-01-15  6:18               ` Sumit Garg via OP-TEE
2026-01-15  6:18                 ` Sumit Garg
2026-01-14 15:42             ` [PATCH v7 1/2] tee: add revision sysfs attribute Jens Wiklander

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.