• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2022 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,SchedParam * param)90 UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB, SchedParam *param)
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             LosTaskCB *task = OS_TCB_FROM_TID(processCB->threadGroupID);
104             task->ops->schedParamGet(task, param);
105         } else {
106             OsSchedProcessDefaultSchedParamGet(param->policy, param);
107         }
108     } else {
109         LosTaskCB *runTask = OsCurrTaskGet();
110         runTask->ops->schedParamGet(runTask, param);
111     }
112 
113 #ifdef LOSCFG_KERNEL_VM
114     taskCB->archMmu = (UINTPTR)&processCB->vmSpace->archMmu;
115 #endif
116     if (!processCB->threadNumber) {
117         processCB->threadGroupID = taskCB->taskID;
118     }
119     processCB->threadNumber++;
120 
121     numCount = processCB->threadCount;
122     processCB->threadCount++;
123     SCHEDULER_UNLOCK(intSave);
124     return numCount;
125 }
126 
OsCreateProcessGroup(UINT32 pid)127 STATIC ProcessGroup *OsCreateProcessGroup(UINT32 pid)
128 {
129     LosProcessCB *processCB = NULL;
130     ProcessGroup *group = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessGroup));
131     if (group == NULL) {
132         return NULL;
133     }
134 
135     group->groupID = pid;
136     LOS_ListInit(&group->processList);
137     LOS_ListInit(&group->exitProcessList);
138 
139     processCB = OS_PCB_FROM_PID(pid);
140     LOS_ListTailInsert(&group->processList, &processCB->subordinateGroupList);
141     processCB->group = group;
142     processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER;
143     if (g_processGroup != NULL) {
144         LOS_ListTailInsert(&g_processGroup->groupList, &group->groupList);
145     }
146 
147     return group;
148 }
149 
OsExitProcessGroup(LosProcessCB * processCB,ProcessGroup ** group)150 STATIC VOID OsExitProcessGroup(LosProcessCB *processCB, ProcessGroup **group)
151 {
152     LosProcessCB *groupProcessCB = OS_PCB_FROM_PID(processCB->group->groupID);
153 
154     LOS_ListDelete(&processCB->subordinateGroupList);
155     if (LOS_ListEmpty(&processCB->group->processList) && LOS_ListEmpty(&processCB->group->exitProcessList)) {
156         LOS_ListDelete(&processCB->group->groupList);
157         groupProcessCB->processStatus &= ~OS_PROCESS_FLAG_GROUP_LEADER;
158         *group = processCB->group;
159         if (OsProcessIsUnused(groupProcessCB) && !(groupProcessCB->processStatus & OS_PROCESS_FLAG_EXIT)) {
160             LOS_ListDelete(&groupProcessCB->pendList);
161             OsInsertPCBToFreeList(groupProcessCB);
162         }
163     }
164 
165     processCB->group = NULL;
166 }
167 
OsFindProcessGroup(UINT32 gid)168 STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid)
169 {
170     ProcessGroup *group = NULL;
171     if (g_processGroup->groupID == gid) {
172         return g_processGroup;
173     }
174 
175     LOS_DL_LIST_FOR_EACH_ENTRY(group, &g_processGroup->groupList, ProcessGroup, groupList) {
176         if (group->groupID == gid) {
177             return group;
178         }
179     }
180 
181     PRINT_INFO("%s failed! group id = %u\n", __FUNCTION__, gid);
182     return NULL;
183 }
184 
OsSendSignalToSpecifyProcessGroup(ProcessGroup * group,siginfo_t * info,INT32 permission)185 STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *group, siginfo_t *info, INT32 permission)
186 {
187     INT32 ret, success, err;
188     LosProcessCB *childCB = NULL;
189 
190     success = 0;
191     ret = -LOS_ESRCH;
192     LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(group->processList), LosProcessCB, subordinateGroupList) {
193         if (childCB->processID == 0) {
194             continue;
195         }
196 
197         err = OsDispatch(childCB->processID, info, permission);
198         success |= !err;
199         ret = err;
200     }
201     /* At least one success. */
202     return success ? LOS_OK : ret;
203 }
204 
OsSendSignalToAllProcess(siginfo_t * info,INT32 permission)205 LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission)
206 {
207     INT32 ret, success, err;
208     ProcessGroup *group = NULL;
209 
210     success = 0;
211     err = OsSendSignalToSpecifyProcessGroup(g_processGroup, info, permission);
212     success |= !err;
213     ret = err;
214     /* all processes group */
215     LOS_DL_LIST_FOR_EACH_ENTRY(group, &g_processGroup->groupList, ProcessGroup, groupList) {
216         /* all processes in the process group. */
217         err = OsSendSignalToSpecifyProcessGroup(group, info, permission);
218         success |= !err;
219         ret = err;
220     }
221     return success ? LOS_OK : ret;
222 }
223 
OsSendSignalToProcessGroup(INT32 pid,siginfo_t * info,INT32 permission)224 LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission)
225 {
226     ProcessGroup *group = NULL;
227     /* Send SIG to all processes in process group PGRP.
228        If PGRP is zero, send SIG to all processes in
229        the current process's process group. */
230     group = OsFindProcessGroup(pid ? -pid : LOS_GetCurrProcessGroupID());
231     if (group == NULL) {
232         return -LOS_ESRCH;
233     }
234     /* all processes in the process group. */
235     return OsSendSignalToSpecifyProcessGroup(group, info, permission);
236 }
237 
OsFindGroupExitProcess(ProcessGroup * group,INT32 pid)238 STATIC LosProcessCB *OsFindGroupExitProcess(ProcessGroup *group, INT32 pid)
239 {
240     LosProcessCB *childCB = NULL;
241 
242     LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(group->exitProcessList), LosProcessCB, subordinateGroupList) {
243         if ((childCB->processID == pid) || (pid == OS_INVALID_VALUE)) {
244             return childCB;
245         }
246     }
247 
248     PRINT_INFO("%s find exit process : %d failed in group : %u\n", __FUNCTION__, pid, group->groupID);
249     return NULL;
250 }
251 
OsFindChildProcess(const LosProcessCB * processCB,INT32 childPid)252 STATIC UINT32 OsFindChildProcess(const LosProcessCB *processCB, INT32 childPid)
253 {
254     LosProcessCB *childCB = NULL;
255 
256     if (childPid < 0) {
257         goto ERR;
258     }
259 
260     LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(processCB->childrenList), LosProcessCB, siblingList) {
261         if (childCB->processID == childPid) {
262             return LOS_OK;
263         }
264     }
265 
266 ERR:
267     PRINT_INFO("%s is find the child : %d failed in parent : %u\n", __FUNCTION__, childPid, processCB->processID);
268     return LOS_NOK;
269 }
270 
OsFindExitChildProcess(const LosProcessCB * processCB,INT32 childPid)271 STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, INT32 childPid)
272 {
273     LosProcessCB *exitChild = NULL;
274 
275     LOS_DL_LIST_FOR_EACH_ENTRY(exitChild, &(processCB->exitChildList), LosProcessCB, siblingList) {
276         if ((childPid == OS_INVALID_VALUE) || (exitChild->processID == childPid)) {
277             return exitChild;
278         }
279     }
280 
281     PRINT_INFO("%s is find the exit child : %d failed in parent : %u\n", __FUNCTION__, childPid, processCB->processID);
282     return NULL;
283 }
284 
OsWaitWakeTask(LosTaskCB * taskCB,UINT32 wakePID)285 VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID)
286 {
287     taskCB->waitID = wakePID;
288     taskCB->ops->wake(taskCB);
289 #ifdef LOSCFG_KERNEL_SMP
290     LOS_MpSchedule(OS_MP_CPU_ALL);
291 #endif
292 }
293 
OsWaitWakeSpecifiedProcess(LOS_DL_LIST * head,const LosProcessCB * processCB,LOS_DL_LIST ** anyList)294 STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList)
295 {
296     LOS_DL_LIST *list = head;
297     LosTaskCB *taskCB = NULL;
298     UINT32 pid = 0;
299     BOOL find = FALSE;
300 
301     while (list->pstNext != head) {
302         taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
303         if ((taskCB->waitFlag == OS_PROCESS_WAIT_PRO) && (taskCB->waitID == processCB->processID)) {
304             if (pid == 0) {
305                 pid = processCB->processID;
306                 find = TRUE;
307             } else {
308                 pid = OS_INVALID_VALUE;
309             }
310 
311             OsWaitWakeTask(taskCB, pid);
312             continue;
313         }
314 
315         if (taskCB->waitFlag != OS_PROCESS_WAIT_PRO) {
316             *anyList = list;
317             break;
318         }
319         list = list->pstNext;
320     }
321 
322     return find;
323 }
324 
OsWaitCheckAndWakeParentProcess(LosProcessCB * parentCB,const LosProcessCB * processCB)325 STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB)
326 {
327     LOS_DL_LIST *head = &parentCB->waitList;
328     LOS_DL_LIST *list = NULL;
329     LosTaskCB *taskCB = NULL;
330     BOOL findSpecified = FALSE;
331 
332     if (LOS_ListEmpty(&parentCB->waitList)) {
333         return;
334     }
335 
336     findSpecified = OsWaitWakeSpecifiedProcess(head, processCB, &list);
337     if (findSpecified == TRUE) {
338         /* No thread is waiting for any child process to finish */
339         if (LOS_ListEmpty(&parentCB->waitList)) {
340             return;
341         } else if (!LOS_ListEmpty(&parentCB->childrenList)) {
342             /* Other child processes exist, and other threads that are waiting
343              * for the child to finish continue to wait
344              */
345             return;
346         }
347     }
348 
349     /* Waiting threads are waiting for a specified child process to finish */
350     if (list == NULL) {
351         return;
352     }
353 
354     /* No child processes exist and all waiting threads are awakened */
355     if (findSpecified == TRUE) {
356         while (list->pstNext != head) {
357             taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
358             OsWaitWakeTask(taskCB, OS_INVALID_VALUE);
359         }
360         return;
361     }
362 
363     while (list->pstNext != head) {
364         taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
365         if (taskCB->waitFlag == OS_PROCESS_WAIT_GID) {
366             if (taskCB->waitID != processCB->group->groupID) {
367                 list = list->pstNext;
368                 continue;
369             }
370         }
371 
372         if (findSpecified == FALSE) {
373             OsWaitWakeTask(taskCB, processCB->processID);
374             findSpecified = TRUE;
375         } else {
376             OsWaitWakeTask(taskCB, OS_INVALID_VALUE);
377         }
378 
379         if (!LOS_ListEmpty(&parentCB->childrenList)) {
380             break;
381         }
382     }
383 
384     return;
385 }
386 
OsProcessResourcesToFree(LosProcessCB * processCB)387 LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
388 {
389 #ifdef LOSCFG_KERNEL_VM
390     if (OsProcessIsUserMode(processCB)) {
391         (VOID)OsVmSpaceRegionFree(processCB->vmSpace);
392     }
393 #endif
394 
395 #ifdef LOSCFG_FS_VFS
396     if (OsProcessIsUserMode(processCB)) {
397         delete_files(processCB->files);
398     }
399     processCB->files = NULL;
400 #endif
401 
402 #ifdef LOSCFG_SECURITY_CAPABILITY
403     if (processCB->user != NULL) {
404         (VOID)LOS_MemFree(m_aucSysMem1, processCB->user);
405         processCB->user = NULL;
406     }
407 #endif
408 
409     OsSwtmrRecycle(processCB->processID);
410     processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
411 
412 #ifdef LOSCFG_SECURITY_VID
413     if (processCB->timerIdMap.bitMap != NULL) {
414         VidMapDestroy(processCB);
415         processCB->timerIdMap.bitMap = NULL;
416     }
417 #endif
418 
419 #ifdef LOSCFG_KERNEL_LITEIPC
420     (VOID)LiteIpcPoolDestroy(processCB->processID);
421 #endif
422 
423 #ifdef LOSCFG_KERNEL_CPUP
424     UINT32 intSave;
425     OsCpupBase *processCpup = processCB->processCpup;
426     SCHEDULER_LOCK(intSave);
427     processCB->processCpup = NULL;
428     SCHEDULER_UNLOCK(intSave);
429     (VOID)LOS_MemFree(m_aucSysMem1, processCpup);
430 #endif
431 
432     if (processCB->resourceLimit != NULL) {
433         (VOID)LOS_MemFree((VOID *)m_aucSysMem0, processCB->resourceLimit);
434         processCB->resourceLimit = NULL;
435     }
436 }
437 
OsRecycleZombiesProcess(LosProcessCB * childCB,ProcessGroup ** group)438 LITE_OS_SEC_TEXT STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **group)
439 {
440     OsExitProcessGroup(childCB, group);
441     LOS_ListDelete(&childCB->siblingList);
442     if (childCB->processStatus & OS_PROCESS_STATUS_ZOMBIES) {
443         OsDeleteTaskFromProcess(OS_TCB_FROM_TID(childCB->threadGroupID));
444         childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES;
445         childCB->processStatus |= OS_PROCESS_FLAG_UNUSED;
446     }
447 
448     LOS_ListDelete(&childCB->pendList);
449     if (childCB->processStatus & OS_PROCESS_FLAG_EXIT) {
450         LOS_ListHeadInsert(&g_processRecycleList, &childCB->pendList);
451     } else if (childCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) {
452         LOS_ListTailInsert(&g_processRecycleList, &childCB->pendList);
453     } else {
454         OsInsertPCBToFreeList(childCB);
455     }
456 }
457 
OsDealAliveChildProcess(LosProcessCB * processCB)458 STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
459 {
460     UINT32 parentID;
461     LosProcessCB *childCB = NULL;
462     LosProcessCB *parentCB = NULL;
463     LOS_DL_LIST *nextList = NULL;
464     LOS_DL_LIST *childHead = NULL;
465 
466     if (!LOS_ListEmpty(&processCB->childrenList)) {
467         childHead = processCB->childrenList.pstNext;
468         LOS_ListDelete(&(processCB->childrenList));
469         if (OsProcessIsUserMode(processCB)) {
470             parentID = g_userInitProcess;
471         } else {
472             parentID = g_kernelInitProcess;
473         }
474 
475         for (nextList = childHead; ;) {
476             childCB = OS_PCB_FROM_SIBLIST(nextList);
477             childCB->parentProcessID = parentID;
478             nextList = nextList->pstNext;
479             if (nextList == childHead) {
480                 break;
481             }
482         }
483 
484         parentCB = OS_PCB_FROM_PID(parentID);
485         LOS_ListTailInsertList(&parentCB->childrenList, childHead);
486     }
487 
488     return;
489 }
490 
OsChildProcessResourcesFree(const LosProcessCB * processCB)491 STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB)
492 {
493     LosProcessCB *childCB = NULL;
494     ProcessGroup *group = NULL;
495 
496     while (!LOS_ListEmpty(&((LosProcessCB *)processCB)->exitChildList)) {
497         childCB = LOS_DL_LIST_ENTRY(processCB->exitChildList.pstNext, LosProcessCB, siblingList);
498         OsRecycleZombiesProcess(childCB, &group);
499         (VOID)LOS_MemFree(m_aucSysMem1, group);
500     }
501 }
502 
OsProcessNaturalExit(LosProcessCB * processCB,UINT32 status)503 VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status)
504 {
505     LosProcessCB *parentCB = NULL;
506 
507     OsChildProcessResourcesFree(processCB);
508 
509     /* is a child process */
510     if (processCB->parentProcessID != OS_INVALID_VALUE) {
511         parentCB = OS_PCB_FROM_PID(processCB->parentProcessID);
512         LOS_ListDelete(&processCB->siblingList);
513         if (!OsProcessExitCodeSignalIsSet(processCB)) {
514             OsProcessExitCodeSet(processCB, status);
515         }
516         LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList);
517         LOS_ListDelete(&processCB->subordinateGroupList);
518         LOS_ListTailInsert(&processCB->group->exitProcessList, &processCB->subordinateGroupList);
519 
520         OsWaitCheckAndWakeParentProcess(parentCB, processCB);
521 
522         OsDealAliveChildProcess(processCB);
523 
524         processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES;
525 
526 #ifdef LOSCFG_KERNEL_VM
527         (VOID)OsKill(processCB->parentProcessID, SIGCHLD, OS_KERNEL_KILL_PERMISSION);
528 #endif
529         LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);
530         return;
531     }
532 
533     LOS_Panic("pid : %u is the root process exit!\n", processCB->processID);
534     return;
535 }
536 
OsProcessInit(VOID)537 STATIC UINT32 OsProcessInit(VOID)
538 {
539     UINT32 index;
540     UINT32 size;
541 
542     g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT;
543     size = g_processMaxNum * sizeof(LosProcessCB);
544 
545     g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);
546     if (g_processCBArray == NULL) {
547         return LOS_NOK;
548     }
549     (VOID)memset_s(g_processCBArray, size, 0, size);
550 
551     LOS_ListInit(&g_freeProcess);
552     LOS_ListInit(&g_processRecycleList);
553 
554     for (index = 0; index < g_processMaxNum; index++) {
555         g_processCBArray[index].processID = index;
556         g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED;
557         LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList);
558     }
559 
560     g_kernelIdleProcess = 0; /* 0: The idle process ID of the kernel-mode process is fixed at 0 */
561     LOS_ListDelete(&OS_PCB_FROM_PID(g_kernelIdleProcess)->pendList);
562 
563     g_userInitProcess = 1; /* 1: The root process ID of the user-mode process is fixed at 1 */
564     LOS_ListDelete(&OS_PCB_FROM_PID(g_userInitProcess)->pendList);
565 
566     g_kernelInitProcess = 2; /* 2: The root process ID of the kernel-mode process is fixed at 2 */
567     LOS_ListDelete(&OS_PCB_FROM_PID(g_kernelInitProcess)->pendList);
568 
569     return LOS_OK;
570 }
571 
OsProcessCBRecycleToFree(VOID)572 LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
573 {
574     UINT32 intSave;
575     LosProcessCB *processCB = NULL;
576 
577     SCHEDULER_LOCK(intSave);
578     while (!LOS_ListEmpty(&g_processRecycleList)) {
579         processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList));
580         if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) {
581             break;
582         }
583         SCHEDULER_UNLOCK(intSave);
584 
585         OsTaskCBRecycleToFree();
586 
587         SCHEDULER_LOCK(intSave);
588         processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT;
589 #ifdef LOSCFG_KERNEL_VM
590         LosVmSpace *space = NULL;
591         if (OsProcessIsUserMode(processCB)) {
592             space = processCB->vmSpace;
593         }
594         processCB->vmSpace = NULL;
595 #endif
596         /* OS_PROCESS_FLAG_GROUP_LEADER: The lead process group cannot be recycled without destroying the PCB.
597          * !OS_PROCESS_FLAG_UNUSED: Parent process does not reclaim child process resources.
598          */
599         LOS_ListDelete(&processCB->pendList);
600         if ((processCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) ||
601             (processCB->processStatus & OS_PROCESS_STATUS_ZOMBIES)) {
602             LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList);
603         } else {
604             /* Clear the bottom 4 bits of process status */
605             OsInsertPCBToFreeList(processCB);
606         }
607 #ifdef LOSCFG_KERNEL_VM
608         SCHEDULER_UNLOCK(intSave);
609         (VOID)LOS_VmSpaceFree(space);
610         SCHEDULER_LOCK(intSave);
611 #endif
612     }
613 
614     SCHEDULER_UNLOCK(intSave);
615 }
616 
OsDeInitPCB(LosProcessCB * processCB)617 STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
618 {
619     UINT32 intSave;
620     ProcessGroup *group = NULL;
621 
622     if (processCB == NULL) {
623         return;
624     }
625 
626     OsProcessResourcesToFree(processCB);
627 
628     SCHEDULER_LOCK(intSave);
629     if (processCB->parentProcessID != OS_INVALID_VALUE) {
630         LOS_ListDelete(&processCB->siblingList);
631         processCB->parentProcessID = OS_INVALID_VALUE;
632     }
633 
634     if (processCB->group != NULL) {
635         OsExitProcessGroup(processCB, &group);
636     }
637 
638     processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;
639     processCB->processStatus |= OS_PROCESS_FLAG_EXIT;
640     LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);
641     SCHEDULER_UNLOCK(intSave);
642 
643     (VOID)LOS_MemFree(m_aucSysMem1, group);
644     OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE);
645     return;
646 }
647 
OsSetProcessName(LosProcessCB * processCB,const CHAR * name)648 UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name)
649 {
650     errno_t errRet;
651 
652     if (processCB == NULL) {
653         return LOS_EINVAL;
654     }
655 
656     if (name != NULL) {
657         errRet = strncpy_s(processCB->processName, OS_PCB_NAME_LEN, name, OS_PCB_NAME_LEN - 1);
658         if (errRet == EOK) {
659             return LOS_OK;
660         }
661     }
662 
663     switch (processCB->processMode) {
664         case OS_KERNEL_MODE:
665             errRet = snprintf_s(processCB->processName, OS_PCB_NAME_LEN, OS_PCB_NAME_LEN - 1,
666                                 "KerProcess%u", processCB->processID);
667             break;
668         default:
669             errRet = snprintf_s(processCB->processName, OS_PCB_NAME_LEN, OS_PCB_NAME_LEN - 1,
670                                 "UserProcess%u", processCB->processID);
671             break;
672     }
673 
674     if (errRet < 0) {
675         return LOS_NOK;
676     }
677     return LOS_OK;
678 }
679 
OsInitPCB(LosProcessCB * processCB,UINT32 mode,const CHAR * name)680 STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name)
681 {
682     processCB->processMode = mode;
683     processCB->processStatus = OS_PROCESS_STATUS_INIT;
684     processCB->parentProcessID = OS_INVALID_VALUE;
685     processCB->threadGroupID = OS_INVALID_VALUE;
686     processCB->umask = OS_PROCESS_DEFAULT_UMASK;
687     processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
688 
689     LOS_ListInit(&processCB->threadSiblingList);
690     LOS_ListInit(&processCB->childrenList);
691     LOS_ListInit(&processCB->exitChildList);
692     LOS_ListInit(&(processCB->waitList));
693 
694 #ifdef LOSCFG_KERNEL_VM
695     if (OsProcessIsUserMode(processCB)) {
696         processCB->vmSpace = OsCreateUserVmSpace();
697         if (processCB->vmSpace == NULL) {
698             processCB->processStatus = OS_PROCESS_FLAG_UNUSED;
699             return LOS_ENOMEM;
700         }
701     } else {
702         processCB->vmSpace = LOS_GetKVmSpace();
703     }
704 #endif
705 
706 #ifdef LOSCFG_KERNEL_CPUP
707     processCB->processCpup = (OsCpupBase *)LOS_MemAlloc(m_aucSysMem1, sizeof(OsCpupBase));
708     if (processCB->processCpup == NULL) {
709         return LOS_ENOMEM;
710     }
711     (VOID)memset_s(processCB->processCpup, sizeof(OsCpupBase), 0, sizeof(OsCpupBase));
712 #endif
713 
714 #ifdef LOSCFG_SECURITY_VID
715     status_t status = VidMapListInit(processCB);
716     if (status != LOS_OK) {
717         return LOS_ENOMEM;
718     }
719 #endif
720 
721 #ifdef LOSCFG_SECURITY_CAPABILITY
722     OsInitCapability(processCB);
723 #endif
724 
725     if (OsSetProcessName(processCB, name) != LOS_OK) {
726         return LOS_ENOMEM;
727     }
728 
729     return LOS_OK;
730 }
731 
732 #ifdef LOSCFG_SECURITY_CAPABILITY
OsCreateUser(UINT32 userID,UINT32 gid,UINT32 size)733 STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)
734 {
735     User *user = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + (size - 1) * sizeof(UINT32));
736     if (user == NULL) {
737         return NULL;
738     }
739 
740     user->userID = userID;
741     user->effUserID = userID;
742     user->gid = gid;
743     user->effGid = gid;
744     user->groupNumber = size;
745     user->groups[0] = gid;
746     return user;
747 }
748 
LOS_CheckInGroups(UINT32 gid)749 LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid)
750 {
751     UINT32 intSave;
752     UINT32 count;
753     User *user = NULL;
754 
755     SCHEDULER_LOCK(intSave);
756     user = OsCurrUserGet();
757     for (count = 0; count < user->groupNumber; count++) {
758         if (user->groups[count] == gid) {
759             SCHEDULER_UNLOCK(intSave);
760             return TRUE;
761         }
762     }
763 
764     SCHEDULER_UNLOCK(intSave);
765     return FALSE;
766 }
767 #endif
768 
LOS_GetUserID(VOID)769 LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID)
770 {
771 #ifdef LOSCFG_SECURITY_CAPABILITY
772     UINT32 intSave;
773     INT32 uid;
774 
775     SCHEDULER_LOCK(intSave);
776     uid = (INT32)OsCurrUserGet()->userID;
777     SCHEDULER_UNLOCK(intSave);
778     return uid;
779 #else
780     return 0;
781 #endif
782 }
783 
LOS_GetGroupID(VOID)784 LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID)
785 {
786 #ifdef LOSCFG_SECURITY_CAPABILITY
787     UINT32 intSave;
788     INT32 gid;
789 
790     SCHEDULER_LOCK(intSave);
791     gid = (INT32)OsCurrUserGet()->gid;
792     SCHEDULER_UNLOCK(intSave);
793 
794     return gid;
795 #else
796     return 0;
797 #endif
798 }
799 
OsProcessCreateInit(LosProcessCB * processCB,UINT32 flags,const CHAR * name)800 STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name)
801 {
802     ProcessGroup *group = NULL;
803     UINT32 ret = OsInitPCB(processCB, flags, name);
804     if (ret != LOS_OK) {
805         goto EXIT;
806     }
807 
808 #ifdef LOSCFG_FS_VFS
809     processCB->files = alloc_files();
810     if (processCB->files == NULL) {
811         ret = LOS_ENOMEM;
812         goto EXIT;
813     }
814 #endif
815 
816     group = OsCreateProcessGroup(processCB->processID);
817     if (group == NULL) {
818         ret = LOS_ENOMEM;
819         goto EXIT;
820     }
821 
822 #ifdef LOSCFG_SECURITY_CAPABILITY
823     processCB->user = OsCreateUser(0, 0, 1);
824     if (processCB->user == NULL) {
825         ret = LOS_ENOMEM;
826         goto EXIT;
827     }
828 #endif
829 
830     return LOS_OK;
831 
832 EXIT:
833     OsDeInitPCB(processCB);
834     return ret;
835 }
836 
OsSystemProcessCreate(VOID)837 LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
838 {
839     UINT32 ret = OsProcessInit();
840     if (ret != LOS_OK) {
841         return ret;
842     }
843 
844     LosProcessCB *kerInitProcess = OS_PCB_FROM_PID(g_kernelInitProcess);
845     ret = OsProcessCreateInit(kerInitProcess, OS_KERNEL_MODE, "KProcess");
846     if (ret != LOS_OK) {
847         return ret;
848     }
849 
850     kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;
851     g_processGroup = kerInitProcess->group;
852     LOS_ListInit(&g_processGroup->groupList);
853 
854     LosProcessCB *idleProcess = OS_PCB_FROM_PID(g_kernelIdleProcess);
855     ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle");
856     if (ret != LOS_OK) {
857         return ret;
858     }
859     idleProcess->parentProcessID = kerInitProcess->processID;
860     LOS_ListTailInsert(&kerInitProcess->childrenList, &idleProcess->siblingList);
861     idleProcess->group = kerInitProcess->group;
862     LOS_ListTailInsert(&kerInitProcess->group->processList, &idleProcess->subordinateGroupList);
863 #ifdef LOSCFG_SECURITY_CAPABILITY
864     idleProcess->user = kerInitProcess->user;
865 #endif
866 #ifdef LOSCFG_FS_VFS
867     idleProcess->files = kerInitProcess->files;
868 #endif
869     idleProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;
870 
871     ret = OsIdleTaskCreate();
872     if (ret != LOS_OK) {
873         return ret;
874     }
875     idleProcess->threadGroupID = OsGetIdleTaskId();
876 
877     return LOS_OK;
878 }
879 
OsProcessSchedlerParamCheck(INT32 which,INT32 pid,UINT16 prio,UINT16 policy)880 STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
881 {
882     if (OS_PID_CHECK_INVALID(pid)) {
883         return LOS_EINVAL;
884     }
885 
886     if (which != LOS_PRIO_PROCESS) {
887         return LOS_EINVAL;
888     }
889 
890     if (prio > OS_PROCESS_PRIORITY_LOWEST) {
891         return LOS_EINVAL;
892     }
893 
894     if (policy != LOS_SCHED_RR) {
895         return LOS_EINVAL;
896     }
897 
898     return LOS_OK;
899 }
900 
901 #ifdef LOSCFG_SECURITY_CAPABILITY
OsProcessCapPermitCheck(const LosProcessCB * processCB,const SchedParam * param,UINT16 prio)902 STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 prio)
903 {
904     LosProcessCB *runProcess = OsCurrProcessGet();
905 
906     /* always trust kernel process */
907     if (!OsProcessIsUserMode(runProcess)) {
908         return TRUE;
909     }
910 
911     /* user mode process can reduce the priority of itself */
912     if ((runProcess->processID == processCB->processID) && (prio > param->basePrio)) {
913         return TRUE;
914     }
915 
916     /* user mode process with privilege of CAP_SCHED_SETPRIORITY can change the priority */
917     if (IsCapPermit(CAP_SCHED_SETPRIORITY)) {
918         return TRUE;
919     }
920     return FALSE;
921 }
922 #endif
923 
OsSetProcessScheduler(INT32 which,INT32 pid,UINT16 prio,UINT16 policy)924 LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
925 {
926     SchedParam param = { 0 };
927     UINT32 intSave;
928 
929     INT32 ret = OsProcessSchedlerParamCheck(which, pid, prio, policy);
930     if (ret != LOS_OK) {
931         return -ret;
932     }
933 
934     LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
935     SCHEDULER_LOCK(intSave);
936     if (OsProcessIsInactive(processCB)) {
937         ret = LOS_ESRCH;
938         goto EXIT;
939     }
940 
941 #ifdef LOSCFG_SECURITY_CAPABILITY
942     if (!OsProcessCapPermitCheck(processCB, &param, prio)) {
943         ret = LOS_EPERM;
944         goto EXIT;
945     }
946 #endif
947 
948     LosTaskCB *taskCB = OS_TCB_FROM_TID(processCB->threadGroupID);
949     taskCB->ops->schedParamGet(taskCB, &param);
950     param.basePrio = prio;
951 
952     BOOL needSched = taskCB->ops->schedParamModify(taskCB, &param);
953     SCHEDULER_UNLOCK(intSave);
954 
955     LOS_MpSchedule(OS_MP_CPU_ALL);
956     if (needSched && OS_SCHEDULER_ACTIVE) {
957         LOS_Schedule();
958     }
959     return LOS_OK;
960 
961 EXIT:
962     SCHEDULER_UNLOCK(intSave);
963     return -ret;
964 }
965 
LOS_SetProcessScheduler(INT32 pid,UINT16 policy,UINT16 prio)966 LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, UINT16 prio)
967 {
968     return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, policy);
969 }
970 
LOS_GetProcessScheduler(INT32 pid)971 LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid)
972 {
973     UINT32 intSave;
974 
975     if (OS_PID_CHECK_INVALID(pid)) {
976         return -LOS_EINVAL;
977     }
978 
979     SCHEDULER_LOCK(intSave);
980     LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
981     if (OsProcessIsUnused(processCB)) {
982         SCHEDULER_UNLOCK(intSave);
983         return -LOS_ESRCH;
984     }
985 
986     SCHEDULER_UNLOCK(intSave);
987 
988     return LOS_SCHED_RR;
989 }
990 
LOS_SetProcessPriority(INT32 pid,UINT16 prio)991 LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio)
992 {
993     return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, LOS_GetProcessScheduler(pid));
994 }
995 
OsGetProcessPriority(INT32 which,INT32 pid)996 LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
997 {
998     UINT32 intSave;
999     SchedParam param = { 0 };
1000     (VOID)which;
1001 
1002     if (OS_PID_CHECK_INVALID(pid)) {
1003         return -LOS_EINVAL;
1004     }
1005 
1006     if (which != LOS_PRIO_PROCESS) {
1007         return -LOS_EINVAL;
1008     }
1009 
1010     LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
1011     SCHEDULER_LOCK(intSave);
1012     if (OsProcessIsUnused(processCB)) {
1013         SCHEDULER_UNLOCK(intSave);
1014         return -LOS_ESRCH;
1015     }
1016 
1017     LosTaskCB *taskCB = OS_TCB_FROM_TID(processCB->threadGroupID);
1018     taskCB->ops->schedParamGet(taskCB, &param);
1019 
1020     SCHEDULER_UNLOCK(intSave);
1021     return param.basePrio;
1022 }
1023 
LOS_GetProcessPriority(INT32 pid)1024 LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid)
1025 {
1026     return OsGetProcessPriority(LOS_PRIO_PROCESS, pid);
1027 }
1028 
OsWaitInsertWaitListInOrder(LosTaskCB * runTask,LosProcessCB * processCB)1029 STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *processCB)
1030 {
1031     LOS_DL_LIST *head = &processCB->waitList;
1032     LOS_DL_LIST *list = head;
1033     LosTaskCB *taskCB = NULL;
1034 
1035     if (runTask->waitFlag == OS_PROCESS_WAIT_GID) {
1036         while (list->pstNext != head) {
1037             taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
1038             if (taskCB->waitFlag == OS_PROCESS_WAIT_PRO) {
1039                 list = list->pstNext;
1040                 continue;
1041             }
1042             break;
1043         }
1044     } else if (runTask->waitFlag == OS_PROCESS_WAIT_ANY) {
1045         while (list->pstNext != head) {
1046             taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
1047             if (taskCB->waitFlag != OS_PROCESS_WAIT_ANY) {
1048                 list = list->pstNext;
1049                 continue;
1050             }
1051             break;
1052         }
1053     }
1054     /* if runTask->waitFlag == OS_PROCESS_WAIT_PRO,
1055      * this node is inserted directly into the header of the waitList
1056      */
1057     (VOID)runTask->ops->wait(runTask, list->pstNext, LOS_WAIT_FOREVER);
1058     return;
1059 }
1060 
OsWaitSetFlag(const LosProcessCB * processCB,INT32 pid,LosProcessCB ** child)1061 STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcessCB **child)
1062 {
1063     LosProcessCB *childCB = NULL;
1064     ProcessGroup *group = NULL;
1065     LosTaskCB *runTask = OsCurrTaskGet();
1066     UINT32 ret;
1067 
1068     if (pid > 0) {
1069         /* Wait for the child process whose process number is pid. */
1070         childCB = OsFindExitChildProcess(processCB, pid);
1071         if (childCB != NULL) {
1072             goto WAIT_BACK;
1073         }
1074 
1075         ret = OsFindChildProcess(processCB, pid);
1076         if (ret != LOS_OK) {
1077             return LOS_ECHILD;
1078         }
1079         runTask->waitFlag = OS_PROCESS_WAIT_PRO;
1080         runTask->waitID = pid;
1081     } else if (pid == 0) {
1082         /* Wait for any child process in the same process group */
1083         childCB = OsFindGroupExitProcess(processCB->group, OS_INVALID_VALUE);
1084         if (childCB != NULL) {
1085             goto WAIT_BACK;
1086         }
1087         runTask->waitID = processCB->group->groupID;
1088         runTask->waitFlag = OS_PROCESS_WAIT_GID;
1089     } else if (pid == -1) {
1090         /* Wait for any child process */
1091         childCB = OsFindExitChildProcess(processCB, OS_INVALID_VALUE);
1092         if (childCB != NULL) {
1093             goto WAIT_BACK;
1094         }
1095         runTask->waitID = pid;
1096         runTask->waitFlag = OS_PROCESS_WAIT_ANY;
1097     } else { /* pid < -1 */
1098         /* Wait for any child process whose group number is the pid absolute value. */
1099         group = OsFindProcessGroup(-pid);
1100         if (group == NULL) {
1101             return LOS_ECHILD;
1102         }
1103 
1104         childCB = OsFindGroupExitProcess(group, OS_INVALID_VALUE);
1105         if (childCB != NULL) {
1106             goto WAIT_BACK;
1107         }
1108 
1109         runTask->waitID = -pid;
1110         runTask->waitFlag = OS_PROCESS_WAIT_GID;
1111     }
1112 
1113 WAIT_BACK:
1114     *child = childCB;
1115     return LOS_OK;
1116 }
1117 
OsWaitRecycleChildProcess(const LosProcessCB * childCB,UINT32 intSave,INT32 * status,siginfo_t * info)1118 STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info)
1119 {
1120     ProcessGroup *group = NULL;
1121     UINT32 pid = childCB->processID;
1122     UINT16 mode = childCB->processMode;
1123     INT32 exitCode = childCB->exitCode;
1124     UINT32 uid = 0;
1125 
1126 #ifdef LOSCFG_SECURITY_CAPABILITY
1127     if (childCB->user != NULL) {
1128         uid = childCB->user->userID;
1129     }
1130 #endif
1131 
1132     OsRecycleZombiesProcess((LosProcessCB *)childCB, &group);
1133     SCHEDULER_UNLOCK(intSave);
1134 
1135     if (status != NULL) {
1136         if (mode == OS_USER_MODE) {
1137             (VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32));
1138         } else {
1139             *status = exitCode;
1140         }
1141     }
1142     /* get signal info */
1143     if (info != NULL) {
1144         siginfo_t tempinfo = { 0 };
1145 
1146         tempinfo.si_signo = SIGCHLD;
1147         tempinfo.si_errno = 0;
1148         tempinfo.si_pid = pid;
1149         tempinfo.si_uid = uid;
1150         /*
1151          * Process exit code
1152          * 31	 15 		  8 		  7 	   0
1153          * |	 | exit code  | core dump | signal |
1154          */
1155         if ((exitCode & 0x7f) == 0) {
1156             tempinfo.si_code = CLD_EXITED;
1157             tempinfo.si_status = (exitCode >> 8U);
1158         } else {
1159             tempinfo.si_code = (exitCode & 0x80) ? CLD_DUMPED : CLD_KILLED;
1160             tempinfo.si_status = (exitCode & 0x7f);
1161         }
1162 
1163         if (mode == OS_USER_MODE) {
1164             (VOID)LOS_ArchCopyToUser((VOID *)(info), (const VOID *)(&(tempinfo)), sizeof(siginfo_t));
1165         } else {
1166             (VOID)memcpy_s((VOID *)(info), sizeof(siginfo_t), (const VOID *)(&(tempinfo)), sizeof(siginfo_t));
1167         }
1168     }
1169     (VOID)LOS_MemFree(m_aucSysMem1, group);
1170     return pid;
1171 }
1172 
OsWaitChildProcessCheck(LosProcessCB * processCB,INT32 pid,LosProcessCB ** childCB)1173 STATIC UINT32 OsWaitChildProcessCheck(LosProcessCB *processCB, INT32 pid, LosProcessCB **childCB)
1174 {
1175     if (LOS_ListEmpty(&(processCB->childrenList)) && LOS_ListEmpty(&(processCB->exitChildList))) {
1176         return LOS_ECHILD;
1177     }
1178 
1179     return OsWaitSetFlag(processCB, pid, childCB);
1180 }
1181 
OsWaitOptionsCheck(UINT32 options)1182 STATIC UINT32 OsWaitOptionsCheck(UINT32 options)
1183 {
1184     UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WUNTRACED | LOS_WAIT_WCONTINUED;
1185 
1186     flag = ~flag & options;
1187     if (flag != 0) {
1188         return LOS_EINVAL;
1189     }
1190 
1191     if ((options & (LOS_WAIT_WCONTINUED | LOS_WAIT_WUNTRACED)) != 0) {
1192         return LOS_EOPNOTSUPP;
1193     }
1194 
1195     if (OS_INT_ACTIVE) {
1196         return LOS_EINTR;
1197     }
1198 
1199     return LOS_OK;
1200 }
1201 
OsWait(INT32 pid,USER INT32 * status,USER siginfo_t * info,UINT32 options,VOID * rusage)1202 STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage)
1203 {
1204     (VOID)rusage;
1205     UINT32 ret;
1206     UINT32 intSave;
1207     LosProcessCB *childCB = NULL;
1208 
1209     LosProcessCB *processCB = OsCurrProcessGet();
1210     LosTaskCB *runTask = OsCurrTaskGet();
1211     SCHEDULER_LOCK(intSave);
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 
OsCopyTask(UINT32 flags,LosProcessCB * childProcessCB,const CHAR * name,UINTPTR entry,UINT32 size)1728 STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size)
1729 {
1730     LosTaskCB *runTask = OsCurrTaskGet();
1731     TSK_INIT_PARAM_S taskParam = { 0 };
1732     UINT32 ret, taskID, intSave;
1733     SchedParam param = { 0 };
1734 
1735     SCHEDULER_LOCK(intSave);
1736     if (OsProcessIsUserMode(childProcessCB)) {
1737         taskParam.pfnTaskEntry = runTask->taskEntry;
1738         taskParam.uwStackSize = runTask->stackSize;
1739         taskParam.userParam.userArea = runTask->userArea;
1740         taskParam.userParam.userMapBase = runTask->userMapBase;
1741         taskParam.userParam.userMapSize = runTask->userMapSize;
1742     } else {
1743         taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)entry;
1744         taskParam.uwStackSize = size;
1745     }
1746     if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
1747         taskParam.uwResved = LOS_TASK_ATTR_JOINABLE;
1748     }
1749 
1750     runTask->ops->schedParamGet(runTask, &param);
1751     SCHEDULER_UNLOCK(intSave);
1752 
1753     taskParam.pcName = (CHAR *)name;
1754     taskParam.policy = param.policy;
1755     taskParam.usTaskPrio = param.priority;
1756     taskParam.processID = childProcessCB->processID;
1757 
1758     ret = LOS_TaskCreateOnly(&taskID, &taskParam);
1759     if (ret != LOS_OK) {
1760         if (ret == LOS_ERRNO_TSK_TCB_UNAVAILABLE) {
1761             return LOS_EAGAIN;
1762         }
1763         return LOS_ENOMEM;
1764     }
1765 
1766     LosTaskCB *childTaskCB = OS_TCB_FROM_TID(taskID);
1767     childTaskCB->taskStatus = runTask->taskStatus;
1768     childTaskCB->ops->schedParamModify(childTaskCB, &param);
1769     if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
1770         childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING;
1771     } else {
1772         if (OS_SCHEDULER_ACTIVE) {
1773             LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus);
1774         }
1775         childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED;
1776     }
1777 
1778     if (OsProcessIsUserMode(childProcessCB)) {
1779         SCHEDULER_LOCK(intSave);
1780         OsUserCloneParentStack(childTaskCB->stackPointer, runTask->topOfStack, runTask->stackSize);
1781         SCHEDULER_UNLOCK(intSave);
1782     }
1783     return LOS_OK;
1784 }
1785 
OsCopyParent(UINT32 flags,LosProcessCB * childProcessCB,LosProcessCB * runProcessCB)1786 STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
1787 {
1788     UINT32 ret;
1789     UINT32 intSave;
1790     LosProcessCB *parentProcessCB = NULL;
1791 
1792     SCHEDULER_LOCK(intSave);
1793 
1794     if (flags & CLONE_PARENT) {
1795         parentProcessCB = OS_PCB_FROM_PID(runProcessCB->parentProcessID);
1796     } else {
1797         parentProcessCB = runProcessCB;
1798     }
1799     childProcessCB->parentProcessID = parentProcessCB->processID;
1800     LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);
1801     childProcessCB->group = parentProcessCB->group;
1802     LOS_ListTailInsert(&parentProcessCB->group->processList, &childProcessCB->subordinateGroupList);
1803     ret = OsCopyUser(childProcessCB, parentProcessCB);
1804 
1805     SCHEDULER_UNLOCK(intSave);
1806     return ret;
1807 }
1808 
OsCopyMM(UINT32 flags,LosProcessCB * childProcessCB,LosProcessCB * runProcessCB)1809 STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
1810 {
1811     status_t status;
1812     UINT32 intSave;
1813 
1814     if (!OsProcessIsUserMode(childProcessCB)) {
1815         return LOS_OK;
1816     }
1817 
1818     if (flags & CLONE_VM) {
1819         SCHEDULER_LOCK(intSave);
1820         childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb;
1821         childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb;
1822         SCHEDULER_UNLOCK(intSave);
1823         return LOS_OK;
1824     }
1825 
1826     status = LOS_VmSpaceClone(runProcessCB->vmSpace, childProcessCB->vmSpace);
1827     if (status != LOS_OK) {
1828         return LOS_ENOMEM;
1829     }
1830     return LOS_OK;
1831 }
1832 
OsCopyFile(UINT32 flags,LosProcessCB * childProcessCB,LosProcessCB * runProcessCB)1833 STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
1834 {
1835 #ifdef LOSCFG_FS_VFS
1836     if (flags & CLONE_FILES) {
1837         childProcessCB->files = runProcessCB->files;
1838     } else {
1839         childProcessCB->files = dup_fd(runProcessCB->files);
1840     }
1841     if (childProcessCB->files == NULL) {
1842         return LOS_ENOMEM;
1843     }
1844 #endif
1845 
1846     childProcessCB->consoleID = runProcessCB->consoleID;
1847     childProcessCB->umask = runProcessCB->umask;
1848     return LOS_OK;
1849 }
1850 
OsForkInitPCB(UINT32 flags,LosProcessCB * child,const CHAR * name,UINTPTR sp,UINT32 size)1851 STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINTPTR sp, UINT32 size)
1852 {
1853     UINT32 ret;
1854     LosProcessCB *run = OsCurrProcessGet();
1855 
1856     ret = OsInitPCB(child, run->processMode, name);
1857     if (ret != LOS_OK) {
1858         return ret;
1859     }
1860 
1861     ret = OsCopyParent(flags, child, run);
1862     if (ret != LOS_OK) {
1863         return ret;
1864     }
1865 
1866     return OsCopyTask(flags, child, name, sp, size);
1867 }
1868 
OsChildSetProcessGroupAndSched(LosProcessCB * child,LosProcessCB * run)1869 STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *run)
1870 {
1871     UINT32 intSave;
1872     UINT32 ret;
1873     ProcessGroup *group = NULL;
1874 
1875     LosTaskCB *taskCB = OS_TCB_FROM_TID(child->threadGroupID);
1876     SCHEDULER_LOCK(intSave);
1877     if (run->group->groupID == OS_USER_PRIVILEGE_PROCESS_GROUP) {
1878         ret = OsSetProcessGroupIDUnsafe(child->processID, child->processID, &group);
1879         if (ret != LOS_OK) {
1880             SCHEDULER_UNLOCK(intSave);
1881             return LOS_ENOMEM;
1882         }
1883     }
1884 
1885     child->processStatus &= ~OS_PROCESS_STATUS_INIT;
1886     taskCB->ops->enqueue(OsSchedRunqueue(), taskCB);
1887     SCHEDULER_UNLOCK(intSave);
1888 
1889     (VOID)LOS_MemFree(m_aucSysMem1, group);
1890     return LOS_OK;
1891 }
1892 
OsCopyProcessResources(UINT32 flags,LosProcessCB * child,LosProcessCB * run)1893 STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProcessCB *run)
1894 {
1895     UINT32 ret;
1896 
1897     ret = OsCopyMM(flags, child, run);
1898     if (ret != LOS_OK) {
1899         return ret;
1900     }
1901 
1902     ret = OsCopyFile(flags, child, run);
1903     if (ret != LOS_OK) {
1904         return ret;
1905     }
1906 
1907 #ifdef LOSCFG_KERNEL_LITEIPC
1908     if (run->ipcInfo != NULL) {
1909         child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo));
1910         if (child->ipcInfo == NULL) {
1911             return LOS_ENOMEM;
1912         }
1913     }
1914 #endif
1915 
1916 #ifdef LOSCFG_SECURITY_CAPABILITY
1917     OsCopyCapability(run, child);
1918 #endif
1919 
1920     return LOS_OK;
1921 }
1922 
OsCopyProcess(UINT32 flags,const CHAR * name,UINTPTR sp,UINT32 size)1923 STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size)
1924 {
1925     UINT32 ret, processID;
1926     LosProcessCB *run = OsCurrProcessGet();
1927 
1928     LosProcessCB *child = OsGetFreePCB();
1929     if (child == NULL) {
1930         return -LOS_EAGAIN;
1931     }
1932     processID = child->processID;
1933 
1934     ret = OsForkInitPCB(flags, child, name, sp, size);
1935     if (ret != LOS_OK) {
1936         goto ERROR_INIT;
1937     }
1938 
1939     ret = OsCopyProcessResources(flags, child, run);
1940     if (ret != LOS_OK) {
1941         goto ERROR_TASK;
1942     }
1943 
1944     ret = OsChildSetProcessGroupAndSched(child, run);
1945     if (ret != LOS_OK) {
1946         goto ERROR_TASK;
1947     }
1948 
1949     LOS_MpSchedule(OS_MP_CPU_ALL);
1950     if (OS_SCHEDULER_ACTIVE) {
1951         LOS_Schedule();
1952     }
1953 
1954     return processID;
1955 
1956 ERROR_TASK:
1957     (VOID)LOS_TaskDelete(child->threadGroupID);
1958 ERROR_INIT:
1959     OsDeInitPCB(child);
1960     return -ret;
1961 }
1962 
OsClone(UINT32 flags,UINTPTR sp,UINT32 size)1963 LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size)
1964 {
1965     UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_VM;
1966 
1967     if (flags & (~cloneFlag)) {
1968         PRINT_WARN("Clone dont support some flags!\n");
1969     }
1970 
1971     return OsCopyProcess(cloneFlag & flags, NULL, sp, size);
1972 }
1973 
LOS_Fork(UINT32 flags,const CHAR * name,const TSK_ENTRY_FUNC entry,UINT32 stackSize)1974 LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize)
1975 {
1976     UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES;
1977 
1978     if (flags & (~cloneFlag)) {
1979         PRINT_WARN("Clone dont support some flags!\n");
1980     }
1981 
1982     flags |= CLONE_FILES;
1983     return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize);
1984 }
1985 #else
OsUserInitProcess(VOID)1986 LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID)
1987 {
1988     return 0;
1989 }
1990 #endif
1991 
LOS_Exit(INT32 status)1992 LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status)
1993 {
1994     UINT32 intSave;
1995 
1996     (void)status;
1997 
1998     /* The exit of a kernel - state process must be kernel - state and all threads must actively exit */
1999     LosProcessCB *processCB = OsCurrProcessGet();
2000     SCHEDULER_LOCK(intSave);
2001     if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) {
2002         SCHEDULER_UNLOCK(intSave);
2003         PRINT_ERR("Kernel-state processes with multiple threads are not allowed to exit directly\n");
2004         return;
2005     }
2006     SCHEDULER_UNLOCK(intSave);
2007 
2008     OsProcessThreadGroupDestroy();
2009     OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK);
2010 }
2011 
LOS_GetUsedPIDList(UINT32 * pidList,INT32 pidMaxNum)2012 LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum)
2013 {
2014     LosProcessCB *pcb = NULL;
2015     INT32 num = 0;
2016     UINT32 intSave;
2017     UINT32 pid = 1;
2018 
2019     if (pidList == NULL) {
2020         return 0;
2021     }
2022     SCHEDULER_LOCK(intSave);
2023     while (OsProcessIDUserCheckInvalid(pid) == false) {
2024         pcb = OS_PCB_FROM_PID(pid);
2025         pid++;
2026         if (OsProcessIsUnused(pcb)) {
2027             continue;
2028         }
2029         pidList[num] = pcb->processID;
2030         num++;
2031         if (num >= pidMaxNum) {
2032             break;
2033         }
2034     }
2035     SCHEDULER_UNLOCK(intSave);
2036     return num;
2037 }
2038 
2039 #ifdef LOSCFG_FS_VFS
LOS_GetFdTable(UINT32 pid)2040 LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid)
2041 {
2042     LosProcessCB *pcb = NULL;
2043     struct files_struct *files = NULL;
2044 
2045     if (OS_PID_CHECK_INVALID(pid)) {
2046         return NULL;
2047     }
2048     pcb = OS_PCB_FROM_PID(pid);
2049     files = pcb->files;
2050     if (files == NULL) {
2051         return NULL;
2052     }
2053 
2054     return files->fdt;
2055 }
2056 #endif
2057 
LOS_GetCurrProcessID(VOID)2058 LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID)
2059 {
2060     return OsCurrProcessGet()->processID;
2061 }
2062 
2063 #ifdef LOSCFG_KERNEL_VM
ThreadGroupActiveTaskKilled(LosTaskCB * taskCB)2064 STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB)
2065 {
2066     INT32 ret;
2067 
2068     taskCB->taskStatus |= OS_TASK_FLAG_EXIT_KILL;
2069 #ifdef LOSCFG_KERNEL_SMP
2070     /** The other core that the thread is running on and is currently running in a non-system call */
2071     if (!taskCB->sig.sigIntLock && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
2072         taskCB->signal = SIGNAL_KILL;
2073         LOS_MpSchedule(taskCB->currCpu);
2074     } else
2075 #endif
2076     {
2077         ret = OsTaskKillUnsafe(taskCB->taskID, SIGKILL);
2078         if (ret != LOS_OK) {
2079             PRINT_ERR("pid %u exit, Exit task group %u kill %u failed! ERROR: %d\n",
2080                       taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, ret);
2081         }
2082     }
2083 
2084     if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) {
2085         taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN;
2086         LOS_ListInit(&taskCB->joinList);
2087     }
2088 
2089     ret = OsTaskJoinPendUnsafe(taskCB);
2090     if (ret != LOS_OK) {
2091         PRINT_ERR("pid %u exit, Exit task group %u to wait others task %u(0x%x) exit failed! ERROR: %d\n",
2092                   taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, taskCB->taskStatus, ret);
2093     }
2094 }
2095 #endif
2096 
OsProcessThreadGroupDestroy(VOID)2097 LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID)
2098 {
2099 #ifdef LOSCFG_KERNEL_VM
2100     UINT32 intSave;
2101 
2102     LosProcessCB *processCB = OsCurrProcessGet();
2103     LosTaskCB *currTask = OsCurrTaskGet();
2104     SCHEDULER_LOCK(intSave);
2105     if ((processCB->processStatus & OS_PROCESS_FLAG_EXIT) || !OsProcessIsUserMode(processCB)) {
2106         SCHEDULER_UNLOCK(intSave);
2107         return;
2108     }
2109 
2110     processCB->processStatus |= OS_PROCESS_FLAG_EXIT;
2111     processCB->threadGroupID = currTask->taskID;
2112 
2113     LOS_DL_LIST *list = &processCB->threadSiblingList;
2114     LOS_DL_LIST *head = list;
2115     do {
2116         LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList);
2117         if ((OsTaskIsInactive(taskCB) ||
2118             ((taskCB->taskStatus & OS_TASK_STATUS_READY) && !taskCB->sig.sigIntLock)) &&
2119             !(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
2120             OsInactiveTaskDelete(taskCB);
2121         } else if (taskCB != currTask) {
2122             ThreadGroupActiveTaskKilled(taskCB);
2123         } else {
2124             /* Skip the current task */
2125             list = list->pstNext;
2126         }
2127     } while (head != list->pstNext);
2128 
2129     SCHEDULER_UNLOCK(intSave);
2130 
2131     LOS_ASSERT(processCB->threadNumber == 1);
2132 #endif
2133     return;
2134 }
2135 
LOS_GetSystemProcessMaximum(VOID)2136 LITE_OS_SEC_TEXT UINT32 LOS_GetSystemProcessMaximum(VOID)
2137 {
2138     return g_processMaxNum;
2139 }
2140 
OsGetUserInitProcessID(VOID)2141 LITE_OS_SEC_TEXT UINT32 OsGetUserInitProcessID(VOID)
2142 {
2143     return g_userInitProcess;
2144 }
2145 
OsGetKernelInitProcessID(VOID)2146 LITE_OS_SEC_TEXT UINT32 OsGetKernelInitProcessID(VOID)
2147 {
2148     return g_kernelInitProcess;
2149 }
2150 
OsGetIdleProcessID(VOID)2151 LITE_OS_SEC_TEXT UINT32 OsGetIdleProcessID(VOID)
2152 {
2153     return g_kernelIdleProcess;
2154 }
2155 
OsSetSigHandler(UINTPTR addr)2156 LITE_OS_SEC_TEXT VOID OsSetSigHandler(UINTPTR addr)
2157 {
2158     OsCurrProcessGet()->sigHandler = addr;
2159 }
2160 
OsGetSigHandler(VOID)2161 LITE_OS_SEC_TEXT UINTPTR OsGetSigHandler(VOID)
2162 {
2163     return OsCurrProcessGet()->sigHandler;
2164 }
2165 
2166