diff options
author | Petr Mladek <pmladek@suse.com> | 2019-01-09 07:43:19 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2019-01-11 14:51:23 -0500 |
commit | 19514910d021c93c7823ec32067e6b7dea224f0f (patch) | |
tree | 3df053de0eb62fec2557e24bd807cae328d4f21a /kernel/livepatch/patch.c | |
parent | 1686cc1a31f45a3fd090e5d0c6fce777422e13fa (diff) |
livepatch: Change unsigned long old_addr -> void *old_func in struct klp_func
The address of the to be patched function and new function is stored
in struct klp_func as:
void *new_func;
unsigned long old_addr;
The different naming scheme and type are derived from the way
the addresses are set. @old_addr is assigned at runtime using
kallsyms-based search. @new_func is statically initialized,
for example:
static struct klp_func funcs[] = {
{
.old_name = "cmdline_proc_show",
.new_func = livepatch_cmdline_proc_show,
}, { }
};
This patch changes unsigned long old_addr -> void *old_func. It removes
some confusion when these address are later used in the code. It is
motivated by a followup patch that adds special NOP struct klp_func
where we want to assign func->new_func = func->old_addr respectively
func->new_func = func->old_func.
This patch does not modify the existing behavior.
Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Acked-by: Miroslav Benes <mbenes@suse.cz>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Alice Ferrazzi <alice.ferrazzi@gmail.com>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'kernel/livepatch/patch.c')
-rw-r--r-- | kernel/livepatch/patch.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/kernel/livepatch/patch.c b/kernel/livepatch/patch.c index 7702cb4064fc..825022d70912 100644 --- a/kernel/livepatch/patch.c +++ b/kernel/livepatch/patch.c | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | static LIST_HEAD(klp_ops); | 35 | static LIST_HEAD(klp_ops); |
36 | 36 | ||
37 | struct klp_ops *klp_find_ops(unsigned long old_addr) | 37 | struct klp_ops *klp_find_ops(void *old_func) |
38 | { | 38 | { |
39 | struct klp_ops *ops; | 39 | struct klp_ops *ops; |
40 | struct klp_func *func; | 40 | struct klp_func *func; |
@@ -42,7 +42,7 @@ struct klp_ops *klp_find_ops(unsigned long old_addr) | |||
42 | list_for_each_entry(ops, &klp_ops, node) { | 42 | list_for_each_entry(ops, &klp_ops, node) { |
43 | func = list_first_entry(&ops->func_stack, struct klp_func, | 43 | func = list_first_entry(&ops->func_stack, struct klp_func, |
44 | stack_node); | 44 | stack_node); |
45 | if (func->old_addr == old_addr) | 45 | if (func->old_func == old_func) |
46 | return ops; | 46 | return ops; |
47 | } | 47 | } |
48 | 48 | ||
@@ -142,17 +142,18 @@ static void klp_unpatch_func(struct klp_func *func) | |||
142 | 142 | ||
143 | if (WARN_ON(!func->patched)) | 143 | if (WARN_ON(!func->patched)) |
144 | return; | 144 | return; |
145 | if (WARN_ON(!func->old_addr)) | 145 | if (WARN_ON(!func->old_func)) |
146 | return; | 146 | return; |
147 | 147 | ||
148 | ops = klp_find_ops(func->old_addr); | 148 | ops = klp_find_ops(func->old_func); |
149 | if (WARN_ON(!ops)) | 149 | if (WARN_ON(!ops)) |
150 | return; | 150 | return; |
151 | 151 | ||
152 | if (list_is_singular(&ops->func_stack)) { | 152 | if (list_is_singular(&ops->func_stack)) { |
153 | unsigned long ftrace_loc; | 153 | unsigned long ftrace_loc; |
154 | 154 | ||
155 | ftrace_loc = klp_get_ftrace_location(func->old_addr); | 155 | ftrace_loc = |
156 | klp_get_ftrace_location((unsigned long)func->old_func); | ||
156 | if (WARN_ON(!ftrace_loc)) | 157 | if (WARN_ON(!ftrace_loc)) |
157 | return; | 158 | return; |
158 | 159 | ||
@@ -174,17 +175,18 @@ static int klp_patch_func(struct klp_func *func) | |||
174 | struct klp_ops *ops; | 175 | struct klp_ops *ops; |
175 | int ret; | 176 | int ret; |
176 | 177 | ||
177 | if (WARN_ON(!func->old_addr)) | 178 | if (WARN_ON(!func->old_func)) |
178 | return -EINVAL; | 179 | return -EINVAL; |
179 | 180 | ||
180 | if (WARN_ON(func->patched)) | 181 | if (WARN_ON(func->patched)) |
181 | return -EINVAL; | 182 | return -EINVAL; |
182 | 183 | ||
183 | ops = klp_find_ops(func->old_addr); | 184 | ops = klp_find_ops(func->old_func); |
184 | if (!ops) { | 185 | if (!ops) { |
185 | unsigned long ftrace_loc; | 186 | unsigned long ftrace_loc; |
186 | 187 | ||
187 | ftrace_loc = klp_get_ftrace_location(func->old_addr); | 188 | ftrace_loc = |
189 | klp_get_ftrace_location((unsigned long)func->old_func); | ||
188 | if (!ftrace_loc) { | 190 | if (!ftrace_loc) { |
189 | pr_err("failed to find location for function '%s'\n", | 191 | pr_err("failed to find location for function '%s'\n", |
190 | func->old_name); | 192 | func->old_name); |