0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0082
0083 #include <linux/module.h>
0084 #include <linux/kernel.h>
0085 #include <linux/livepatch.h>
0086
0087 static int pre_patch_ret;
0088 module_param(pre_patch_ret, int, 0644);
0089 MODULE_PARM_DESC(pre_patch_ret, "pre_patch_ret (default=0)");
0090
0091 static const char *const module_state[] = {
0092 [MODULE_STATE_LIVE] = "[MODULE_STATE_LIVE] Normal state",
0093 [MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init",
0094 [MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away",
0095 [MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up",
0096 };
0097
0098 static void callback_info(const char *callback, struct klp_object *obj)
0099 {
0100 if (obj->mod)
0101 pr_info("%s: %s -> %s\n", callback, obj->mod->name,
0102 module_state[obj->mod->state]);
0103 else
0104 pr_info("%s: vmlinux\n", callback);
0105 }
0106
0107
0108 static int pre_patch_callback(struct klp_object *obj)
0109 {
0110 callback_info(__func__, obj);
0111 return pre_patch_ret;
0112 }
0113
0114
0115 static void post_patch_callback(struct klp_object *obj)
0116 {
0117 callback_info(__func__, obj);
0118 }
0119
0120
0121 static void pre_unpatch_callback(struct klp_object *obj)
0122 {
0123 callback_info(__func__, obj);
0124 }
0125
0126
0127 static void post_unpatch_callback(struct klp_object *obj)
0128 {
0129 callback_info(__func__, obj);
0130 }
0131
0132 static void patched_work_func(struct work_struct *work)
0133 {
0134 pr_info("%s\n", __func__);
0135 }
0136
0137 static struct klp_func no_funcs[] = {
0138 { }
0139 };
0140
0141 static struct klp_func busymod_funcs[] = {
0142 {
0143 .old_name = "busymod_work_func",
0144 .new_func = patched_work_func,
0145 }, { }
0146 };
0147
0148 static struct klp_object objs[] = {
0149 {
0150 .name = NULL,
0151 .funcs = no_funcs,
0152 .callbacks = {
0153 .pre_patch = pre_patch_callback,
0154 .post_patch = post_patch_callback,
0155 .pre_unpatch = pre_unpatch_callback,
0156 .post_unpatch = post_unpatch_callback,
0157 },
0158 }, {
0159 .name = "livepatch_callbacks_mod",
0160 .funcs = no_funcs,
0161 .callbacks = {
0162 .pre_patch = pre_patch_callback,
0163 .post_patch = post_patch_callback,
0164 .pre_unpatch = pre_unpatch_callback,
0165 .post_unpatch = post_unpatch_callback,
0166 },
0167 }, {
0168 .name = "livepatch_callbacks_busymod",
0169 .funcs = busymod_funcs,
0170 .callbacks = {
0171 .pre_patch = pre_patch_callback,
0172 .post_patch = post_patch_callback,
0173 .pre_unpatch = pre_unpatch_callback,
0174 .post_unpatch = post_unpatch_callback,
0175 },
0176 }, { }
0177 };
0178
0179 static struct klp_patch patch = {
0180 .mod = THIS_MODULE,
0181 .objs = objs,
0182 };
0183
0184 static int livepatch_callbacks_demo_init(void)
0185 {
0186 return klp_enable_patch(&patch);
0187 }
0188
0189 static void livepatch_callbacks_demo_exit(void)
0190 {
0191 }
0192
0193 module_init(livepatch_callbacks_demo_init);
0194 module_exit(livepatch_callbacks_demo_exit);
0195 MODULE_LICENSE("GPL");
0196 MODULE_INFO(livepatch, "Y");