xref: /kernel/uniproton/src/om/hook/prt_hook_init.c (revision 54568cb3)
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