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