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