• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 #include "drv_ipc_mgr.h"
13 #include <securec.h>
14 #include <tee_log.h>
15 #include <drv.h>
16 #include <tee_drv_internal.h>
17 #include "task_mgr.h"
18 #include <ipclib.h>
19 
get_drv_param(const struct tee_drv_param * params,char ** param,uint32_t * len)20 static int32_t get_drv_param(const struct tee_drv_param *params, char **param, uint32_t *len)
21 {
22     uint64_t *args = (uint64_t *)(uintptr_t)params->args;
23     char *indata = (char *)(uintptr_t)(params->data);
24     uint64_t param_len = args[DRV_PARAM_LEN_INDEX];
25     uint64_t param_offset = args[DRV_PARAM_INDEX];
26 
27     if (param_len == 0) {
28         tlogd("input null param\n");
29         *param = NULL;
30         *len = 0;
31         return 0;
32     }
33 
34     if (param_len > (SYSCAL_MSG_BUFFER_SIZE - sizeof(struct drv_req_msg_t))) {
35         tloge("param_len:0x%llx is invalid\n", param_len);
36         return -1;
37     }
38 
39     if (param_offset != 0) {
40         tloge("invalid param_offset:0x%llx\n", param_offset);
41         return -1;
42     }
43 
44     if (indata == NULL) {
45         tloge("invalid param_indata\n");
46         return -1;
47     }
48 
49     *param = indata;
50     *len = param_len;
51 
52     return 0;
53 }
54 
trans_uuid_to_ul(const struct tee_uuid * uuid,uint64_t * uuid_time,uint64_t * uuid_clock)55 static void trans_uuid_to_ul(const struct tee_uuid *uuid, uint64_t *uuid_time, uint64_t *uuid_clock)
56 {
57     uint64_t uuid_c = 0;
58 
59     uint64_t uuid_t = uuid->timeLow;
60     uuid_t = (uuid_t << UUID_TIME_LOW_OFFSET) |
61         ((uint64_t)uuid->timeMid << UUID_TIME_MID_OFFSET) |
62         ((uint64_t)uuid->timeHiAndVersion);
63 
64     uint32_t i;
65     for (i = 0; i < NODE_LEN; i++)
66         uuid_c = (uuid_c << BITS_NUM_PER_BYTE) | uuid->clockSeqAndNode[i];
67 
68     *uuid_time = uuid_t;
69     *uuid_clock = uuid_c;
70 
71     tlogd("tran uuid:0x%x uuid_time:0x%llx uuid_clock:0x%llx\n", uuid->timeLow, *uuid_time, *uuid_clock);
72 }
73 
call_drv_open(const struct tee_drv_param * params,cref_t channel,uint64_t perm)74 static int64_t call_drv_open(const struct tee_drv_param *params, cref_t channel, uint64_t perm)
75 {
76     char buf[SYSCAL_MSG_BUFFER_SIZE] = { 0 };
77     struct drv_req_msg_t *msg    = (struct drv_req_msg_t *)buf;
78     struct drv_reply_msg_t *rmsg = (struct drv_reply_msg_t *)buf;
79 
80     uint32_t ext_data = SYSCAL_MSG_BUFFER_SIZE - sizeof(struct drv_req_msg_t);
81     char *param = NULL;
82     uint32_t param_len;
83 
84     int32_t ret = get_drv_param(params, &param, &param_len);
85     if (ret != 0)
86         return -1;
87 
88     msg->args[DRV_FRAM_CMD_INDEX] = CALL_DRV_OPEN;
89     msg->args[DRV_PARAM_INDEX] = 0; /* offset */
90     msg->args[DRV_PARAM_LEN_INDEX] = param_len; /* buffer len */
91     msg->args[DRV_PERM_INDEX] = perm;
92     msg->args[DRV_CALLER_PID_INDEX] = params->caller_pid;
93     trans_uuid_to_ul(&params->uuid, &msg->args[DRV_UUID_TIME_INDEX], &msg->args[DRV_UUID_CLOCK_INDEX]);
94 
95     if (param != NULL && param_len != 0 && memcpy_s(msg->data, ext_data, param, param_len) != 0) {
96         tloge("copy param to data failed\n");
97         return -1;
98     }
99 
100     msg->header.send.msg_id = 0;
101     msg->header.send.msg_size = sizeof(struct drv_req_msg_t) + param_len;
102 
103     ret = ipc_msg_call(channel, msg, msg->header.send.msg_size, rmsg, SYSCAL_MSG_BUFFER_SIZE, DRV_IPC_MAX_TIMEOUT);
104     if (ret == E_EX_TIMER_TIMEOUT) {
105         tloge("open msg call open timeout:%u\n", DRV_IPC_MAX_TIMEOUT);
106         return -1;
107     }
108 
109     if (ret != 0) {
110         tloge("open msg call fail ret:0x%x\n", ret);
111         return -1;
112     }
113 
114     return rmsg->header.reply.ret_val;
115 }
116 
drv_open_handle(const struct tee_drv_param * params,const struct task_node * node,uint64_t perm)117 int64_t drv_open_handle(const struct tee_drv_param *params, const struct task_node *node, uint64_t perm)
118 {
119     if (params == NULL || params->args == 0 || node == NULL) {
120         tloge("open invalid param\n");
121         return -1;
122     }
123 
124     int64_t ret = call_drv_open(params, node->drv_task.channel, perm);
125     if (ret <= 0 || ret > FD_COUNT_MAX) {
126         tloge("call drv open fail ret:0x%llx\n", ret);
127         return -1;
128     }
129 
130     return (int64_t)(((uint64_t)node->drv_task.drv_index << DRV_INDEX_OFFSET) | (uint64_t)ret);
131 }
132 
call_drv_close(uint32_t taskid,const struct tee_uuid * caller_uuid,int64_t fd,cref_t channel)133 int64_t call_drv_close(uint32_t taskid, const struct tee_uuid *caller_uuid, int64_t fd, cref_t channel)
134 {
135     if (caller_uuid == NULL) {
136         tloge("invalid close uuid\n");
137         return -1;
138     }
139 
140     if (fd < 0) {
141         tloge("close invalid fd\n");
142         return -1;
143     }
144 
145     char buf[SYSCAL_MSG_BUFFER_SIZE] = { 0 };
146     struct drv_req_msg_t *msg    = (struct drv_req_msg_t *)buf;
147     struct drv_reply_msg_t *rmsg = (struct drv_reply_msg_t *)buf;
148 
149     msg->args[DRV_FRAM_CMD_INDEX] = CALL_DRV_CLOSE;
150     msg->args[DRV_CLOSE_FD_INDEX] = (uint64_t)fd;
151     msg->args[DRV_CALLER_PID_INDEX] = taskid;
152     trans_uuid_to_ul(caller_uuid, &msg->args[DRV_UUID_TIME_INDEX], &msg->args[DRV_UUID_CLOCK_INDEX]);
153 
154     msg->header.send.msg_id = 0;
155     msg->header.send.msg_size = sizeof(struct drv_req_msg_t);
156 
157     int32_t ret = ipc_msg_call(channel, msg, msg->header.send.msg_size, rmsg,
158         SYSCAL_MSG_BUFFER_SIZE, DRV_IPC_MAX_TIMEOUT);
159     if (ret == E_EX_TIMER_TIMEOUT) {
160         tloge("close msg call close timeout:%u\n", DRV_IPC_MAX_TIMEOUT);
161         return -1;
162     }
163 
164     if (ret != 0) {
165         tloge("close msg call fail ret:0x%x\n", ret);
166         return -1;
167     }
168 
169     return rmsg->header.reply.ret_val;
170 }
171 
172 #ifdef TEE_SUPPORT_DRV_FD_DUMP
call_drv_dump(cref_t channel)173 void call_drv_dump(cref_t channel)
174 {
175     char buf[SYSCAL_MSG_BUFFER_SIZE] = { 0 };
176     struct drv_req_msg_t *msg    = (struct drv_req_msg_t *)buf;
177     struct drv_reply_msg_t *rmsg = (struct drv_reply_msg_t *)buf;
178 
179     msg->header.send.msg_id = DRV_DUMP_CMD_ID;
180     msg->header.send.msg_size = sizeof(struct drv_req_msg_t);
181 
182     int32_t ret = ipc_msg_call(channel, msg, msg->header.send.msg_size, rmsg,
183         SYSCAL_MSG_BUFFER_SIZE, -1);
184     if (ret != 0)
185         tloge("dump msg call fail ret:0x%x\n", ret);
186 }
187 #endif
188