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