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
13 #include "init.h"
14 #include "teesmcmgr.h"
15 #include <securec.h>
16
17 #include <spawn_ext.h>
18 #include <stdlib.h>
19 #include <ipclib.h>
20 #include <mem_ops.h>
21 #include <tee_config.h>
22
23 #include <stdbool.h>
24 #include <stdio.h>
25 #include <tee_log.h>
26 #include "tee_inner_uuid.h"
27 #include <sched.h>
28
29 #define CASAN_DEFAULT_STACK_SIZE 0x20000
30
31 /* Will be used by tloge and its variants */
32 const char *g_debug_prefix = "GTask";
33
34 struct proc_mem_info {
35 size_t heap_size;
36 size_t stack_size;
37 };
38
set_proc_mem_size(const struct proc_mem_info * info,posix_spawnattr_t * spawnattr)39 static int32_t set_proc_mem_size(const struct proc_mem_info *info, posix_spawnattr_t *spawnattr)
40 {
41 int32_t ret;
42
43 if (info->stack_size != 0) {
44 ret = spawnattr_setstack(spawnattr, info->stack_size);
45 if (ret != 0)
46 return ret;
47 }
48
49 if (info->heap_size != 0) {
50 ret = spawnattr_setheap(spawnattr, info->heap_size);
51 if (ret != 0)
52 return ret;
53 }
54
55 return 0;
56 }
57
run_init_task(char * name,char * envp[],const struct proc_mem_info * info,const struct tee_uuid * uuid,uint32_t * pid_ptr)58 static int run_init_task(char *name, char *envp[], const struct proc_mem_info *info,
59 const struct tee_uuid *uuid, uint32_t *pid_ptr)
60 {
61 char *subargv[] = { name, NULL };
62 pid_t pid = 0;
63 char **p = NULL;
64 posix_spawnattr_t spawnattr;
65 spawn_uuid_t suuid;
66 int ret;
67
68 for (p = subargv; *p != NULL; p++)
69 tlogd("init: subargv %d: %s\n", (int)(p - subargv), *p);
70 for (p = envp; *p != NULL; p++)
71 tlogd("init: envp %d: %s\n", (int)(p - envp), *p);
72
73 (void)memset_s(&spawnattr, sizeof(spawnattr), 0, sizeof(spawnattr));
74 (void)memset_s(&suuid, sizeof(suuid), 0, sizeof(suuid));
75 suuid.uuid = *uuid;
76
77 ret = spawnattr_init(&spawnattr);
78 if (ret != 0)
79 return ret;
80
81 spawnattr_setuuid(&spawnattr, &suuid);
82 if (info->stack_size != 0 || info->heap_size != 0) {
83 ret = set_proc_mem_size(info, &spawnattr);
84 if (ret != 0)
85 return ret;
86 }
87 ret = posix_spawn_ex(&pid, subargv[0], NULL, &spawnattr, subargv, envp, NULL);
88 if (ret < 0) {
89 tloge("spawn %s failed: %d.\n", name, ret);
90 return ret;
91 }
92
93 tlogi("init: \"%s\" started with pid %d.\n", name, pid);
94
95 if (pid_ptr != NULL)
96 *pid_ptr = (uint32_t)pid;
97
98 return 0;
99 }
100
101 static uint32_t g_timer_pid;
102
get_timer_pid(void)103 uint32_t get_timer_pid(void)
104 {
105 return g_timer_pid;
106 }
107
get_drvmgr_pid(uint32_t * task_id)108 int32_t get_drvmgr_pid(uint32_t *task_id)
109 {
110 if (task_id == NULL) {
111 tloge("invalid task id\n");
112 return -1;
113 }
114
115 const struct drv_frame_info *drv_info_list = get_drv_frame_infos();
116 const uint32_t nr = get_drv_frame_nums();
117 uint32_t i;
118
119 for (i = 0; i < nr; i++) {
120 /* sizeof include '\0' */
121 if (strncmp(drv_info_list[i].drv_name, "drvmgr", sizeof("drvmgr")) == 0) {
122 *task_id = drv_info_list[i].pid;
123 return 0;
124 }
125 }
126
127 tloge("drvmgr not found\n");
128 return -1;
129 }
130
is_sys_task(uint32_t task_id)131 bool is_sys_task(uint32_t task_id)
132 {
133 const struct drv_frame_info *drv_info_list = get_drv_frame_infos();
134 const uint32_t nr = get_drv_frame_nums();
135 uint32_t i;
136
137 if (taskid_to_pid(task_id) == taskid_to_pid((uint32_t)RESERVED_SYSMGR_CRED) ||
138 (taskid_to_pid(task_id) == taskid_to_pid((uint32_t)g_timer_pid)))
139 return true;
140
141 for (i = 0; i < nr; i++) {
142 if (taskid_to_pid(task_id) == taskid_to_pid((uint32_t)drv_info_list[i].pid))
143 return true;
144 }
145 return false;
146 }
147
run_drv_frame_tasks(void)148 static int run_drv_frame_tasks(void)
149 {
150 uint32_t i;
151 struct drv_frame_info *drv_info_list = get_drv_frame_infos();
152 const uint32_t nr = get_drv_frame_nums();
153 int ret;
154 char *envp[] = { NULL };
155 char path[PATHNAME_MAX] = { 0 };
156 struct proc_mem_info info = { 0 };
157
158 for (i = 0; i < nr; i++) {
159 if (!drv_info_list[i].is_elf)
160 continue;
161 if (snprintf_s(path, PATHNAME_MAX, PATHNAME_MAX - 1, "/%s.elf", drv_info_list[i].drv_name) < 0) {
162 tloge("pack path failed\n");
163 return -1;
164 }
165
166 info.stack_size = drv_info_list[i].stack_size;
167 info.heap_size = drv_info_list[i].heap_size;
168 struct tee_uuid *drv_uuid = &drv_info_list[i].uuid;
169 ret = run_init_task(path, envp, &info, drv_uuid, &drv_info_list[i].pid);
170
171 (void)memset_s(path, PATHNAME_MAX, 0, PATHNAME_MAX);
172 if (ret != 0)
173 tloge("run drv: %s failed\n", drv_info_list[i].drv_name);
174 }
175
176 return 0;
177 }
178
init_main(void)179 int init_main(void)
180 {
181 int ret;
182 char *envp[] = { NULL };
183 struct proc_mem_info info = {0};
184
185 struct tee_uuid smc_uuid = TEE_SMC_MGR;
186 info.stack_size = SMCMGR_STACK_SIZE;
187 ret = run_init_task("/teesmcmgr.elf", envp, &info, &smc_uuid, NULL);
188 if (ret)
189 return ret;
190
191 ret = run_drv_frame_tasks();
192 if (ret != 0)
193 return ret;
194
195 return 0;
196 }
197
init_shell(void)198 void init_shell(void)
199 {
200 tloge("gtask: *ERROR* GTask exit unexpectedly\n");
201 exit(0);
202 while (true)
203 (void)sched_yield();
204 }
205