livepatch: support for repatching a function
authorJosh Poimboeuf <jpoimboe@redhat.com>
Tue, 20 Jan 2015 15:26:19 +0000 (09:26 -0600)
committerJiri Kosina <jkosina@suse.cz>
Tue, 20 Jan 2015 19:09:41 +0000 (20:09 +0100)
commit3c33f5b99d688deafd21d4a770303691c7c3a320
tree1b133a30910364c15190202616f65c08d306f55e
parent83a90bb1345767f0cb96d242fd8b9db44b2b0e17
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>
include/linux/livepatch.h
kernel/livepatch/core.c