From: Zheng Yejian zhengyejian1@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4UAQ1
--------------------------------
Move 'struct klp_func_node' into include/linux/livepatch.h, then introduce klp_{add,del}_func_node and Move 'klp_func_list' related codes out of 'arch' in order to reduce duplicated codes.
Preparatory only, no functional change.
Signed-off-by: Zheng Yejian zhengyejian1@huawei.com Reviewed-by: Kuohai Xu xukuohai@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm/kernel/livepatch.c | 25 ++----------------------- arch/arm64/kernel/livepatch.c | 28 +++------------------------- arch/powerpc/kernel/livepatch_32.c | 27 +++------------------------ arch/powerpc/kernel/livepatch_64.c | 27 +++------------------------ arch/x86/kernel/livepatch.c | 29 ++--------------------------- include/linux/livepatch.h | 11 +++++++++++ kernel/livepatch/core.c | 24 ++++++++++++++++++++++++ 7 files changed, 48 insertions(+), 123 deletions(-)
diff --git a/arch/arm/kernel/livepatch.c b/arch/arm/kernel/livepatch.c index a72fb2c03d9d..d243f5f3e76a 100644 --- a/arch/arm/kernel/livepatch.c +++ b/arch/arm/kernel/livepatch.c @@ -46,27 +46,6 @@ #define CHECK_JUMP_RANGE 1 #endif
-struct klp_func_node { - struct list_head node; - struct list_head func_stack; - void *old_func; - struct arch_klp_data arch_data; -}; - -static LIST_HEAD(klp_func_list); - -static struct klp_func_node *klp_find_func_node(void *old_func) -{ - struct klp_func_node *func_node; - - list_for_each_entry(func_node, &klp_func_list, node) { - if (func_node->old_func == old_func) - return func_node; - } - - return NULL; -} - #ifdef CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY /* * The instruction set on arm is A32. @@ -406,7 +385,7 @@ int arch_klp_patch_func(struct klp_func *func) if (ret) { return -EPERM; } - list_add_rcu(&func_node->node, &klp_func_list); + klp_add_func_node(func_node); }
list_add_rcu(&func->stack_node, &func_node->func_stack); @@ -464,7 +443,7 @@ void arch_klp_unpatch_func(struct klp_func *func) __patch_text((void *)pc, insn); #endif list_del_rcu(&func->stack_node); - list_del_rcu(&func_node->node); + klp_del_func_node(func_node); } else { list_del_rcu(&func->stack_node); next_func = list_first_or_null_rcu(&func_node->func_stack, diff --git a/arch/arm64/kernel/livepatch.c b/arch/arm64/kernel/livepatch.c index 5c4629c8e6e2..a4b64e74f722 100644 --- a/arch/arm64/kernel/livepatch.c +++ b/arch/arm64/kernel/livepatch.c @@ -51,27 +51,6 @@ static inline bool offset_in_range(unsigned long pc, unsigned long addr, #define CHECK_JUMP_RANGE 1 #endif
-struct klp_func_node { - struct list_head node; - struct list_head func_stack; - void *old_func; - struct arch_klp_data arch_data; -}; - -static LIST_HEAD(klp_func_list); - -static struct klp_func_node *klp_find_func_node(void *old_func) -{ - struct klp_func_node *func_node; - - list_for_each_entry(func_node, &klp_func_list, node) { - if (func_node->old_func == old_func) - return func_node; - } - - return NULL; -} - #ifdef CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY /* * The instruction set on arm64 is A64. @@ -388,8 +367,7 @@ int arch_klp_patch_func(struct klp_func *func) if (ret) { return -EPERM; } - - list_add_rcu(&func_node->node, &klp_func_list); + klp_add_func_node(func_node); }
list_add_rcu(&func->stack_node, &func_node->func_stack); @@ -425,7 +403,7 @@ int arch_klp_patch_func(struct klp_func *func) ERR_OUT: list_del_rcu(&func->stack_node); if (memory_flag) { - list_del_rcu(&func_node->node); + klp_del_func_node(func_node); }
return -EPERM; @@ -454,7 +432,7 @@ void arch_klp_unpatch_func(struct klp_func *func) insn = func_node->arch_data.old_insn; #endif list_del_rcu(&func->stack_node); - list_del_rcu(&func_node->node); + klp_del_func_node(func_node);
#ifdef CONFIG_ARM64_MODULE_PLTS for (i = 0; i < LJMP_INSN_SIZE; i++) { diff --git a/arch/powerpc/kernel/livepatch_32.c b/arch/powerpc/kernel/livepatch_32.c index e4af8faa08bb..e2b9e9b25477 100644 --- a/arch/powerpc/kernel/livepatch_32.c +++ b/arch/powerpc/kernel/livepatch_32.c @@ -33,27 +33,6 @@ defined (CONFIG_LIVEPATCH_WO_FTRACE) #define MAX_SIZE_TO_CHECK (LJMP_INSN_SIZE * sizeof(u32)) #define CHECK_JUMP_RANGE LJMP_INSN_SIZE - -struct klp_func_node { - struct list_head node; - struct list_head func_stack; - void *old_func; - struct arch_klp_data arch_data; -}; - -static LIST_HEAD(klp_func_list); - -static struct klp_func_node *klp_find_func_node(void *old_func) -{ - struct klp_func_node *func_node; - - list_for_each_entry(func_node, &klp_func_list, node) { - if (func_node->old_func == old_func) - return func_node; - } - - return NULL; -} #endif
#ifdef CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY @@ -425,7 +404,7 @@ int arch_klp_patch_func(struct klp_func *func) } }
- list_add_rcu(&func_node->node, &klp_func_list); + klp_add_func_node(func_node); }
list_add_rcu(&func->stack_node, &func_node->func_stack); @@ -463,7 +442,7 @@ int arch_klp_patch_func(struct klp_func *func) ERR_OUT: list_del_rcu(&func->stack_node); if (memory_flag) { - list_del_rcu(&func_node->node); + klp_del_func_node(func_node); }
return -EPERM; @@ -484,7 +463,7 @@ void arch_klp_unpatch_func(struct klp_func *func) insns[i] = func_node->arch_data.old_insns[i];
list_del_rcu(&func->stack_node); - list_del_rcu(&func_node->node); + klp_del_func_node(func_node);
for (i = 0; i < LJMP_INSN_SIZE; i++) patch_instruction((struct ppc_inst *)(((u32 *)pc) + i), diff --git a/arch/powerpc/kernel/livepatch_64.c b/arch/powerpc/kernel/livepatch_64.c index 30e4ba7db602..94decee6cb8d 100644 --- a/arch/powerpc/kernel/livepatch_64.c +++ b/arch/powerpc/kernel/livepatch_64.c @@ -38,27 +38,6 @@ defined(CONFIG_LIVEPATCH_WO_FTRACE) #define MAX_SIZE_TO_CHECK (LJMP_INSN_SIZE * sizeof(u32)) #define CHECK_JUMP_RANGE LJMP_INSN_SIZE - -struct klp_func_node { - struct list_head node; - struct list_head func_stack; - void *old_func; - struct arch_klp_data arch_data; -}; - -static LIST_HEAD(klp_func_list); - -static struct klp_func_node *klp_find_func_node(void *old_func) -{ - struct klp_func_node *func_node; - - list_for_each_entry(func_node, &klp_func_list, node) { - if (func_node->old_func == old_func) - return func_node; - } - - return NULL; -} #endif
#ifdef CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY @@ -469,7 +448,7 @@ int arch_klp_patch_func(struct klp_func *func) return -EPERM; } } - list_add_rcu(&func_node->node, &klp_func_list); + klp_add_func_node(func_node); }
list_add_rcu(&func->stack_node, &func_node->func_stack); @@ -495,7 +474,7 @@ int arch_klp_patch_func(struct klp_func *func) ERR_OUT: list_del_rcu(&func->stack_node); if (memory_flag) { - list_del_rcu(&func_node->node); + klp_del_func_node(func_node); }
return -EPERM; @@ -516,7 +495,7 @@ void arch_klp_unpatch_func(struct klp_func *func) insns[i] = func_node->arch_data.old_insns[i];
list_del_rcu(&func->stack_node); - list_del_rcu(&func_node->node); + klp_del_func_node(func_node);
for (i = 0; i < LJMP_INSN_SIZE; i++) patch_instruction((struct ppc_inst *)((u32 *)pc + i), diff --git a/arch/x86/kernel/livepatch.c b/arch/x86/kernel/livepatch.c index 469a7e1323f5..640ce1053a87 100644 --- a/arch/x86/kernel/livepatch.c +++ b/arch/x86/kernel/livepatch.c @@ -31,31 +31,6 @@ #include <asm/nops.h> #include <asm/sections.h>
-#if defined (CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY) || \ - defined (CONFIG_LIVEPATCH_WO_FTRACE) - -struct klp_func_node { - struct list_head node; - struct list_head func_stack; - void *old_func; - struct arch_klp_data arch_data; -}; - -static LIST_HEAD(klp_func_list); - -static struct klp_func_node *klp_find_func_node(void *old_func) -{ - struct klp_func_node *func_node; - - list_for_each_entry(func_node, &klp_func_list, node) { - if (func_node->old_func == old_func) - return func_node; - } - - return NULL; -} -#endif - #ifdef CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY /* * The instruction set on x86 is CISC. @@ -434,7 +409,7 @@ int arch_klp_patch_func(struct klp_func *func) if (ret) { return -EPERM; } - list_add_rcu(&func_node->node, &klp_func_list); + klp_add_func_node(func_node); }
list_add_rcu(&func->stack_node, &func_node->func_stack); @@ -458,7 +433,7 @@ void arch_klp_unpatch_func(struct klp_func *func) ip = (unsigned long)func_node->old_func; if (list_is_singular(&func_node->func_stack)) { list_del_rcu(&func->stack_node); - list_del_rcu(&func_node->node); + klp_del_func_node(func_node); new = klp_old_code(func_node->arch_data.old_code); } else { list_del_rcu(&func->stack_node); diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index 229216646d50..5f88e6429484 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -223,6 +223,17 @@ int klp_enable_patch(struct klp_patch *); #elif defined(CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY) int klp_register_patch(struct klp_patch *patch); int klp_unregister_patch(struct klp_patch *patch); + +struct klp_func_node { + struct list_head node; + struct list_head func_stack; + void *old_func; + struct arch_klp_data arch_data; +}; + +struct klp_func_node *klp_find_func_node(const void *old_func); +void klp_add_func_node(struct klp_func_node *func_node); +void klp_del_func_node(struct klp_func_node *func_node); #endif
int klp_apply_section_relocs(struct module *pmod, Elf_Shdr *sechdrs, diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 660a4b4f61e4..bfa9462f8f38 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -1248,6 +1248,30 @@ int __weak klp_check_calltrace(struct klp_patch *patch, int enable) return 0; }
+static LIST_HEAD(klp_func_list); + +struct klp_func_node *klp_find_func_node(const void *old_func) +{ + struct klp_func_node *func_node; + + list_for_each_entry(func_node, &klp_func_list, node) { + if (func_node->old_func == old_func) + return func_node; + } + + return NULL; +} + +void klp_add_func_node(struct klp_func_node *func_node) +{ + list_add_rcu(&func_node->node, &klp_func_list); +} + +void klp_del_func_node(struct klp_func_node *func_node) +{ + list_del_rcu(&func_node->node); +} + /* * This function is called from stop_machine() context. */