Loading arch/x86/include/asm/livepatch.h +2 −2 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ static inline int klp_check_compiler_support(void) #endif return 0; } extern int klp_write_module_reloc(struct module *mod, unsigned long type, int klp_write_module_reloc(struct module *mod, unsigned long type, unsigned long loc, unsigned long value); static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip) Loading include/linux/livepatch.h +4 −4 Original line number Diff line number Diff line Loading @@ -123,10 +123,10 @@ struct klp_patch { enum klp_state state; }; extern int klp_register_patch(struct klp_patch *); extern int klp_unregister_patch(struct klp_patch *); extern int klp_enable_patch(struct klp_patch *); extern int klp_disable_patch(struct klp_patch *); int klp_register_patch(struct klp_patch *); int klp_unregister_patch(struct klp_patch *); int klp_enable_patch(struct klp_patch *); int klp_disable_patch(struct klp_patch *); #endif /* CONFIG_LIVEPATCH */ Loading kernel/livepatch/core.c +17 −52 Original line number Diff line number Diff line Loading @@ -335,32 +335,20 @@ static void notrace klp_ftrace_handler(unsigned long ip, rcu_read_unlock(); } static int klp_disable_func(struct klp_func *func) static void klp_disable_func(struct klp_func *func) { struct klp_ops *ops; int ret; if (WARN_ON(func->state != KLP_ENABLED)) return -EINVAL; if (WARN_ON(!func->old_addr)) return -EINVAL; WARN_ON(func->state != KLP_ENABLED); WARN_ON(!func->old_addr); ops = klp_find_ops(func->old_addr); if (WARN_ON(!ops)) return -EINVAL; return; if (list_is_singular(&ops->func_stack)) { ret = unregister_ftrace_function(&ops->fops); if (ret) { pr_err("failed to unregister ftrace handler for function '%s' (%d)\n", func->old_name, ret); return ret; } ret = ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0); if (ret) pr_warn("function unregister succeeded but failed to clear the filter\n"); WARN_ON(unregister_ftrace_function(&ops->fops)); WARN_ON(ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0)); list_del_rcu(&func->stack_node); list_del(&ops->node); Loading @@ -370,8 +358,6 @@ static int klp_disable_func(struct klp_func *func) } func->state = KLP_DISABLED; return 0; } static int klp_enable_func(struct klp_func *func) Loading Loading @@ -432,23 +418,15 @@ static int klp_enable_func(struct klp_func *func) return ret; } static int klp_disable_object(struct klp_object *obj) static void klp_disable_object(struct klp_object *obj) { struct klp_func *func; int ret; for (func = obj->funcs; func->old_name; func++) { if (func->state != KLP_ENABLED) continue; ret = klp_disable_func(func); if (ret) return ret; } for (func = obj->funcs; func->old_name; func++) if (func->state == KLP_ENABLED) klp_disable_func(func); obj->state = KLP_DISABLED; return 0; } static int klp_enable_object(struct klp_object *obj) Loading @@ -464,22 +442,19 @@ static int klp_enable_object(struct klp_object *obj) for (func = obj->funcs; func->old_name; func++) { ret = klp_enable_func(func); if (ret) goto unregister; if (ret) { klp_disable_object(obj); return ret; } } obj->state = KLP_ENABLED; return 0; unregister: WARN_ON(klp_disable_object(obj)); return ret; } static int __klp_disable_patch(struct klp_patch *patch) { struct klp_object *obj; int ret; /* enforce stacking: only the last enabled patch can be disabled */ if (!list_is_last(&patch->list, &klp_patches) && Loading @@ -489,12 +464,8 @@ static int __klp_disable_patch(struct klp_patch *patch) pr_notice("disabling patch '%s'\n", patch->mod->name); for (obj = patch->objs; obj->funcs; obj++) { if (obj->state != KLP_ENABLED) continue; ret = klp_disable_object(obj); if (ret) return ret; if (obj->state == KLP_ENABLED) klp_disable_object(obj); } patch->state = KLP_DISABLED; Loading Loading @@ -553,8 +524,6 @@ static int __klp_enable_patch(struct klp_patch *patch) pr_notice("enabling patch '%s'\n", patch->mod->name); for (obj = patch->objs; obj->funcs; obj++) { klp_find_object_module(obj); if (!klp_is_object_loaded(obj)) continue; Loading Loading @@ -945,7 +914,6 @@ static void klp_module_notify_going(struct klp_patch *patch, { struct module *pmod = patch->mod; struct module *mod = obj->mod; int ret; if (patch->state == KLP_DISABLED) goto disabled; Loading @@ -953,10 +921,7 @@ static void klp_module_notify_going(struct klp_patch *patch, pr_notice("reverting patch '%s' on unloading module '%s'\n", pmod->name, mod->name); ret = klp_disable_object(obj); if (ret) pr_warn("failed to revert patch '%s' on module '%s' (%d)\n", pmod->name, mod->name, ret); klp_disable_object(obj); disabled: klp_free_object_loaded(obj); Loading Loading
arch/x86/include/asm/livepatch.h +2 −2 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ static inline int klp_check_compiler_support(void) #endif return 0; } extern int klp_write_module_reloc(struct module *mod, unsigned long type, int klp_write_module_reloc(struct module *mod, unsigned long type, unsigned long loc, unsigned long value); static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip) Loading
include/linux/livepatch.h +4 −4 Original line number Diff line number Diff line Loading @@ -123,10 +123,10 @@ struct klp_patch { enum klp_state state; }; extern int klp_register_patch(struct klp_patch *); extern int klp_unregister_patch(struct klp_patch *); extern int klp_enable_patch(struct klp_patch *); extern int klp_disable_patch(struct klp_patch *); int klp_register_patch(struct klp_patch *); int klp_unregister_patch(struct klp_patch *); int klp_enable_patch(struct klp_patch *); int klp_disable_patch(struct klp_patch *); #endif /* CONFIG_LIVEPATCH */ Loading
kernel/livepatch/core.c +17 −52 Original line number Diff line number Diff line Loading @@ -335,32 +335,20 @@ static void notrace klp_ftrace_handler(unsigned long ip, rcu_read_unlock(); } static int klp_disable_func(struct klp_func *func) static void klp_disable_func(struct klp_func *func) { struct klp_ops *ops; int ret; if (WARN_ON(func->state != KLP_ENABLED)) return -EINVAL; if (WARN_ON(!func->old_addr)) return -EINVAL; WARN_ON(func->state != KLP_ENABLED); WARN_ON(!func->old_addr); ops = klp_find_ops(func->old_addr); if (WARN_ON(!ops)) return -EINVAL; return; if (list_is_singular(&ops->func_stack)) { ret = unregister_ftrace_function(&ops->fops); if (ret) { pr_err("failed to unregister ftrace handler for function '%s' (%d)\n", func->old_name, ret); return ret; } ret = ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0); if (ret) pr_warn("function unregister succeeded but failed to clear the filter\n"); WARN_ON(unregister_ftrace_function(&ops->fops)); WARN_ON(ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0)); list_del_rcu(&func->stack_node); list_del(&ops->node); Loading @@ -370,8 +358,6 @@ static int klp_disable_func(struct klp_func *func) } func->state = KLP_DISABLED; return 0; } static int klp_enable_func(struct klp_func *func) Loading Loading @@ -432,23 +418,15 @@ static int klp_enable_func(struct klp_func *func) return ret; } static int klp_disable_object(struct klp_object *obj) static void klp_disable_object(struct klp_object *obj) { struct klp_func *func; int ret; for (func = obj->funcs; func->old_name; func++) { if (func->state != KLP_ENABLED) continue; ret = klp_disable_func(func); if (ret) return ret; } for (func = obj->funcs; func->old_name; func++) if (func->state == KLP_ENABLED) klp_disable_func(func); obj->state = KLP_DISABLED; return 0; } static int klp_enable_object(struct klp_object *obj) Loading @@ -464,22 +442,19 @@ static int klp_enable_object(struct klp_object *obj) for (func = obj->funcs; func->old_name; func++) { ret = klp_enable_func(func); if (ret) goto unregister; if (ret) { klp_disable_object(obj); return ret; } } obj->state = KLP_ENABLED; return 0; unregister: WARN_ON(klp_disable_object(obj)); return ret; } static int __klp_disable_patch(struct klp_patch *patch) { struct klp_object *obj; int ret; /* enforce stacking: only the last enabled patch can be disabled */ if (!list_is_last(&patch->list, &klp_patches) && Loading @@ -489,12 +464,8 @@ static int __klp_disable_patch(struct klp_patch *patch) pr_notice("disabling patch '%s'\n", patch->mod->name); for (obj = patch->objs; obj->funcs; obj++) { if (obj->state != KLP_ENABLED) continue; ret = klp_disable_object(obj); if (ret) return ret; if (obj->state == KLP_ENABLED) klp_disable_object(obj); } patch->state = KLP_DISABLED; Loading Loading @@ -553,8 +524,6 @@ static int __klp_enable_patch(struct klp_patch *patch) pr_notice("enabling patch '%s'\n", patch->mod->name); for (obj = patch->objs; obj->funcs; obj++) { klp_find_object_module(obj); if (!klp_is_object_loaded(obj)) continue; Loading Loading @@ -945,7 +914,6 @@ static void klp_module_notify_going(struct klp_patch *patch, { struct module *pmod = patch->mod; struct module *mod = obj->mod; int ret; if (patch->state == KLP_DISABLED) goto disabled; Loading @@ -953,10 +921,7 @@ static void klp_module_notify_going(struct klp_patch *patch, pr_notice("reverting patch '%s' on unloading module '%s'\n", pmod->name, mod->name); ret = klp_disable_object(obj); if (ret) pr_warn("failed to revert patch '%s' on module '%s' (%d)\n", pmod->name, mod->name, ret); klp_disable_object(obj); disabled: klp_free_object_loaded(obj); Loading