Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (C) 2018 Joe Lawrence <joe.lawrence@redhat.com>
0003 
0004 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0005 
0006 #include <linux/module.h>
0007 #include <linux/kernel.h>
0008 #include <linux/livepatch.h>
0009 
0010 static int pre_patch_ret;
0011 module_param(pre_patch_ret, int, 0644);
0012 MODULE_PARM_DESC(pre_patch_ret, "pre_patch_ret (default=0)");
0013 
0014 static const char *const module_state[] = {
0015     [MODULE_STATE_LIVE] = "[MODULE_STATE_LIVE] Normal state",
0016     [MODULE_STATE_COMING]   = "[MODULE_STATE_COMING] Full formed, running module_init",
0017     [MODULE_STATE_GOING]    = "[MODULE_STATE_GOING] Going away",
0018     [MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up",
0019 };
0020 
0021 static void callback_info(const char *callback, struct klp_object *obj)
0022 {
0023     if (obj->mod)
0024         pr_info("%s: %s -> %s\n", callback, obj->mod->name,
0025             module_state[obj->mod->state]);
0026     else
0027         pr_info("%s: vmlinux\n", callback);
0028 }
0029 
0030 /* Executed on object patching (ie, patch enablement) */
0031 static int pre_patch_callback(struct klp_object *obj)
0032 {
0033     callback_info(__func__, obj);
0034     return pre_patch_ret;
0035 }
0036 
0037 /* Executed on object unpatching (ie, patch disablement) */
0038 static void post_patch_callback(struct klp_object *obj)
0039 {
0040     callback_info(__func__, obj);
0041 }
0042 
0043 /* Executed on object unpatching (ie, patch disablement) */
0044 static void pre_unpatch_callback(struct klp_object *obj)
0045 {
0046     callback_info(__func__, obj);
0047 }
0048 
0049 /* Executed on object unpatching (ie, patch disablement) */
0050 static void post_unpatch_callback(struct klp_object *obj)
0051 {
0052     callback_info(__func__, obj);
0053 }
0054 
0055 static void patched_work_func(struct work_struct *work)
0056 {
0057     pr_info("%s\n", __func__);
0058 }
0059 
0060 static struct klp_func no_funcs[] = {
0061     {}
0062 };
0063 
0064 static struct klp_func busymod_funcs[] = {
0065     {
0066         .old_name = "busymod_work_func",
0067         .new_func = patched_work_func,
0068     }, {}
0069 };
0070 
0071 static struct klp_object objs[] = {
0072     {
0073         .name = NULL,   /* vmlinux */
0074         .funcs = no_funcs,
0075         .callbacks = {
0076             .pre_patch = pre_patch_callback,
0077             .post_patch = post_patch_callback,
0078             .pre_unpatch = pre_unpatch_callback,
0079             .post_unpatch = post_unpatch_callback,
0080         },
0081     },  {
0082         .name = "test_klp_callbacks_mod",
0083         .funcs = no_funcs,
0084         .callbacks = {
0085             .pre_patch = pre_patch_callback,
0086             .post_patch = post_patch_callback,
0087             .pre_unpatch = pre_unpatch_callback,
0088             .post_unpatch = post_unpatch_callback,
0089         },
0090     },  {
0091         .name = "test_klp_callbacks_busy",
0092         .funcs = busymod_funcs,
0093         .callbacks = {
0094             .pre_patch = pre_patch_callback,
0095             .post_patch = post_patch_callback,
0096             .pre_unpatch = pre_unpatch_callback,
0097             .post_unpatch = post_unpatch_callback,
0098         },
0099     }, { }
0100 };
0101 
0102 static struct klp_patch patch = {
0103     .mod = THIS_MODULE,
0104     .objs = objs,
0105 };
0106 
0107 static int test_klp_callbacks_demo_init(void)
0108 {
0109     return klp_enable_patch(&patch);
0110 }
0111 
0112 static void test_klp_callbacks_demo_exit(void)
0113 {
0114 }
0115 
0116 module_init(test_klp_callbacks_demo_init);
0117 module_exit(test_klp_callbacks_demo_exit);
0118 MODULE_LICENSE("GPL");
0119 MODULE_INFO(livepatch, "Y");
0120 MODULE_AUTHOR("Joe Lawrence <joe.lawrence@redhat.com>");
0121 MODULE_DESCRIPTION("Livepatch test: livepatch demo");