mirror of
https://github.com/dynup/kpatch
synced 2025-01-05 04:29:31 +00:00
kmod/core: fail more gracefully in kpatch_unregister
In kpatch_unregister(), if kpatch_remove_patch succeeds but one of the subsequent ftrace unregistering calls fails, it returns an error and fails to module_put() the patch module, even though the patch has been removed. This causes the patch module to get stuck in a weird place where its patch has been unregistered but the patch module can't ever be removed. These errors aren't serious and wouldn't cause any real problems if they did somehow fail, so instead just WARN if they fail.
This commit is contained in:
parent
065619ec68
commit
87d852afa2
@ -321,8 +321,8 @@ static struct ftrace_ops kpatch_ftrace_ops __read_mostly = {
|
||||
};
|
||||
|
||||
/* Remove kpatch_funcs from ftrace filter */
|
||||
static int kpatch_remove_funcs_from_filter(struct kpatch_func *funcs,
|
||||
int num_funcs)
|
||||
static void kpatch_remove_funcs_from_filter(struct kpatch_func *funcs,
|
||||
int num_funcs)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
@ -339,14 +339,8 @@ static int kpatch_remove_funcs_from_filter(struct kpatch_func *funcs,
|
||||
/* Remove the ftrace handler for this function. */
|
||||
ret = ftrace_set_filter_ip(&kpatch_ftrace_ops, func->old_addr,
|
||||
1, 0);
|
||||
if (ret) {
|
||||
pr_err("can't remove ftrace filter at address 0x%lx\n",
|
||||
func->old_addr);
|
||||
break;
|
||||
}
|
||||
WARN_ON(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kpatch_register(struct kpatch_module *kpmod)
|
||||
@ -480,12 +474,11 @@ int kpatch_unregister(struct kpatch_module *kpmod)
|
||||
|
||||
if (kpatch_num_registered == 1) {
|
||||
ret = unregister_ftrace_function(&kpatch_ftrace_ops);
|
||||
if (ret) {
|
||||
pr_err("can't unregister ftrace handler\n");
|
||||
goto out;
|
||||
}
|
||||
if (ret)
|
||||
WARN_ON(1);
|
||||
else
|
||||
kpatch_num_registered--;
|
||||
}
|
||||
kpatch_num_registered--;
|
||||
|
||||
/*
|
||||
* This synchronize_rcu is to ensure any other kpatch_get_func
|
||||
@ -494,9 +487,7 @@ int kpatch_unregister(struct kpatch_module *kpmod)
|
||||
*/
|
||||
synchronize_rcu();
|
||||
|
||||
ret = kpatch_remove_funcs_from_filter(funcs, num_funcs);
|
||||
if (ret)
|
||||
goto out;
|
||||
kpatch_remove_funcs_from_filter(funcs, num_funcs);
|
||||
|
||||
pr_notice("unloaded patch module \"%s\"\n", kpmod->mod->name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user