From: Zheng Yejian zhengyejian1@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4UAQ1
--------------------------------
Introduce __weak arch_klp_mem_{alloc, free}, then reduce duplicated arch_klp_mem_{prepare,recycle}
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 | 30 ---------------------- arch/arm64/kernel/livepatch.c | 30 ---------------------- arch/powerpc/kernel/livepatch_32.c | 30 ---------------------- arch/powerpc/kernel/livepatch_64.c | 33 ++++++++---------------- arch/x86/kernel/livepatch.c | 30 ---------------------- kernel/livepatch/core.c | 41 ++++++++++++++++++++++++++---- 6 files changed, 47 insertions(+), 147 deletions(-)
diff --git a/arch/arm/kernel/livepatch.c b/arch/arm/kernel/livepatch.c index d243f5f3e76a..6d53e8d250b0 100644 --- a/arch/arm/kernel/livepatch.c +++ b/arch/arm/kernel/livepatch.c @@ -499,33 +499,3 @@ int arch_klp_func_can_patch(struct klp_func *func) return 0; } #endif /* #ifdef CONFIG_ARM_MODULE_PLTS */ - -void arch_klp_mem_prepare(struct klp_patch *patch) -{ - struct klp_object *obj; - struct klp_func *func; - - klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func->func_node = kzalloc(sizeof(struct klp_func_node), - GFP_ATOMIC); - } - } -} - -void arch_klp_mem_recycle(struct klp_patch *patch) -{ - struct klp_object *obj; - struct klp_func *func; - struct klp_func_node *func_node; - - klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func_node = func->func_node; - if (func_node && list_is_singular(&func_node->func_stack)) { - kfree(func_node); - func->func_node = NULL; - } - } - } -} diff --git a/arch/arm64/kernel/livepatch.c b/arch/arm64/kernel/livepatch.c index a4b64e74f722..3746c689a6f1 100644 --- a/arch/arm64/kernel/livepatch.c +++ b/arch/arm64/kernel/livepatch.c @@ -498,33 +498,3 @@ int arch_klp_func_can_patch(struct klp_func *func) return 0; } #endif - -void arch_klp_mem_prepare(struct klp_patch *patch) -{ - struct klp_object *obj; - struct klp_func *func; - - klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func->func_node = kzalloc(sizeof(struct klp_func_node), - GFP_ATOMIC); - } - } -} - -void arch_klp_mem_recycle(struct klp_patch *patch) -{ - struct klp_object *obj; - struct klp_func *func; - struct klp_func_node *func_node; - - klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func_node = func->func_node; - if (func_node && list_is_singular(&func_node->func_stack)) { - kfree(func_node); - func->func_node = NULL; - } - } - } -} diff --git a/arch/powerpc/kernel/livepatch_32.c b/arch/powerpc/kernel/livepatch_32.c index e2b9e9b25477..638f18d88c33 100644 --- a/arch/powerpc/kernel/livepatch_32.c +++ b/arch/powerpc/kernel/livepatch_32.c @@ -515,34 +515,4 @@ int arch_klp_func_can_patch(struct klp_func *func) } return 0; } - -void arch_klp_mem_prepare(struct klp_patch *patch) -{ - struct klp_object *obj; - struct klp_func *func; - - klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func->func_node = kzalloc(sizeof(struct klp_func_node), - GFP_ATOMIC); - } - } -} - -void arch_klp_mem_recycle(struct klp_patch *patch) -{ - struct klp_object *obj; - struct klp_func *func; - struct klp_func_node *func_node; - - klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func_node = func->func_node; - if (func_node && list_is_singular(&func_node->func_stack)) { - kfree(func_node); - func->func_node = NULL; - } - } - } -} #endif diff --git a/arch/powerpc/kernel/livepatch_64.c b/arch/powerpc/kernel/livepatch_64.c index 94decee6cb8d..c0d6fd5ead8e 100644 --- a/arch/powerpc/kernel/livepatch_64.c +++ b/arch/powerpc/kernel/livepatch_64.c @@ -579,32 +579,21 @@ int arch_klp_init_func(struct klp_object *obj, struct klp_func *func) return 0; }
-void arch_klp_mem_prepare(struct klp_patch *patch) +/* + * Trampoline would be stored in the allocated memory and it need + * executable permission, so ppc64 use 'module_alloc' but not 'kmalloc'. + */ +void *arch_klp_mem_alloc(size_t size) { - struct klp_object *obj; - struct klp_func *func; + void *mem = module_alloc(size);
- klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func->func_node = module_alloc(sizeof(struct klp_func_node)); - } - } + if (mem) + memset(mem, 0, size); /* initially clear the memory */ + return mem; }
-void arch_klp_mem_recycle(struct klp_patch *patch) +void arch_klp_mem_free(void *mem) { - struct klp_object *obj; - struct klp_func *func; - struct klp_func_node *func_node; - - klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func_node = func->func_node; - if (func_node && list_is_singular(&func_node->func_stack)) { - module_memfree(func_node); - func->func_node = NULL; - } - } - } + module_memfree(mem); } #endif diff --git a/arch/x86/kernel/livepatch.c b/arch/x86/kernel/livepatch.c index 640ce1053a87..02c869ea18fb 100644 --- a/arch/x86/kernel/livepatch.c +++ b/arch/x86/kernel/livepatch.c @@ -447,34 +447,4 @@ void arch_klp_unpatch_func(struct klp_func *func) /* replace the text with the new text */ text_poke((void *)ip, new, JMP_E9_INSN_SIZE); } - -void arch_klp_mem_prepare(struct klp_patch *patch) -{ - struct klp_object *obj; - struct klp_func *func; - - klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func->func_node = kzalloc(sizeof(struct klp_func_node), - GFP_ATOMIC); - } - } -} - -void arch_klp_mem_recycle(struct klp_patch *patch) -{ - struct klp_object *obj; - struct klp_func *func; - struct klp_func_node *func_node; - - klp_for_each_object(patch, obj) { - klp_for_each_func(obj, func) { - func_node = func->func_node; - if (func_node && list_is_singular(&func_node->func_stack)) { - kfree(func_node); - func->func_node = NULL; - } - } - } -} #endif diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index bfa9462f8f38..38c2b603b6a8 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -1327,12 +1327,43 @@ void __weak arch_klp_code_modify_post_process(void) { }
-void __weak arch_klp_mem_prepare(struct klp_patch *patch) +void __weak *arch_klp_mem_alloc(size_t size) { + return kzalloc(size, GFP_ATOMIC); }
-void __weak arch_klp_mem_recycle(struct klp_patch *patch) +void __weak arch_klp_mem_free(void *mem) { + kfree(mem); +} + +static void klp_mem_prepare(struct klp_patch *patch) +{ + struct klp_object *obj; + struct klp_func *func; + + klp_for_each_object(patch, obj) { + klp_for_each_func(obj, func) { + func->func_node = arch_klp_mem_alloc(sizeof(struct klp_func_node)); + } + } +} + +static void klp_mem_recycle(struct klp_patch *patch) +{ + struct klp_object *obj; + struct klp_func *func; + struct klp_func_node *func_node; + + klp_for_each_object(patch, obj) { + klp_for_each_func(obj, func) { + func_node = func->func_node; + if (func_node && list_is_singular(&func_node->func_stack)) { + arch_klp_mem_free(func_node); + func->func_node = NULL; + } + } + } }
static int __klp_disable_patch(struct klp_patch *patch) @@ -1361,7 +1392,7 @@ static int __klp_disable_patch(struct klp_patch *patch) if (ret) return ret;
- arch_klp_mem_recycle(patch); + klp_mem_recycle(patch); return 0; } #endif /* if defined(CONFIG_LIVEPATCH_PER_TASK_CONSISTENCY) */ @@ -1594,11 +1625,11 @@ static int __klp_enable_patch(struct klp_patch *patch) #endif
arch_klp_code_modify_prepare(); - arch_klp_mem_prepare(patch); + klp_mem_prepare(patch); ret = stop_machine(klp_try_enable_patch, &patch_data, cpu_online_mask); arch_klp_code_modify_post_process(); if (ret) { - arch_klp_mem_recycle(patch); + klp_mem_recycle(patch); return ret; }