summaryrefslogtreecommitdiffstats
path: root/lib/livepatch/test_klp_callbacks_demo2.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-08 08:58:25 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-08 08:58:25 -0800
commitb7af27bf9471f5d54d71dc2e4228d6bc065bdb57 (patch)
treeefe61bdce366720345f4f4fb663c31c9a4f00a08 /lib/livepatch/test_klp_callbacks_demo2.c
parent851ca779d110f694b5d078bc4af06d3ad37169e8 (diff)
parentf9d138145686b52b48ccb36557d6842076e2b9dd (diff)
downloadlinux-b7af27bf9471f5d54d71dc2e4228d6bc065bdb57.tar.bz2
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching
Pull livepatching updates from Jiri Kosina: - support for something we call 'atomic replace', and allows for much better handling of cumulative patches (which is something very useful for distros), from Jason Baron with help of Petr Mladek and Joe Lawrence - improvement of handling of tasks blocking finalization, from Miroslav Benes - update of MAINTAINERS file to reflect move towards group maintainership * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching: (22 commits) livepatch/selftests: use "$@" to preserve argument list livepatch: Module coming and going callbacks can proceed with all listed patches livepatch: Proper error handling in the shadow variables selftest livepatch: return -ENOMEM on ptr_id() allocation failure livepatch: Introduce klp_for_each_patch macro livepatch: core: Return EOPNOTSUPP instead of ENOSYS selftests/livepatch: add DYNAMIC_DEBUG config dependency livepatch: samples: non static warnings fix livepatch: update MAINTAINERS livepatch: Remove signal sysfs attribute livepatch: Send a fake signal periodically selftests/livepatch: introduce tests livepatch: Remove ordering (stacking) of the livepatches livepatch: Atomic replace and cumulative patches documentation livepatch: Remove Nop structures when unused livepatch: Add atomic replace livepatch: Use lists to manage patches, objects and functions livepatch: Simplify API by removing registration step livepatch: Don't block the removal of patches loaded after a forced transition livepatch: Consolidate klp_free functions ...
Diffstat (limited to 'lib/livepatch/test_klp_callbacks_demo2.c')
-rw-r--r--lib/livepatch/test_klp_callbacks_demo2.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/lib/livepatch/test_klp_callbacks_demo2.c b/lib/livepatch/test_klp_callbacks_demo2.c
new file mode 100644
index 000000000000..5417573e80af
--- /dev/null
+++ b/lib/livepatch/test_klp_callbacks_demo2.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Joe Lawrence <joe.lawrence@redhat.com>
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/livepatch.h>
+
+static int replace;
+module_param(replace, int, 0644);
+MODULE_PARM_DESC(replace, "replace (default=0)");
+
+static const char *const module_state[] = {
+ [MODULE_STATE_LIVE] = "[MODULE_STATE_LIVE] Normal state",
+ [MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init",
+ [MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away",
+ [MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up",
+};
+
+static void callback_info(const char *callback, struct klp_object *obj)
+{
+ if (obj->mod)
+ pr_info("%s: %s -> %s\n", callback, obj->mod->name,
+ module_state[obj->mod->state]);
+ else
+ pr_info("%s: vmlinux\n", callback);
+}
+
+/* Executed on object patching (ie, patch enablement) */
+static int pre_patch_callback(struct klp_object *obj)
+{
+ callback_info(__func__, obj);
+ return 0;
+}
+
+/* Executed on object unpatching (ie, patch disablement) */
+static void post_patch_callback(struct klp_object *obj)
+{
+ callback_info(__func__, obj);
+}
+
+/* Executed on object unpatching (ie, patch disablement) */
+static void pre_unpatch_callback(struct klp_object *obj)
+{
+ callback_info(__func__, obj);
+}
+
+/* Executed on object unpatching (ie, patch disablement) */
+static void post_unpatch_callback(struct klp_object *obj)
+{
+ callback_info(__func__, obj);
+}
+
+static struct klp_func no_funcs[] = {
+ { }
+};
+
+static struct klp_object objs[] = {
+ {
+ .name = NULL, /* vmlinux */
+ .funcs = no_funcs,
+ .callbacks = {
+ .pre_patch = pre_patch_callback,
+ .post_patch = post_patch_callback,
+ .pre_unpatch = pre_unpatch_callback,
+ .post_unpatch = post_unpatch_callback,
+ },
+ }, { }
+};
+
+static struct klp_patch patch = {
+ .mod = THIS_MODULE,
+ .objs = objs,
+ /* set .replace in the init function below for demo purposes */
+};
+
+static int test_klp_callbacks_demo2_init(void)
+{
+ patch.replace = replace;
+ return klp_enable_patch(&patch);
+}
+
+static void test_klp_callbacks_demo2_exit(void)
+{
+}
+
+module_init(test_klp_callbacks_demo2_init);
+module_exit(test_klp_callbacks_demo2_exit);
+MODULE_LICENSE("GPL");
+MODULE_INFO(livepatch, "Y");
+MODULE_AUTHOR("Joe Lawrence <joe.lawrence@redhat.com>");
+MODULE_DESCRIPTION("Livepatch test: livepatch demo2");