1b700e7f0SSeth Jennings /* 2b700e7f0SSeth Jennings * livepatch.h - Kernel Live Patching Core 3b700e7f0SSeth Jennings * 4b700e7f0SSeth Jennings * Copyright (C) 2014 Seth Jennings <[email protected]> 5b700e7f0SSeth Jennings * Copyright (C) 2014 SUSE 6b700e7f0SSeth Jennings * 7b700e7f0SSeth Jennings * This program is free software; you can redistribute it and/or 8b700e7f0SSeth Jennings * modify it under the terms of the GNU General Public License 9b700e7f0SSeth Jennings * as published by the Free Software Foundation; either version 2 10b700e7f0SSeth Jennings * of the License, or (at your option) any later version. 11b700e7f0SSeth Jennings * 12b700e7f0SSeth Jennings * This program is distributed in the hope that it will be useful, 13b700e7f0SSeth Jennings * but WITHOUT ANY WARRANTY; without even the implied warranty of 14b700e7f0SSeth Jennings * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15b700e7f0SSeth Jennings * GNU General Public License for more details. 16b700e7f0SSeth Jennings * 17b700e7f0SSeth Jennings * You should have received a copy of the GNU General Public License 18b700e7f0SSeth Jennings * along with this program; if not, see <http://www.gnu.org/licenses/>. 19b700e7f0SSeth Jennings */ 20b700e7f0SSeth Jennings 21b700e7f0SSeth Jennings #ifndef _LINUX_LIVEPATCH_H_ 22b700e7f0SSeth Jennings #define _LINUX_LIVEPATCH_H_ 23b700e7f0SSeth Jennings 24b700e7f0SSeth Jennings #include <linux/module.h> 25b700e7f0SSeth Jennings #include <linux/ftrace.h> 26b700e7f0SSeth Jennings 277e545d6eSJessica Yu #if IS_ENABLED(CONFIG_LIVEPATCH) 287e545d6eSJessica Yu 29b700e7f0SSeth Jennings #include <asm/livepatch.h> 30b700e7f0SSeth Jennings 31b700e7f0SSeth Jennings enum klp_state { 32b700e7f0SSeth Jennings KLP_DISABLED, 33b700e7f0SSeth Jennings KLP_ENABLED 34b700e7f0SSeth Jennings }; 35b700e7f0SSeth Jennings 36b700e7f0SSeth Jennings /** 37b700e7f0SSeth Jennings * struct klp_func - function structure for live patching 38b700e7f0SSeth Jennings * @old_name: name of the function to be patched 39b700e7f0SSeth Jennings * @new_func: pointer to the patched function code 40b2b018efSChris J Arges * @old_sympos: a hint indicating which symbol position the old function 41b2b018efSChris J Arges * can be found (optional) 42b2b018efSChris J Arges * @old_addr: the address of the function being patched 43b700e7f0SSeth Jennings * @kobj: kobject for sysfs resources 44b700e7f0SSeth Jennings * @state: tracks function-level patch application state 453c33f5b9SJosh Poimboeuf * @stack_node: list node for klp_ops func_stack list 46b700e7f0SSeth Jennings */ 47b700e7f0SSeth Jennings struct klp_func { 48b700e7f0SSeth Jennings /* external */ 49b700e7f0SSeth Jennings const char *old_name; 50b700e7f0SSeth Jennings void *new_func; 51b700e7f0SSeth Jennings /* 52b2b018efSChris J Arges * The old_sympos field is optional and can be used to resolve 53b2b018efSChris J Arges * duplicate symbol names in livepatch objects. If this field is zero, 54b2b018efSChris J Arges * it is expected the symbol is unique, otherwise patching fails. If 55b2b018efSChris J Arges * this value is greater than zero then that occurrence of the symbol 56b2b018efSChris J Arges * in kallsyms for the given object is used. 57b700e7f0SSeth Jennings */ 58b2b018efSChris J Arges unsigned long old_sympos; 59b700e7f0SSeth Jennings 60b700e7f0SSeth Jennings /* internal */ 61b2b018efSChris J Arges unsigned long old_addr; 62b700e7f0SSeth Jennings struct kobject kobj; 63b700e7f0SSeth Jennings enum klp_state state; 643c33f5b9SJosh Poimboeuf struct list_head stack_node; 65b700e7f0SSeth Jennings }; 66b700e7f0SSeth Jennings 67b700e7f0SSeth Jennings /** 68b700e7f0SSeth Jennings * struct klp_object - kernel object structure for live patching 69b700e7f0SSeth Jennings * @name: module name (or NULL for vmlinux) 70b700e7f0SSeth Jennings * @funcs: function entries for functions to be patched in the object 71b700e7f0SSeth Jennings * @kobj: kobject for sysfs resources 72b700e7f0SSeth Jennings * @mod: kernel module associated with the patched object 73b700e7f0SSeth Jennings * (NULL for vmlinux) 74b700e7f0SSeth Jennings * @state: tracks object-level patch application state 75b700e7f0SSeth Jennings */ 76b700e7f0SSeth Jennings struct klp_object { 77b700e7f0SSeth Jennings /* external */ 78b700e7f0SSeth Jennings const char *name; 79b700e7f0SSeth Jennings struct klp_func *funcs; 80b700e7f0SSeth Jennings 81b700e7f0SSeth Jennings /* internal */ 82cad706dfSMiroslav Benes struct kobject kobj; 83b700e7f0SSeth Jennings struct module *mod; 84b700e7f0SSeth Jennings enum klp_state state; 85b700e7f0SSeth Jennings }; 86b700e7f0SSeth Jennings 87b700e7f0SSeth Jennings /** 88b700e7f0SSeth Jennings * struct klp_patch - patch structure for live patching 89b700e7f0SSeth Jennings * @mod: reference to the live patch module 90b700e7f0SSeth Jennings * @objs: object entries for kernel objects to be patched 91b700e7f0SSeth Jennings * @list: list node for global list of registered patches 92b700e7f0SSeth Jennings * @kobj: kobject for sysfs resources 93b700e7f0SSeth Jennings * @state: tracks patch-level application state 94b700e7f0SSeth Jennings */ 95b700e7f0SSeth Jennings struct klp_patch { 96b700e7f0SSeth Jennings /* external */ 97b700e7f0SSeth Jennings struct module *mod; 98b700e7f0SSeth Jennings struct klp_object *objs; 99b700e7f0SSeth Jennings 100b700e7f0SSeth Jennings /* internal */ 101b700e7f0SSeth Jennings struct list_head list; 102b700e7f0SSeth Jennings struct kobject kobj; 103b700e7f0SSeth Jennings enum klp_state state; 104b700e7f0SSeth Jennings }; 105b700e7f0SSeth Jennings 1068cdd043aSJiri Slaby #define klp_for_each_object(patch, obj) \ 107f09d9086SMiroslav Benes for (obj = patch->objs; obj->funcs || obj->name; obj++) 1088cdd043aSJiri Slaby 1098cdd043aSJiri Slaby #define klp_for_each_func(obj, func) \ 110f09d9086SMiroslav Benes for (func = obj->funcs; \ 111f09d9086SMiroslav Benes func->old_name || func->new_func || func->old_sympos; \ 112f09d9086SMiroslav Benes func++) 1138cdd043aSJiri Slaby 1144421f8f0SMiroslav Benes int klp_register_patch(struct klp_patch *); 1154421f8f0SMiroslav Benes int klp_unregister_patch(struct klp_patch *); 1164421f8f0SMiroslav Benes int klp_enable_patch(struct klp_patch *); 1174421f8f0SMiroslav Benes int klp_disable_patch(struct klp_patch *); 118b700e7f0SSeth Jennings 119*255e732cSJessica Yu void arch_klp_init_object_loaded(struct klp_patch *patch, 120*255e732cSJessica Yu struct klp_object *obj); 121*255e732cSJessica Yu 1227e545d6eSJessica Yu /* Called from the module loader during module coming/going states */ 1237e545d6eSJessica Yu int klp_module_coming(struct module *mod); 1247e545d6eSJessica Yu void klp_module_going(struct module *mod); 1257e545d6eSJessica Yu 1267e545d6eSJessica Yu #else /* !CONFIG_LIVEPATCH */ 1277e545d6eSJessica Yu 1287e545d6eSJessica Yu static inline int klp_module_coming(struct module *mod) { return 0; } 1297e545d6eSJessica Yu static inline void klp_module_going(struct module *mod) { } 1307e545d6eSJessica Yu 1317e545d6eSJessica Yu #endif /* CONFIG_LIVEPATCH */ 1327e545d6eSJessica Yu 133b700e7f0SSeth Jennings #endif /* _LINUX_LIVEPATCH_H_ */ 134