• 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 
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