162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci// Copyright (C) 2018 Joe Lawrence <joe.lawrence@redhat.com> 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/module.h> 762306a36Sopenharmony_ci#include <linux/kernel.h> 862306a36Sopenharmony_ci#include <linux/livepatch.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_cistatic int replace; 1162306a36Sopenharmony_cimodule_param(replace, int, 0644); 1262306a36Sopenharmony_ciMODULE_PARM_DESC(replace, "replace (default=0)"); 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistatic const char *const module_state[] = { 1562306a36Sopenharmony_ci [MODULE_STATE_LIVE] = "[MODULE_STATE_LIVE] Normal state", 1662306a36Sopenharmony_ci [MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init", 1762306a36Sopenharmony_ci [MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away", 1862306a36Sopenharmony_ci [MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up", 1962306a36Sopenharmony_ci}; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistatic void callback_info(const char *callback, struct klp_object *obj) 2262306a36Sopenharmony_ci{ 2362306a36Sopenharmony_ci if (obj->mod) 2462306a36Sopenharmony_ci pr_info("%s: %s -> %s\n", callback, obj->mod->name, 2562306a36Sopenharmony_ci module_state[obj->mod->state]); 2662306a36Sopenharmony_ci else 2762306a36Sopenharmony_ci pr_info("%s: vmlinux\n", callback); 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* Executed on object patching (ie, patch enablement) */ 3162306a36Sopenharmony_cistatic int pre_patch_callback(struct klp_object *obj) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci callback_info(__func__, obj); 3462306a36Sopenharmony_ci return 0; 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* Executed on object unpatching (ie, patch disablement) */ 3862306a36Sopenharmony_cistatic void post_patch_callback(struct klp_object *obj) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci callback_info(__func__, obj); 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* Executed on object unpatching (ie, patch disablement) */ 4462306a36Sopenharmony_cistatic void pre_unpatch_callback(struct klp_object *obj) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci callback_info(__func__, obj); 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/* Executed on object unpatching (ie, patch disablement) */ 5062306a36Sopenharmony_cistatic void post_unpatch_callback(struct klp_object *obj) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci callback_info(__func__, obj); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic struct klp_func no_funcs[] = { 5662306a36Sopenharmony_ci { } 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic struct klp_object objs[] = { 6062306a36Sopenharmony_ci { 6162306a36Sopenharmony_ci .name = NULL, /* vmlinux */ 6262306a36Sopenharmony_ci .funcs = no_funcs, 6362306a36Sopenharmony_ci .callbacks = { 6462306a36Sopenharmony_ci .pre_patch = pre_patch_callback, 6562306a36Sopenharmony_ci .post_patch = post_patch_callback, 6662306a36Sopenharmony_ci .pre_unpatch = pre_unpatch_callback, 6762306a36Sopenharmony_ci .post_unpatch = post_unpatch_callback, 6862306a36Sopenharmony_ci }, 6962306a36Sopenharmony_ci }, { } 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistatic struct klp_patch patch = { 7362306a36Sopenharmony_ci .mod = THIS_MODULE, 7462306a36Sopenharmony_ci .objs = objs, 7562306a36Sopenharmony_ci /* set .replace in the init function below for demo purposes */ 7662306a36Sopenharmony_ci}; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cistatic int test_klp_callbacks_demo2_init(void) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci patch.replace = replace; 8162306a36Sopenharmony_ci return klp_enable_patch(&patch); 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic void test_klp_callbacks_demo2_exit(void) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cimodule_init(test_klp_callbacks_demo2_init); 8962306a36Sopenharmony_cimodule_exit(test_klp_callbacks_demo2_exit); 9062306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 9162306a36Sopenharmony_ciMODULE_INFO(livepatch, "Y"); 9262306a36Sopenharmony_ciMODULE_AUTHOR("Joe Lawrence <joe.lawrence@redhat.com>"); 9362306a36Sopenharmony_ciMODULE_DESCRIPTION("Livepatch test: livepatch demo2"); 94