• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "agent.h"
33 #include <securec.h>
34 #include "cmdmonitor.h"
35 #include "mailbox_mempool.h"
36 #include "smc.h"
37 #include "tc_client_sub_driver.h"
38 #include "tc_ns_log.h"
39 #include "teek_client_constants.h"
40 #include "tzdriver_compat.h"
41 
42 #define HASH_FILE_MAX_SIZE         (16 * 1024)
43 #define AGENT_BUFF_SIZE            (4 * 1024)
44 #define AGENT_MAX                  32
45 #define MAX_PATH_SIZE              512
46 #define PAGE_ORDER_RATIO           2
47 
48 /* kernel agent, TeeAgentKernelOps list */
49 static struct list_head g_teeAgentList;
50 
51 struct AgentControl {
52     spinlock_t lock;
53     struct list_head agentList; /* SmcEventData list */
54 };
55 static struct AgentControl g_agentControl;
56 
57 typedef struct TagCaInfo {
58     char path[MAX_PATH_SIZE];
59     uint32_t uid;
60     uint32_t agentId;
61 } CaInfo;
62 
63 static CaInfo g_allowedExtAgentCa[] = {
64     /* just for test in ENG version */
65 #ifdef DEF_ENG
66     {
67         "/vendor/bin/tee_test_agent",
68         0,
69         TEE_SECE_AGENT_ID,
70     },
71 
72 #endif
73 };
74 
IsAllowedAgentCa(const CaInfo * ca,bool checkAgentIdFlag)75 static int IsAllowedAgentCa(const CaInfo *ca, bool checkAgentIdFlag)
76 {
77     uint32_t i;
78     bool tmpCheckStatus = false;
79     CaInfo *tmpCa = g_allowedExtAgentCa;
80 
81     if (!checkAgentIdFlag) {
82         for (i = 0; i < ARRAY_SIZE(g_allowedExtAgentCa); i++) {
83             if ((memcmp(ca->path, tmpCa->path, MAX_PATH_SIZE) == EOK) &&
84                 (ca->uid == tmpCa->uid)) {
85                 return AGENT_SUCCESS;
86             }
87             tmpCa++;
88         }
89     } else {
90         for (i = 0; i < ARRAY_SIZE(g_allowedExtAgentCa); i++) {
91             tmpCheckStatus = ((memcmp(ca->path, tmpCa->path, MAX_PATH_SIZE) == EOK) &&
92                 (ca->uid == tmpCa->uid) && (ca->agentId == tmpCa->agentId));
93             if (tmpCheckStatus) {
94                 return AGENT_SUCCESS;
95             }
96             tmpCa++;
97         }
98     }
99     tlogd("ca-uid is %u, ca_path is %s, agent id is %x\n", ca->uid, ca->path, ca->agentId);
100     return AGENT_FALSE;
101 }
102 
GetCaPathAndUid(LosTaskCB * caTask,CaInfo * ca)103 static int GetCaPathAndUid(LosTaskCB *caTask, CaInfo *ca)
104 {
105     char *path = NULL;
106     int messageSize;
107     int ret = -1;
108     char *tPath = NULL;
109 
110     tPath = malloc(MAX_PATH_SIZE);
111     if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)tPath)) {
112         tloge("tPath malloc fail\n");
113         return -EPERM;
114     }
115 
116     path = GetProcessPath(caTask, tPath, MAX_PATH_SIZE);
117     if (IS_ERR_OR_NULL(path)) {
118         ret = -ENOMEM;
119         tloge("get process path failed\n");
120         goto END;
121     }
122 
123     messageSize = snprintf_s(ca->path, MAX_PATH_SIZE - 1, MAX_PATH_SIZE - 1, "%s", path);
124     ca->uid = GetTaskUid(caTask);
125     if (ca->uid < 0) {
126         free(tPath);
127         tPath = NULL;
128         return -EPERM;
129     }
130     tlogd("caTask->comm is %s, path is %s, ca uid is %u\n", caTask->taskName, path, ca->uid);
131 
132     if (messageSize > 0) {
133         ret = 0;
134     }
135 
136 END:
137     free(tPath);
138     tPath = NULL;
139     return ret;
140 }
141 
CheckExtAgentAccess(LosTaskCB * caTask)142 int CheckExtAgentAccess(LosTaskCB *caTask)
143 {
144     int ret;
145     CaInfo agentCa = { {0}, 0 };
146 
147     if (caTask == NULL) {
148         tloge("caTask is NULL.\n");
149         return -EPERM;
150     }
151 
152     ret = GetCaPathAndUid(caTask, &agentCa);
153     if (ret) {
154         tloge("get cp path or uid failed.\n");
155         return ret;
156     }
157 
158     ret = IsAllowedAgentCa(&agentCa, 0);
159     return ret;
160 }
161 
CheckExtAgentAccessWithAgentId(LosTaskCB * caTask,uint32_t agentId)162 int CheckExtAgentAccessWithAgentId(LosTaskCB *caTask,
163     uint32_t agentId)
164 {
165     int ret;
166     CaInfo agentCa = {"", 0, 0};
167 
168     if (caTask == NULL) {
169         tloge("caTask is NULL\n");
170         return -EPERM;
171     }
172 
173     ret = GetCaPathAndUid(caTask, &agentCa);
174     if (ret) {
175         tloge("get cp path or uid failed\n");
176         return ret;
177     }
178     agentCa.agentId = agentId;
179     ret = IsAllowedAgentCa(&agentCa, 1);
180     return ret;
181 }
182 
CheckNativeHashParam(uint8_t * inBuf,uint32_t * bufLen)183 static int CheckNativeHashParam(uint8_t *inBuf, uint32_t *bufLen)
184 {
185     if (inBuf == NULL) {
186         return AGENT_FALSE;
187     }
188     if (TcNsGetUid() != 0) {
189         tloge("It is a fake tee agent\n");
190         return -EACCES;
191     }
192     if (copy_from_user(bufLen, inBuf, sizeof(*bufLen))) {
193         tloge("copy from user failed\n");
194         return -EFAULT;
195     }
196     if (*bufLen > HASH_FILE_MAX_SIZE) {
197         tloge("ERROR: file size[0x%x] too big\n", *bufLen);
198         return AGENT_FALSE;
199     }
200     return 0;
201 }
202 
TcNsSetNativeHash(unsigned long arg,unsigned int cmdId)203 int TcNsSetNativeHash(unsigned long arg, unsigned int cmdId)
204 {
205     int ret;
206     TcNsSmcCmd smcCmd = { {0}, 0 };
207     uint8_t *inBuf = (uint8_t *)(uintptr_t)arg;
208     uint32_t bufLen = 0;
209     uint8_t *bufToTee = NULL;
210     struct MbCmdPack *mbPack = NULL;
211 
212     ret = CheckNativeHashParam(inBuf, &bufLen);
213     if (ret) {
214         return ret;
215     }
216 
217     bufToTee = MailboxAlloc(bufLen, 0);
218     if (bufToTee == NULL) {
219         tloge("failed to alloc memory!\n");
220         return AGENT_FALSE;
221     }
222     if (copy_from_user(bufToTee, inBuf, bufLen)) {
223         tloge("copy from user failed\n");
224         MailboxFree(bufToTee);
225         return -EFAULT;
226     }
227     mbPack = MailboxAllocCmdPack();
228     if (mbPack == NULL) {
229         tloge("alloc cmd pack failed\n");
230         MailboxFree(bufToTee);
231         return -ENOMEM;
232     }
233     mbPack->operation.paramTypes = TEE_PARAM_TYPE_VALUE_INPUT |
234         (TEE_PARAM_TYPE_VALUE_INPUT << TEE_PARAM_NUM);
235     mbPack->operation.params[TEE_PARAM_ONE].value.a =
236         (unsigned int)LOS_PaddrQuery(bufToTee);
237     mbPack->operation.params[TEE_PARAM_ONE].value.b = 0;
238     mbPack->operation.params[TEE_PARAM_TWO].value.a = bufLen;
239     smcCmd.globalCmd = true;
240     smcCmd.cmdId = cmdId;
241     smcCmd.operationPhys = LOS_PaddrQuery(&mbPack->operation);
242     smcCmd.operationHphys = 0;
243     ret = TcNsSmc(&smcCmd);
244     MailboxFree(bufToTee);
245     MailboxFree(mbPack);
246     bufToTee = NULL;
247     mbPack = NULL;
248     return ret;
249 }
250 
TcNsLateInit(unsigned long arg)251 int TcNsLateInit(unsigned long arg)
252 {
253     int ret;
254     TcNsSmcCmd smcCmd = { {0}, 0 };
255     uint32_t index = (uint32_t)arg; // index is uint32, no truncate risk
256     struct MbCmdPack *mbPack = NULL;
257 
258     if (TcNsGetUid() != 0) {
259         tloge("It is a fake tee agent\n");
260         return -EACCES;
261     }
262 
263     mbPack = MailboxAllocCmdPack();
264     if (mbPack == NULL) {
265         tloge("alloc cmd pack failed\n");
266         return -ENOMEM;
267     }
268 
269     mbPack->operation.paramTypes = TEE_PARAM_TYPE_VALUE_INPUT;
270     mbPack->operation.params[TEE_PARAM_ONE].value.a = index;
271 
272     smcCmd.globalCmd = true;
273     smcCmd.cmdId = GLOBAL_CMD_ID_LATE_INIT;
274     smcCmd.operationPhys = LOS_PaddrQuery(&mbPack->operation);
275     smcCmd.operationHphys = 0;
276 
277     ret = TcNsSmc(&smcCmd);
278 
279     MailboxFree(mbPack);
280     mbPack = NULL;
281 
282     return ret;
283 }
284 
SendEventResponseSingle(const TcNsDevFile * devFile)285 void SendEventResponseSingle(const TcNsDevFile *devFile)
286 {
287     struct SmcEventData *eventData = NULL;
288     struct SmcEventData *tmp = NULL;
289     unsigned long flags;
290     unsigned int agentId = 0;
291 
292     if (devFile == NULL) {
293         return;
294     }
295 
296     spin_lock_irqsave(&g_agentControl.lock, flags);
297     list_for_each_entry_safe(eventData, tmp, &g_agentControl.agentList, head) {
298         if (eventData->owner == devFile) {
299             agentId = eventData->agentId;
300             break;
301         }
302     }
303     spin_unlock_irqrestore(&g_agentControl.lock, flags);
304     SendEventResponse(agentId);
305     return;
306 }
307 
FindEventControl(unsigned int agentId)308 struct SmcEventData *FindEventControl(unsigned int agentId)
309 {
310     struct SmcEventData *eventData = NULL;
311     struct SmcEventData *tmpData = NULL;
312     unsigned long flags;
313 
314     spin_lock_irqsave(&g_agentControl.lock, flags);
315     list_for_each_entry(eventData, &g_agentControl.agentList, head) {
316         if (eventData->agentId == agentId) {
317             tmpData = eventData;
318             GetAgentEvent(eventData);
319             break;
320         }
321     }
322     spin_unlock_irqrestore(&g_agentControl.lock, flags);
323 
324     return tmpData;
325 }
326 
UnmapAgentBuffer(struct SmcEventData * eventData)327 static void UnmapAgentBuffer(struct SmcEventData *eventData)
328 {
329     if (eventData == NULL) {
330         tloge("event data is NULL\n");
331         return;
332     }
333 
334     if (IS_ERR_OR_NULL(eventData->agentBuffUser)) {
335         return;
336     }
337 
338     if (LOS_UnMMap((VADDR_T)eventData->agentBuffUser, eventData->agentBuffSize) != 0) {
339         tloge("unmap failed\n");
340     }
341 
342     eventData->agentBuffUser = NULL;
343 }
344 
FreeEventControl(unsigned int agentId)345 static void FreeEventControl(unsigned int agentId)
346 {
347     struct SmcEventData *eventData = NULL;
348     struct SmcEventData *tmpEvent = NULL;
349     unsigned long flags;
350     bool find = false;
351 
352     spin_lock_irqsave(&g_agentControl.lock, flags);
353     list_for_each_entry_safe(eventData, tmpEvent, &g_agentControl.agentList, head) {
354         if (eventData->agentId == agentId) {
355             list_del(&eventData->head);
356             find = true;
357             break;
358         }
359     }
360     spin_unlock_irqrestore(&g_agentControl.lock, flags);
361 
362     if (find) {
363         UnmapAgentBuffer(eventData);
364 
365         MailboxFree(eventData->agentBuffKernel);
366         eventData->agentBuffKernel = NULL;
367         PutAgentEvent(eventData);
368     }
369 }
370 
InitAgentContext(unsigned int agentId,const TcNsSmcCmd * smcCmd,struct SmcEventData ** eventData)371 static int InitAgentContext(unsigned int agentId,
372     const TcNsSmcCmd *smcCmd,
373     struct SmcEventData **eventData)
374 {
375     if (eventData == NULL) {
376         return TEEC_ERROR_GENERIC;
377     }
378     *eventData = FindEventControl(agentId);
379     if (*eventData == NULL) {
380         tloge("agent %u not exist\n", agentId);
381         return TEEC_ERROR_GENERIC;
382     }
383     tlogd("AgentProcessWork(0x%x): returning client command", agentId);
384 
385 #ifndef CONFIG_TEE_SMP
386     /* Keep a copy of the SMC cmd to return to TEE when the work is done */
387     if (memcpy_s(&((*eventData)->cmd), sizeof((*eventData)->cmd), smcCmd, sizeof(*smcCmd))) {
388         tloge("failed to memcpy_s smcCmd\n");
389         PutAgentEvent(*eventData);
390         return TEEC_ERROR_GENERIC;
391     }
392     ISB;
393     DSB;
394 #endif
395     return TEEC_SUCCESS;
396 }
397 
WaitAgentResponse(struct SmcEventData * eventData)398 static int WaitAgentResponse(struct SmcEventData *eventData)
399 {
400     int ret = TEEC_SUCCESS;
401     bool answered = true;
402 
403     do {
404         answered = true;
405         int r = wait_event_interruptible_timeout(eventData->caPendingWq,
406             atomic_read(&eventData->caRun), (long)(RESLEEP_TIMEOUT * HZ));
407         if (r != 0) {
408             continue;
409         }
410         /* if no kill signal, just resleep before agent wake */
411         if (SigkillPending(OsCurrTaskGet()) == 0) {
412             answered = false;
413         } else {
414             tloge("CA is killed, no need to wait agent response\n");
415             eventData->retFlag = 0;
416             ret = TEEC_ERROR_GENERIC;
417         }
418     } while (!answered);
419 
420     return ret;
421 }
422 
AgentProcessWork(const TcNsSmcCmd * smcCmd,unsigned int agentId)423 int AgentProcessWork(const TcNsSmcCmd *smcCmd, unsigned int agentId)
424 {
425     struct SmcEventData *eventData = NULL;
426     int ret = 0;
427 
428     if (smcCmd == NULL) {
429         tloge("smcCmd is null\n");
430         return TEEC_ERROR_GENERIC;
431     }
432     if (InitAgentContext(agentId, smcCmd, &eventData) != TEEC_SUCCESS) {
433         return TEEC_ERROR_GENERIC;
434     }
435 
436 #ifdef CONFIG_TEE_SMP
437     if (atomic_read(&eventData->agentReady) == AGENT_CRASHED) {
438         tloge("agent 0x%x is killed and restarting\n", agentId);
439         PutAgentEvent(eventData);
440         return TEEC_ERROR_GENERIC;
441     }
442     eventData->retFlag = 1;
443     /* Wake up the agent that will process the command */
444     tlogd("AgentProcessWork: wakeup the agent");
445     wake_up(&eventData->waitEventWq);
446     tlogd("agent 0x%x request, goto sleep, pe->run=%d\n",
447           agentId, atomic_read(&eventData->caRun));
448 
449     ret = WaitAgentResponse(eventData);
450     atomic_set(&eventData->caRun, 0);
451 #endif
452 
453     PutAgentEvent(eventData);
454     /*
455      * when agent work is done, reset cmd monitor time
456      * add agent call count, cause it's a new smc cmd.
457      */
458     CmdMonitorResetContext();
459     return ret;
460 }
461 
IsAgentAlive(unsigned int agentId)462 int IsAgentAlive(unsigned int agentId)
463 {
464     struct SmcEventData *eventData = NULL;
465 
466     eventData = FindEventControl(agentId);
467     if (eventData != NULL) {
468         PutAgentEvent(eventData);
469         return AGENT_ALIVE;
470     } else {
471         return AGENT_DEAD;
472     }
473 }
474 
TcNsWaitEvent(unsigned int agentId)475 int TcNsWaitEvent(unsigned int agentId)
476 {
477     int ret = -EINVAL;
478     struct SmcEventData *eventData = NULL;
479 
480     if ((TcNsGetUid() != 0) &&
481         CheckExtAgentAccessWithAgentId(OsCurrTaskGet(), agentId)) {
482         tloge("It is a fake tee agent\n");
483         return -EACCES;
484     }
485     tlogd("agent %u waits for command\n", agentId);
486     eventData = FindEventControl(agentId);
487     if (eventData != NULL) {
488         /* only when agent wait event, it's in ready state to work */
489         atomic_set(&(eventData->agentReady), AGENT_READY);
490         ret = wait_event_interruptible(eventData->waitEventWq, eventData->retFlag);
491         PutAgentEvent(eventData);
492     }
493 
494     return ret;
495 }
496 
TcNsSyncSysTime(const TcNsClientTime * tcNsTime)497 int TcNsSyncSysTime(const TcNsClientTime *tcNsTime)
498 {
499     TcNsSmcCmd smcCmd = { {0}, 0 };
500     int ret;
501     TcNsClientTime tmpTcNsTime = {0};
502     struct MbCmdPack *mbPack = NULL;
503 
504     if (tcNsTime == NULL) {
505         tloge("tcNsTime is NULL input buffer\n");
506         return -EINVAL;
507     }
508     if (TcNsGetUid() != 0) {
509         tloge("It is a fake tee agent\n");
510         return TEEC_ERROR_GENERIC;
511     }
512     if (copy_from_user(&tmpTcNsTime, tcNsTime,
513         sizeof(tmpTcNsTime))) {
514         tloge("copy from user failed\n");
515         return -EFAULT;
516     }
517 
518     mbPack = MailboxAllocCmdPack();
519     if (mbPack == NULL) {
520         tloge("alloc mb pack failed\n");
521         return -ENOMEM;
522     }
523 
524     smcCmd.globalCmd = true;
525     smcCmd.cmdId = GLOBAL_CMD_ID_ADJUST_TIME;
526     smcCmd.errOrigin = tmpTcNsTime.seconds;
527     smcCmd.retVal = (int)tmpTcNsTime.millis;
528 
529     ret = TcNsSmc(&smcCmd);
530     if (ret) {
531         tloge("tee adjust time failed, return error %x\n", ret);
532     }
533 
534     MailboxFree(mbPack);
535     mbPack = NULL;
536 
537     return ret;
538 }
539 
CheckForSendEventResponse(unsigned int agentId)540 static struct SmcEventData *CheckForSendEventResponse(unsigned int agentId)
541 {
542     struct SmcEventData *eventData = FindEventControl(agentId);
543     bool tmpCheckStatus = false;
544 
545     if (eventData == NULL) {
546         tloge("Can't get eventData\n");
547         return NULL;
548     }
549     tmpCheckStatus = ((TcNsGetUid() != 0) &&
550         CheckExtAgentAccessWithAgentId(OsCurrTaskGet(), agentId));
551     if (tmpCheckStatus) {
552         tloge("It is a fake tee agent\n");
553         PutAgentEvent(eventData);
554         return NULL;
555     }
556     return eventData;
557 }
558 
ProcessSendEventResponse(struct SmcEventData * eventData)559 static int ProcessSendEventResponse(struct SmcEventData *eventData)
560 {
561     int ret = 0;
562     if (eventData->retFlag) {
563         eventData->retFlag = 0;
564         /* Send the command back to the TA session waiting for it */
565 #ifdef CONFIG_TEE_SMP
566         tlogd("agent wakeup ca\n");
567         atomic_set(&eventData->caRun, 1);
568         /* make sure reset working_ca before wakeup CA */
569         wake_up(&eventData->caPendingWq);
570         ret = 0;
571 #else
572         ret = TcNsPostSmc(&eventData->cmd);
573 #endif
574     }
575     return ret;
576 }
577 
TcNsSendEventResponse(unsigned int agentId)578 int TcNsSendEventResponse(unsigned int agentId)
579 {
580     struct SmcEventData *eventData = NULL;
581     int ret;
582 
583     eventData = CheckForSendEventResponse(agentId);
584     if (eventData == NULL) {
585         tlogd("agent %u pre-check failed\n", agentId);
586         return -1;
587     }
588     tlogd("agent %u sends answer back\n", agentId);
589     ret = ProcessSendEventResponse(eventData);
590     PutAgentEvent(eventData);
591     return ret;
592 }
593 
SendEventResponse(unsigned int agentId)594 void SendEventResponse(unsigned int agentId)
595 {
596     struct SmcEventData *eventData = FindEventControl(agentId);
597     int ret;
598 
599     if (eventData == NULL) {
600         tloge("Can't get eventData\n");
601         return;
602     }
603 
604     tloge("agent 0x%x sends answer back\n", agentId);
605     atomic_set(&eventData->agentReady, AGENT_CRASHED);
606     ret = ProcessSendEventResponse(eventData);
607     PutAgentEvent(eventData);
608     if (ret) {
609         tloge("agent 0x%x sends answer back failed\n", agentId);
610     }
611     return;
612 }
613 
InitEventDataForRestart(TcNsDevFile * devFile,struct SmcEventData * eventData)614 static void InitEventDataForRestart(TcNsDevFile *devFile,
615     struct SmcEventData *eventData)
616 {
617     eventData->retFlag = 0;
618     eventData->owner = devFile;
619     atomic_set(&eventData->agentReady, AGENT_REGISTERED);
620     init_waitqueue_head(&(eventData->waitEventWq));
621     init_waitqueue_head(&(eventData->sendResponseWq));
622 #ifdef CONFIG_TEE_SMP
623     init_waitqueue_head(&(eventData->caPendingWq));
624     atomic_set(&(eventData->caRun), 0);
625 #endif
626     return;
627 }
628 
AllocAndInitEventData(TcNsDevFile * devFile,struct SmcEventData ** eventData,unsigned int agentId,UINTPTR * agentBuff,uint32_t agentBuffSize)629 static int AllocAndInitEventData(TcNsDevFile *devFile,
630     struct SmcEventData **eventData, unsigned int agentId,
631     UINTPTR *agentBuff, uint32_t agentBuffSize)
632 {
633     *agentBuff = (UINTPTR)MailboxAlloc(agentBuffSize, MB_FLAG_ZERO);
634     if (*agentBuff == 0) {
635         tloge("alloc agent buff failed\n");
636         return -ENOMEM;
637     }
638     *eventData = calloc(1, sizeof(**eventData));
639     if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)(*eventData))) {
640         MailboxFree((void *)*agentBuff);
641         *agentBuff = 0;
642         *eventData = NULL;
643         tloge("alloc event data failed\n");
644         return -ENOMEM;
645     }
646     (*eventData)->agentId = agentId;
647     (*eventData)->retFlag = 0;
648     (*eventData)->agentBuffKernel = (void *)*agentBuff;
649     (*eventData)->agentBuffSize = agentBuffSize;
650     (*eventData)->owner = devFile;
651     atomic_set(&(*eventData)->agentReady, AGENT_REGISTERED);
652     init_waitqueue_head(&(*eventData)->waitEventWq);
653     init_waitqueue_head(&(*eventData)->sendResponseWq);
654     INIT_LIST_HEAD(&(*eventData)->head);
655 #ifdef CONFIG_TEE_SMP
656     init_waitqueue_head(&(*eventData)->caPendingWq);
657     atomic_set(&(*eventData)->caRun, 0);
658 #endif
659     return TEEC_SUCCESS;
660 }
661 
IsBuiltInAgent(unsigned int agentId)662 static bool IsBuiltInAgent(unsigned int agentId)
663 {
664     bool checkValue = false;
665 
666     checkValue = ((agentId == AGENT_FS_ID) ||
667         (agentId == AGENT_MISC_ID) ||
668         (agentId == AGENT_SOCKET_ID) ||
669         (agentId == SECFILE_LOAD_AGENT_ID));
670     return checkValue;
671 }
672 
AgentBufferMap(unsigned long buffer,uint32_t size)673 static unsigned long AgentBufferMap(unsigned long buffer, uint32_t size)
674 {
675     int ret;
676 
677     if (!IS_PAGE_ALIGNED(buffer) || !IS_PAGE_ALIGNED(size)) {
678         return -EFAULT;
679     }
680 
681     vaddr_t userAddr = LOS_MMap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
682     if (IS_ERR_OR_NULL(userAddr)) {
683         goto ERR_OUT;
684     }
685 
686     for (int i = 0; i < (size >> PAGE_SHIFT); i++) {
687         LosVmPage *page = LOS_VmPageGet(buffer + PAGE_SIZE * i);
688         if (page == NULL) {
689             goto ERR_OUT;
690         }
691         LOS_AtomicInc(&page->refCounts);
692     }
693 
694     // agent buffer page is physically contiguous, so can entirety mmap
695     ret = remap_pfn_range(userAddr, buffer >> PAGE_SHIFT, size,
696         VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE);
697     if (ret) {
698         tloge("remap agent buffer failed, err=%d", ret);
699         goto ERR_OUT;
700     }
701     return userAddr;
702 
703 ERR_OUT:
704     if (LOS_UnMMap(userAddr, size) != 0) {
705         tloge("munmap failed\n");
706     }
707     return -EFAULT;
708 }
709 
IsValidAgent(unsigned int agentId,unsigned int bufferSize,bool userAgent)710 static bool IsValidAgent(unsigned int agentId,
711     unsigned int bufferSize, bool userAgent)
712 {
713     if (TcNsGetUid() != 0 &&
714         CheckExtAgentAccessWithAgentId(OsCurrTaskGet(), agentId)) {
715         tloge("It is a fake tee agent\n");
716         return false;
717     }
718 
719     if (userAgent && (bufferSize > SZ_4K)) {
720         tloge("size: %u of user agent's shared mem is invalid\n",
721             bufferSize);
722         return false;
723     }
724     return true;
725 }
726 
IsAgentAlreadyExist(unsigned int agentId,struct SmcEventData ** eventData,bool * findFlag)727 static void IsAgentAlreadyExist(unsigned int agentId,
728     struct SmcEventData **eventData, bool *findFlag)
729 {
730     unsigned long flags;
731     bool flag = false;
732     struct SmcEventData *agentNode = NULL;
733 
734     spin_lock_irqsave(&g_agentControl.lock, flags);
735     list_for_each_entry(agentNode, &g_agentControl.agentList, head) {
736         if (agentNode->agentId == agentId) {
737             flag = true;
738             GetAgentEvent(agentNode);
739             break;
740         }
741     }
742     spin_unlock_irqrestore(&g_agentControl.lock, flags);
743     *findFlag = flag;
744     if (flag == true) {
745         *eventData = agentNode;
746     }
747     return;
748 }
749 
AddEventNodeToList(struct SmcEventData * eventData)750 static void AddEventNodeToList(struct SmcEventData *eventData)
751 {
752     unsigned long flags;
753     spin_lock_irqsave(&g_agentControl.lock, flags);
754     list_add_tail(&eventData->head, &g_agentControl.agentList);
755     atomic_set(&eventData->usage, 1);
756     spin_unlock_irqrestore(&g_agentControl.lock, flags);
757     return;
758 }
759 
RegisterAgentToTee(unsigned int agentId,UINTPTR agentBuff,uint32_t agentBuffSize)760 static int RegisterAgentToTee(unsigned int agentId, UINTPTR agentBuff,
761     uint32_t agentBuffSize)
762 {
763     int ret;
764     TcNsSmcCmd smcCmd = { {0}, 0 };
765     struct MbCmdPack *mbPack = NULL;
766 
767     mbPack = MailboxAllocCmdPack();
768     if (mbPack == NULL) {
769         tloge("alloc mailbox failed\n");
770         return AGENT_FALSE;
771     }
772 
773     mbPack->operation.paramTypes = TEE_PARAM_TYPE_VALUE_INPUT |
774         (TEE_PARAM_TYPE_VALUE_INPUT << TEE_PARAM_NUM);
775     mbPack->operation.params[TEE_PARAM_ONE].value.a =
776         LOS_PaddrQuery((void *)agentBuff);
777     mbPack->operation.params[TEE_PARAM_ONE].value.b = 0;
778     mbPack->operation.params[TEE_PARAM_TWO].value.a = agentBuffSize;
779     smcCmd.globalCmd = true;
780     smcCmd.cmdId = GLOBAL_CMD_ID_REGISTER_AGENT;
781     smcCmd.operationPhys = LOS_PaddrQuery(&mbPack->operation);
782     smcCmd.operationHphys = 0;
783     smcCmd.agentId = agentId;
784 
785     ret = TcNsSmc(&smcCmd);
786     /* mbPack should be released no matter what ret is */
787     MailboxFree(mbPack);
788     mbPack = NULL;
789 
790     return ret;
791 }
792 
ReleaseAgentResource(bool findFlag,struct SmcEventData * eventData,UINTPTR agentBuff)793 static void ReleaseAgentResource(bool findFlag, struct SmcEventData *eventData, UINTPTR agentBuff)
794 {
795     if (findFlag) {
796         PutAgentEvent(eventData); // match get action
797     } else {
798         free(eventData); // here eventData can never be NULL;
799     }
800 
801     if (agentBuff != 0) {
802         MailboxFree((void *)agentBuff);
803     }
804 }
805 
TcNsRegisterAgent(TcNsDevFile * devFile,unsigned int agentId,unsigned int bufferSize,void ** buffer,bool userAgent)806 int TcNsRegisterAgent(TcNsDevFile *devFile, unsigned int agentId,
807     unsigned int bufferSize, void **buffer, bool userAgent)
808 {
809     struct SmcEventData *eventData = NULL;
810     bool findFlag = false;
811     UINTPTR agentBuff = 0;
812     uint32_t sizeAlign;
813 
814     if (buffer == NULL || devFile == NULL) {
815         return TEEC_ERROR_GENERIC;
816     }
817 
818     if (IsValidAgent(agentId, bufferSize, userAgent) != true) {
819         return TEEC_ERROR_GENERIC;
820     }
821 
822     sizeAlign = ALIGN(bufferSize, SZ_4K);
823 
824     IsAgentAlreadyExist(agentId, &eventData, &findFlag);
825     /*
826      * We find the agent's eventData aready in agentList, it indicate agent
827      * didn't unregister normally, so the eventData will be reused.
828      */
829     if (findFlag) {
830         InitEventDataForRestart(devFile, eventData);
831     } else {
832         if (AllocAndInitEventData(devFile, &eventData,
833             agentId, &agentBuff, sizeAlign) != TEEC_SUCCESS) {
834             return TEEC_ERROR_GENERIC;
835         }
836     }
837 
838     /* if the agent is first time or restart register, both case need a remap */
839     if (userAgent) {
840         eventData->agentBuffUser = (void *)(uintptr_t)AgentBufferMap(
841             LOS_PaddrQuery(eventData->agentBuffKernel),
842             eventData->agentBuffSize);
843         if (IS_ERR(eventData->agentBuffUser)) {
844             tloge("vm map agent buffer failed\n");
845             goto RELEASE_RSRC;
846         }
847         *buffer = eventData->agentBuffUser;
848     } else {
849         *buffer = eventData->agentBuffKernel;
850     }
851 
852     /* findFlag is false means it's a new agent register */
853     if (findFlag == false) {
854         /* Obtain share memory which is released in TcNsUnregisterAgent */
855         if (RegisterAgentToTee(agentId, agentBuff, sizeAlign) != TEEC_SUCCESS) {
856             UnmapAgentBuffer(eventData);
857             goto RELEASE_RSRC;
858         }
859         AddEventNodeToList(eventData);
860     }
861     if (findFlag) {
862         PutAgentEvent(eventData); // match get action
863     }
864     return TEEC_SUCCESS;
865 RELEASE_RSRC:
866     ReleaseAgentResource(findFlag, eventData, agentBuff);
867     return TEEC_ERROR_GENERIC;
868 }
869 
CheckForUnregisterAgent(unsigned int agentId)870 static int CheckForUnregisterAgent(unsigned int agentId)
871 {
872     bool checkValue = false;
873 
874     checkValue = (TcNsGetUid() != 0);
875     if (checkValue) {
876         tloge("It is a fake tee agent\n");
877         return TEEC_ERROR_GENERIC;
878     }
879 
880     checkValue = (IsBuiltInAgent(agentId) ||
881         agentId == TEE_RPMB_AGENT_ID);
882     if (checkValue) {
883         tloge("agent: 0x%x is not allowed to unregister\n", agentId);
884         return TEEC_ERROR_GENERIC;
885     }
886     return TEEC_SUCCESS;
887 }
888 
IsThirdPartyAgent(unsigned int agentId)889 static bool IsThirdPartyAgent(unsigned int agentId)
890 {
891     uint32_t i;
892     CaInfo *tmpCa = g_allowedExtAgentCa;
893 
894     for (i = 0; i < ARRAY_SIZE(g_allowedExtAgentCa); i++) {
895         if (tmpCa->agentId == agentId) {
896             return true;
897         }
898         tmpCa++;
899     }
900 
901     return false;
902 }
903 
TcNsUnregisterAgent(unsigned int agentId)904 int TcNsUnregisterAgent(unsigned int agentId)
905 {
906     struct SmcEventData *eventData = NULL;
907     int ret;
908     TcNsSmcCmd smcCmd = { {0}, 0 };
909     struct MbCmdPack *mbPack = NULL;
910 
911     if (CheckForUnregisterAgent(agentId) != TEEC_SUCCESS) {
912         return TEEC_ERROR_GENERIC;
913     }
914     /* if third party itself trigger unregister agent
915      * we allow them to unregister.
916      */
917     if (IsThirdPartyAgent(agentId) != true) {
918         tloge("invalid agent id: 0x%x\n", agentId);
919         return TEEC_ERROR_GENERIC;
920     }
921 
922     eventData = FindEventControl(agentId);
923     if (eventData == NULL || eventData->agentBuffKernel == NULL) {
924         tloge("agent is not found or kernelAddr is not allocated\n");
925         return TEEC_ERROR_GENERIC;
926     }
927 
928     mbPack = MailboxAllocCmdPack();
929     if (mbPack == NULL) {
930         tloge("alloc mailbox failed\n");
931         PutAgentEvent(eventData);
932         return TEEC_ERROR_GENERIC;
933     }
934     mbPack->operation.paramTypes = TEE_PARAM_TYPE_VALUE_INPUT |
935         (TEE_PARAM_TYPE_VALUE_INPUT << TEE_PARAM_NUM);
936     mbPack->operation.params[TEE_PARAM_ONE].value.a =
937         LOS_PaddrQuery(eventData->agentBuffKernel);
938 
939     mbPack->operation.params[TEE_PARAM_ONE].value.b = 0;
940     mbPack->operation.params[TEE_PARAM_TWO].value.a = SZ_4K;
941     smcCmd.globalCmd = true;
942     smcCmd.cmdId = GLOBAL_CMD_ID_UNREGISTER_AGENT;
943     smcCmd.operationPhys = LOS_PaddrQuery(&mbPack->operation);
944     smcCmd.operationHphys = 0;
945 
946     smcCmd.agentId = agentId;
947     tlogd("Unregistering agent 0x%x\n", agentId);
948     ret = TcNsSmc(&smcCmd);
949     if (ret == TEEC_SUCCESS) {
950         FreeEventControl(agentId);
951     }
952     PutAgentEvent(eventData);
953     MailboxFree(mbPack);
954     return ret;
955 }
956 
IsSystemAgent(const TcNsDevFile * devFile)957 bool IsSystemAgent(const TcNsDevFile *devFile)
958 {
959     struct SmcEventData *eventData = NULL;
960     struct SmcEventData *tmp = NULL;
961     bool systemAgent = false;
962     unsigned long flags;
963 
964     if (devFile == NULL) {
965         return systemAgent;
966     }
967 
968     spin_lock_irqsave(&g_agentControl.lock, flags);
969     list_for_each_entry_safe(eventData, tmp, &g_agentControl.agentList, head) {
970         if (eventData->owner == devFile) {
971             systemAgent = true;
972             break;
973         }
974     }
975     spin_unlock_irqrestore(&g_agentControl.lock, flags);
976 
977     return systemAgent;
978 }
979 
SendCrashedEventResponseAll(const TcNsDevFile * devFile)980 void SendCrashedEventResponseAll(const TcNsDevFile *devFile)
981 {
982     struct SmcEventData *eventData = NULL;
983     struct SmcEventData *tmp = NULL;
984     unsigned int agentId[AGENT_MAX] = {0};
985     unsigned int i = 0;
986     unsigned long flags;
987 
988     spin_lock_irqsave(&g_agentControl.lock, flags);
989     list_for_each_entry_safe(eventData, tmp, &g_agentControl.agentList,
990         head) {
991         if ((eventData->owner == devFile) && (i < AGENT_MAX)) {
992             agentId[i++] = eventData->agentId;
993         }
994     }
995     spin_unlock_irqrestore(&g_agentControl.lock, flags);
996 
997     for (i = 0; i < AGENT_MAX; i++) {
998         if (agentId[i]) {
999             SendEventResponse(agentId[i]);
1000         }
1001     }
1002 
1003     return;
1004 }
1005 
TeeAgentClearDevOwner(const TcNsDevFile * devFile)1006 void TeeAgentClearDevOwner(const TcNsDevFile *devFile)
1007 {
1008     struct SmcEventData *eventData = NULL;
1009     struct SmcEventData *tmp = NULL;
1010     unsigned long flags;
1011 
1012     spin_lock_irqsave(&g_agentControl.lock, flags);
1013     list_for_each_entry_safe(eventData, tmp, &g_agentControl.agentList, head) {
1014         if (eventData->owner == devFile) {
1015             eventData->owner = NULL;
1016             break;
1017         }
1018     }
1019     spin_unlock_irqrestore(&g_agentControl.lock, flags);
1020     return;
1021 }
1022 
DefTeeAgentWork(UINTPTR instance,int len)1023 static int DefTeeAgentWork(UINTPTR instance, int len)
1024 {
1025     int ret = 0;
1026     struct TeeAgentKernelOps *agentInstance = NULL;
1027 
1028     if (len != sizeof(struct TeeAgentKernelOps)) {
1029         return ret;
1030     }
1031 
1032     agentInstance = (struct TeeAgentKernelOps *)instance;
1033     while (!KthreadShouldStop()) {
1034         tlogd("%s agent loop++++\n", agentInstance->agentName);
1035         ret = TcNsWaitEvent(agentInstance->agentId);
1036         if (ret) {
1037             tloge("%s wait event fail\n",
1038                 agentInstance->agentName);
1039             break;
1040         }
1041         if (agentInstance->teeAgentWork != NULL) {
1042             ret = agentInstance->teeAgentWork(agentInstance);
1043             if (ret) {
1044                 tloge("%s agent work fail\n", agentInstance->agentName);
1045             }
1046         }
1047         ret = TcNsSendEventResponse(agentInstance->agentId);
1048         if (ret) {
1049             tloge("%s send event response fail\n",
1050                 agentInstance->agentName);
1051             break;
1052         }
1053         tlogd("%s agent loop----\n", agentInstance->agentName);
1054     }
1055 
1056     return ret;
1057 }
1058 
DefTeeAgentRun(struct TeeAgentKernelOps * agentInstance)1059 static int DefTeeAgentRun(struct TeeAgentKernelOps *agentInstance)
1060 {
1061     TcNsDevFile dev = {0};
1062     int ret;
1063     char agentName[OS_TCB_NAME_LEN] = {0};
1064 
1065     /* 1. Register agent buffer to TEE */
1066     ret = TcNsRegisterAgent(&dev, agentInstance->agentId,
1067         agentInstance->agentBuffSize, &agentInstance->agentBuff, false);
1068     if (ret) {
1069         tloge("register agent buffer fail,ret =0x%x\n", ret);
1070         ret = -1;
1071         goto OUT;
1072     }
1073 
1074     /* 2. Create thread to run agent */
1075     ret = sprintf_s(agentName, OS_TCB_NAME_LEN, "agent_%s", agentInstance->agentName);
1076     if (ret == -1) {
1077         goto OUT;
1078     }
1079     agentInstance->agentThread =
1080         KthreadRun(DefTeeAgentWork, (void *)agentInstance, sizeof(struct TeeAgentKernelOps), agentName);
1081     if (IS_ERR_OR_NULL(agentInstance->agentThread)) {
1082         tloge("kthread create fail\n");
1083         ret = PTR_ERR(agentInstance->agentThread);
1084         agentInstance->agentThread = NULL;
1085         goto OUT;
1086     }
1087     return AGENT_SUCCESS;
1088 
1089 OUT:
1090     return ret;
1091 }
1092 
DefTeeAgentStop(struct TeeAgentKernelOps * agentInstance)1093 static int DefTeeAgentStop(struct TeeAgentKernelOps *agentInstance)
1094 {
1095     int ret;
1096 
1097     if (TcNsSendEventResponse(agentInstance->agentId)) {
1098         tloge("failed to send response for agent %u\n",
1099             agentInstance->agentId);
1100     }
1101 
1102     ret = TcNsUnregisterAgent(agentInstance->agentId);
1103     if (ret != 0) {
1104         tloge("failed to unregister agent %u\n",
1105             agentInstance->agentId);
1106     }
1107     if (!IS_ERR_OR_NULL(agentInstance->agentThread)) {
1108         KthreadStop(agentInstance->agentThread);
1109     }
1110 
1111     return AGENT_SUCCESS;
1112 }
1113 
1114 /* default kernel agent ops */
1115 static struct TeeAgentKernelOps g_defTeeAgentOps = {
1116     .agentName = "default",
1117     .agentId = 0,
1118     .teeAgentInit = NULL,
1119     .teeAgentRun = DefTeeAgentRun,
1120     .teeAgentWork = NULL,
1121     .teeAgentExit = NULL,
1122     .teeAgentStop = DefTeeAgentStop,
1123     .teeAgentCrashWork = NULL,
1124     .agentBuffSize = PAGE_SIZE,
1125     .list = LINUX_LIST_HEAD_INIT(g_defTeeAgentOps.list)
1126 };
1127 
TeeAgentKernelInit(void)1128 static int TeeAgentKernelInit(void)
1129 {
1130     struct TeeAgentKernelOps *agentOps = NULL;
1131     int ret = 0;
1132     bool tmpCheckStatus = false;
1133 
1134     list_for_each_entry(agentOps, &g_teeAgentList, list) {
1135         /* Check the agent validity */
1136         tmpCheckStatus = ((agentOps->agentId == 0) ||
1137             (agentOps->agentName == NULL) ||
1138             (agentOps->teeAgentWork == NULL));
1139         if (tmpCheckStatus) {
1140             tloge("agent is invalid\n");
1141             continue;
1142         }
1143         tlogd("ready to init %s agent, id=0x%x\n",
1144             agentOps->agentName, agentOps->agentId);
1145 
1146         /* Set agent buff size */
1147         if (agentOps->agentBuffSize == 0) {
1148             agentOps->agentBuffSize = g_defTeeAgentOps.agentBuffSize;
1149         }
1150 
1151         /* Initialize the agent */
1152         if (agentOps->teeAgentInit != NULL) {
1153             ret = agentOps->teeAgentInit(agentOps);
1154         } else if (g_defTeeAgentOps.teeAgentInit != NULL) {
1155             ret = g_defTeeAgentOps.teeAgentInit(agentOps);
1156         } else {
1157             tlogw("agent id %u has no init function\n",
1158                 agentOps->agentId);
1159         }
1160         if (ret) {
1161             tloge("teeAgentInit %s failed\n",
1162                 agentOps->agentName);
1163             continue;
1164         }
1165 
1166         /* Run the agent */
1167         if (agentOps->teeAgentRun != NULL) {
1168             ret = agentOps->teeAgentRun(agentOps);
1169         } else if (g_defTeeAgentOps.teeAgentRun != NULL) {
1170             ret = g_defTeeAgentOps.teeAgentRun(agentOps);
1171         } else {
1172             tlogw("agent id %u has no run function\n",
1173                 agentOps->agentId);
1174         }
1175         if (ret) {
1176             tloge("teeAgentRun %s failed\n",
1177                 agentOps->agentName);
1178             if (agentOps->teeAgentExit != NULL) {
1179                 agentOps->teeAgentExit(agentOps);
1180             }
1181             continue;
1182         }
1183     }
1184 
1185     return AGENT_SUCCESS;
1186 }
1187 
TeeAgentKernelExit(void)1188 static void TeeAgentKernelExit(void)
1189 {
1190     struct TeeAgentKernelOps *agentOps = NULL;
1191 
1192     list_for_each_entry(agentOps, &g_teeAgentList, list) {
1193         /* Stop the agent */
1194         if (agentOps->teeAgentStop != NULL) {
1195             agentOps->teeAgentStop(agentOps);
1196         } else if (g_defTeeAgentOps.teeAgentStop != NULL) {
1197             g_defTeeAgentOps.teeAgentStop(agentOps);
1198         } else {
1199             tlogw("agent id %u has no stop function\n",
1200                 agentOps->agentId);
1201         }
1202         /* Uninitialize the agent */
1203         if (agentOps->teeAgentExit != NULL) {
1204             agentOps->teeAgentExit(agentOps);
1205         } else if (g_defTeeAgentOps.teeAgentExit != NULL) {
1206             g_defTeeAgentOps.teeAgentExit(agentOps);
1207         } else {
1208             tlogw("agent id %u has no exit function\n",
1209                 agentOps->agentId);
1210         }
1211     }
1212 }
1213 
TeeAgentClearWork(TcNsClientContext * context,unsigned int devFileId)1214 int TeeAgentClearWork(TcNsClientContext *context,
1215     unsigned int devFileId)
1216 {
1217     struct TeeAgentKernelOps *agentOps = NULL;
1218 
1219     list_for_each_entry(agentOps, &g_teeAgentList, list) {
1220         if (agentOps->teeAgentCrashWork != NULL) {
1221             agentOps->teeAgentCrashWork(agentOps,
1222                 context, devFileId);
1223         }
1224     }
1225     return AGENT_SUCCESS;
1226 }
1227 
1228 /* register kernel agent, for TeeAgentKernelInit load */
TeeAgentKernelRegister(struct TeeAgentKernelOps * newAgent)1229 int TeeAgentKernelRegister(struct TeeAgentKernelOps *newAgent)
1230 {
1231     if (newAgent == NULL) {
1232         return AGENT_FALSE;
1233     }
1234     INIT_LIST_HEAD(&newAgent->list);
1235     list_add_tail(&newAgent->list, &g_teeAgentList);
1236     return AGENT_SUCCESS;
1237 }
1238 
AgentInit(void)1239 void AgentInit(void)
1240 {
1241     spin_lock_init(&g_agentControl.lock);
1242     INIT_LIST_HEAD(&g_agentControl.agentList);
1243     INIT_LIST_HEAD(&g_teeAgentList);
1244 
1245     if (TeeAgentKernelInit() != AGENT_SUCCESS) {
1246         tloge("tee agent kernel init failed\n");
1247     }
1248 
1249     return;
1250 }
1251 
AgentExit(void)1252 int AgentExit(void)
1253 {
1254     TeeAgentKernelExit();
1255     return AGENT_SUCCESS;
1256 }
1257