1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2019 Linaro Ltd.
6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8 #include <linux/kernel.h>
9 #include <linux/slab.h>
10 #include <linux/tee_drv.h>
11 #include <linux/uuid.h>
12 #include "optee_private.h"
14 static int optee_ctx_match(struct tee_ioctl_version_data
*ver
, const void *data
)
16 if (ver
->impl_id
== TEE_IMPL_ID_OPTEE
)
22 static int get_devices(struct tee_context
*ctx
, u32 session
,
23 struct tee_shm
*device_shm
, u32
*shm_size
,
27 struct tee_ioctl_invoke_arg inv_arg
;
28 struct tee_param param
[4];
30 memset(&inv_arg
, 0, sizeof(inv_arg
));
31 memset(¶m
, 0, sizeof(param
));
34 inv_arg
.session
= session
;
35 inv_arg
.num_params
= 4;
37 /* Fill invoke cmd params */
38 param
[0].attr
= TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT
;
39 param
[0].u
.memref
.shm
= device_shm
;
40 param
[0].u
.memref
.size
= *shm_size
;
41 param
[0].u
.memref
.shm_offs
= 0;
43 ret
= tee_client_invoke_func(ctx
, &inv_arg
, param
);
44 if ((ret
< 0) || ((inv_arg
.ret
!= TEEC_SUCCESS
) &&
45 (inv_arg
.ret
!= TEEC_ERROR_SHORT_BUFFER
))) {
46 pr_err("PTA_CMD_GET_DEVICES invoke function err: %x\n",
51 *shm_size
= param
[0].u
.memref
.size
;
56 static void optee_release_device(struct device
*dev
)
58 struct tee_client_device
*optee_device
= to_tee_client_device(dev
);
63 static int optee_register_device(const uuid_t
*device_uuid
)
65 struct tee_client_device
*optee_device
= NULL
;
68 optee_device
= kzalloc(sizeof(*optee_device
), GFP_KERNEL
);
72 optee_device
->dev
.bus
= &tee_bus_type
;
73 optee_device
->dev
.release
= optee_release_device
;
74 if (dev_set_name(&optee_device
->dev
, "optee-ta-%pUb", device_uuid
)) {
78 uuid_copy(&optee_device
->id
.uuid
, device_uuid
);
80 rc
= device_register(&optee_device
->dev
);
82 pr_err("device registration failed, err: %d\n", rc
);
83 put_device(&optee_device
->dev
);
89 static int __optee_enumerate_devices(u32 func
)
91 const uuid_t pta_uuid
=
92 UUID_INIT(0x7011a688, 0xddde, 0x4053,
93 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8);
94 struct tee_ioctl_open_session_arg sess_arg
;
95 struct tee_shm
*device_shm
= NULL
;
96 const uuid_t
*device_uuid
= NULL
;
97 struct tee_context
*ctx
= NULL
;
98 u32 shm_size
= 0, idx
, num_devices
= 0;
101 memset(&sess_arg
, 0, sizeof(sess_arg
));
103 /* Open context with OP-TEE driver */
104 ctx
= tee_client_open_context(NULL
, optee_ctx_match
, NULL
, NULL
);
108 /* Open session with device enumeration pseudo TA */
109 export_uuid(sess_arg
.uuid
, &pta_uuid
);
110 sess_arg
.clnt_login
= TEE_IOCTL_LOGIN_PUBLIC
;
111 sess_arg
.num_params
= 0;
113 rc
= tee_client_open_session(ctx
, &sess_arg
, NULL
);
114 if ((rc
< 0) || (sess_arg
.ret
!= TEEC_SUCCESS
)) {
115 /* Device enumeration pseudo TA not found */
120 rc
= get_devices(ctx
, sess_arg
.session
, NULL
, &shm_size
, func
);
121 if (rc
< 0 || !shm_size
)
124 device_shm
= tee_shm_alloc_kernel_buf(ctx
, shm_size
);
125 if (IS_ERR(device_shm
)) {
126 pr_err("tee_shm_alloc_kernel_buf failed\n");
127 rc
= PTR_ERR(device_shm
);
131 rc
= get_devices(ctx
, sess_arg
.session
, device_shm
, &shm_size
, func
);
135 device_uuid
= tee_shm_get_va(device_shm
, 0);
136 if (IS_ERR(device_uuid
)) {
137 pr_err("tee_shm_get_va failed\n");
138 rc
= PTR_ERR(device_uuid
);
142 num_devices
= shm_size
/ sizeof(uuid_t
);
144 for (idx
= 0; idx
< num_devices
; idx
++) {
145 rc
= optee_register_device(&device_uuid
[idx
]);
151 tee_shm_free(device_shm
);
153 tee_client_close_session(ctx
, sess_arg
.session
);
155 tee_client_close_context(ctx
);
160 int optee_enumerate_devices(u32 func
)
162 return __optee_enumerate_devices(func
);
165 static int __optee_unregister_device(struct device
*dev
, void *data
)
167 if (!strncmp(dev_name(dev
), "optee-ta", strlen("optee-ta")))
168 device_unregister(dev
);
173 void optee_unregister_devices(void)
175 bus_for_each_dev(&tee_bus_type
, NULL
, NULL
,
176 __optee_unregister_device
);