1 /*
2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2009-12-22
13 * Description: HOOK模块的内部头文件
14 */
15 #ifndef PRT_HOOK_EXTERNAL_H
16 #define PRT_HOOK_EXTERNAL_H
17
18 #include "prt_hook.h"
19 #include "prt_sys.h"
20
21 /* 限制:参数类型不能为U64大于uintptr_t */
22 typedef void (*OsFunPara0)(void);
23 typedef void (*OsFunPara1)(uintptr_t);
24 typedef void (*OsFunPara2)(uintptr_t, uintptr_t);
25 typedef void (*OsFunPara3)(uintptr_t, uintptr_t, uintptr_t);
26 typedef void (*OsFunPara4)(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
27 typedef void (*OsFunPara5)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
28
29 /*
30 * 内核钩子管理原则
31 * 1)服务于内核模块的钩子才可纳入钩子模块统一管理,例如补丁、shell模块的钩子就不适合。
32 * 内核模块指mem,kernel,ipc,服务于内核的arch。
33 * 2)没有返回值,没有输出参数的钩子才可纳入钩子模块统一管理。
34 */
35 #define OS_MHOOK_BOUNDARY ((U32)1)
36
37 #define OS_MHOOK_NODE_DEAD ((OsVoidFunc)2)
38
39 // 除了OS_HOOK_EMPTY和OS_MHOOK_BOUNDARY外,都是有效钩子
40 #define OS_MHOOK_IS_VALID(hook) ((uintptr_t)(hook) > OS_MHOOK_BOUNDARY)
41
42 #define OS_MHOOK_NOT_BOUNDARY(hook) ((uintptr_t)(hook) != OS_MHOOK_BOUNDARY)
43
OsMhookBoundaryCheck(OsVoidFunc hook)44 OS_SEC_ALW_INLINE INLINE bool OsMhookBoundaryCheck(OsVoidFunc hook)
45 {
46 return ((uintptr_t)hook <= OS_MHOOK_BOUNDARY);
47 }
48
OsMhookValidCheck(OsVoidFunc hook)49 OS_SEC_ALW_INLINE INLINE bool OsMhookValidCheck(OsVoidFunc hook)
50 {
51 return (hook != OS_MHOOK_NODE_DEAD);
52 }
53
54 #define OS_MHOOK_ACTIVATE_PROC(hook, funcType, pfn, list) \
55 do { \
56 OsVoidFunc *tmp_ = hook; \
57 while (!OsMhookBoundaryCheck((OsVoidFunc)((pfn) = (funcType)(*tmp_)))) { \
58 if (OsMhookValidCheck((OsVoidFunc)(pfn))) { \
59 (list); \
60 } \
61 tmp_++; \
62 } \
63 } while (0)
64
65 #define OS_MHOOK_ACTIVATE(hookType, funcType, list) \
66 do { \
67 OsVoidFunc *hook = g_hookCb[(hookType)].mulHook; \
68 funcType pfn; \
69 if (hook != NULL) { \
70 OS_MHOOK_ACTIVATE_PROC(hook, funcType, pfn, (list)); \
71 } \
72 } while (0)
73
74 #define OS_SHOOK_ACTIVATE(hookType, funcType, list) \
75 do { \
76 funcType pfn = (funcType)g_hookCb[(hookType)].sigHook; \
77 if (pfn != NULL) \
78 (list); \
79 } while (0)
80
81 #define OS_MHOOK_ACTIVATE_PARA0(hookType) OS_MHOOK_ACTIVATE((hookType), OsFunPara0, pfn())
82 #define OS_MHOOK_ACTIVATE_PARA1(hookType, arg0) OS_MHOOK_ACTIVATE((hookType), OsFunPara1, pfn((uintptr_t)(arg0)))
83 #define OS_MHOOK_ACTIVATE_PARA2(hookType, arg0, arg1) OS_MHOOK_ACTIVATE((hookType), \
84 OsFunPara2, pfn((uintptr_t)(arg0), (uintptr_t)(arg1)))
85 #define OS_MHOOK_ACTIVATE_PARA3(hookType, arg0, arg1, arg2) OS_MHOOK_ACTIVATE((hookType), \
86 OsFunPara3, pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2)))
87 #define OS_MHOOK_ACTIVATE_PARA4(hookType, arg0, arg1, arg2, arg3) \
88 OS_MHOOK_ACTIVATE((hookType), \
89 OsFunPara4, pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3)))
90 #define OS_MHOOK_ACTIVATE_PARA5(hookType, arg0, arg1, arg2, arg3, arg4) \
91 OS_MHOOK_ACTIVATE((hookType), OsFunPara5, \
92 pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3), (uintptr_t)(arg4)))
93
94 #define OS_SHOOK_ACTIVATE_PARA0(hookType) OS_SHOOK_ACTIVATE((hookType), OsFunPara0, pfn())
95 #define OS_SHOOK_ACTIVATE_PARA1(hookType, arg0) OS_SHOOK_ACTIVATE((hookType), OsFunPara1, pfn((uintptr_t)(arg0)))
96 #define OS_SHOOK_ACTIVATE_PARA2(hookType, arg0, arg1) OS_SHOOK_ACTIVATE((hookType), \
97 OsFunPara2, pfn((uintptr_t)(arg0), (uintptr_t)(arg1)))
98 #define OS_SHOOK_ACTIVATE_PARA3(hookType, arg0, arg1, arg2) OS_SHOOK_ACTIVATE((hookType), \
99 OsFunPara3, pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2)))
100 #define OS_SHOOK_ACTIVATE_PARA4(hookType, arg0, arg1, arg2, arg3) \
101 OS_SHOOK_ACTIVATE((hookType), OsFunPara4, \
102 pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3)))
103 #define OS_SHOOK_ACTIVATE_PARA5(hookType, arg0, arg1, arg2, arg3, arg4) \
104 OS_SHOOK_ACTIVATE((hookType), OsFunPara5, \
105 pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3), (uintptr_t)(arg4)))
106
107 #define HOOK_ADD_IRQ_LOCK(intSave) \
108 do { \
109 (intSave) = PRT_HwiLock(); \
110 } while (0)
111 #define HOOK_ADD_IRQ_UNLOCK(intSave) PRT_HwiRestore((intSave))
112
113 #define HOOK_DEL_IRQ_LOCK(intSave) \
114 do { \
115 (intSave) = PRT_HwiLock(); \
116 } while (0)
117 #define HOOK_DEL_IRQ_UNLOCK(intSave) PRT_HwiRestore((intSave))
118
119 enum {
120 OS_HOOK_TICK_ENTRY = OS_HOOK_TYPE_NUM,
121 OS_HOOK_TICK_EXIT,
122 OS_HOOK_FIRST_TIME_SWH,
123 OS_HOOK_TSK_MON, /* TSKMON钩子 */
124 OS_HOOK_CPUP_WARN, /* CPUP告警钩子 */
125 OS_HOOK_ERR_REG, /* 错误处理钩子 */
126 OS_HOOK_IDLE_PREFIX, /* IDLE前置钩子 */
127 OS_HOOK_MEM_DAMAGE, /* 踩内存处理钩子 */
128
129 OS_HOOK_TYPE_TOTAL
130 };
131
132 #define OS_SHOOK_TYPE_START ((U32)OS_HOOK_TSK_MON)
133
134 enum HookChgType {
135 HOOK_ADD_FIRST,
136 HOOK_DEL_LAST
137 };
138
139 union TagMhookCb {
140 // 在初始化阶段复用为钩子注册数目
141 uintptr_t num;
142 // 单钩子
143 OsVoidFunc sigHook;
144 OsVoidFunc *mulHook;
145 };
146
147 typedef U32(*OsHookChgFunc)(U32 hookType, enum HookChgType chgType);
148
149 extern union TagMhookCb g_hookCb[OS_HOOK_TYPE_TOTAL];
150
151 typedef void *(*MemAllocHook)(enum MoudleId mid, U8 ptNo, U32 size);
152 extern MemAllocHook g_osMemAlloc;
153
154 /*
155 * 多钩子添加内部接口
156 */
157 extern U32 OsMhookAdd(U32 hookType, OsVoidFunc hook);
158
159 /*
160 * 多钩子删除内部接口
161 */
162 extern U32 OsMhookDel(U32 hookType, OsVoidFunc hook);
163
164 /*
165 * 钩子添加内部接口
166 */
167 extern U32 OsHookAdd(enum HookType hookType, OsVoidFunc hook);
168
169 /*
170 * 钩子删除内部接口
171 */
172 extern U32 OsHookDel(enum HookType hookType, OsVoidFunc hook);
173
174 /*
175 * 多钩子注册内部接口, 为了与原有规格兼容,传入NULL表示删除
176 */
177 extern U32 OsShookReg(U32 hookType, OsVoidFunc hook);
178
179 /*
180 * 在注册阶段,不同模块通过osMhookReserve接口预留钩子,不影响用户注册钩子数
181 * 仅在register阶段使用
182 */
183 extern void OsMhookReserve(U32 hookType, U32 incCnt);
184
185 #endif /* PRT_HOOK_EXTERNAL_H */
186