• 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 "los_process_pri.h"
33 #include "los_sched_pri.h"
34 #include "los_task_pri.h"
35 #include "los_hw_pri.h"
36 #include "los_sem_pri.h"
37 #include "los_mp.h"
38 #include "los_exc.h"
39 #include "asm/page.h"
40 #ifdef LOSCFG_FS_VFS
41 #include "fs/fd_table.h"
42 #include "fs/fs_operation.h"
43 #endif
44 #include "time.h"
45 #include "user_copy.h"
46 #include "los_signal.h"
47 #ifdef LOSCFG_SECURITY_VID
48 #include "vid_api.h"
49 #endif
50 #ifdef LOSCFG_SECURITY_CAPABILITY
51 #include "capability_api.h"
52 #endif
53 #ifdef LOSCFG_KERNEL_DYNLOAD
54 #include "los_load_elf.h"
55 #endif
56 #include "los_swtmr_pri.h"
57 #include "los_vm_map.h"
58 #include "los_vm_phys.h"
59 #include "los_vm_syscall.h"
60 
61 
62 LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL;
63 LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;
64 LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList;
65 LITE_OS_SEC_BSS UINT32 g_userInitProcess = OS_INVALID_VALUE;
66 LITE_OS_SEC_BSS UINT32 g_kernelInitProcess = OS_INVALID_VALUE;
67 LITE_OS_SEC_BSS UINT32 g_kernelIdleProcess = OS_INVALID_VALUE;
68 LITE_OS_SEC_BSS UINT32 g_processMaxNum;
69 LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;
70 
OsInsertPCBToFreeList(LosProcessCB * processCB)71 STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB)
72 {
73     UINT32 pid = processCB->processID;
74     (VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB));
75     processCB->processID = pid;
76     processCB->processStatus = OS_PROCESS_FLAG_UNUSED;
77     processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
78     LOS_ListTailInsert(&g_freeProcess, &processCB->pendList);
79 }
80 
OsDeleteTaskFromProcess(LosTaskCB * taskCB)81 VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB)
82 {
83     LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);
84 
85     LOS_ListDelete(&taskCB->threadList);
86     processCB->threadNumber--;
87     OsTaskInsertToRecycleList(taskCB);
88 }
89 
OsProcessAddNewTask(UINT32 pid,LosTaskCB * taskCB)90 UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB)
91 {
92     UINT32 intSave;
93     UINT16 numCount;
94     LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
95 
96     SCHEDULER_LOCK(intSave);
97     taskCB->processID = pid;
98     LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList));
99 
100     if (OsProcessIsUserMode(processCB)) {
101         taskCB->taskStatus |= OS_TASK_FLAG_USER_MODE;
102         if (processCB->threadNumber > 0) {
103             taskCB->basePrio = OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio;
104         } else {
105             taskCB->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST;
106         }
107     } else {
108         taskCB->basePrio = OsCurrTaskGet()->basePrio;
109     }
110 
111 #ifdef LOSCFG_KERNEL_VM
112     taskCB->archMmu = (UINTPTR)&processCB->vmSpace->archMmu;
113 #endif
114     if (!processCB->threadNumber) {
115         processCB->threadGroupID = taskCB->taskID;
116     }
117     processCB->threadNumber++;
118 
119     numCount = processCB->threadCount;
120     processCB->threadCount++;
121     SCHEDULER_UNLOCK(intSave);
122     return numCount;
123 }
124 
OsCreateProcessGroup(UINT32 pid)125 STATIC ProcessGroup *OsCreateProcessGroup(UINT32 pid)
126 {
127     LosProcessCB *processCB = NULL;
128     ProcessGroup *group = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessGroup));
129     if (group == NULL) {
130         return NULL;
131     }
132 
133     group->groupID = pid;
134     LOS_ListInit(&group->processList);
135     LOS_ListInit(&group->exitProcessList);
136 
137     processCB = OS_PCB_FROM_PID(pid);
138     LOS_ListTailInsert(&group->processList, &processCB->subordinateGroupList);
139     processCB->group = group;
140     processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER;
141     if (g_processGroup != NULL) {
142         LOS_ListTailInsert(&g_processGroup->groupList, &group->groupList);
143     }
144 
145     return group;
146 }
147 
OsExitProcessGroup(LosProcessCB * processCB,ProcessGroup ** group)148 STATIC VOID OsExitProcessGroup(LosProcessCB *processCB, ProcessGroup **group)
149 {
150     LosProcessCB *groupProcessCB = OS_PCB_FROM_PID(processCB->group->groupID);
151 
152     LOS_ListDelete(&processCB->subordinateGroupList);
153     if (LOS_ListEmpty(&processCB->group->processList) && LOS_ListEmpty(&processCB->group->exitProcessList)) {
154         LOS_ListDelete(&processCB->group->groupList);
155         groupProcessCB->processStatus &= ~OS_PROCESS_FLAG_GROUP_LEADER;
156         *group = processCB->group;
157         if (OsProcessIsUnused(groupProcessCB) && !(groupProcessCB->processStatus & OS_PROCESS_FLAG_EXIT)) {
158             LOS_ListDelete(&groupProcessCB->pendList);
159             OsInsertPCBToFreeList(groupProcessCB);
160         }
161     }
162 
163     processCB->group = NULL;
164 }
165 
OsFindProcessGroup(UINT32 gid)166 STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid)
167 {
168     ProcessGroup *group = NULL;
169     if (g_processGroup->groupID == gid) {
170         return g_processGroup;
171     }
172 
173     LOS_DL_LIST_FOR_EACH_ENTRY(group, &g_processGroup->groupList, ProcessGroup, groupList) {
174         if (group->groupID == gid) {
175             return group;
176         }
177     }
178 
179     PRINT_INFO("%s failed! group id = %u\n", __FUNCTION__, gid);
180     return NULL;
181 }
182 
OsSendSignalToSpecifyProcessGroup(ProcessGroup * group,siginfo_t * info,INT32 permission)183 STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *group, siginfo_t *info, INT32 permission)
184 {
185     INT32 ret, success, err;
186     LosProcessCB *childCB = NULL;
187 
188     success = 0;
189     ret = -LOS_ESRCH;
190     LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(group->processList), LosProcessCB, subordinateGroupList) {
191         if (childCB->processID == 0) {
192             continue;
193         }
194 
195         err = OsDispatch(childCB->processID, info, permission);
196         success |= !err;
197         ret = err;
198     }
199     /* At least one success. */
200     return success ? LOS_OK : ret;
201 }
202 
OsSendSignalToAllProcess(siginfo_t * info,INT32 permission)203 LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission)
204 {
205     INT32 ret, success, err;
206     ProcessGroup *group = NULL;
207 
208     success = 0;
209     err = OsSendSignalToSpecifyProcessGroup(g_processGroup, info, permission);
210     success |= !err;
211     ret = err;
212     /* all processes group */
213     LOS_DL_LIST_FOR_EACH_ENTRY(group, &g_processGroup->groupList, ProcessGroup, groupList) {
214         /* all processes in the process group. */
215         err = OsSendSignalToSpecifyProcessGroup(group, info, permission);
216         success |= !err;
217         ret = err;
218     }
219     return success ? LOS_OK : ret;
220 }
221 
OsSendSignalToProcessGroup(INT32 pid,siginfo_t * info,INT32 permission)222 LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission)
223 {
224     ProcessGroup *group = NULL;
225     /* Send SIG to all processes in process group PGRP.
226        If PGRP is zero, send SIG to all processes in
227        the current process's process group. */
228     group = OsFindProcessGroup(pid ? -pid : LOS_GetCurrProcessGroupID());
229     if (group == NULL) {
230         return -LOS_ESRCH;
231     }
232     /* all processes in the process group. */
233     return OsSendSignalToSpecifyProcessGroup(group, info, permission);
234 }
235 
OsFindGroupExitProcess(ProcessGroup * group,INT32 pid)236 STATIC LosProcessCB *OsFindGroupExitProcess(ProcessGroup *group, INT32 pid)
237 {
238     LosProcessCB *childCB = NULL;
239 
240     LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(group->exitProcessList), LosProcessCB, subordinateGroupList) {
241         if ((childCB->processID == pid) || (pid == OS_INVALID_VALUE)) {
242             return childCB;
243         }
244     }
245 
246     PRINT_INFO("%s find exit process : %d failed in group : %u\n", __FUNCTION__, pid, group->groupID);
247     return NULL;
248 }
249 
OsFindChildProcess(const LosProcessCB * processCB,INT32 childPid)250 STATIC UINT32 OsFindChildProcess(const LosProcessCB *processCB, INT32 childPid)
251 {
252     LosProcessCB *childCB = NULL;
253 
254     if (childPid < 0) {
255         goto ERR;
256     }
257 
258     LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(processCB->childrenList), LosProcessCB, siblingList) {
259         if (childCB->processID == childPid) {
260             return LOS_OK;
261         }
262     }
263 
264 ERR:
265     PRINT_INFO("%s is find the child : %d failed in parent : %u\n", __FUNCTION__, childPid, processCB->processID);
266     return LOS_NOK;
267 }
268 
OsFindExitChildProcess(const LosProcessCB * processCB,INT32 childPid)269 STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, INT32 childPid)
270 {
271     LosProcessCB *exitChild = NULL;
272 
273     LOS_DL_LIST_FOR_EACH_ENTRY(exitChild, &(processCB->exitChildList), LosProcessCB, siblingList) {
274         if ((childPid == OS_INVALID_VALUE) || (exitChild->processID == childPid)) {
275             return exitChild;
276         }
277     }
278 
279     PRINT_INFO("%s is find the exit child : %d failed in parent : %u\n", __FUNCTION__, childPid, processCB->processID);
280     return NULL;
281 }
282 
OsWaitWakeTask(LosTaskCB * taskCB,UINT32 wakePID)283 VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID)
284 {
285     taskCB->waitID = wakePID;
286     OsSchedTaskWake(taskCB);
287 #ifdef LOSCFG_KERNEL_SMP
288     LOS_MpSchedule(OS_MP_CPU_ALL);
289 #endif
290 }
291 
OsWaitWakeSpecifiedProcess(LOS_DL_LIST * head,const LosProcessCB * processCB,LOS_DL_LIST ** anyList)292 STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList)
293 {
294     LOS_DL_LIST *list = head;
295     LosTaskCB *taskCB = NULL;
296     UINT32 pid = 0;
297     BOOL find = FALSE;
298 
299     while (list->pstNext != head) {
300         taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
301         if ((taskCB->waitFlag == OS_PROCESS_WAIT_PRO) && (taskCB->waitID == processCB->processID)) {
302             if (pid == 0) {
303                 pid = processCB->processID;
304                 find = TRUE;
305             } else {
306                 pid = OS_INVALID_VALUE;
307             }
308 
309             OsWaitWakeTask(taskCB, pid);
310             continue;
311         }
312 
313         if (taskCB->waitFlag != OS_PROCESS_WAIT_PRO) {
314             *anyList = list;
315             break;
316         }
317         list = list->pstNext;
318     }
319 
320     return find;
321 }
322 
OsWaitCheckAndWakeParentProcess(LosProcessCB * parentCB,const LosProcessCB * processCB)323 STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB)
324 {
325     LOS_DL_LIST *head = &parentCB->waitList;
326     LOS_DL_LIST *list = NULL;
327     LosTaskCB *taskCB = NULL;
328     BOOL findSpecified = FALSE;
329 
330     if (LOS_ListEmpty(&parentCB->waitList)) {
331         return;
332     }
333 
334     findSpecified = OsWaitWakeSpecifiedProcess(head, processCB, &list);
335     if (findSpecified == TRUE) {
336         /* No thread is waiting for any child process to finish */
337         if (LOS_ListEmpty(&parentCB->waitList)) {
338             return;
339         } else if (!LOS_ListEmpty(&parentCB->childrenList)) {
340             /* Other child processes exist, and other threads that are waiting
341              * for the child to finish continue to wait
342              */
343             return;
344         }
345     }
346 
347     /* Waiting threads are waiting for a specified child process to finish */
348     if (list == NULL) {
349         return;
350     }
351 
352     /* No child processes exist and all waiting threads are awakened */
353     if (findSpecified == TRUE) {
354         while (list->pstNext != head) {
355             taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
356             OsWaitWakeTask(taskCB, OS_INVALID_VALUE);
357         }
358         return;
359     }
360 
361     while (list->pstNext != head) {
362         taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
363         if (taskCB->waitFlag == OS_PROCESS_WAIT_GID) {
364             if (taskCB->waitID != processCB->group->groupID) {
365                 list = list->pstNext;
366                 continue;
367             }
368         }
369 
370         if (findSpecified == FALSE) {
371             OsWaitWakeTask(taskCB, processCB->processID);
372             findSpecified = TRUE;
373         } else {
374             OsWaitWakeTask(taskCB, OS_INVALID_VALUE);
375         }
376 
377         if (!LOS_ListEmpty(&parentCB->childrenList)) {
378             break;
379         }
380     }
381 
382     return;
383 }
384 
OsProcessResourcesToFree(LosProcessCB * processCB)385 LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
386 {
387 #ifdef LOSCFG_KERNEL_VM
388     if (OsProcessIsUserMode(processCB)) {
389         (VOID)OsVmSpaceRegionFree(processCB->vmSpace);
390     }
391 #endif
392 
393 #ifdef LOSCFG_FS_VFS
394     if (OsProcessIsUserMode(processCB)) {
395         delete_files(processCB->files);
396     }
397     processCB->files = NULL;
398 #endif
399 
400 #ifdef LOSCFG_SECURITY_CAPABILITY
401     if (processCB->user != NULL) {
402         (VOID)LOS_MemFree(m_aucSysMem1, processCB->user);
403         processCB->user = NULL;
404     }
405 #endif
406 
407     OsSwtmrRecycle(processCB->processID);
408     processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
409 
410 #ifdef LOSCFG_SECURITY_VID
411     if (processCB->timerIdMap.bitMap != NULL) {
412         VidMapDestroy(processCB);
413         processCB->timerIdMap.bitMap = NULL;
414     }
415 #endif
416 
417 #ifdef LOSCFG_KERNEL_LITEIPC
418     (VOID)LiteIpcPoolDestroy(processCB->processID);
419 #endif
420 
421 #ifdef LOSCFG_KERNEL_CPUP
422     UINT32 intSave;
423     OsCpupBase *processCpup = processCB->processCpup;
424     SCHEDULER_LOCK(intSave);
425     processCB->processCpup = NULL;
426     SCHEDULER_UNLOCK(intSave);
427     (VOID)LOS_MemFree(m_aucSysMem1, processCpup);
428 #endif
429 
430     if (processCB->resourceLimit != NULL) {
431         (VOID)LOS_MemFree((VOID *)m_aucSysMem0, processCB->resourceLimit);
432         processCB->resourceLimit = NULL;
433     }
434 }
435 
OsRecycleZombiesProcess(LosProcessCB * childCB,ProcessGroup ** group)436 LITE_OS_SEC_TEXT STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **group)
437 {
438     OsExitProcessGroup(childCB, group);
439     LOS_ListDelete(&childCB->siblingList);
440     if (childCB->processStatus & OS_PROCESS_STATUS_ZOMBIES) {
441         OsDeleteTaskFromProcess(OS_TCB_FROM_TID(childCB->threadGroupID));
442         childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES;
443         childCB->processStatus |= OS_PROCESS_FLAG_UNUSED;
444     }
445 
446     LOS_ListDelete(&childCB->pendList);
447     if (childCB->processStatus & OS_PROCESS_FLAG_EXIT) {
448         LOS_ListHeadInsert(&g_processRecycleList, &childCB->pendList);
449     } else if (childCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) {
450         LOS_ListTailInsert(&g_processRecycleList, &childCB->pendList);
451     } else {
452         OsInsertPCBToFreeList(childCB);
453     }
454 }
455 
OsDealAliveChildProcess(LosProcessCB * processCB)456 STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
457 {
458     UINT32 parentID;
459     LosProcessCB *childCB = NULL;
460     LosProcessCB *parentCB = NULL;
461     LOS_DL_LIST *nextList = NULL;
462     LOS_DL_LIST *childHead = NULL;
463 
464     if (!LOS_ListEmpty(&processCB->childrenList)) {
465         childHead = processCB->childrenList.pstNext;
466         LOS_ListDelete(&(processCB->childrenList));
467         if (OsProcessIsUserMode(processCB)) {
468             parentID = g_userInitProcess;
469         } else {
470             parentID = g_kernelInitProcess;
471         }
472 
473         for (nextList = childHead; ;) {
474             childCB = OS_PCB_FROM_SIBLIST(nextList);
475             childCB->parentProcessID = parentID;
476             nextList = nextList->pstNext;
477             if (nextList == childHead) {
478                 break;
479             }
480         }
481 
482         parentCB = OS_PCB_FROM_PID(parentID);
483         LOS_ListTailInsertList(&parentCB->childrenList, childHead);
484     }
485 
486     return;
487 }
488 
OsChildProcessResourcesFree(const LosProcessCB * processCB)489 STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB)
490 {
491     LosProcessCB *childCB = NULL;
492     ProcessGroup *group = NULL;
493 
494     while (!LOS_ListEmpty(&((LosProcessCB *)processCB)->exitChildList)) {
495         childCB = LOS_DL_LIST_ENTRY(processCB->exitChildList.pstNext, LosProcessCB, siblingList);
496         OsRecycleZombiesProcess(childCB, &group);
497         (VOID)LOS_MemFree(m_aucSysMem1, group);
498     }
499 }
500 
OsProcessNaturalExit(LosProcessCB * processCB,UINT32 status)501 VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status)
502 {
503     LosProcessCB *parentCB = NULL;
504 
505     OsChildProcessResourcesFree(processCB);
506 
507     /* is a child process */
508     if (processCB->parentProcessID != OS_INVALID_VALUE) {
509         parentCB = OS_PCB_FROM_PID(processCB->parentProcessID);
510         LOS_ListDelete(&processCB->siblingList);
511         if (!OsProcessExitCodeSignalIsSet(processCB)) {
512             OsProcessExitCodeSet(processCB, status);
513         }
514         LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList);
515         LOS_ListDelete(&processCB->subordinateGroupList);
516         LOS_ListTailInsert(&processCB->group->exitProcessList, &processCB->subordinateGroupList);
517 
518         OsWaitCheckAndWakeParentProcess(parentCB, processCB);
519 
520         OsDealAliveChildProcess(processCB);
521 
522         processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES;
523 
524 #ifdef LOSCFG_KERNEL_VM
525         (VOID)OsKill(processCB->parentProcessID, SIGCHLD, OS_KERNEL_KILL_PERMISSION);
526 #endif
527         LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);
528         return;
529     }
530 
531     LOS_Panic("pid : %u is the root process exit!\n", processCB->processID);
532     return;
533 }
534 
OsProcessInit(VOID)535 STATIC UINT32 OsProcessInit(VOID)
536 {
537     UINT32 index;
538     UINT32 size;
539 
540     g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT;
541     size = g_processMaxNum * sizeof(LosProcessCB);
542 
543     g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);
544     if (g_processCBArray == NULL) {
545         return LOS_NOK;
546     }
547     (VOID)memset_s(g_processCBArray, size, 0, size);
548 
549     LOS_ListInit(&g_freeProcess);
550     LOS_ListInit(&g_processRecycleList);
551 
552     for (index = 0; index < g_processMaxNum; index++) {
553         g_processCBArray[index].processID = index;
554         g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED;
555         LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList);
556     }
557 
558     g_kernelIdleProcess = 0; /* 0: The idle process ID of the kernel-mode process is fixed at 0 */
559     LOS_ListDelete(&OS_PCB_FROM_PID(g_kernelIdleProcess)->pendList);
560 
561     g_userInitProcess = 1; /* 1: The root process ID of the user-mode process is fixed at 1 */
562     LOS_ListDelete(&OS_PCB_FROM_PID(g_userInitProcess)->pendList);
563 
564     g_kernelInitProcess = 2; /* 2: The root process ID of the kernel-mode process is fixed at 2 */
565     LOS_ListDelete(&OS_PCB_FROM_PID(g_kernelInitProcess)->pendList);
566 
567     return LOS_OK;
568 }
569 
OsProcessCBRecycleToFree(VOID)570 LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
571 {
572     UINT32 intSave;
573     LosProcessCB *processCB = NULL;
574 
575     SCHEDULER_LOCK(intSave);
576     while (!LOS_ListEmpty(&g_processRecycleList)) {
577         processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList));
578         if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) {
579             break;
580         }
581         SCHEDULER_UNLOCK(intSave);
582 
583         OsTaskCBRecycleToFree();
584 
585         SCHEDULER_LOCK(intSave);
586         processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT;
587 #ifdef LOSCFG_KERNEL_VM
588         LosVmSpace *space = NULL;
589         if (OsProcessIsUserMode(processCB)) {
590             space = processCB->vmSpace;
591         }
592         processCB->vmSpace = NULL;
593 #endif
594         /* OS_PROCESS_FLAG_GROUP_LEADER: The lead process group cannot be recycled without destroying the PCB.
595          * !OS_PROCESS_FLAG_UNUSED: Parent process does not reclaim child process resources.
596          */
597         LOS_ListDelete(&processCB->pendList);
598         if ((processCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) ||
599             (processCB->processStatus & OS_PROCESS_STATUS_ZOMBIES)) {
600             LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList);
601         } else {
602             /* Clear the bottom 4 bits of process status */
603             OsInsertPCBToFreeList(processCB);
604         }
605 #ifdef LOSCFG_KERNEL_VM
606         SCHEDULER_UNLOCK(intSave);
607         (VOID)LOS_VmSpaceFree(space);
608         SCHEDULER_LOCK(intSave);
609 #endif
610     }
611 
612     SCHEDULER_UNLOCK(intSave);
613 }
614 
OsDeInitPCB(LosProcessCB * processCB)615 STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
616 {
617     UINT32 intSave;
618     ProcessGroup *group = NULL;
619 
620     if (processCB == NULL) {
621         return;
622     }
623 
624     OsProcessResourcesToFree(processCB);
625 
626     SCHEDULER_LOCK(intSave);
627     if (processCB->parentProcessID != OS_INVALID_VALUE) {
628         LOS_ListDelete(&processCB->siblingList);
629         processCB->parentProcessID = OS_INVALID_VALUE;
630     }
631 
632     if (processCB->group != NULL) {
633         OsExitProcessGroup(processCB, &group);
634     }
635 
636     processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;
637     processCB->processStatus |= OS_PROCESS_FLAG_EXIT;
638     LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);
639     SCHEDULER_UNLOCK(intSave);
640 
641     (VOID)LOS_MemFree(m_aucSysMem1, group);
642     OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE);
643     return;
644 }
645 
OsSetProcessName(LosProcessCB * processCB,const CHAR * name)646 UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name)
647 {
648     errno_t errRet;
649 
650     if (processCB == NULL) {
651         return LOS_EINVAL;
652     }
653 
654     if (name != NULL) {
655         errRet = strncpy_s(processCB->processName, OS_PCB_NAME_LEN, name, OS_PCB_NAME_LEN - 1);
656         if (errRet == EOK) {
657             return LOS_OK;
658         }
659     }
660 
661     switch (processCB->processMode) {
662         case OS_KERNEL_MODE:
663             errRet = snprintf_s(processCB->processName, OS_PCB_NAME_LEN, OS_PCB_NAME_LEN - 1,
664                                 "KerProcess%u", processCB->processID);
665             break;
666         default:
667             errRet = snprintf_s(processCB->processName, OS_PCB_NAME_LEN, OS_PCB_NAME_LEN - 1,
668                                 "UserProcess%u", processCB->processID);
669             break;
670     }
671 
672     if (errRet < 0) {
673         return LOS_NOK;
674     }
675     return LOS_OK;
676 }
677 
OsInitPCB(LosProcessCB * processCB,UINT32 mode,const CHAR * name)678 STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name)
679 {
680     processCB->processMode = mode;
681     processCB->processStatus = OS_PROCESS_STATUS_INIT;
682     processCB->parentProcessID = OS_INVALID_VALUE;
683     processCB->threadGroupID = OS_INVALID_VALUE;
684     processCB->umask = OS_PROCESS_DEFAULT_UMASK;
685     processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
686 
687     LOS_ListInit(&processCB->threadSiblingList);
688     LOS_ListInit(&processCB->childrenList);
689     LOS_ListInit(&processCB->exitChildList);
690     LOS_ListInit(&(processCB->waitList));
691 
692 #ifdef LOSCFG_KERNEL_VM
693     if (OsProcessIsUserMode(processCB)) {
694         processCB->vmSpace = OsCreateUserVmSpace();
695         if (processCB->vmSpace == NULL) {
696             processCB->processStatus = OS_PROCESS_FLAG_UNUSED;
697             return LOS_ENOMEM;
698         }
699     } else {
700         processCB->vmSpace = LOS_GetKVmSpace();
701     }
702 #endif
703 
704 #ifdef LOSCFG_KERNEL_CPUP
705     processCB->processCpup = (OsCpupBase *)LOS_MemAlloc(m_aucSysMem1, sizeof(OsCpupBase));
706     if (processCB->processCpup == NULL) {
707         return LOS_ENOMEM;
708     }
709     (VOID)memset_s(processCB->processCpup, sizeof(OsCpupBase), 0, sizeof(OsCpupBase));
710 #endif
711 
712 #ifdef LOSCFG_SECURITY_VID
713     status_t status = VidMapListInit(processCB);
714     if (status != LOS_OK) {
715         return LOS_ENOMEM;
716     }
717 #endif
718 
719 #ifdef LOSCFG_SECURITY_CAPABILITY
720     OsInitCapability(processCB);
721 #endif
722 
723     if (OsSetProcessName(processCB, name) != LOS_OK) {
724         return LOS_ENOMEM;
725     }
726 
727     return LOS_OK;
728 }
729 
730 #ifdef LOSCFG_SECURITY_CAPABILITY
OsCreateUser(UINT32 userID,UINT32 gid,UINT32 size)731 STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)
732 {
733     User *user = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + (size - 1) * sizeof(UINT32));
734     if (user == NULL) {
735         return NULL;
736     }
737 
738     user->userID = userID;
739     user->effUserID = userID;
740     user->gid = gid;
741     user->effGid = gid;
742     user->groupNumber = size;
743     user->groups[0] = gid;
744     return user;
745 }
746 
LOS_CheckInGroups(UINT32 gid)747 LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid)
748 {
749     UINT32 intSave;
750     UINT32 count;
751     User *user = NULL;
752 
753     SCHEDULER_LOCK(intSave);
754     user = OsCurrUserGet();
755     for (count = 0; count < user->groupNumber; count++) {
756         if (user->groups[count] == gid) {
757             SCHEDULER_UNLOCK(intSave);
758             return TRUE;
759         }
760     }
761 
762     SCHEDULER_UNLOCK(intSave);
763     return FALSE;
764 }
765 #endif
766 
LOS_GetUserID(VOID)767 LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID)
768 {
769 #ifdef LOSCFG_SECURITY_CAPABILITY
770     UINT32 intSave;
771     INT32 uid;
772 
773     SCHEDULER_LOCK(intSave);
774     uid = (INT32)OsCurrUserGet()->userID;
775     SCHEDULER_UNLOCK(intSave);
776     return uid;
777 #else
778     return 0;
779 #endif
780 }
781 
LOS_GetGroupID(VOID)782 LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID)
783 {
784 #ifdef LOSCFG_SECURITY_CAPABILITY
785     UINT32 intSave;
786     INT32 gid;
787 
788     SCHEDULER_LOCK(intSave);
789     gid = (INT32)OsCurrUserGet()->gid;
790     SCHEDULER_UNLOCK(intSave);
791 
792     return gid;
793 #else
794     return 0;
795 #endif
796 }
797 
OsProcessCreateInit(LosProcessCB * processCB,UINT32 flags,const CHAR * name)798 STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name)
799 {
800     ProcessGroup *group = NULL;
801     UINT32 ret = OsInitPCB(processCB, flags, name);
802     if (ret != LOS_OK) {
803         goto EXIT;
804     }
805 
806 #ifdef LOSCFG_FS_VFS
807     processCB->files = alloc_files();
808     if (processCB->files == NULL) {
809         ret = LOS_ENOMEM;
810         goto EXIT;
811     }
812 #endif
813 
814     group = OsCreateProcessGroup(processCB->processID);
815     if (group == NULL) {
816         ret = LOS_ENOMEM;
817         goto EXIT;
818     }
819 
820 #ifdef LOSCFG_SECURITY_CAPABILITY
821     processCB->user = OsCreateUser(0, 0, 1);
822     if (processCB->user == NULL) {
823         ret = LOS_ENOMEM;
824         goto EXIT;
825     }
826 #endif
827 
828     return LOS_OK;
829 
830 EXIT:
831     OsDeInitPCB(processCB);
832     return ret;
833 }
834 
OsSystemProcessCreate(VOID)835 LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
836 {
837     UINT32 ret = OsProcessInit();
838     if (ret != LOS_OK) {
839         return ret;
840     }
841 
842     LosProcessCB *kerInitProcess = OS_PCB_FROM_PID(g_kernelInitProcess);
843     ret = OsProcessCreateInit(kerInitProcess, OS_KERNEL_MODE, "KProcess");
844     if (ret != LOS_OK) {
845         return ret;
846     }
847 
848     kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;
849     g_processGroup = kerInitProcess->group;
850     LOS_ListInit(&g_processGroup->groupList);
851 
852     LosProcessCB *idleProcess = OS_PCB_FROM_PID(g_kernelIdleProcess);
853     ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle");
854     if (ret != LOS_OK) {
855         return ret;
856     }
857     idleProcess->parentProcessID = kerInitProcess->processID;
858     LOS_ListTailInsert(&kerInitProcess->childrenList, &idleProcess->siblingList);
859     idleProcess->group = kerInitProcess->group;
860     LOS_ListTailInsert(&kerInitProcess->group->processList, &idleProcess->subordinateGroupList);
861 #ifdef LOSCFG_SECURITY_CAPABILITY
862     idleProcess->user = kerInitProcess->user;
863 #endif
864 #ifdef LOSCFG_FS_VFS
865     idleProcess->files = kerInitProcess->files;
866 #endif
867     idleProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;
868 
869     ret = OsIdleTaskCreate();
870     if (ret != LOS_OK) {
871         return ret;
872     }
873     idleProcess->threadGroupID = OsGetIdleTaskId();
874 
875     return LOS_OK;
876 }
877 
OsProcessSchedlerParamCheck(INT32 which,INT32 pid,UINT16 prio,UINT16 policy)878 STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
879 {
880     if (OS_PID_CHECK_INVALID(pid)) {
881         return LOS_EINVAL;
882     }
883 
884     if (which != LOS_PRIO_PROCESS) {
885         return LOS_EINVAL;
886     }
887 
888     if (prio > OS_PROCESS_PRIORITY_LOWEST) {
889         return LOS_EINVAL;
890     }
891 
892     if (policy != LOS_SCHED_RR) {
893         return LOS_EINVAL;
894     }
895 
896     return LOS_OK;
897 }
898 
899 #ifdef LOSCFG_SECURITY_CAPABILITY
OsProcessCapPermitCheck(const LosProcessCB * processCB,UINT16 prio)900 STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, UINT16 prio)
901 {
902     LosProcessCB *runProcess = OsCurrProcessGet();
903 
904     /* always trust kernel process */
905     if (!OsProcessIsUserMode(runProcess)) {
906         return TRUE;
907     }
908 
909     /* user mode process can reduce the priority of itself */
910     if ((runProcess->processID == processCB->processID) && (prio > OsCurrTaskGet()->basePrio)) {
911         return TRUE;
912     }
913 
914     /* user mode process with privilege of CAP_SCHED_SETPRIORITY can change the priority */
915     if (IsCapPermit(CAP_SCHED_SETPRIORITY)) {
916         return TRUE;
917     }
918     return FALSE;
919 }
920 #endif
921 
OsSetProcessScheduler(INT32 which,INT32 pid,UINT16 prio,UINT16 policy)922 LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
923 {
924     LosProcessCB *processCB = NULL;
925     BOOL needSched = FALSE;
926     UINT32 intSave;
927     INT32 ret;
928 
929     ret = OsProcessSchedlerParamCheck(which, pid, prio, policy);
930     if (ret != LOS_OK) {
931         return -ret;
932     }
933 
934     SCHEDULER_LOCK(intSave);
935     processCB = OS_PCB_FROM_PID(pid);
936     if (OsProcessIsInactive(processCB)) {
937         ret = LOS_ESRCH;
938         goto EXIT;
939     }
940 
941 #ifdef LOSCFG_SECURITY_CAPABILITY
942     if (!OsProcessCapPermitCheck(processCB, prio)) {
943         ret = LOS_EPERM;
944         goto EXIT;
945     }
946 #endif
947 
948     needSched = OsSchedModifyProcessSchedParam(pid, policy, prio);
949     SCHEDULER_UNLOCK(intSave);
950 
951     LOS_MpSchedule(OS_MP_CPU_ALL);
952     if (needSched && OS_SCHEDULER_ACTIVE) {
953         LOS_Schedule();
954     }
955     return LOS_OK;
956 
957 EXIT:
958     SCHEDULER_UNLOCK(intSave);
959     return -ret;
960 }
961 
LOS_SetProcessScheduler(INT32 pid,UINT16 policy,UINT16 prio)962 LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, UINT16 prio)
963 {
964     return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, policy);
965 }
966 
LOS_GetProcessScheduler(INT32 pid)967 LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid)
968 {
969     UINT32 intSave;
970 
971     if (OS_PID_CHECK_INVALID(pid)) {
972         return -LOS_EINVAL;
973     }
974 
975     SCHEDULER_LOCK(intSave);
976     LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
977     if (OsProcessIsUnused(processCB)) {
978         SCHEDULER_UNLOCK(intSave);
979         return -LOS_ESRCH;
980     }
981 
982     SCHEDULER_UNLOCK(intSave);
983 
984     return LOS_SCHED_RR;
985 }
986 
LOS_SetProcessPriority(INT32 pid,UINT16 prio)987 LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio)
988 {
989     return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, LOS_GetProcessScheduler(pid));
990 }
991 
OsGetProcessPriority(INT32 which,INT32 pid)992 LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
993 {
994     INT32 prio;
995     UINT32 intSave;
996     (VOID)which;
997 
998     if (OS_PID_CHECK_INVALID(pid)) {
999         return -LOS_EINVAL;
1000     }
1001 
1002     if (which != LOS_PRIO_PROCESS) {
1003         return -LOS_EINVAL;
1004     }
1005 
1006     LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
1007     SCHEDULER_LOCK(intSave);
1008     if (OsProcessIsUnused(processCB)) {
1009         prio = -LOS_ESRCH;
1010         goto OUT;
1011     }
1012 
1013     prio = (INT32)OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio;
1014 
1015 OUT:
1016     SCHEDULER_UNLOCK(intSave);
1017     return prio;
1018 }
1019 
LOS_GetProcessPriority(INT32 pid)1020 LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid)
1021 {
1022     return OsGetProcessPriority(LOS_PRIO_PROCESS, pid);
1023 }
1024 
OsWaitInsertWaitListInOrder(LosTaskCB * runTask,LosProcessCB * processCB)1025 STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *processCB)
1026 {
1027     LOS_DL_LIST *head = &processCB->waitList;
1028     LOS_DL_LIST *list = head;
1029     LosTaskCB *taskCB = NULL;
1030 
1031     if (runTask->waitFlag == OS_PROCESS_WAIT_GID) {
1032         while (list->pstNext != head) {
1033             taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
1034             if (taskCB->waitFlag == OS_PROCESS_WAIT_PRO) {
1035                 list = list->pstNext;
1036                 continue;
1037             }
1038             break;
1039         }
1040     } else if (runTask->waitFlag == OS_PROCESS_WAIT_ANY) {
1041         while (list->pstNext != head) {
1042             taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
1043             if (taskCB->waitFlag != OS_PROCESS_WAIT_ANY) {
1044                 list = list->pstNext;
1045                 continue;
1046             }
1047             break;
1048         }
1049     }
1050     /* if runTask->waitFlag == OS_PROCESS_WAIT_PRO,
1051      * this node is inserted directly into the header of the waitList
1052      */
1053 
1054     (VOID)OsSchedTaskWait(list->pstNext, LOS_WAIT_FOREVER, TRUE);
1055     return;
1056 }
1057 
OsWaitSetFlag(const LosProcessCB * processCB,INT32 pid,LosProcessCB ** child)1058 STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcessCB **child)
1059 {
1060     LosProcessCB *childCB = NULL;
1061     ProcessGroup *group = NULL;
1062     LosTaskCB *runTask = OsCurrTaskGet();
1063     UINT32 ret;
1064 
1065     if (pid > 0) {
1066         /* Wait for the child process whose process number is pid. */
1067         childCB = OsFindExitChildProcess(processCB, pid);
1068         if (childCB != NULL) {
1069             goto WAIT_BACK;
1070         }
1071 
1072         ret = OsFindChildProcess(processCB, pid);
1073         if (ret != LOS_OK) {
1074             return LOS_ECHILD;
1075         }
1076         runTask->waitFlag = OS_PROCESS_WAIT_PRO;
1077         runTask->waitID = pid;
1078     } else if (pid == 0) {
1079         /* Wait for any child process in the same process group */
1080         childCB = OsFindGroupExitProcess(processCB->group, OS_INVALID_VALUE);
1081         if (childCB != NULL) {
1082             goto WAIT_BACK;
1083         }
1084         runTask->waitID = processCB->group->groupID;
1085         runTask->waitFlag = OS_PROCESS_WAIT_GID;
1086     } else if (pid == -1) {
1087         /* Wait for any child process */
1088         childCB = OsFindExitChildProcess(processCB, OS_INVALID_VALUE);
1089         if (childCB != NULL) {
1090             goto WAIT_BACK;
1091         }
1092         runTask->waitID = pid;
1093         runTask->waitFlag = OS_PROCESS_WAIT_ANY;
1094     } else { /* pid < -1 */
1095         /* Wait for any child process whose group number is the pid absolute value. */
1096         group = OsFindProcessGroup(-pid);
1097         if (group == NULL) {
1098             return LOS_ECHILD;
1099         }
1100 
1101         childCB = OsFindGroupExitProcess(group, OS_INVALID_VALUE);
1102         if (childCB != NULL) {
1103             goto WAIT_BACK;
1104         }
1105 
1106         runTask->waitID = -pid;
1107         runTask->waitFlag = OS_PROCESS_WAIT_GID;
1108     }
1109 
1110 WAIT_BACK:
1111     *child = childCB;
1112     return LOS_OK;
1113 }
1114 
OsWaitRecycleChildProcess(const LosProcessCB * childCB,UINT32 intSave,INT32 * status,siginfo_t * info)1115 STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info)
1116 {
1117     ProcessGroup *group = NULL;
1118     UINT32 pid = childCB->processID;
1119     UINT16 mode = childCB->processMode;
1120     INT32 exitCode = childCB->exitCode;
1121     UINT32 uid = 0;
1122 
1123 #ifdef LOSCFG_SECURITY_CAPABILITY
1124     if (childCB->user != NULL) {
1125         uid = childCB->user->userID;
1126     }
1127 #endif
1128 
1129     OsRecycleZombiesProcess((LosProcessCB *)childCB, &group);
1130     SCHEDULER_UNLOCK(intSave);
1131 
1132     if (status != NULL) {
1133         if (mode == OS_USER_MODE) {
1134             (VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32));
1135         } else {
1136             *status = exitCode;
1137         }
1138     }
1139     /* get signal info */
1140     if (info != NULL) {
1141         siginfo_t tempinfo = { 0 };
1142 
1143         tempinfo.si_signo = SIGCHLD;
1144         tempinfo.si_errno = 0;
1145         tempinfo.si_pid = pid;
1146         tempinfo.si_uid = uid;
1147         /*
1148          * Process exit code
1149          * 31	 15 		  8 		  7 	   0
1150          * |	 | exit code  | core dump | signal |
1151          */
1152         if ((exitCode & 0x7f) == 0) {
1153             tempinfo.si_code = CLD_EXITED;
1154             tempinfo.si_status = (exitCode >> 8U);
1155         } else {
1156             tempinfo.si_code = (exitCode & 0x80) ? CLD_DUMPED : CLD_KILLED;
1157             tempinfo.si_status = (exitCode & 0x7f);
1158         }
1159 
1160         if (mode == OS_USER_MODE) {
1161             (VOID)LOS_ArchCopyToUser((VOID *)(info), (const VOID *)(&(tempinfo)), sizeof(siginfo_t));
1162         } else {
1163             (VOID)memcpy_s((VOID *)(info), sizeof(siginfo_t), (const VOID *)(&(tempinfo)), sizeof(siginfo_t));
1164         }
1165     }
1166     (VOID)LOS_MemFree(m_aucSysMem1, group);
1167     return pid;
1168 }
1169 
OsWaitChildProcessCheck(LosProcessCB * processCB,INT32 pid,LosProcessCB ** childCB)1170 STATIC UINT32 OsWaitChildProcessCheck(LosProcessCB *processCB, INT32 pid, LosProcessCB **childCB)
1171 {
1172     if (LOS_ListEmpty(&(processCB->childrenList)) && LOS_ListEmpty(&(processCB->exitChildList))) {
1173         return LOS_ECHILD;
1174     }
1175 
1176     return OsWaitSetFlag(processCB, pid, childCB);
1177 }
1178 
OsWaitOptionsCheck(UINT32 options)1179 STATIC UINT32 OsWaitOptionsCheck(UINT32 options)
1180 {
1181     UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WUNTRACED | LOS_WAIT_WCONTINUED;
1182 
1183     flag = ~flag & options;
1184     if (flag != 0) {
1185         return LOS_EINVAL;
1186     }
1187 
1188     if ((options & (LOS_WAIT_WCONTINUED | LOS_WAIT_WUNTRACED)) != 0) {
1189         return LOS_EOPNOTSUPP;
1190     }
1191 
1192     if (OS_INT_ACTIVE) {
1193         return LOS_EINTR;
1194     }
1195 
1196     return LOS_OK;
1197 }
1198 
OsWait(INT32 pid,USER INT32 * status,USER siginfo_t * info,UINT32 options,VOID * rusage)1199 STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage)
1200 {
1201     (VOID)rusage;
1202     UINT32 ret;
1203     UINT32 intSave;
1204     LosProcessCB *childCB = NULL;
1205     LosProcessCB *processCB = NULL;
1206     LosTaskCB *runTask = NULL;
1207 
1208     SCHEDULER_LOCK(intSave);
1209     processCB = OsCurrProcessGet();
1210     runTask = OsCurrTaskGet();
1211 
1212     ret = OsWaitChildProcessCheck(processCB, pid, &childCB);
1213     if (ret != LOS_OK) {
1214         pid = -ret;
1215         goto ERROR;
1216     }
1217 
1218     if (childCB != NULL) {
1219         return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info);
1220     }
1221 
1222     if ((options & LOS_WAIT_WNOHANG) != 0) {
1223         runTask->waitFlag = 0;
1224         pid = 0;
1225         goto ERROR;
1226     }
1227 
1228     OsWaitInsertWaitListInOrder(runTask, processCB);
1229 
1230     runTask->waitFlag = 0;
1231     if (runTask->waitID == OS_INVALID_VALUE) {
1232         pid = -LOS_ECHILD;
1233         goto ERROR;
1234     }
1235 
1236     childCB = OS_PCB_FROM_PID(runTask->waitID);
1237     if (!(childCB->processStatus & OS_PROCESS_STATUS_ZOMBIES)) {
1238         pid = -LOS_ESRCH;
1239         goto ERROR;
1240     }
1241 
1242     return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info);
1243 
1244 ERROR:
1245     SCHEDULER_UNLOCK(intSave);
1246     return pid;
1247 }
1248 
LOS_Wait(INT32 pid,USER INT32 * status,UINT32 options,VOID * rusage)1249 LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage)
1250 {
1251     (VOID)rusage;
1252     UINT32 ret;
1253 
1254     ret = OsWaitOptionsCheck(options);
1255     if (ret != LOS_OK) {
1256         return -ret;
1257     }
1258 
1259     return OsWait(pid, status, NULL, options, NULL);
1260 }
1261 
OsWaitidOptionsCheck(UINT32 options)1262 STATIC UINT32 OsWaitidOptionsCheck(UINT32 options)
1263 {
1264     UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WEXITED | LOS_WAIT_WNOWAIT;
1265 
1266     flag = ~flag & options;
1267     if ((flag != 0) || (options == 0)) {
1268         return LOS_EINVAL;
1269     }
1270 
1271     /*
1272      * only support LOS_WAIT_WNOHANG | LOS_WAIT_WEXITED
1273      * notsupport LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WNOWAIT
1274      */
1275     if ((options & (LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WNOWAIT)) != 0) {
1276         return LOS_EOPNOTSUPP;
1277     }
1278 
1279     if (OS_INT_ACTIVE) {
1280         return LOS_EINTR;
1281     }
1282 
1283     return LOS_OK;
1284 }
1285 
LOS_Waitid(INT32 pid,USER siginfo_t * info,UINT32 options,VOID * rusage)1286 LITE_OS_SEC_TEXT INT32 LOS_Waitid(INT32 pid, USER siginfo_t *info, UINT32 options, VOID *rusage)
1287 {
1288     (VOID)rusage;
1289     UINT32 ret;
1290 
1291     /* check options value */
1292     ret = OsWaitidOptionsCheck(options);
1293     if (ret != LOS_OK) {
1294         return -ret;
1295     }
1296 
1297     return OsWait(pid, NULL, info, options, NULL);
1298 }
1299 
OsSetProcessGroupCheck(const LosProcessCB * processCB,UINT32 gid)1300 STATIC UINT32 OsSetProcessGroupCheck(const LosProcessCB *processCB, UINT32 gid)
1301 {
1302     LosProcessCB *runProcessCB = OsCurrProcessGet();
1303     LosProcessCB *groupProcessCB = OS_PCB_FROM_PID(gid);
1304 
1305     if (OsProcessIsInactive(processCB)) {
1306         return LOS_ESRCH;
1307     }
1308 
1309     if (!OsProcessIsUserMode(processCB) || !OsProcessIsUserMode(groupProcessCB)) {
1310         return LOS_EPERM;
1311     }
1312 
1313     if (runProcessCB->processID == processCB->parentProcessID) {
1314         if (processCB->processStatus & OS_PROCESS_FLAG_ALREADY_EXEC) {
1315             return LOS_EACCES;
1316         }
1317     } else if (processCB->processID != runProcessCB->processID) {
1318         return LOS_ESRCH;
1319     }
1320 
1321     /* Add the process to another existing process group */
1322     if (processCB->processID != gid) {
1323         if (!(groupProcessCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER)) {
1324             return LOS_EPERM;
1325         }
1326 
1327         if ((groupProcessCB->parentProcessID != processCB->parentProcessID) && (gid != processCB->parentProcessID)) {
1328             return LOS_EPERM;
1329         }
1330     }
1331 
1332     return LOS_OK;
1333 }
1334 
OsSetProcessGroupIDUnsafe(UINT32 pid,UINT32 gid,ProcessGroup ** group)1335 STATIC UINT32 OsSetProcessGroupIDUnsafe(UINT32 pid, UINT32 gid, ProcessGroup **group)
1336 {
1337     ProcessGroup *oldGroup = NULL;
1338     ProcessGroup *newGroup = NULL;
1339     LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
1340     UINT32 ret = OsSetProcessGroupCheck(processCB, gid);
1341     if (ret != LOS_OK) {
1342         return ret;
1343     }
1344 
1345     if (processCB->group->groupID == gid) {
1346         return LOS_OK;
1347     }
1348 
1349     oldGroup = processCB->group;
1350     OsExitProcessGroup(processCB, group);
1351 
1352     newGroup = OsFindProcessGroup(gid);
1353     if (newGroup != NULL) {
1354         LOS_ListTailInsert(&newGroup->processList, &processCB->subordinateGroupList);
1355         processCB->group = newGroup;
1356         return LOS_OK;
1357     }
1358 
1359     newGroup = OsCreateProcessGroup(gid);
1360     if (newGroup == NULL) {
1361         LOS_ListTailInsert(&oldGroup->processList, &processCB->subordinateGroupList);
1362         processCB->group = oldGroup;
1363         if (*group != NULL) {
1364             LOS_ListTailInsert(&g_processGroup->groupList, &oldGroup->groupList);
1365             processCB = OS_PCB_FROM_PID(oldGroup->groupID);
1366             processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER;
1367             *group = NULL;
1368         }
1369         return LOS_EPERM;
1370     }
1371     return LOS_OK;
1372 }
1373 
OsSetProcessGroupID(UINT32 pid,UINT32 gid)1374 LITE_OS_SEC_TEXT INT32 OsSetProcessGroupID(UINT32 pid, UINT32 gid)
1375 {
1376     ProcessGroup *group = NULL;
1377     UINT32 ret;
1378     UINT32 intSave;
1379 
1380     if ((OS_PID_CHECK_INVALID(pid)) || (OS_PID_CHECK_INVALID(gid))) {
1381         return -LOS_EINVAL;
1382     }
1383 
1384     SCHEDULER_LOCK(intSave);
1385     ret = OsSetProcessGroupIDUnsafe(pid, gid, &group);
1386     SCHEDULER_UNLOCK(intSave);
1387     (VOID)LOS_MemFree(m_aucSysMem1, group);
1388     return -ret;
1389 }
1390 
OsSetCurrProcessGroupID(UINT32 gid)1391 LITE_OS_SEC_TEXT INT32 OsSetCurrProcessGroupID(UINT32 gid)
1392 {
1393     return OsSetProcessGroupID(OsCurrProcessGet()->processID, gid);
1394 }
1395 
LOS_GetProcessGroupID(UINT32 pid)1396 LITE_OS_SEC_TEXT INT32 LOS_GetProcessGroupID(UINT32 pid)
1397 {
1398     INT32 gid;
1399     UINT32 intSave;
1400     LosProcessCB *processCB = NULL;
1401 
1402     if (OS_PID_CHECK_INVALID(pid)) {
1403         return -LOS_EINVAL;
1404     }
1405 
1406     SCHEDULER_LOCK(intSave);
1407     processCB = OS_PCB_FROM_PID(pid);
1408     if (OsProcessIsUnused(processCB)) {
1409         gid = -LOS_ESRCH;
1410         goto EXIT;
1411     }
1412 
1413     gid = (INT32)processCB->group->groupID;
1414 
1415 EXIT:
1416     SCHEDULER_UNLOCK(intSave);
1417     return gid;
1418 }
1419 
LOS_GetCurrProcessGroupID(VOID)1420 LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID)
1421 {
1422     return LOS_GetProcessGroupID(OsCurrProcessGet()->processID);
1423 }
1424 
1425 #ifdef LOSCFG_KERNEL_VM
OsGetFreePCB(VOID)1426 STATIC LosProcessCB *OsGetFreePCB(VOID)
1427 {
1428     LosProcessCB *processCB = NULL;
1429     UINT32 intSave;
1430 
1431     SCHEDULER_LOCK(intSave);
1432     if (LOS_ListEmpty(&g_freeProcess)) {
1433         SCHEDULER_UNLOCK(intSave);
1434         PRINT_ERR("No idle PCB in the system!\n");
1435         return NULL;
1436     }
1437 
1438     processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_freeProcess));
1439     LOS_ListDelete(&processCB->pendList);
1440     SCHEDULER_UNLOCK(intSave);
1441 
1442     return processCB;
1443 }
1444 
OsUserInitStackAlloc(LosProcessCB * processCB,UINT32 * size)1445 STATIC VOID *OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size)
1446 {
1447     LosVmMapRegion *region = NULL;
1448     UINT32 stackSize = ALIGN(OS_USER_TASK_STACK_SIZE, PAGE_SIZE);
1449 
1450     region = LOS_RegionAlloc(processCB->vmSpace, 0, stackSize,
1451                              VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ |
1452                              VM_MAP_REGION_FLAG_PERM_WRITE, 0);
1453     if (region == NULL) {
1454         return NULL;
1455     }
1456 
1457     LOS_SetRegionTypeAnon(region);
1458     region->regionFlags |= VM_MAP_REGION_FLAG_STACK;
1459 
1460     *size = stackSize;
1461 
1462     return (VOID *)(UINTPTR)region->range.base;
1463 }
1464 
1465 #ifdef LOSCFG_KERNEL_DYNLOAD
OsExecProcessVmSpaceRestore(LosVmSpace * oldSpace)1466 LITE_OS_SEC_TEXT VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace)
1467 {
1468     LosProcessCB *processCB = OsCurrProcessGet();
1469     LosTaskCB *runTask = OsCurrTaskGet();
1470 
1471     processCB->vmSpace = oldSpace;
1472     runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu;
1473     LOS_ArchMmuContextSwitch((LosArchMmu *)runTask->archMmu);
1474 }
1475 
OsExecProcessVmSpaceReplace(LosVmSpace * newSpace,UINTPTR stackBase,INT32 randomDevFD)1476 LITE_OS_SEC_TEXT LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD)
1477 {
1478     LosProcessCB *processCB = OsCurrProcessGet();
1479     LosTaskCB *runTask = OsCurrTaskGet();
1480 
1481     OsProcessThreadGroupDestroy();
1482     OsTaskCBRecycleToFree();
1483 
1484     LosVmSpace *oldSpace = processCB->vmSpace;
1485     processCB->vmSpace = newSpace;
1486     processCB->vmSpace->heapBase += OsGetRndOffset(randomDevFD);
1487     processCB->vmSpace->heapNow = processCB->vmSpace->heapBase;
1488     processCB->vmSpace->mapBase += OsGetRndOffset(randomDevFD);
1489     processCB->vmSpace->mapSize = stackBase - processCB->vmSpace->mapBase;
1490     runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu;
1491     LOS_ArchMmuContextSwitch((LosArchMmu *)runTask->archMmu);
1492     return oldSpace;
1493 }
1494 
OsExecRecycleAndInit(LosProcessCB * processCB,const CHAR * name,LosVmSpace * oldSpace,UINTPTR oldFiles)1495 LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name,
1496                                              LosVmSpace *oldSpace, UINTPTR oldFiles)
1497 {
1498     UINT32 ret;
1499     const CHAR *processName = NULL;
1500 
1501     if ((processCB == NULL) || (name == NULL)) {
1502         return LOS_NOK;
1503     }
1504 
1505     processName = strrchr(name, '/');
1506     processName = (processName == NULL) ? name : (processName + 1); /* 1: Do not include '/' */
1507 
1508     ret = (UINT32)OsSetTaskName(OsCurrTaskGet(), processName, TRUE);
1509     if (ret != LOS_OK) {
1510         return ret;
1511     }
1512 
1513 #ifdef LOSCFG_KERNEL_LITEIPC
1514     (VOID)LiteIpcPoolDestroy(processCB->processID);
1515 #endif
1516 
1517     processCB->sigHandler = 0;
1518     OsCurrTaskGet()->sig.sigprocmask = 0;
1519 
1520     LOS_VmSpaceFree(oldSpace);
1521 #ifdef LOSCFG_FS_VFS
1522     CloseOnExec((struct files_struct *)oldFiles);
1523     delete_files_snapshot((struct files_struct *)oldFiles);
1524 #endif
1525 
1526     OsSwtmrRecycle(processCB->processID);
1527     processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
1528 
1529 #ifdef LOSCFG_SECURITY_VID
1530     VidMapDestroy(processCB);
1531     ret = VidMapListInit(processCB);
1532     if (ret != LOS_OK) {
1533         return LOS_NOK;
1534     }
1535 #endif
1536 
1537     processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT;
1538     processCB->processStatus |= OS_PROCESS_FLAG_ALREADY_EXEC;
1539 
1540     return LOS_OK;
1541 }
1542 
OsExecStart(const TSK_ENTRY_FUNC entry,UINTPTR sp,UINTPTR mapBase,UINT32 mapSize)1543 LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize)
1544 {
1545     UINT32 intSave;
1546 
1547     if (entry == NULL) {
1548         return LOS_NOK;
1549     }
1550 
1551     if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) {
1552         return LOS_NOK;
1553     }
1554 
1555     if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) {
1556         return LOS_NOK;
1557     }
1558 
1559     LosTaskCB *taskCB = OsCurrTaskGet();
1560 
1561     SCHEDULER_LOCK(intSave);
1562     taskCB->userMapBase = mapBase;
1563     taskCB->userMapSize = mapSize;
1564     taskCB->taskEntry = (TSK_ENTRY_FUNC)entry;
1565 
1566     TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize,
1567                                                               (VOID *)taskCB->topOfStack, FALSE);
1568     OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp);
1569     SCHEDULER_UNLOCK(intSave);
1570     return LOS_OK;
1571 }
1572 #endif
1573 
OsUserInitProcessStart(LosProcessCB * processCB,TSK_INIT_PARAM_S * param)1574 STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param)
1575 {
1576     UINT32 intSave;
1577     INT32 ret;
1578 
1579     UINT32 taskID = OsCreateUserTask(processCB->processID, param);
1580     if (taskID == OS_INVALID_VALUE) {
1581         return LOS_NOK;
1582     }
1583 
1584     ret = LOS_SetProcessPriority(processCB->processID, OS_PROCESS_USERINIT_PRIORITY);
1585     if (ret != LOS_OK) {
1586         PRINT_ERR("User init process set priority failed! ERROR:%d \n", ret);
1587         goto EXIT;
1588     }
1589 
1590     SCHEDULER_LOCK(intSave);
1591     processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;
1592     SCHEDULER_UNLOCK(intSave);
1593 
1594     ret = LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST);
1595     if (ret != LOS_OK) {
1596         PRINT_ERR("User init process set scheduler failed! ERROR:%d \n", ret);
1597         goto EXIT;
1598     }
1599 
1600     return LOS_OK;
1601 
1602 EXIT:
1603     (VOID)LOS_TaskDelete(taskID);
1604     return ret;
1605 }
1606 
OsLoadUserInit(LosProcessCB * processCB)1607 STATIC UINT32 OsLoadUserInit(LosProcessCB *processCB)
1608 {
1609     /*              userInitTextStart               -----
1610      * | user text |
1611      *
1612      * | user data |                                initSize
1613      *              userInitBssStart  ---
1614      * | user bss  |                  initBssSize
1615      *              userInitEnd       ---           -----
1616      */
1617     errno_t errRet;
1618     INT32 ret;
1619     CHAR *userInitTextStart = (CHAR *)&__user_init_entry;
1620     CHAR *userInitBssStart = (CHAR *)&__user_init_bss;
1621     CHAR *userInitEnd = (CHAR *)&__user_init_end;
1622     UINT32 initBssSize = userInitEnd - userInitBssStart;
1623     UINT32 initSize = userInitEnd - userInitTextStart;
1624     VOID *userBss = NULL;
1625     VOID *userText = NULL;
1626 
1627     if ((LOS_Align((UINTPTR)userInitTextStart, PAGE_SIZE) != (UINTPTR)userInitTextStart) ||
1628         (LOS_Align((UINTPTR)userInitEnd, PAGE_SIZE) != (UINTPTR)userInitEnd)) {
1629         return LOS_EINVAL;
1630     }
1631 
1632     if ((initSize == 0) || (initSize <= initBssSize)) {
1633         return LOS_EINVAL;
1634     }
1635 
1636     userText = LOS_PhysPagesAllocContiguous(initSize >> PAGE_SHIFT);
1637     if (userText == NULL) {
1638         return LOS_NOK;
1639     }
1640 
1641     errRet = memcpy_s(userText, initSize, (VOID *)&__user_init_load_addr, initSize - initBssSize);
1642     if (errRet != EOK) {
1643         PRINT_ERR("Load user init text, data and bss failed! err : %d\n", errRet);
1644         goto ERROR;
1645     }
1646     ret = LOS_VaddrToPaddrMmap(processCB->vmSpace, (VADDR_T)(UINTPTR)userInitTextStart, LOS_PaddrQuery(userText),
1647                                initSize, VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE |
1648                                VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_PERM_EXECUTE |
1649                                VM_MAP_REGION_FLAG_PERM_USER);
1650     if (ret < 0) {
1651         PRINT_ERR("Mmap user init text, data and bss failed! err : %d\n", ret);
1652         goto ERROR;
1653     }
1654 
1655     /* The User init boot segment may not actually exist */
1656     if (initBssSize != 0) {
1657         userBss = (VOID *)((UINTPTR)userText + userInitBssStart - userInitTextStart);
1658         errRet = memset_s(userBss, initBssSize, 0, initBssSize);
1659         if (errRet != EOK) {
1660             PRINT_ERR("memset user init bss failed! err : %d\n", errRet);
1661             goto ERROR;
1662         }
1663     }
1664 
1665     return LOS_OK;
1666 
1667 ERROR:
1668     (VOID)LOS_PhysPagesFreeContiguous(userText, initSize >> PAGE_SHIFT);
1669     return LOS_NOK;
1670 }
1671 
OsUserInitProcess(VOID)1672 LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID)
1673 {
1674     UINT32 ret;
1675     UINT32 size;
1676     TSK_INIT_PARAM_S param = { 0 };
1677     VOID *stack = NULL;
1678 
1679     LosProcessCB *processCB = OS_PCB_FROM_PID(g_userInitProcess);
1680     ret = OsProcessCreateInit(processCB, OS_USER_MODE, "Init");
1681     if (ret != LOS_OK) {
1682         return ret;
1683     }
1684 
1685     ret = OsLoadUserInit(processCB);
1686     if (ret != LOS_OK) {
1687         goto ERROR;
1688     }
1689 
1690     stack = OsUserInitStackAlloc(processCB, &size);
1691     if (stack == NULL) {
1692         PRINT_ERR("Alloc user init process user stack failed!\n");
1693         goto ERROR;
1694     }
1695 
1696     param.pfnTaskEntry = (TSK_ENTRY_FUNC)(CHAR *)&__user_init_entry;
1697     param.userParam.userSP = (UINTPTR)stack + size;
1698     param.userParam.userMapBase = (UINTPTR)stack;
1699     param.userParam.userMapSize = size;
1700     param.uwResved = OS_TASK_FLAG_PTHREAD_JOIN;
1701     ret = OsUserInitProcessStart(processCB, &param);
1702     if (ret != LOS_OK) {
1703         (VOID)OsUnMMap(processCB->vmSpace, param.userParam.userMapBase, param.userParam.userMapSize);
1704         goto ERROR;
1705     }
1706 
1707     return LOS_OK;
1708 
1709 ERROR:
1710     OsDeInitPCB(processCB);
1711     return ret;
1712 }
1713 
OsCopyUser(LosProcessCB * childCB,LosProcessCB * parentCB)1714 STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
1715 {
1716 #ifdef LOSCFG_SECURITY_CAPABILITY
1717     UINT32 size = sizeof(User) + sizeof(UINT32) * (parentCB->user->groupNumber - 1);
1718     childCB->user = LOS_MemAlloc(m_aucSysMem1, size);
1719     if (childCB->user == NULL) {
1720         return LOS_ENOMEM;
1721     }
1722 
1723     (VOID)memcpy_s(childCB->user, size, parentCB->user, size);
1724 #endif
1725     return LOS_OK;
1726 }
1727 
OsInitCopyTaskParam(LosProcessCB * childProcessCB,const CHAR * name,UINTPTR entry,UINT32 size,TSK_INIT_PARAM_S * childPara)1728 STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size,
1729                                 TSK_INIT_PARAM_S *childPara)
1730 {
1731     LosTaskCB *mainThread = NULL;
1732     UINT32 intSave;
1733 
1734     SCHEDULER_LOCK(intSave);
1735     mainThread = OsCurrTaskGet();
1736 
1737     if (OsProcessIsUserMode(childProcessCB)) {
1738         childPara->pfnTaskEntry = mainThread->taskEntry;
1739         childPara->uwStackSize = mainThread->stackSize;
1740         childPara->userParam.userArea = mainThread->userArea;
1741         childPara->userParam.userMapBase = mainThread->userMapBase;
1742         childPara->userParam.userMapSize = mainThread->userMapSize;
1743     } else {
1744         childPara->pfnTaskEntry = (TSK_ENTRY_FUNC)entry;
1745         childPara->uwStackSize = size;
1746     }
1747     childPara->pcName = (CHAR *)name;
1748     childPara->policy = mainThread->policy;
1749     childPara->usTaskPrio = mainThread->priority;
1750     childPara->processID = childProcessCB->processID;
1751     if (mainThread->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
1752         childPara->uwResved = LOS_TASK_ATTR_JOINABLE;
1753     }
1754 
1755     SCHEDULER_UNLOCK(intSave);
1756 }
1757 
OsCopyTask(UINT32 flags,LosProcessCB * childProcessCB,const CHAR * name,UINTPTR entry,UINT32 size)1758 STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size)
1759 {
1760     LosTaskCB *runTask = OsCurrTaskGet();
1761     TSK_INIT_PARAM_S childPara = { 0 };
1762     UINT32 ret;
1763     UINT32 intSave;
1764     UINT32 taskID;
1765 
1766     OsInitCopyTaskParam(childProcessCB, name, entry, size, &childPara);
1767 
1768     ret = LOS_TaskCreateOnly(&taskID, &childPara);
1769     if (ret != LOS_OK) {
1770         if (ret == LOS_ERRNO_TSK_TCB_UNAVAILABLE) {
1771             return LOS_EAGAIN;
1772         }
1773         return LOS_ENOMEM;
1774     }
1775 
1776     LosTaskCB *childTaskCB = OS_TCB_FROM_TID(taskID);
1777     childTaskCB->taskStatus = runTask->taskStatus;
1778     childTaskCB->basePrio = runTask->basePrio;
1779     if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
1780         childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING;
1781     } else {
1782         if (OS_SCHEDULER_ACTIVE) {
1783             LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus);
1784         }
1785         childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED;
1786     }
1787 
1788     if (OsProcessIsUserMode(childProcessCB)) {
1789         SCHEDULER_LOCK(intSave);
1790         OsUserCloneParentStack(childTaskCB->stackPointer, runTask->topOfStack, runTask->stackSize);
1791         SCHEDULER_UNLOCK(intSave);
1792     }
1793     return LOS_OK;
1794 }
1795 
OsCopyParent(UINT32 flags,LosProcessCB * childProcessCB,LosProcessCB * runProcessCB)1796 STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
1797 {
1798     UINT32 ret;
1799     UINT32 intSave;
1800     LosProcessCB *parentProcessCB = NULL;
1801 
1802     SCHEDULER_LOCK(intSave);
1803 
1804     if (flags & CLONE_PARENT) {
1805         parentProcessCB = OS_PCB_FROM_PID(runProcessCB->parentProcessID);
1806     } else {
1807         parentProcessCB = runProcessCB;
1808     }
1809     childProcessCB->parentProcessID = parentProcessCB->processID;
1810     LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);
1811     childProcessCB->group = parentProcessCB->group;
1812     LOS_ListTailInsert(&parentProcessCB->group->processList, &childProcessCB->subordinateGroupList);
1813     ret = OsCopyUser(childProcessCB, parentProcessCB);
1814 
1815     SCHEDULER_UNLOCK(intSave);
1816     return ret;
1817 }
1818 
OsCopyMM(UINT32 flags,LosProcessCB * childProcessCB,LosProcessCB * runProcessCB)1819 STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
1820 {
1821     status_t status;
1822     UINT32 intSave;
1823 
1824     if (!OsProcessIsUserMode(childProcessCB)) {
1825         return LOS_OK;
1826     }
1827 
1828     if (flags & CLONE_VM) {
1829         SCHEDULER_LOCK(intSave);
1830         childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb;
1831         childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb;
1832         SCHEDULER_UNLOCK(intSave);
1833         return LOS_OK;
1834     }
1835 
1836     status = LOS_VmSpaceClone(runProcessCB->vmSpace, childProcessCB->vmSpace);
1837     if (status != LOS_OK) {
1838         return LOS_ENOMEM;
1839     }
1840     return LOS_OK;
1841 }
1842 
OsCopyFile(UINT32 flags,LosProcessCB * childProcessCB,LosProcessCB * runProcessCB)1843 STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
1844 {
1845 #ifdef LOSCFG_FS_VFS
1846     if (flags & CLONE_FILES) {
1847         childProcessCB->files = runProcessCB->files;
1848     } else {
1849         childProcessCB->files = dup_fd(runProcessCB->files);
1850     }
1851     if (childProcessCB->files == NULL) {
1852         return LOS_ENOMEM;
1853     }
1854 #endif
1855 
1856     childProcessCB->consoleID = runProcessCB->consoleID;
1857     childProcessCB->umask = runProcessCB->umask;
1858     return LOS_OK;
1859 }
1860 
OsForkInitPCB(UINT32 flags,LosProcessCB * child,const CHAR * name,UINTPTR sp,UINT32 size)1861 STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINTPTR sp, UINT32 size)
1862 {
1863     UINT32 ret;
1864     LosProcessCB *run = OsCurrProcessGet();
1865 
1866     ret = OsInitPCB(child, run->processMode, name);
1867     if (ret != LOS_OK) {
1868         return ret;
1869     }
1870 
1871     ret = OsCopyParent(flags, child, run);
1872     if (ret != LOS_OK) {
1873         return ret;
1874     }
1875 
1876     return OsCopyTask(flags, child, name, sp, size);
1877 }
1878 
OsChildSetProcessGroupAndSched(LosProcessCB * child,LosProcessCB * run)1879 STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *run)
1880 {
1881     UINT32 intSave;
1882     UINT32 ret;
1883     ProcessGroup *group = NULL;
1884 
1885     SCHEDULER_LOCK(intSave);
1886     if (run->group->groupID == OS_USER_PRIVILEGE_PROCESS_GROUP) {
1887         ret = OsSetProcessGroupIDUnsafe(child->processID, child->processID, &group);
1888         if (ret != LOS_OK) {
1889             SCHEDULER_UNLOCK(intSave);
1890             return LOS_ENOMEM;
1891         }
1892     }
1893 
1894     child->processStatus &= ~OS_PROCESS_STATUS_INIT;
1895     OsSchedTaskEnQueue(OS_TCB_FROM_TID(child->threadGroupID));
1896     SCHEDULER_UNLOCK(intSave);
1897 
1898     (VOID)LOS_MemFree(m_aucSysMem1, group);
1899     return LOS_OK;
1900 }
1901 
OsCopyProcessResources(UINT32 flags,LosProcessCB * child,LosProcessCB * run)1902 STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProcessCB *run)
1903 {
1904     UINT32 ret;
1905 
1906     ret = OsCopyMM(flags, child, run);
1907     if (ret != LOS_OK) {
1908         return ret;
1909     }
1910 
1911     ret = OsCopyFile(flags, child, run);
1912     if (ret != LOS_OK) {
1913         return ret;
1914     }
1915 
1916 #ifdef LOSCFG_KERNEL_LITEIPC
1917     if (run->ipcInfo != NULL) {
1918         child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo));
1919         if (child->ipcInfo == NULL) {
1920             return LOS_ENOMEM;
1921         }
1922     }
1923 #endif
1924 
1925 #ifdef LOSCFG_SECURITY_CAPABILITY
1926     OsCopyCapability(run, child);
1927 #endif
1928 
1929     return LOS_OK;
1930 }
1931 
OsCopyProcess(UINT32 flags,const CHAR * name,UINTPTR sp,UINT32 size)1932 STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size)
1933 {
1934     UINT32 ret, processID;
1935     LosProcessCB *run = OsCurrProcessGet();
1936 
1937     LosProcessCB *child = OsGetFreePCB();
1938     if (child == NULL) {
1939         return -LOS_EAGAIN;
1940     }
1941     processID = child->processID;
1942 
1943     ret = OsForkInitPCB(flags, child, name, sp, size);
1944     if (ret != LOS_OK) {
1945         goto ERROR_INIT;
1946     }
1947 
1948     ret = OsCopyProcessResources(flags, child, run);
1949     if (ret != LOS_OK) {
1950         goto ERROR_TASK;
1951     }
1952 
1953     ret = OsChildSetProcessGroupAndSched(child, run);
1954     if (ret != LOS_OK) {
1955         goto ERROR_TASK;
1956     }
1957 
1958     LOS_MpSchedule(OS_MP_CPU_ALL);
1959     if (OS_SCHEDULER_ACTIVE) {
1960         LOS_Schedule();
1961     }
1962 
1963     return processID;
1964 
1965 ERROR_TASK:
1966     (VOID)LOS_TaskDelete(child->threadGroupID);
1967 ERROR_INIT:
1968     OsDeInitPCB(child);
1969     return -ret;
1970 }
1971 
OsClone(UINT32 flags,UINTPTR sp,UINT32 size)1972 LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size)
1973 {
1974     UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_VM;
1975 
1976     if (flags & (~cloneFlag)) {
1977         PRINT_WARN("Clone dont support some flags!\n");
1978     }
1979 
1980     return OsCopyProcess(cloneFlag & flags, NULL, sp, size);
1981 }
1982 
LOS_Fork(UINT32 flags,const CHAR * name,const TSK_ENTRY_FUNC entry,UINT32 stackSize)1983 LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize)
1984 {
1985     UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES;
1986 
1987     if (flags & (~cloneFlag)) {
1988         PRINT_WARN("Clone dont support some flags!\n");
1989     }
1990 
1991     flags |= CLONE_FILES;
1992     return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize);
1993 }
1994 #else
OsUserInitProcess(VOID)1995 LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID)
1996 {
1997     return 0;
1998 }
1999 #endif
2000 
LOS_Exit(INT32 status)2001 LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status)
2002 {
2003     UINT32 intSave;
2004 
2005     (void)status;
2006 
2007     /* The exit of a kernel - state process must be kernel - state and all threads must actively exit */
2008     LosProcessCB *processCB = OsCurrProcessGet();
2009     SCHEDULER_LOCK(intSave);
2010     if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) {
2011         SCHEDULER_UNLOCK(intSave);
2012         PRINT_ERR("Kernel-state processes with multiple threads are not allowed to exit directly\n");
2013         return;
2014     }
2015     SCHEDULER_UNLOCK(intSave);
2016 
2017     OsProcessThreadGroupDestroy();
2018     OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK);
2019 }
2020 
LOS_GetUsedPIDList(UINT32 * pidList,INT32 pidMaxNum)2021 LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum)
2022 {
2023     LosProcessCB *pcb = NULL;
2024     INT32 num = 0;
2025     UINT32 intSave;
2026     UINT32 pid = 1;
2027 
2028     if (pidList == NULL) {
2029         return 0;
2030     }
2031     SCHEDULER_LOCK(intSave);
2032     while (OsProcessIDUserCheckInvalid(pid) == false) {
2033         pcb = OS_PCB_FROM_PID(pid);
2034         pid++;
2035         if (OsProcessIsUnused(pcb)) {
2036             continue;
2037         }
2038         pidList[num] = pcb->processID;
2039         num++;
2040         if (num >= pidMaxNum) {
2041             break;
2042         }
2043     }
2044     SCHEDULER_UNLOCK(intSave);
2045     return num;
2046 }
2047 
2048 #ifdef LOSCFG_FS_VFS
LOS_GetFdTable(UINT32 pid)2049 LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid)
2050 {
2051     LosProcessCB *pcb = NULL;
2052     struct files_struct *files = NULL;
2053 
2054     if (OS_PID_CHECK_INVALID(pid)) {
2055         return NULL;
2056     }
2057     pcb = OS_PCB_FROM_PID(pid);
2058     files = pcb->files;
2059     if (files == NULL) {
2060         return NULL;
2061     }
2062 
2063     return files->fdt;
2064 }
2065 #endif
2066 
LOS_GetCurrProcessID(VOID)2067 LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID)
2068 {
2069     return OsCurrProcessGet()->processID;
2070 }
2071 
2072 #ifdef LOSCFG_KERNEL_VM
ThreadGroupActiveTaskKilled(LosTaskCB * taskCB)2073 STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB)
2074 {
2075     INT32 ret;
2076 
2077     taskCB->taskStatus |= OS_TASK_FLAG_EXIT_KILL;
2078 #ifdef LOSCFG_KERNEL_SMP
2079     /** The other core that the thread is running on and is currently running in a non-system call */
2080     if (!taskCB->sig.sigIntLock && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
2081         taskCB->signal = SIGNAL_KILL;
2082         LOS_MpSchedule(taskCB->currCpu);
2083     } else
2084 #endif
2085     {
2086         ret = OsTaskKillUnsafe(taskCB->taskID, SIGKILL);
2087         if (ret != LOS_OK) {
2088             PRINT_ERR("pid %u exit, Exit task group %u kill %u failed! ERROR: %d\n",
2089                       taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, ret);
2090         }
2091     }
2092 
2093     if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) {
2094         taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN;
2095         LOS_ListInit(&taskCB->joinList);
2096     }
2097 
2098     ret = OsTaskJoinPendUnsafe(taskCB);
2099     if (ret != LOS_OK) {
2100         PRINT_ERR("pid %u exit, Exit task group %u to wait others task %u(0x%x) exit failed! ERROR: %d\n",
2101                   taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, taskCB->taskStatus, ret);
2102     }
2103 }
2104 #endif
2105 
OsProcessThreadGroupDestroy(VOID)2106 LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID)
2107 {
2108 #ifdef LOSCFG_KERNEL_VM
2109     UINT32 intSave;
2110 
2111     LosProcessCB *processCB = OsCurrProcessGet();
2112     LosTaskCB *currTask = OsCurrTaskGet();
2113     SCHEDULER_LOCK(intSave);
2114     if ((processCB->processStatus & OS_PROCESS_FLAG_EXIT) || !OsProcessIsUserMode(processCB)) {
2115         SCHEDULER_UNLOCK(intSave);
2116         return;
2117     }
2118 
2119     processCB->processStatus |= OS_PROCESS_FLAG_EXIT;
2120     processCB->threadGroupID = currTask->taskID;
2121 
2122     LOS_DL_LIST *list = &processCB->threadSiblingList;
2123     LOS_DL_LIST *head = list;
2124     do {
2125         LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList);
2126         if ((OsTaskIsInactive(taskCB) ||
2127             ((taskCB->taskStatus & OS_TASK_STATUS_READY) && !taskCB->sig.sigIntLock)) &&
2128             !(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
2129             OsInactiveTaskDelete(taskCB);
2130         } else if (taskCB != currTask) {
2131             ThreadGroupActiveTaskKilled(taskCB);
2132         } else {
2133             /* Skip the current task */
2134             list = list->pstNext;
2135         }
2136     } while (head != list->pstNext);
2137 
2138     SCHEDULER_UNLOCK(intSave);
2139 
2140     LOS_ASSERT(processCB->threadNumber == 1);
2141 #endif
2142     return;
2143 }
2144 
LOS_GetSystemProcessMaximum(VOID)2145 LITE_OS_SEC_TEXT UINT32 LOS_GetSystemProcessMaximum(VOID)
2146 {
2147     return g_processMaxNum;
2148 }
2149 
OsGetUserInitProcessID(VOID)2150 LITE_OS_SEC_TEXT UINT32 OsGetUserInitProcessID(VOID)
2151 {
2152     return g_userInitProcess;
2153 }
2154 
OsGetKernelInitProcessID(VOID)2155 LITE_OS_SEC_TEXT UINT32 OsGetKernelInitProcessID(VOID)
2156 {
2157     return g_kernelInitProcess;
2158 }
2159 
OsGetIdleProcessID(VOID)2160 LITE_OS_SEC_TEXT UINT32 OsGetIdleProcessID(VOID)
2161 {
2162     return g_kernelIdleProcess;
2163 }
2164 
OsSetSigHandler(UINTPTR addr)2165 LITE_OS_SEC_TEXT VOID OsSetSigHandler(UINTPTR addr)
2166 {
2167     OsCurrProcessGet()->sigHandler = addr;
2168 }
2169 
OsGetSigHandler(VOID)2170 LITE_OS_SEC_TEXT UINTPTR OsGetSigHandler(VOID)
2171 {
2172     return OsCurrProcessGet()->sigHandler;
2173 }
2174 
2175