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 int optee_register_device(const uuid_t
*device_uuid
)
58 struct tee_client_device
*optee_device
= NULL
;
61 optee_device
= kzalloc(sizeof(*optee_device
), GFP_KERNEL
);
65 optee_device
->dev
.bus
= &tee_bus_type
;
66 if (dev_set_name(&optee_device
->dev
, "optee-ta-%pUb", device_uuid
)) {
70 uuid_copy(&optee_device
->id
.uuid
, device_uuid
);
72 rc
= device_register(&optee_device
->dev
);
74 pr_err("device registration failed, err: %d\n", rc
);
81 static int __optee_enumerate_devices(u32 func
)
83 const uuid_t pta_uuid
=
84 UUID_INIT(0x7011a688, 0xddde, 0x4053,
85 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8);
86 struct tee_ioctl_open_session_arg sess_arg
;
87 struct tee_shm
*device_shm
= NULL
;
88 const uuid_t
*device_uuid
= NULL
;
89 struct tee_context
*ctx
= NULL
;
90 u32 shm_size
= 0, idx
, num_devices
= 0;
93 memset(&sess_arg
, 0, sizeof(sess_arg
));
95 /* Open context with OP-TEE driver */
96 ctx
= tee_client_open_context(NULL
, optee_ctx_match
, NULL
, NULL
);
100 /* Open session with device enumeration pseudo TA */
101 export_uuid(sess_arg
.uuid
, &pta_uuid
);
102 sess_arg
.clnt_login
= TEE_IOCTL_LOGIN_PUBLIC
;
103 sess_arg
.num_params
= 0;
105 rc
= tee_client_open_session(ctx
, &sess_arg
, NULL
);
106 if ((rc
< 0) || (sess_arg
.ret
!= TEEC_SUCCESS
)) {
107 /* Device enumeration pseudo TA not found */
112 rc
= get_devices(ctx
, sess_arg
.session
, NULL
, &shm_size
, func
);
113 if (rc
< 0 || !shm_size
)
116 device_shm
= tee_shm_alloc(ctx
, shm_size
,
117 TEE_SHM_MAPPED
| TEE_SHM_DMA_BUF
);
118 if (IS_ERR(device_shm
)) {
119 pr_err("tee_shm_alloc failed\n");
120 rc
= PTR_ERR(device_shm
);
124 rc
= get_devices(ctx
, sess_arg
.session
, device_shm
, &shm_size
, func
);
128 device_uuid
= tee_shm_get_va(device_shm
, 0);
129 if (IS_ERR(device_uuid
)) {
130 pr_err("tee_shm_get_va failed\n");
131 rc
= PTR_ERR(device_uuid
);
135 num_devices
= shm_size
/ sizeof(uuid_t
);
137 for (idx
= 0; idx
< num_devices
; idx
++) {
138 rc
= optee_register_device(&device_uuid
[idx
]);
144 tee_shm_free(device_shm
);
146 tee_client_close_session(ctx
, sess_arg
.session
);
148 tee_client_close_context(ctx
);
153 int optee_enumerate_devices(u32 func
)
155 return __optee_enumerate_devices(func
);