154568cb3Sopenharmony_ci/* 254568cb3Sopenharmony_ci * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved. 354568cb3Sopenharmony_ci * 454568cb3Sopenharmony_ci * UniProton is licensed under Mulan PSL v2. 554568cb3Sopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2. 654568cb3Sopenharmony_ci * You may obtain a copy of Mulan PSL v2 at: 754568cb3Sopenharmony_ci * http://license.coscl.org.cn/MulanPSL2 854568cb3Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 954568cb3Sopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 1054568cb3Sopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 1154568cb3Sopenharmony_ci * See the Mulan PSL v2 for more details. 1254568cb3Sopenharmony_ci * Create: 2009-12-22 1354568cb3Sopenharmony_ci * Description: hook模块的初始化文件 1454568cb3Sopenharmony_ci */ 1554568cb3Sopenharmony_ci#include "prt_idle.h" 1654568cb3Sopenharmony_ci#include "prt_cpu_external.h" 1754568cb3Sopenharmony_ci#include "prt_hook_internal.h" 1854568cb3Sopenharmony_ci 1954568cb3Sopenharmony_ciOS_SEC_BSS union TagMhookCb g_hookCb[OS_HOOK_TYPE_TOTAL]; 2054568cb3Sopenharmony_ci 2154568cb3Sopenharmony_ci/* 2254568cb3Sopenharmony_ci * 有些模块在钩子变化时,希望得到及时通知。比如tick钩子需要做g_tickDispatcher置换等 2354568cb3Sopenharmony_ci */ 2454568cb3Sopenharmony_ciOS_SEC_BSS OsHookChgFunc g_hookChgHandler[OS_HOOK_TYPE_TOTAL]; 2554568cb3Sopenharmony_ci// 注册钩子用的锁 2654568cb3Sopenharmony_ciOS_SEC_BSS volatile uintptr_t g_hookRegLock; 2754568cb3Sopenharmony_ciOS_SEC_BSS MemAllocHook g_osMemAlloc; 2854568cb3Sopenharmony_ci 2954568cb3Sopenharmony_ci/* 3054568cb3Sopenharmony_ci * 描述:内核钩子模块注册 3154568cb3Sopenharmony_ci */ 3254568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsHookRegister(struct HookModInfo *modInfo) 3354568cb3Sopenharmony_ci{ 3454568cb3Sopenharmony_ci U32 hookIndex; 3554568cb3Sopenharmony_ci 3654568cb3Sopenharmony_ci for (hookIndex = 0; hookIndex < (U32)OS_HOOK_TYPE_NUM; hookIndex++) { 3754568cb3Sopenharmony_ci g_hookCb[hookIndex].num += modInfo->maxNum[hookIndex]; 3854568cb3Sopenharmony_ci } 3954568cb3Sopenharmony_ci 4054568cb3Sopenharmony_ci return OS_OK; 4154568cb3Sopenharmony_ci} 4254568cb3Sopenharmony_ci 4354568cb3Sopenharmony_ci/* 4454568cb3Sopenharmony_ci * 描述:多钩子使用预留 4554568cb3Sopenharmony_ci */ 4654568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsMhookReserve(U32 hookType, U32 incCnt) 4754568cb3Sopenharmony_ci{ 4854568cb3Sopenharmony_ci g_hookCb[hookType].num += incCnt; 4954568cb3Sopenharmony_ci} 5054568cb3Sopenharmony_ci 5154568cb3Sopenharmony_ci/* 5254568cb3Sopenharmony_ci * 描述:内核钩子模块初始化 5354568cb3Sopenharmony_ci */ 5454568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsHookConfigInit(void) 5554568cb3Sopenharmony_ci{ 5654568cb3Sopenharmony_ci U32 size = 0; 5754568cb3Sopenharmony_ci U32 hookCnt; 5854568cb3Sopenharmony_ci U32 hookIndex; 5954568cb3Sopenharmony_ci OsVoidFunc *hooks = NULL; 6054568cb3Sopenharmony_ci 6154568cb3Sopenharmony_ci for (hookIndex = 0; hookIndex < OS_SHOOK_TYPE_START; hookIndex++) { 6254568cb3Sopenharmony_ci hookCnt = g_hookCb[hookIndex].num; 6354568cb3Sopenharmony_ci if (hookCnt > 0) { 6454568cb3Sopenharmony_ci // 增加一个用于保护节点 6554568cb3Sopenharmony_ci size += hookCnt + 1; 6654568cb3Sopenharmony_ci } 6754568cb3Sopenharmony_ci } 6854568cb3Sopenharmony_ci 6954568cb3Sopenharmony_ci if (size == 0) { // 没有配置任何钩子 7054568cb3Sopenharmony_ci return OS_OK; 7154568cb3Sopenharmony_ci } 7254568cb3Sopenharmony_ci 7354568cb3Sopenharmony_ci size = (U32)(size * sizeof(OsVoidFunc)); 7454568cb3Sopenharmony_ci 7554568cb3Sopenharmony_ci if (g_osMemAlloc != NULL) { 7654568cb3Sopenharmony_ci hooks = g_osMemAlloc(OS_MID_HOOK, OS_MEM_DEFAULT_FSC_PT, size); 7754568cb3Sopenharmony_ci } 7854568cb3Sopenharmony_ci 7954568cb3Sopenharmony_ci if (hooks == NULL) { 8054568cb3Sopenharmony_ci return OS_ERRNO_HOOK_NO_MEMORY; 8154568cb3Sopenharmony_ci } 8254568cb3Sopenharmony_ci 8354568cb3Sopenharmony_ci if (memset_s((void *)hooks, size, 0, size) != EOK) { 8454568cb3Sopenharmony_ci OS_GOTO_SYS_ERROR1(); 8554568cb3Sopenharmony_ci } 8654568cb3Sopenharmony_ci 8754568cb3Sopenharmony_ci for (hookIndex = 0; hookIndex < OS_SHOOK_TYPE_START; hookIndex++) { 8854568cb3Sopenharmony_ci hookCnt = g_hookCb[hookIndex].num; 8954568cb3Sopenharmony_ci if (hookCnt == 0) { 9054568cb3Sopenharmony_ci continue; 9154568cb3Sopenharmony_ci } 9254568cb3Sopenharmony_ci 9354568cb3Sopenharmony_ci g_hookCb[hookIndex].mulHook = hooks; 9454568cb3Sopenharmony_ci *(hooks + hookCnt) = (OsVoidFunc)OS_MHOOK_BOUNDARY; 9554568cb3Sopenharmony_ci hooks += hookCnt + 1; 9654568cb3Sopenharmony_ci } 9754568cb3Sopenharmony_ci 9854568cb3Sopenharmony_ci OS_SPIN_LOCK_INIT(g_hookRegLock); 9954568cb3Sopenharmony_ci 10054568cb3Sopenharmony_ci return OS_OK; 10154568cb3Sopenharmony_ci} 10254568cb3Sopenharmony_ci 10354568cb3Sopenharmony_ci/* 10454568cb3Sopenharmony_ci * 描述:多钩子添加 10554568cb3Sopenharmony_ci */ 10654568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsMhookAdd(U32 hookType, OsVoidFunc hook) 10754568cb3Sopenharmony_ci{ 10854568cb3Sopenharmony_ci uintptr_t intSave; 10954568cb3Sopenharmony_ci OsVoidFunc *mHook = NULL; 11054568cb3Sopenharmony_ci U32 ret = OS_OK; 11154568cb3Sopenharmony_ci U32 hookCnt = 0; 11254568cb3Sopenharmony_ci OsVoidFunc *add = NULL; 11354568cb3Sopenharmony_ci 11454568cb3Sopenharmony_ci mHook = g_hookCb[hookType].mulHook; 11554568cb3Sopenharmony_ci 11654568cb3Sopenharmony_ci /* 配置多钩子数为0,返回错误码 */ 11754568cb3Sopenharmony_ci if (mHook == NULL) { 11854568cb3Sopenharmony_ci return OS_ERRNO_HOOK_NOT_CFG; 11954568cb3Sopenharmony_ci } 12054568cb3Sopenharmony_ci 12154568cb3Sopenharmony_ci HOOK_ADD_IRQ_LOCK(intSave); 12254568cb3Sopenharmony_ci 12354568cb3Sopenharmony_ci while (OS_MHOOK_IS_VALID(*mHook)) { 12454568cb3Sopenharmony_ci /* 如果是之前删除过的Dead节点,直接跳过 */ 12554568cb3Sopenharmony_ci if (*mHook == OS_MHOOK_NODE_DEAD) { 12654568cb3Sopenharmony_ci /* 记录第一个Dead节点,作为后面新添加节点 */ 12754568cb3Sopenharmony_ci if (add == NULL) { 12854568cb3Sopenharmony_ci add = mHook; 12954568cb3Sopenharmony_ci } 13054568cb3Sopenharmony_ci mHook++; 13154568cb3Sopenharmony_ci continue; 13254568cb3Sopenharmony_ci } 13354568cb3Sopenharmony_ci 13454568cb3Sopenharmony_ci /* 如果该钩子已经注册,返回错误码 */ 13554568cb3Sopenharmony_ci if (*mHook == hook) { 13654568cb3Sopenharmony_ci HOOK_ADD_IRQ_UNLOCK(intSave); 13754568cb3Sopenharmony_ci return OS_ERRNO_HOOK_EXISTED; 13854568cb3Sopenharmony_ci } 13954568cb3Sopenharmony_ci mHook++; 14054568cb3Sopenharmony_ci hookCnt++; 14154568cb3Sopenharmony_ci } 14254568cb3Sopenharmony_ci 14354568cb3Sopenharmony_ci /* 如果新添加节点没有从Dead节点上分配,从尾部划取一个节点 */ 14454568cb3Sopenharmony_ci if (add == NULL) { 14554568cb3Sopenharmony_ci if (!OS_MHOOK_NOT_BOUNDARY(*mHook)) { 14654568cb3Sopenharmony_ci HOOK_ADD_IRQ_UNLOCK(intSave); 14754568cb3Sopenharmony_ci return OS_ERRNO_HOOK_FULL; 14854568cb3Sopenharmony_ci } 14954568cb3Sopenharmony_ci add = mHook; 15054568cb3Sopenharmony_ci } 15154568cb3Sopenharmony_ci 15254568cb3Sopenharmony_ci /* 调用钩子变更通知钩子 */ 15354568cb3Sopenharmony_ci if ((hookCnt == 0) && (g_hookChgHandler[hookType] != NULL)) { 15454568cb3Sopenharmony_ci ret = g_hookChgHandler[hookType](hookType, HOOK_ADD_FIRST); 15554568cb3Sopenharmony_ci } 15654568cb3Sopenharmony_ci 15754568cb3Sopenharmony_ci /* 添加钩子 */ 15854568cb3Sopenharmony_ci if (ret == OS_OK) { 15954568cb3Sopenharmony_ci *add = hook; 16054568cb3Sopenharmony_ci } 16154568cb3Sopenharmony_ci 16254568cb3Sopenharmony_ci HOOK_ADD_IRQ_UNLOCK(intSave); 16354568cb3Sopenharmony_ci return ret; 16454568cb3Sopenharmony_ci} 16554568cb3Sopenharmony_ci 16654568cb3Sopenharmony_ci/* 16754568cb3Sopenharmony_ci * 描述:多钩子删除 16854568cb3Sopenharmony_ci */ 16954568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsMhookDel(U32 hookType, OsVoidFunc hook) 17054568cb3Sopenharmony_ci{ 17154568cb3Sopenharmony_ci uintptr_t intSave; 17254568cb3Sopenharmony_ci OsVoidFunc *mHook = NULL; 17354568cb3Sopenharmony_ci U32 ret; 17454568cb3Sopenharmony_ci U32 hookCnt = 0; 17554568cb3Sopenharmony_ci OsVoidFunc *del = NULL; 17654568cb3Sopenharmony_ci 17754568cb3Sopenharmony_ci mHook = g_hookCb[hookType].mulHook; 17854568cb3Sopenharmony_ci if (mHook == NULL) { 17954568cb3Sopenharmony_ci return OS_ERRNO_HOOK_NOT_CFG; 18054568cb3Sopenharmony_ci } 18154568cb3Sopenharmony_ci 18254568cb3Sopenharmony_ci HOOK_DEL_IRQ_LOCK(intSave); 18354568cb3Sopenharmony_ci 18454568cb3Sopenharmony_ci while (OS_MHOOK_IS_VALID(*mHook)) { 18554568cb3Sopenharmony_ci if (*mHook == OS_MHOOK_NODE_DEAD) { 18654568cb3Sopenharmony_ci mHook++; 18754568cb3Sopenharmony_ci continue; 18854568cb3Sopenharmony_ci } 18954568cb3Sopenharmony_ci 19054568cb3Sopenharmony_ci if (*mHook == hook) { 19154568cb3Sopenharmony_ci // 可断言del为空 19254568cb3Sopenharmony_ci del = mHook; 19354568cb3Sopenharmony_ci } 19454568cb3Sopenharmony_ci 19554568cb3Sopenharmony_ci mHook++; 19654568cb3Sopenharmony_ci hookCnt++; 19754568cb3Sopenharmony_ci } 19854568cb3Sopenharmony_ci 19954568cb3Sopenharmony_ci if (del == NULL) { 20054568cb3Sopenharmony_ci HOOK_DEL_IRQ_UNLOCK(intSave); 20154568cb3Sopenharmony_ci return OS_ERRNO_HOOK_NOT_EXISTED; 20254568cb3Sopenharmony_ci } 20354568cb3Sopenharmony_ci 20454568cb3Sopenharmony_ci if ((hookCnt == 1) && (g_hookChgHandler[hookType] != NULL)) { 20554568cb3Sopenharmony_ci ret = g_hookChgHandler[hookType](hookType, HOOK_DEL_LAST); 20654568cb3Sopenharmony_ci if (ret != OS_OK) { 20754568cb3Sopenharmony_ci HOOK_DEL_IRQ_UNLOCK(intSave); 20854568cb3Sopenharmony_ci return ret; 20954568cb3Sopenharmony_ci } 21054568cb3Sopenharmony_ci } 21154568cb3Sopenharmony_ci 21254568cb3Sopenharmony_ci // 如果是最后一个,置为FREE,避免每次钩子调用遍历。 否则置为DEAD态。 21354568cb3Sopenharmony_ci if (OS_MHOOK_IS_VALID(*(del + 1))) { 21454568cb3Sopenharmony_ci *del = OS_MHOOK_NODE_DEAD; 21554568cb3Sopenharmony_ci } else { 21654568cb3Sopenharmony_ci *del-- = OS_HOOK_EMPTY; 21754568cb3Sopenharmony_ci while ((del >= g_hookCb[hookType].mulHook) && (*del == OS_MHOOK_NODE_DEAD)) { 21854568cb3Sopenharmony_ci *del-- = OS_HOOK_EMPTY; 21954568cb3Sopenharmony_ci } 22054568cb3Sopenharmony_ci } 22154568cb3Sopenharmony_ci 22254568cb3Sopenharmony_ci HOOK_DEL_IRQ_UNLOCK(intSave); 22354568cb3Sopenharmony_ci return OS_OK; 22454568cb3Sopenharmony_ci} 22554568cb3Sopenharmony_ci 22654568cb3Sopenharmony_ci/* 22754568cb3Sopenharmony_ci * 描述:钩子添加 22854568cb3Sopenharmony_ci */ 22954568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsHookAdd(enum HookType hookType, OsVoidFunc hook) 23054568cb3Sopenharmony_ci{ 23154568cb3Sopenharmony_ci if ((U32)hookType >= (U32)OS_HOOK_TYPE_NUM) { 23254568cb3Sopenharmony_ci return OS_ERRNO_HOOK_TYPE_INVALID; 23354568cb3Sopenharmony_ci } 23454568cb3Sopenharmony_ci 23554568cb3Sopenharmony_ci if (hook == NULL) { 23654568cb3Sopenharmony_ci return OS_ERRNO_HOOK_PTR_NULL; 23754568cb3Sopenharmony_ci } 23854568cb3Sopenharmony_ci 23954568cb3Sopenharmony_ci return OsMhookAdd((U32)hookType, hook); 24054568cb3Sopenharmony_ci} 24154568cb3Sopenharmony_ci 24254568cb3Sopenharmony_ci/* 24354568cb3Sopenharmony_ci * 描述:钩子删除 24454568cb3Sopenharmony_ci */ 24554568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsHookDel(enum HookType hookType, OsVoidFunc hook) 24654568cb3Sopenharmony_ci{ 24754568cb3Sopenharmony_ci if ((U32)hookType >= (U32)(OS_HOOK_TYPE_NUM)) { 24854568cb3Sopenharmony_ci return OS_ERRNO_HOOK_TYPE_INVALID; 24954568cb3Sopenharmony_ci } 25054568cb3Sopenharmony_ci 25154568cb3Sopenharmony_ci if (hook == NULL) { 25254568cb3Sopenharmony_ci return OS_ERRNO_HOOK_PTR_NULL; 25354568cb3Sopenharmony_ci } 25454568cb3Sopenharmony_ci 25554568cb3Sopenharmony_ci return OsMhookDel((U32)hookType, hook); 25654568cb3Sopenharmony_ci} 25754568cb3Sopenharmony_ci 25854568cb3Sopenharmony_ci/* 25954568cb3Sopenharmony_ci * 描述:单钩子注册 26054568cb3Sopenharmony_ci */ 26154568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsShookReg(U32 hookType, OsVoidFunc hook) 26254568cb3Sopenharmony_ci{ 26354568cb3Sopenharmony_ci uintptr_t intSave; 26454568cb3Sopenharmony_ci U32 ret = OS_OK; 26554568cb3Sopenharmony_ci 26654568cb3Sopenharmony_ci if (!OS_IS_SHOOK_TYPE(hookType)) { 26754568cb3Sopenharmony_ci return OS_ERRNO_HOOK_TYPE_INVALID; 26854568cb3Sopenharmony_ci } 26954568cb3Sopenharmony_ci 27054568cb3Sopenharmony_ci HOOK_ADD_IRQ_LOCK(intSave); 27154568cb3Sopenharmony_ci 27254568cb3Sopenharmony_ci if (hook == NULL) { // unreg 27354568cb3Sopenharmony_ci if (g_hookCb[hookType].sigHook == NULL) { 27454568cb3Sopenharmony_ci HOOK_ADD_IRQ_UNLOCK(intSave); 27554568cb3Sopenharmony_ci return OS_OK; 27654568cb3Sopenharmony_ci } 27754568cb3Sopenharmony_ci 27854568cb3Sopenharmony_ci if (g_hookChgHandler[hookType] != NULL) { 27954568cb3Sopenharmony_ci ret = g_hookChgHandler[hookType](hookType, HOOK_DEL_LAST); 28054568cb3Sopenharmony_ci } 28154568cb3Sopenharmony_ci 28254568cb3Sopenharmony_ci if (ret == OS_OK) { 28354568cb3Sopenharmony_ci g_hookCb[hookType].sigHook = NULL; 28454568cb3Sopenharmony_ci } 28554568cb3Sopenharmony_ci } else { 28654568cb3Sopenharmony_ci if (g_hookCb[hookType].sigHook != NULL) { 28754568cb3Sopenharmony_ci HOOK_ADD_IRQ_UNLOCK(intSave); 28854568cb3Sopenharmony_ci return OS_ERRNO_HOOK_FULL; 28954568cb3Sopenharmony_ci } 29054568cb3Sopenharmony_ci 29154568cb3Sopenharmony_ci if (g_hookChgHandler[hookType] != NULL) { 29254568cb3Sopenharmony_ci ret = g_hookChgHandler[hookType](hookType, HOOK_ADD_FIRST); 29354568cb3Sopenharmony_ci } 29454568cb3Sopenharmony_ci 29554568cb3Sopenharmony_ci if (ret == OS_OK) { 29654568cb3Sopenharmony_ci g_hookCb[hookType].sigHook = hook; 29754568cb3Sopenharmony_ci } 29854568cb3Sopenharmony_ci } 29954568cb3Sopenharmony_ci 30054568cb3Sopenharmony_ci HOOK_ADD_IRQ_UNLOCK(intSave); 30154568cb3Sopenharmony_ci return ret; 30254568cb3Sopenharmony_ci} 30354568cb3Sopenharmony_ci 30454568cb3Sopenharmony_ci/* 30554568cb3Sopenharmony_ci * 描述:前置钩子添加 30654568cb3Sopenharmony_ci */ 30754568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 PRT_IdleAddPrefixHook(IdleHook hook) 30854568cb3Sopenharmony_ci{ 30954568cb3Sopenharmony_ci if (hook == NULL) { 31054568cb3Sopenharmony_ci return OS_ERRNO_SYS_PTR_NULL; 31154568cb3Sopenharmony_ci } 31254568cb3Sopenharmony_ci 31354568cb3Sopenharmony_ci return OsShookReg(OS_HOOK_IDLE_PREFIX, (OsVoidFunc)hook); 31454568cb3Sopenharmony_ci} 315