From cf89f016e93f28f8d72e6f5de08640d08a155908 Mon Sep 17 00:00:00 2001 From: zhushengle Date: Thu, 20 May 2021 19:51:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3kill=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E6=97=B6=E6=97=A0=E6=B3=95=E4=BF=9D=E8=AF=81=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E7=9A=84=E5=B7=B2=E6=8C=81=E6=9C=89=E7=9A=84=E5=86=85=E6=A0=B8?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E5=90=88=E7=90=86=E9=87=8A=E6=94=BE.=20?= =?UTF-8?q?=E8=83=8C=E6=99=AF:=20=E5=BD=93=E5=89=8D=E4=BF=A1=E5=8F=B7?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8E=9F=E7=90=86=E6=98=AF=E5=9C=A8=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E8=B0=83=E7=94=A8=E7=BB=93=E6=9D=9F=E5=92=8C=E4=B8=AD?= =?UTF-8?q?=E6=96=AD=E7=BB=93=E6=9D=9F=E6=97=B6=E6=A3=80=E6=9F=A5=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E6=9C=89=E4=BF=A1=E5=8F=B7=E5=A4=84=E7=90=86,=20=20?= =?UTF-8?q?=20=20=20=20=20=E5=A6=82=E6=9E=9C=E6=9C=89=E4=BF=A1=E5=8F=B7?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=B0=B1=E5=88=87=E5=8E=BB=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BF=A1=E5=8F=B7=EF=BC=8C=E4=BF=A1=E5=8F=B7=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=BB=93=E6=9D=9F=E5=90=8E=E5=9B=9E=E6=9D=A5=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E6=8C=89=E5=8E=9F=E6=9D=A5=E6=B5=81=E7=A8=8B=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E3=80=82=20=E9=97=AE=E9=A2=98=EF=BC=9A=E5=BD=93=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=80=81=E7=BA=BF=E7=A8=8B=E5=9C=A8=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8=E6=88=96=E7=BC=BA=E9=A1=B5?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E6=97=B6=EF=BC=8C=E8=BF=90=E8=A1=8C=E5=9C=A8?= =?UTF-8?q?=E5=86=85=E6=A0=B8=E6=80=81=EF=BC=8C=E5=A6=82=E6=9E=9C=E6=AD=A4?= =?UTF-8?q?=E6=97=B6=E6=9C=89=E4=BF=A1=20=20=20=20=20=20=20=E5=8F=B7?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E5=A4=84=E7=90=86=EF=BC=8C=E4=B8=94=E8=AF=A5?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E5=B7=B2=E7=BB=8F=E6=8C=81=E6=9C=89=E4=BA=86?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=86=85=E6=A0=B8=E8=B5=84=E6=BA=90(?= =?UTF-8?q?=E5=A6=82=EF=BC=9A=E9=94=81=EF=BC=8C=E5=86=85=E5=AD=98=E7=AD=89?= =?UTF-8?q?),=20=E6=AD=A4=E6=97=B6=E5=A6=82=20=20=20=20=20=20=20=E6=9E=9C?= =?UTF-8?q?=E6=9C=89=E4=B8=AD=E6=96=AD=E5=8F=91=E7=94=9F=EF=BC=8C=E5=88=99?= =?UTF-8?q?=E5=9C=A8=E4=B8=AD=E6=96=AD=E7=BB=93=E6=9D=9F=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E5=B0=B1=E4=BC=9A=E5=8E=BB=E5=A4=84=E7=90=86=E8=AF=A5=E4=BF=A1?= =?UTF-8?q?=E5=8F=B7=EF=BC=8C=E6=AD=A4=E6=97=B6=E7=94=A8=E6=88=B7=E6=80=81?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E6=8C=81=E6=9C=89=20=20=20=20=20=20=20?= =?UTF-8?q?=E4=BA=86=E5=86=85=E6=A0=B8=E6=9C=AA=E9=87=8A=E6=94=BE=E7=9A=84?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E8=B7=91=E5=88=B0=E4=BA=86=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=80=81=E5=8E=BB=E8=BF=90=E8=A1=8C=EF=BC=8C=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E8=AF=A5=E7=BA=BF=E7=A8=8B=E5=9C=A8=E7=94=A8=E6=88=B7=E6=80=81?= =?UTF-8?q?=E5=87=BA=E7=8E=B0=E9=97=AE=E9=A2=98,=20=20=20=20=20=20=20?= =?UTF-8?q?=E9=82=A3=E4=B9=88=E5=AE=83=E6=8C=81=E6=9C=89=E7=9A=84=E5=86=85?= =?UTF-8?q?=E6=A0=B8=E8=B5=84=E6=BA=90=E5=B0=B1=E6=97=A0=E6=B3=95=E8=A2=AB?= =?UTF-8?q?=E9=87=8A=E6=94=BE=E4=BA=86=E3=80=82=20=E6=96=B9=E6=A1=88?= =?UTF-8?q?=EF=BC=9A=E7=94=A8=E6=88=B7=E6=80=81=E7=BA=BF=E7=A8=8B=E5=9C=A8?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8=E5=92=8C?= =?UTF-8?q?=E7=BC=BA=E9=A1=B5=E5=BC=82=E5=B8=B8=E6=97=B6=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E5=B1=8F=E8=94=BD=E4=BF=A1=E5=8F=B7=EF=BC=8C=E9=98=B2=E6=AD=A2?= =?UTF-8?q?=E6=AD=A4=E6=97=B6=E6=9C=89=E4=B8=AD=E6=96=AD=E5=8E=BB=20=20=20?= =?UTF-8?q?=20=20=20=20=E5=A4=84=E7=90=86=E4=BF=A1=E5=8F=B7=EF=BC=8C?= =?UTF-8?q?=E7=AD=89=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=E6=88=96=E7=BC=BA=E9=A1=B5=E5=BC=82=E5=B8=B8=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=E6=97=B6=E5=86=8D=E5=8E=BB=E5=A4=84=E7=90=86=E4=BF=A1=E5=8F=B7?= =?UTF-8?q?=E3=80=82=20=E8=A7=A3=E5=86=B3=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9A=20=20=201.=20=E6=89=A7=E8=A1=8C=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E6=88=96=E7=BC=BA=E9=A1=B5=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E6=97=B6=E5=B1=8F=E8=94=BD=E4=BF=A1=E5=8F=B7=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E4=B8=AD=E6=96=AD=E5=8E=BB=E5=A4=84=E7=90=86=E4=BF=A1?= =?UTF-8?q?=E5=8F=B7=20=20=202.=E8=A7=A3=E5=86=B3=E6=97=A0=E6=B3=95kill=20?= =?UTF-8?q?=E5=9B=A0=E4=B8=BA=E7=94=A8=E6=88=B7=E6=80=81=E7=9A=84=E9=94=81?= =?UTF-8?q?=E3=80=81ipc=E7=AD=89=E9=98=BB=E5=A1=9E=E7=9A=84=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=80=81=E7=BA=BF=E7=A8=8B=20=20=203.=E8=BF=9B?= =?UTF-8?q?=E7=A8=8B=E9=80=80=E5=87=BA=E6=96=B9=E5=BC=8F=E8=BD=AC=E5=8F=98?= =?UTF-8?q?=E4=B8=BA:=20=E4=BE=9D=E6=AC=A1=E9=80=9A=E8=BF=87kill=E5=8E=BB?= =?UTF-8?q?=E6=9D=80=E6=AD=BB=E8=AF=A5=E8=BF=9B=E7=A8=8B=E7=9A=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=BA=BF=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close #I3S0N0 Change-Id: I0c48b9c89382826191b8a9326c71b57ba84124c2 --- arch/arm/arm/src/los_dispatch.S | 2 + arch/arm/arm/src/los_exc.c | 55 +++++----- arch/arm/arm/src/los_hw_exc.S | 8 ++ kernel/base/core/los_process.c | 41 +++---- kernel/base/core/los_task.c | 150 ++++++++++++-------------- kernel/base/include/los_process_pri.h | 3 +- kernel/base/include/los_signal.h | 10 +- kernel/base/include/los_task_pri.h | 89 ++++++++------- kernel/base/ipc/los_signal.c | 150 ++++++++++++++++++-------- syscall/los_syscall.c | 2 + 10 files changed, 293 insertions(+), 217 deletions(-) diff --git a/arch/arm/arm/src/los_dispatch.S b/arch/arm/arm/src/los_dispatch.S index 66a719e1..3b7df79c 100644 --- a/arch/arm/arm/src/los_dispatch.S +++ b/arch/arm/arm/src/los_dispatch.S @@ -173,6 +173,7 @@ OsIrqHandler: POP_FPU_REGS R0 LDR R4, [SP, #0] +#ifdef LOSCFG_KERNEL_VM /* Obtain the CPSR to determine the mode the system is in when the interrupt is triggered */ LDR R3, [SP, #(11 * 4)] AND R1, R3, #CPSR_MASK_MODE @@ -187,6 +188,7 @@ OsIrqHandler: BLX OsSaveSignalContext MOV SP, R0 1: +#endif ADD SP, SP, #(2 * 4) /* load user sp and lr, and jump cpsr */ LDMFD SP, {R13, R14}^ diff --git a/arch/arm/arm/src/los_exc.c b/arch/arm/arm/src/los_exc.c index 47430b82..e6f678d0 100644 --- a/arch/arm/arm/src/los_exc.c +++ b/arch/arm/arm/src/los_exc.c @@ -220,7 +220,9 @@ UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT3 pfFlags |= user ? VM_MAP_PF_FLAG_USER : 0; pfFlags |= instructionFault ? VM_MAP_PF_FLAG_INSTRUCTION : 0; pfFlags |= VM_MAP_PF_FLAG_NOT_PRESENT; + OsSigIntLock(); ret = OsVmPageFaultHandler(far, pfFlags, frame); + OsSigIntUnlock(); break; } default: @@ -537,7 +539,9 @@ STATIC VOID OsExcRestore(VOID) STATIC VOID OsUserExcHandle(ExcContext *excBufAddr) { + UINT32 intSave; UINT32 currCpu = ArchCurrCpuid(); + LosTaskCB *runTask = OsCurrTaskGet(); LosProcessCB *runProcess = OsCurrProcessGet(); if (g_excFromUserMode[ArchCurrCpuid()] == FALSE) { @@ -565,16 +569,28 @@ STATIC VOID OsUserExcHandle(ExcContext *excBufAddr) #endif #endif + SCHEDULER_LOCK(intSave); #ifdef LOSCFG_SAVE_EXCINFO OsProcessExitCodeCoreDumpSet(runProcess); #endif OsProcessExitCodeSignalSet(runProcess, SIGUSR2); - /* Exception handling All operations should be kept prior to that operation */ - OsExcRestore(); + /* An exception was raised by a task that is not the current main thread during the exit process of + * the current process. + */ + if ((runProcess->processStatus & OS_PROCESS_FLAG_EXIT) && (runProcess->threadGroupID != runTask->taskID)) { + SCHEDULER_UNLOCK(intSave); + /* Exception handling All operations should be kept prior to that operation */ + OsExcRestore(); + OsTaskToExit(runTask, OS_PRO_EXIT_OK); + } else { + SCHEDULER_UNLOCK(intSave); - /* kill user exc process */ - LOS_Exit(OS_PRO_EXIT_OK); + /* Exception handling All operations should be kept prior to that operation */ + OsExcRestore(); + /* kill user exc process */ + LOS_Exit(OS_PRO_EXIT_OK); + } /* User mode exception handling failed , which normally does not exist */ g_curNestCount[currCpu]++; @@ -940,7 +956,6 @@ STATIC VOID WaitAllCpuStop(UINT32 cpuID) STATIC VOID OsWaitOtherCoresHandleExcEnd(UINT32 currCpuID) { - OsProcessSuspendAllTask(); while (1) { LOS_SpinLock(&g_excSerializerSpin); if ((g_currHandleExcCpuID == INVALID_CPUID) || (g_currHandleExcCpuID == currCpuID)) { @@ -967,6 +982,7 @@ STATIC VOID OsCheckAllCpuStatus(VOID) LOCKDEP_CLEAR_LOCKS(); LOS_SpinLock(&g_excSerializerSpin); + /* Only the current nuclear anomaly */ if (g_currHandleExcCpuID == INVALID_CPUID) { g_currHandleExcCpuID = currCpuID; g_currHandleExcPID = OsCurrProcessGet()->processID; @@ -976,13 +992,14 @@ STATIC VOID OsCheckAllCpuStatus(VOID) HalIrqSendIpi(target, LOS_MP_IPI_HALT); } } else if (g_excFromUserMode[currCpuID] == TRUE) { + /* Both cores raise exceptions, and the current core is a user-mode exception. + * Both cores are abnormal and come from the same process + */ if (OsCurrProcessGet()->processID == g_currHandleExcPID) { LOS_SpinUnlock(&g_excSerializerSpin); OsExcRestore(); - while (1) { - ret = LOS_TaskSuspend(OsCurrTaskGet()->taskID); - PrintExcInfo("%s supend task :%u failed: 0x%x\n", __FUNCTION__, OsCurrTaskGet()->taskID, ret); - } + ret = LOS_TaskDelete(OsCurrTaskGet()->taskID); + LOS_Panic("%s supend task :%u failed: 0x%x\n", __FUNCTION__, OsCurrTaskGet()->taskID, ret); } LOS_SpinUnlock(&g_excSerializerSpin); @@ -1017,10 +1034,6 @@ STATIC VOID OsCheckCpuStatus(VOID) LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr) { -#if (LOSCFG_KERNEL_SMP == YES) - UINT16 runCount; -#endif - if ((excBufAddr->regCPSR & CPSR_MASK_MODE) == CPSR_USER_MODE) { g_minAddr = USER_ASPACE_BASE; g_maxAddr = USER_ASPACE_BASE + USER_ASPACE_SIZE; @@ -1033,22 +1046,6 @@ LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr) OsCheckCpuStatus(); - if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) { - while (1) { - OsProcessSuspendAllTask(); -#if (LOSCFG_KERNEL_SMP == YES) - LOS_SpinLock(&g_taskSpin); - runCount = OS_PROCESS_GET_RUNTASK_COUNT(OsCurrProcessGet()->processStatus); - LOS_SpinUnlock(&g_taskSpin); - if (runCount == 1) { - break; - } -#else - break; -#endif - } - } - #if (LOSCFG_KERNEL_SMP == YES) #ifdef LOSCFG_FS_VFS /* Wait for the end of the Console task to avoid multicore printing code */ diff --git a/arch/arm/arm/src/los_hw_exc.S b/arch/arm/arm/src/los_hw_exc.S index 0ef952d2..18805462 100644 --- a/arch/arm/arm/src/los_hw_exc.S +++ b/arch/arm/arm/src/los_hw_exc.S @@ -325,6 +325,14 @@ _osExceptDataAbortHdl: #ifdef LOSCFG_KERNEL_VM _osExcPageFaultReturn: LDMFD SP!, {R4-R11} + + MOV R0, SP + STR R7, [SP, #0] + SUB SP, SP, #(12 * 4) @ sp - sizeof(IrqContext), reserved for signal + MOV R1, SP + BLX OsSaveSignalContext + MOV SP, R0 + ADD SP, SP, #(2 * 4) LDMFD SP, {R13, R14}^ ADD SP, SP, #(2 * 4) @ Jump reserved fileds diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 7d273d13..3ab52c1b 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -179,7 +179,7 @@ STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, INT32 return NULL; } -STATIC INLINE VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID) +VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID) { taskCB->waitID = wakePID; OsSchedTaskWake(taskCB); @@ -410,7 +410,9 @@ STATIC VOID OsProcessNaturalExit(LosTaskCB *runTask, UINT32 status) processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES; +#ifdef LOSCFG_KERNEL_VM (VOID)OsKill(processCB->parentProcessID, SIGCHLD, OS_KERNEL_KILL_PERMISSION); +#endif LOS_ListHeadInsert(&g_processRecyleList, &processCB->pendList); OsRunTaskToDelete(runTask); return; @@ -909,27 +911,6 @@ LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid) return OsGetProcessPriority(LOS_PRIO_PROCESS, pid); } -LITE_OS_SEC_TEXT VOID OsWaitSignalToWakeProcess(LosProcessCB *processCB) -{ - LosTaskCB *taskCB = NULL; - - if (processCB == NULL) { - return; - } - - /* only suspend process can continue */ - if (!(processCB->processStatus & OS_PROCESS_STATUS_PENDING)) { - return; - } - - if (!LOS_ListEmpty(&processCB->waitList)) { - taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&processCB->waitList)); - OsWaitWakeTask(taskCB, OS_INVALID_VALUE); - } - - return; -} - STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *processCB) { LOS_DL_LIST *head = &processCB->waitList; @@ -1595,9 +1576,9 @@ STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProces childProcessCB->priority = runProcessCB->priority; if (flags & CLONE_PARENT) { - parentProcessCB = OS_PCB_FROM_PID(runProcessCB->parentProcessID); + parentProcessCB = OS_PCB_FROM_PID(runProcessCB->parentProcessID); } else { - parentProcessCB = runProcessCB; + parentProcessCB = runProcessCB; } childProcessCB->parentProcessID = parentProcessCB->processID; LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList); @@ -1793,6 +1774,18 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) { + UINT32 intSave; + + /* The exit of a kernel - state process must be kernel - state and all threads must actively exit */ + LosProcessCB *processCB = OsCurrProcessGet(); + SCHEDULER_LOCK(intSave); + if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) { + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("Kernel-state processes with multiple threads are not allowed to exit directly\n"); + return; + } + SCHEDULER_UNLOCK(intSave); + OsTaskExitGroup((UINT32)status); OsProcessExit(OsCurrTaskGet(), (UINT32)status); } diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index 00bd9e27..353b3f33 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -46,6 +46,7 @@ #include "los_process_pri.h" #include "los_vm_map.h" #include "los_vm_syscall.h" +#include "los_signal.h" #ifdef LOSCFG_KERNEL_CPUP #include "los_cpup_pri.h" @@ -267,30 +268,29 @@ LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID) LITE_OS_SEC_TEXT VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status) { UINT32 intSave; - LosProcessCB *runProcess = NULL; - LosTaskCB *mainTask = NULL; - SCHEDULER_LOCK(intSave); - runProcess = OS_PCB_FROM_PID(taskCB->processID); - mainTask = OS_TCB_FROM_TID(runProcess->threadGroupID); - SCHEDULER_UNLOCK(intSave); + LosProcessCB *runProcess = OS_PCB_FROM_PID(taskCB->processID); + LosTaskCB *mainTask = OS_TCB_FROM_TID(runProcess->threadGroupID); if (mainTask == taskCB) { OsTaskExitGroup(status); } SCHEDULER_LOCK(intSave); + if (runProcess->threadNumber == 1) { /* 1: The last task of the process exits */ SCHEDULER_UNLOCK(intSave); (VOID)OsProcessExit(taskCB, status); return; } - if (taskCB->taskStatus & OS_TASK_FLAG_DETACHED) { + /* The thread being killed must be able to exit automatically and will have the detached property */ + OsTaskJoinPostUnsafe(taskCB); + + if (taskCB->taskStatus & (OS_TASK_FLAG_DETACHED | OS_TASK_FLAG_EXIT_KILL)) { UINT32 ret = OsTaskDeleteUnsafe(taskCB, status, intSave); LOS_Panic("Task delete failed! ERROR : 0x%x\n", ret); } - OsTaskJoinPostUnsafe(taskCB); OsSchedResched(); SCHEDULER_UNLOCK(intSave); return; @@ -536,8 +536,8 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, if (initParam->uwResved & OS_TASK_FLAG_DETACHED) { taskCB->taskStatus |= OS_TASK_FLAG_DETACHED; } else { - LOS_ListInit(&taskCB->joinList); taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; + LOS_ListInit(&taskCB->joinList); } taskCB->futex.index = OS_INVALID_VALUE; @@ -870,6 +870,7 @@ STATIC INLINE VOID OsTaskReleaseHoldLock(LosProcessCB *processCB, LosTaskCB *tas if (processCB->processMode == OS_USER_MODE) { OsTaskJoinPostUnsafe(taskCB); + #ifdef LOSCFG_KERNEL_VM OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); #endif @@ -878,15 +879,16 @@ STATIC INLINE VOID OsTaskReleaseHoldLock(LosProcessCB *processCB, LosTaskCB *tas OsTaskSyncWake(taskCB); } -LITE_OS_SEC_TEXT VOID OsRunTaskToDelete(LosTaskCB *taskCB) +LITE_OS_SEC_TEXT VOID OsRunTaskToDelete(LosTaskCB *runTask) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - OsTaskReleaseHoldLock(processCB, taskCB); - OsTaskStatusUnusedSet(taskCB); + LosProcessCB *processCB = OS_PCB_FROM_PID(runTask->processID); - LOS_ListDelete(&taskCB->threadList); + OsTaskReleaseHoldLock(processCB, runTask); + OsTaskStatusUnusedSet(runTask); + + LOS_ListDelete(&runTask->threadList); processCB->threadNumber--; - LOS_ListTailInsert(&g_taskRecyleList, &taskCB->pendList); + LOS_ListTailInsert(&g_taskRecyleList, &runTask->pendList); OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL); OsSchedResched(); @@ -1033,7 +1035,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) } processCB = OS_PCB_FROM_PID(taskCB->processID); - if (processCB->threadNumber == 1) { + if (processCB->threadNumber == 1) { /* 1: The last task of the process exits */ if (processCB == OsCurrProcessGet()) { SCHEDULER_UNLOCK(intSave); OsProcessExit(taskCB, OS_PRO_EXIT_OK); @@ -1399,57 +1401,70 @@ EXIT: return err; } +STATIC VOID OsExitGroupActiveTaskKilled(LosProcessCB *processCB, LosTaskCB *taskCB) +{ + INT32 ret; + + taskCB->taskStatus |= OS_TASK_FLAG_EXIT_KILL; +#if (LOSCFG_KERNEL_SMP == YES) + /* The other core that the thread is running on and is currently running in a non-system call */ + if (!taskCB->sig.sigIntLock && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + taskCB->signal = SIGNAL_KILL; + LOS_MpSchedule(taskCB->currCpu); + } else +#endif + { + ret = OsTaskKillUnsafe(taskCB->taskID, SIGKILL); + if (ret != LOS_OK) { + PRINT_ERR("pid %u exit, Exit task group %u kill %u failed! ERROR: %d\n", + taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, ret); + } + } + + if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { + taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; + LOS_ListInit(&taskCB->joinList); + } + + ret = OsTaskJoinPendUnsafe(taskCB); + if (ret != LOS_OK) { + PRINT_ERR("pid %u exit, Exit task group %u to wait others task %u(0x%x) exit failed! ERROR: %d\n", + taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, taskCB->taskStatus, ret); + } +} + LITE_OS_SEC_TEXT VOID OsTaskExitGroup(UINT32 status) { - LosProcessCB *processCB = NULL; - LosTaskCB *taskCB = NULL; - LOS_DL_LIST *list = NULL; - LOS_DL_LIST *head = NULL; - LosTaskCB *runTask[LOSCFG_KERNEL_CORE_NUM] = { 0 }; UINT32 intSave; -#if (LOSCFG_KERNEL_SMP == YES) - UINT16 cpu; -#endif + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *currTask = OsCurrTaskGet(); SCHEDULER_LOCK(intSave); - processCB = OsCurrProcessGet(); - if (processCB->processStatus & OS_PROCESS_FLAG_EXIT) { + if ((processCB->processStatus & OS_PROCESS_FLAG_EXIT) || !OsProcessIsUserMode(processCB)) { SCHEDULER_UNLOCK(intSave); return; } processCB->processStatus |= OS_PROCESS_FLAG_EXIT; - runTask[ArchCurrCpuid()] = OsCurrTaskGet(); - runTask[ArchCurrCpuid()]->sig.sigprocmask = OS_INVALID_VALUE; + processCB->threadGroupID = currTask->taskID; - list = &processCB->threadSiblingList; - head = list; + LOS_DL_LIST *list = &processCB->threadSiblingList; + LOS_DL_LIST *head = list; do { - taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList); - if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList); + if ((taskCB->taskStatus & (OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) && + !(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { OsTaskDeleteInactive(processCB, taskCB); } else { -#if (LOSCFG_KERNEL_SMP == YES) - if (taskCB->currCpu != ArchCurrCpuid()) { - taskCB->signal = SIGNAL_KILL; - runTask[taskCB->currCpu] = taskCB; - LOS_MpSchedule(taskCB->currCpu); + if (taskCB != currTask) { + OsExitGroupActiveTaskKilled(processCB, taskCB); + } else { + /* Skip the current task */ + list = list->pstNext; } -#endif - list = list->pstNext; } } while (head != list->pstNext); -#if (LOSCFG_KERNEL_SMP == YES) - for (cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { - if ((cpu == ArchCurrCpuid()) || (runTask[cpu] == NULL)) { - continue; - } - - (VOID)OsTaskSyncWait(runTask[cpu]); - } -#endif - processCB->threadGroupID = OsCurrTaskGet()->taskID; SCHEDULER_UNLOCK(intSave); LOS_ASSERT(processCB->threadNumber == 1); @@ -1462,38 +1477,6 @@ LITE_OS_SEC_TEXT VOID OsExecDestroyTaskGroup(VOID) OsTaskCBRecycleToFree(); } -LITE_OS_SEC_TEXT VOID OsProcessSuspendAllTask(VOID) -{ - LosProcessCB *process = NULL; - LosTaskCB *taskCB = NULL; - LosTaskCB *runTask = NULL; - LOS_DL_LIST *list = NULL; - LOS_DL_LIST *head = NULL; - UINT32 intSave; - UINT32 ret; - - SCHEDULER_LOCK(intSave); - process = OsCurrProcessGet(); - runTask = OsCurrTaskGet(); - - list = &process->threadSiblingList; - head = list; - do { - taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList); - if (taskCB != runTask) { - ret = OsTaskSuspend(taskCB); - if ((ret != LOS_OK) && (ret != LOS_ERRNO_TSK_ALREADY_SUSPENDED)) { - PRINT_ERR("process(%d) suspend all task(%u) failed! ERROR: 0x%x\n", - process->processID, taskCB->taskID, ret); - } - } - list = list->pstNext; - } while (head != list->pstNext); - - SCHEDULER_UNLOCK(intSave); - return; -} - UINT32 OsUserTaskOperatePermissionsCheck(LosTaskCB *taskCB) { if (taskCB == NULL) { @@ -1640,6 +1623,11 @@ LITE_OS_SEC_TEXT VOID OsWriteResourceEvent(UINT32 events) (VOID)LOS_EventWrite(&g_resourceEvent, events); } +LITE_OS_SEC_TEXT VOID OsWriteResourceEventUnsafe(UINT32 events) +{ + (VOID)OsEventWriteUnsafe(&g_resourceEvent, events, FALSE, NULL); +} + STATIC VOID OsResourceRecoveryTask(VOID) { UINT32 ret; diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index 80ad6bec..e07ea820 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -448,7 +448,6 @@ extern UINT32 OsUserInitProcess(VOID); extern VOID OsTaskSchedQueueDequeue(LosTaskCB *taskCB, UINT16 status); extern VOID OsTaskSchedQueueEnqueue(LosTaskCB *taskCB, UINT16 status); extern INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size); -extern VOID OsWaitSignalToWakeProcess(LosProcessCB *processCB); extern UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldAspace, UINTPTR oldFiles); extern UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize); @@ -463,6 +462,8 @@ extern INT32 OsSetCurrProcessGroupID(UINT32 gid); extern UINT32 OsGetKernelInitProcessID(VOID); extern VOID OsSetSigHandler(UINTPTR addr); extern UINTPTR OsGetSigHandler(VOID); +extern VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID); + #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/include/los_signal.h b/kernel/base/include/los_signal.h index e75f5110..aa113374 100644 --- a/kernel/base/include/los_signal.h +++ b/kernel/base/include/los_signal.h @@ -135,11 +135,12 @@ typedef struct sq_queue_s sq_queue_t; typedef struct { sigset_t sigFlag; sigset_t sigPendFlag; - sigset_t sigprocmask; /* Signals that are blocked */ + sigset_t sigprocmask; /* Signals that are blocked */ sq_queue_t sigactionq; LOS_DL_LIST waitList; - sigset_t sigwaitmask; /* Waiting for pending signals */ - siginfo_t sigunbinfo; /* Signal info when task unblocked */ + sigset_t sigwaitmask; /* Waiting for pending signals */ + siginfo_t sigunbinfo; /* Signal info when task unblocked */ + unsigned int sigIntLock; void *sigContext; unsigned int count; } sig_cb; @@ -163,6 +164,9 @@ int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout); int OsPause(void); int OsSigPending(sigset_t *set); int OsSigSuspend(const sigset_t *set); +VOID OsSigIntLock(VOID); +VOID OsSigIntUnlock(VOID); +INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h index d95474f2..f3c6c2be 100644 --- a/kernel/base/include/los_task_pri.h +++ b/kernel/base/include/los_task_pri.h @@ -208,7 +208,15 @@ extern SPIN_LOCK_S g_taskSpin; * * The task is no-delete system task, like resourceTask. */ -#define OS_TASK_FLAG_NO_DELETE 0x2000U +#define OS_TASK_FLAG_NO_DELETE 0x2000U + +/** + * @ingroup los_task + * Flag that indicates the task property. + * + * Kills the thread during process exit. + */ +#define OS_TASK_FLAG_EXIT_KILL 0x4000U /** * @ingroup los_task @@ -216,7 +224,7 @@ extern SPIN_LOCK_S g_taskSpin; * * Specifies the process creation task. */ -#define OS_TASK_FLAG_SPECIFIES_PROCESS 0x4000U +#define OS_TASK_FLAG_SPECIFIES_PROCESS 0x0U /** * @ingroup los_task @@ -453,47 +461,23 @@ STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) return FALSE; } +STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB) +{ + if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { + return TRUE; + } + + return FALSE; +} + #define OS_TID_CHECK_INVALID(taskID) ((UINT32)(taskID) >= g_taskMaxNum) /* get task info */ #define OS_ALL_TASK_MASK 0xFFFFFFFF -extern UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB); -extern VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB); -extern UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB); -extern BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask); -extern VOID OsTaskSchedule(LosTaskCB *, LosTaskCB *); -extern VOID OsTaskContextLoad(LosTaskCB *newTask); -extern VOID OsIdleTask(VOID); -extern UINT32 OsIdleTaskCreate(VOID); -extern UINT32 OsTaskInit(VOID); -extern UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv); -extern UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqfile, UINT16 flag); -extern LosTaskCB *OsGetMainTask(VOID); -extern VOID OsSetMainTask(VOID); -extern UINT32 OsGetIdleTaskId(VOID); -extern VOID OsTaskEntry(UINT32 taskID); -extern SortLinkAttribute *OsTaskSortLinkGet(VOID); -extern VOID OsTaskProcSignal(VOID); -extern UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UINT32 intSave); -extern VOID OsTaskResourcesToFree(LosTaskCB *taskCB); -extern VOID OsRunTaskToDelete(LosTaskCB *taskCB); -extern UINT32 OsTaskSyncWait(const LosTaskCB *taskCB); -extern UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam); -extern INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName); -extern VOID OsTaskCBRecycleToFree(VOID); -extern VOID OsTaskExitGroup(UINT32 status); -extern VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status); -extern VOID OsExecDestroyTaskGroup(VOID); -extern VOID OsProcessSuspendAllTask(VOID); -extern UINT32 OsUserTaskOperatePermissionsCheck(LosTaskCB *taskCB); -extern VOID OsWriteResourceEvent(UINT32 events); -extern UINT32 OsResourceFreeTaskCreate(VOID); - #define OS_TASK_WAIT_ANYPROCESS (1 << 0U) #define OS_TASK_WAIT_PROCESS (1 << 1U) #define OS_TASK_WAIT_GID (1 << 2U) -#ifdef LOSCFG_DEBUG_VERSION #define OS_TASK_WAIT_SEM (OS_TASK_WAIT_GID + 1) #define OS_TASK_WAIT_QUEUE (OS_TASK_WAIT_SEM + 1) #define OS_TASK_WAIT_JOIN (OS_TASK_WAIT_QUEUE + 1) @@ -530,6 +514,39 @@ STATIC INLINE VOID OsTaskWakeClearPendMask(LosTaskCB *resumeTask) #endif } +extern UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB); +extern VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB); +extern UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB); +extern BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask); +extern VOID OsTaskSchedule(LosTaskCB *, LosTaskCB *); +extern VOID OsTaskContextLoad(LosTaskCB *newTask); +extern VOID OsIdleTask(VOID); +extern UINT32 OsIdleTaskCreate(VOID); +extern UINT32 OsTaskInit(VOID); +extern UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv); +extern UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqfile, UINT16 flag); +extern LosTaskCB *OsGetMainTask(VOID); +extern VOID OsSetMainTask(VOID); +extern UINT32 OsGetIdleTaskId(VOID); +extern VOID OsTaskEntry(UINT32 taskID); +extern SortLinkAttribute *OsTaskSortLinkGet(VOID); +extern VOID OsTaskProcSignal(VOID); +extern UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UINT32 intSave); +extern VOID OsTaskResourcesToFree(LosTaskCB *taskCB); +extern VOID OsRunTaskToDelete(LosTaskCB *taskCB); +extern UINT32 OsTaskSyncWait(const LosTaskCB *taskCB); +extern UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam); +extern INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName); +extern VOID OsTaskCBRecycleToFree(VOID); +extern VOID OsTaskExitGroup(UINT32 status); +extern VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status); +extern VOID OsExecDestroyTaskGroup(VOID); +extern UINT32 OsUserTaskOperatePermissionsCheck(LosTaskCB *taskCB); +extern VOID OsWriteResourceEvent(UINT32 events); +extern VOID OsWriteResourceEventUnsafe(UINT32 events); +extern UINT32 OsResourceFreeTaskCreate(VOID); + +#ifdef LOSCFG_DEBUG_VERSION STATIC INLINE VOID OsTraceTaskSchedule(LosTaskCB *newTask, LosTaskCB *runTask) { (VOID)newTask; @@ -542,8 +559,6 @@ STATIC INLINE VOID OsTraceTaskSchedule(LosTaskCB *newTask, LosTaskCB *runTask) #else -#define OsTaskWaitSetPendMask(mask, lockID, timeout) -#define OsTaskWakeClearPendMask(taskCB) #define OsTraceTaskSchedule(newTask, runTask) #endif diff --git a/kernel/base/ipc/los_signal.c b/kernel/base/ipc/los_signal.c index 566b8a6b..06fee687 100644 --- a/kernel/base/ipc/los_signal.c +++ b/kernel/base/ipc/los_signal.c @@ -38,7 +38,9 @@ #ifdef LOSCFG_SECURITY_CAPABILITY #include "capability_api.h" #endif +#include "los_atomic.h" +#ifdef LOSCFG_KERNEL_VM int raise(int sig) { @@ -65,6 +67,57 @@ int OsSigIsMember(const sigset_t *set, int signo) return ret; } +STATIC INLINE VOID OsSigWaitTaskWake(LosTaskCB *taskCB, INT32 signo) +{ + sig_cb *sigcb = &taskCB->sig; + + if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, signo)) { + OsTaskWakeClearPendMask(taskCB); + OsSchedTaskWake(taskCB); + OsSigEmptySet(&sigcb->sigwaitmask); + } +} + +STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo) +{ + if (!OsTaskIsPending(taskCB) || !OsProcessIsUserMode(OS_PCB_FROM_PID(taskCB->processID))) { + return 0; + } + + if ((signo != SIGKILL) && (taskCB->waitFlag != OS_TASK_WAIT_SIGNAL)) { + return 0; + } + + switch (taskCB->waitFlag) { + case OS_TASK_WAIT_PROCESS: + case OS_TASK_WAIT_GID: + case OS_TASK_WAIT_ANYPROCESS: + OsWaitWakeTask(taskCB, OS_INVALID_VALUE); + break; + case OS_TASK_WAIT_JOIN: + OsTaskWakeClearPendMask(taskCB); + OsSchedTaskWake(taskCB); + break; + case OS_TASK_WAIT_SIGNAL: + OsSigWaitTaskWake(taskCB, signo); + break; + case OS_TASK_WAIT_LITEIPC: + taskCB->ipcStatus &= ~IPC_THREAD_STATUS_PEND; + OsTaskWakeClearPendMask(taskCB); + OsSchedTaskWake(taskCB); + break; + case OS_TASK_WAIT_FUTEX: + OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); + OsTaskWakeClearPendMask(taskCB); + OsSchedTaskWake(taskCB); + break; + default: + break; + } + + return 0; +} + int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info) { bool masked = FALSE; @@ -78,24 +131,17 @@ int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info) masked = (bool)OsSigIsMember(&sigcb->sigprocmask, info->si_signo); if (masked) { /* If signal is in wait list and mask list, need unblock it */ - if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, info->si_signo)) { - OsTaskWakeClearPendMask(stcb); - OsSchedTaskWake(stcb); - OsSigEmptySet(&sigcb->sigwaitmask); - } else { + if (LOS_ListEmpty(&sigcb->waitList) || + (!LOS_ListEmpty(&sigcb->waitList) && !OsSigIsMember(&sigcb->sigwaitmask, info->si_signo))) { OsSigAddSet(&sigcb->sigPendFlag, info->si_signo); } } else { /* unmasked signal actions */ OsSigAddSet(&sigcb->sigFlag, info->si_signo); - if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, info->si_signo)) { - OsTaskWakeClearPendMask(stcb); - OsSchedTaskWake(stcb); - OsSigEmptySet(&sigcb->sigwaitmask); - } } (void) memcpy_s(&sigcb->sigunbinfo, sizeof(siginfo_t), info, sizeof(siginfo_t)); - return 0; + + return OsPendingTaskWake(stcb, info->si_signo); } void OsSigMaskSwitch(LosTaskCB * const rtcb, sigset_t set) @@ -231,15 +277,7 @@ static int SigProcessKillSigHandler(LosTaskCB *tcb, void *arg) { struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg; - if ((tcb != NULL) && (info != NULL) && (info->sigInfo != NULL)) { - sig_cb *sigcb = &tcb->sig; - if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, info->sigInfo->si_signo)) { - OsTaskWakeClearPendMask(tcb); - OsSchedTaskWake(tcb); - OsSigEmptySet(&sigcb->sigwaitmask); - } - } - return 0; + return OsPendingTaskWake(tcb, info->sigInfo->si_signo); } static void SigProcessLoadTcb(struct ProcessSignalInfo *info, siginfo_t *sigInfo) @@ -276,9 +314,8 @@ int OsSigProcessSend(LosProcessCB *spcb, siginfo_t *sigInfo) /* visit all taskcb and dispatch signal */ if (info.sigInfo->si_signo == SIGKILL) { - (void)OsSigProcessForeachChild(spcb, SigProcessKillSigHandler, &info); OsSigAddSet(&spcb->sigShare, info.sigInfo->si_signo); - OsWaitSignalToWakeProcess(spcb); + (void)OsSigProcessForeachChild(spcb, SigProcessKillSigHandler, &info); return 0; } else { ret = OsSigProcessForeachChild(spcb, SigProcessSignalHandler, &info); @@ -316,14 +353,14 @@ int OsDispatch(pid_t pid, siginfo_t *info, int permission) if (OsProcessIsUnused(spcb)) { return -ESRCH; } -#ifdef LOSCFG_SECURITY_CAPABILITY - LosProcessCB *current = OsCurrProcessGet(); /* If the process you want to kill had been inactive, but still exist. should return LOS_OK */ if (OsProcessIsInactive(spcb)) { return LOS_OK; } +#ifdef LOSCFG_SECURITY_CAPABILITY + LosProcessCB *current = OsCurrProcessGet(); /* Kernel process always has kill permission and user process should check permission */ if (OsProcessIsUserMode(current) && !(current->processStatus & OS_PROCESS_FLAG_EXIT)) { if ((current != spcb) && (!IsCapPermit(CAP_KILL)) && (current->user->userID != spcb->user->userID)) { @@ -371,11 +408,27 @@ int OsKillLock(pid_t pid, int sig) return ret; } +INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo) +{ + siginfo_t info; + LosTaskCB *taskCB = OsGetTaskCB(taskID); + INT32 ret = OsUserTaskOperatePermissionsCheck(taskCB); + if (ret != LOS_OK) { + return -ret; + } + + /* Create the siginfo structure */ + info.si_signo = signo; + info.si_code = SI_USER; + info.si_value.sival_ptr = NULL; + + /* Dispatch the signal to thread, bypassing normal task group thread + * dispatch rules. */ + return OsTcbDispatch(taskCB, &info); +} + int OsPthreadKill(UINT32 tid, int signo) { - LosTaskCB *stcb = NULL; - siginfo_t info; - int ret; UINT32 intSave; @@ -385,23 +438,9 @@ int OsPthreadKill(UINT32 tid, int signo) return -ESRCH; } - /* Create the siginfo structure */ - info.si_signo = signo; - info.si_code = SI_USER; - info.si_value.sival_ptr = NULL; /* Keep things stationary through the following */ SCHEDULER_LOCK(intSave); - /* Get the TCB associated with the thread */ - stcb = OsGetTaskCB(tid); - OS_GOTO_EXIT_IF(stcb == NULL, -ESRCH); - - ret = OsUserTaskOperatePermissionsCheck(stcb); - OS_GOTO_EXIT_IF(ret != LOS_OK, -ret); - - /* Dispatch the signal to thread, bypassing normal task group thread - * dispatch rules. */ - ret = OsTcbDispatch(stcb, &info); -EXIT: + ret = OsTaskKillUnsafe(tid, signo); SCHEDULER_UNLOCK(intSave); return ret; } @@ -556,6 +595,22 @@ int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact) return LOS_OK; } +VOID OsSigIntLock(VOID) +{ + LosTaskCB *task = OsCurrTaskGet(); + sig_cb *sigcb = &task->sig; + + (VOID)LOS_AtomicAdd((Atomic *)&sigcb->sigIntLock, 1); +} + +VOID OsSigIntUnlock(VOID) +{ + LosTaskCB *task = OsCurrTaskGet(); + sig_cb *sigcb = &task->sig; + + (VOID)LOS_AtomicSub((Atomic *)&sigcb->sigIntLock, 1); +} + VOID *OsSaveSignalContext(VOID *sp, VOID *newSp) { UINTPTR sigHandler; @@ -565,6 +620,16 @@ VOID *OsSaveSignalContext(VOID *sp, VOID *newSp) LosProcessCB *process = OsCurrProcessGet(); sig_cb *sigcb = &task->sig; + /* A thread is not allowed to interrupt the processing of its signals during a system call */ + if (sigcb->sigIntLock > 0) { + return sp; + } + + if (task->taskStatus & OS_TASK_FLAG_EXIT_KILL) { + OsTaskToExit(task, 0); + return sp; + } + SCHEDULER_LOCK(intSave); if ((sigcb->count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) { sigHandler = OsGetSigHandler(); @@ -618,3 +683,4 @@ VOID *OsRestorSignalContext(VOID *sp) return saveContext; } +#endif diff --git a/syscall/los_syscall.c b/syscall/los_syscall.c index a0ebbef4..fe8d46d8 100644 --- a/syscall/los_syscall.c +++ b/syscall/los_syscall.c @@ -118,6 +118,7 @@ VOID OsArmA32SyscallHandle(TaskContext *regs) return; } + OsSigIntLock(); switch (nArgs) { case ARG_NUM_0: case ARG_NUM_1: @@ -136,6 +137,7 @@ VOID OsArmA32SyscallHandle(TaskContext *regs) } regs->R0 = ret; + OsSigIntUnlock(); return; }