diff options
author | Josh Poimboeuf <jpoimboe@redhat.com> | 2015-01-20 09:26:19 -0600 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2015-01-20 20:09:41 +0100 |
commit | 3c33f5b99d688deafd21d4a770303691c7c3a320 (patch) | |
tree | 1b133a30910364c15190202616f65c08d306f55e /include/linux | |
parent | 83a90bb1345767f0cb96d242fd8b9db44b2b0e17 (diff) | |
download | linux-stable-3c33f5b99d688deafd21d4a770303691c7c3a320.tar.gz linux-stable-3c33f5b99d688deafd21d4a770303691c7c3a320.tar.bz2 linux-stable-3c33f5b99d688deafd21d4a770303691c7c3a320.zip |
livepatch: support for repatching a function
Add support for patching a function multiple times. If multiple patches
affect a function, the function in the most recently enabled patch
"wins". This enables a cumulative patch upgrade path, where each patch
is a superset of previous patches.
This requires restructuring the data a little bit. With the current
design, where each klp_func struct has its own ftrace_ops, we'd have to
unregister the old ops and then register the new ops, because
FTRACE_OPS_FL_IPMODIFY prevents us from having two ops registered for
the same function at the same time. That would leave a regression
window where the function isn't patched at all (not good for a patch
upgrade path).
This patch replaces the per-klp_func ftrace_ops with a global klp_ops
list, with one ftrace_ops per original function. A single ftrace_ops is
shared between all klp_funcs which have the same old_addr. This allows
the switch between function versions to happen instantaneously by
updating the klp_ops struct's func_stack list. The winner is the
klp_func at the top of the func_stack (front of the list).
[ jkosina@suse.cz: turn WARN_ON() into WARN_ON_ONCE() in ftrace handler to
avoid storm in pathological cases ]
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Reviewed-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/livepatch.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index 950bc615842f..f14c6fb262b4 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -40,8 +40,8 @@ enum klp_state { * @old_addr: a hint conveying at what address the old function * can be found (optional, vmlinux patches only) * @kobj: kobject for sysfs resources - * @fops: ftrace operations structure * @state: tracks function-level patch application state + * @stack_node: list node for klp_ops func_stack list */ struct klp_func { /* external */ @@ -59,8 +59,8 @@ struct klp_func { /* internal */ struct kobject kobj; - struct ftrace_ops *fops; enum klp_state state; + struct list_head stack_node; }; /** |