hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8MGE6
--------------------------------
Livepatch allows users to call hook functions to perform some customized operations when insmod the .ko. During the test, it is found that in the ARM64 architecture, if accesses the global variables defined by other ko in hook functions, a crash occurs.
Since relocation is performed during the livepatch insertion, instructions in the icache should be invalid. If the instructions in the icache are directly obtained, incorrect addresses may be obtained, caseing crash. Therefore, flush the icache before calling the hook functions.
Signed-off-by: Ye Weihua yeweihua4@huawei.com Signed-off-by: Zheng Yejian zhengyejian1@huawei.com --- include/linux/moduleloader.h | 2 ++ kernel/livepatch/core.c | 1 + kernel/module/main.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 068362e08747..176fef9870b9 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -121,6 +121,8 @@ void module_arch_cleanup(struct module *mod); /* Any cleanup before freeing mod->module_init */ void module_arch_freeing_init(struct module *mod);
+void flush_module_icache(const struct module *mod); + #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ !defined(CONFIG_KASAN_VMALLOC) #include <linux/kasan.h> diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index b635c8b451e5..e0f93bbc3c93 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -1061,6 +1061,7 @@ static int klp_init_patch(struct klp_patch *patch) }
#ifdef CONFIG_LIVEPATCH_WO_FTRACE + flush_module_icache(patch->mod); set_mod_klp_rel_state(patch->mod, MODULE_KLP_REL_DONE); ret = jump_label_register(patch->mod); if (ret) { diff --git a/kernel/module/main.c b/kernel/module/main.c index d5765c6cd188..4f1592035229 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -2317,7 +2317,7 @@ static int check_export_symbol_versions(struct module *mod) return 0; }
-static void flush_module_icache(const struct module *mod) +void flush_module_icache(const struct module *mod) { /* * Flush the instruction cache, since we've played with text.