提交 8bedd284 编写于 作者: Z Zheng Yejian 提交者: Zheng Zengkai

livepatch: Introduce 'arch_klp_save_old_code'

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4UAQ1

--------------------------------

Introduce 'arch_klp_save_old_code' preparing for moving func_node
initializing codes out of stop_machine.
Signed-off-by: NZheng Yejian <zhengyejian1@huawei.com>
Reviewed-by: NKuohai Xu <xukuohai@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 bfeb55fc
...@@ -51,6 +51,8 @@ struct arch_klp_data { ...@@ -51,6 +51,8 @@ struct arch_klp_data {
#endif #endif
}; };
long arch_klp_save_old_code(struct arch_klp_data *arch_data, void *old_func);
#endif #endif
#endif /* _ASM_ARM_LIVEPATCH_H */ #endif /* _ASM_ARM_LIVEPATCH_H */
...@@ -353,6 +353,23 @@ long arm_insn_read(void *addr, u32 *insnp) ...@@ -353,6 +353,23 @@ long arm_insn_read(void *addr, u32 *insnp)
return ret; return ret;
} }
long arch_klp_save_old_code(struct arch_klp_data *arch_data, void *old_func)
{
long ret;
#ifdef CONFIG_ARM_MODULE_PLTS
int i;
for (i = 0; i < LJMP_INSN_SIZE; i++) {
ret = arm_insn_read((u32 *)old_func + i, &arch_data->old_insns[i]);
if (ret)
break;
}
#else
ret = arm_insn_read(old_func, &arch_data->old_insn);
#endif
return ret;
}
int arch_klp_patch_func(struct klp_func *func) int arch_klp_patch_func(struct klp_func *func)
{ {
struct klp_func_node *func_node; struct klp_func_node *func_node;
...@@ -372,16 +389,7 @@ int arch_klp_patch_func(struct klp_func *func) ...@@ -372,16 +389,7 @@ int arch_klp_patch_func(struct klp_func *func)
INIT_LIST_HEAD(&func_node->func_stack); INIT_LIST_HEAD(&func_node->func_stack);
func_node->old_func = func->old_func; func_node->old_func = func->old_func;
#ifdef CONFIG_ARM_MODULE_PLTS ret = arch_klp_save_old_code(&func_node->arch_data, func->old_func);
for (i = 0; i < LJMP_INSN_SIZE; i++) {
ret = arm_insn_read((u32 *)func->old_func + i,
&func_node->arch_data.old_insns[i]);
if (ret)
break;
}
#else
ret = arm_insn_read(func->old_func, &func_node->arch_data.old_insn);
#endif
if (ret) { if (ret) {
return -EPERM; return -EPERM;
} }
......
...@@ -61,6 +61,8 @@ struct arch_klp_data { ...@@ -61,6 +61,8 @@ struct arch_klp_data {
#endif #endif
}; };
long arch_klp_save_old_code(struct arch_klp_data *arch_data, void *old_func);
#endif #endif
#endif /* _ASM_ARM64_LIVEPATCH_H */ #endif /* _ASM_ARM64_LIVEPATCH_H */
...@@ -331,6 +331,24 @@ int klp_check_calltrace(struct klp_patch *patch, int enable) ...@@ -331,6 +331,24 @@ int klp_check_calltrace(struct klp_patch *patch, int enable)
} }
#endif #endif
long arch_klp_save_old_code(struct arch_klp_data *arch_data, void *old_func)
{
long ret;
#ifdef CONFIG_ARM64_MODULE_PLTS
int i;
for (i = 0; i < LJMP_INSN_SIZE; i++) {
ret = aarch64_insn_read(((u32 *)old_func) + i,
&arch_data->old_insns[i]);
if (ret)
break;
}
#else
ret = aarch64_insn_read(old_func, &arch_data->old_insn);
#endif
return ret;
}
int arch_klp_patch_func(struct klp_func *func) int arch_klp_patch_func(struct klp_func *func)
{ {
struct klp_func_node *func_node; struct klp_func_node *func_node;
...@@ -353,17 +371,7 @@ int arch_klp_patch_func(struct klp_func *func) ...@@ -353,17 +371,7 @@ int arch_klp_patch_func(struct klp_func *func)
INIT_LIST_HEAD(&func_node->func_stack); INIT_LIST_HEAD(&func_node->func_stack);
func_node->old_func = func->old_func; func_node->old_func = func->old_func;
#ifdef CONFIG_ARM64_MODULE_PLTS ret = arch_klp_save_old_code(&func_node->arch_data, func->old_func);
for (i = 0; i < LJMP_INSN_SIZE; i++) {
ret = aarch64_insn_read(((u32 *)func->old_func) + i,
&func_node->arch_data.old_insns[i]);
if (ret)
break;
}
#else
ret = aarch64_insn_read((void *)func->old_func,
&func_node->arch_data.old_insn);
#endif
if (ret) { if (ret) {
return -EPERM; return -EPERM;
} }
......
...@@ -93,6 +93,7 @@ struct arch_klp_data { ...@@ -93,6 +93,7 @@ struct arch_klp_data {
#elif defined(CONFIG_PPC32) #elif defined(CONFIG_PPC32)
#define PPC32_INSN_SIZE 4
#define LJMP_INSN_SIZE 4 #define LJMP_INSN_SIZE 4
struct arch_klp_data { struct arch_klp_data {
u32 old_insns[LJMP_INSN_SIZE]; u32 old_insns[LJMP_INSN_SIZE];
...@@ -100,6 +101,8 @@ struct arch_klp_data { ...@@ -100,6 +101,8 @@ struct arch_klp_data {
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
long arch_klp_save_old_code(struct arch_klp_data *arch_data, void *old_func);
#endif /* CONFIG_LIVEPATCH_FTRACE */ #endif /* CONFIG_LIVEPATCH_FTRACE */
#ifdef CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY #ifdef CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY
......
...@@ -378,6 +378,20 @@ static inline bool offset_in_range(unsigned long pc, unsigned long addr, ...@@ -378,6 +378,20 @@ static inline bool offset_in_range(unsigned long pc, unsigned long addr,
return (offset >= -range && offset < range); return (offset >= -range && offset < range);
} }
long arch_klp_save_old_code(struct arch_klp_data *arch_data, void *old_func)
{
long ret;
int i;
for (i = 0; i < LJMP_INSN_SIZE; i++) {
ret = copy_from_kernel_nofault(&arch_data->old_insns[i],
((u32 *)old_func) + i, PPC32_INSN_SIZE);
if (ret)
break;
}
return ret;
}
int arch_klp_patch_func(struct klp_func *func) int arch_klp_patch_func(struct klp_func *func)
{ {
struct klp_func_node *func_node; struct klp_func_node *func_node;
...@@ -396,13 +410,9 @@ int arch_klp_patch_func(struct klp_func *func) ...@@ -396,13 +410,9 @@ int arch_klp_patch_func(struct klp_func *func)
memory_flag = 1; memory_flag = 1;
INIT_LIST_HEAD(&func_node->func_stack); INIT_LIST_HEAD(&func_node->func_stack);
func_node->old_func = func->old_func; func_node->old_func = func->old_func;
for (i = 0; i < LJMP_INSN_SIZE; i++) { ret = arch_klp_save_old_code(&func_node->arch_data, func->old_func);
ret = copy_from_kernel_nofault(&func_node->arch_data.old_insns[i], if (ret)
((u32 *)func->old_func) + i, LJMP_INSN_SIZE); return -EPERM;
if (ret) {
return -EPERM;
}
}
klp_add_func_node(func_node); klp_add_func_node(func_node);
} }
......
...@@ -424,11 +424,25 @@ int klp_check_calltrace(struct klp_patch *patch, int enable) ...@@ -424,11 +424,25 @@ int klp_check_calltrace(struct klp_patch *patch, int enable)
#endif #endif
#ifdef CONFIG_LIVEPATCH_WO_FTRACE #ifdef CONFIG_LIVEPATCH_WO_FTRACE
long arch_klp_save_old_code(struct arch_klp_data *arch_data, void *old_func)
{
long ret;
int i;
for (i = 0; i < LJMP_INSN_SIZE; i++) {
ret = copy_from_kernel_nofault(&arch_data->old_insns[i],
((u32 *)old_func) + i, PPC64_INSN_SIZE);
if (ret)
break;
}
return ret;
}
int arch_klp_patch_func(struct klp_func *func) int arch_klp_patch_func(struct klp_func *func)
{ {
struct klp_func_node *func_node; struct klp_func_node *func_node;
unsigned long pc, new_addr; unsigned long pc, new_addr;
int i;
int memory_flag = 0; int memory_flag = 0;
long ret; long ret;
...@@ -441,13 +455,9 @@ int arch_klp_patch_func(struct klp_func *func) ...@@ -441,13 +455,9 @@ int arch_klp_patch_func(struct klp_func *func)
memory_flag = 1; memory_flag = 1;
INIT_LIST_HEAD(&func_node->func_stack); INIT_LIST_HEAD(&func_node->func_stack);
func_node->old_func = func->old_func; func_node->old_func = func->old_func;
for (i = 0; i < LJMP_INSN_SIZE; i++) { ret = arch_klp_save_old_code(&func_node->arch_data, func->old_func);
ret = copy_from_kernel_nofault(&func_node->arch_data.old_insns[i], if (ret)
((u32 *)func->old_func) + i, 4); return -EPERM;
if (ret) {
return -EPERM;
}
}
klp_add_func_node(func_node); klp_add_func_node(func_node);
} }
......
...@@ -39,6 +39,8 @@ struct arch_klp_data { ...@@ -39,6 +39,8 @@ struct arch_klp_data {
unsigned char old_code[JMP_E9_INSN_SIZE]; unsigned char old_code[JMP_E9_INSN_SIZE];
}; };
long arch_klp_save_old_code(struct arch_klp_data *arch_data, void *old_func);
#endif #endif
#endif /* _ASM_X86_LIVEPATCH_H */ #endif /* _ASM_X86_LIVEPATCH_H */
...@@ -388,6 +388,12 @@ void arch_klp_code_modify_post_process(void) ...@@ -388,6 +388,12 @@ void arch_klp_code_modify_post_process(void)
mutex_unlock(&text_mutex); mutex_unlock(&text_mutex);
} }
long arch_klp_save_old_code(struct arch_klp_data *arch_data, void *old_func)
{
return copy_from_kernel_nofault(arch_data->old_code,
old_func, JMP_E9_INSN_SIZE);
}
int arch_klp_patch_func(struct klp_func *func) int arch_klp_patch_func(struct klp_func *func)
{ {
struct klp_func_node *func_node; struct klp_func_node *func_node;
...@@ -404,8 +410,7 @@ int arch_klp_patch_func(struct klp_func *func) ...@@ -404,8 +410,7 @@ int arch_klp_patch_func(struct klp_func *func)
INIT_LIST_HEAD(&func_node->func_stack); INIT_LIST_HEAD(&func_node->func_stack);
func_node->old_func = func->old_func; func_node->old_func = func->old_func;
ret = copy_from_kernel_nofault(func_node->arch_data.old_code, ret = arch_klp_save_old_code(&func_node->arch_data, (void *)ip);
(void *)ip, JMP_E9_INSN_SIZE);
if (ret) { if (ret) {
return -EPERM; return -EPERM;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册