Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

livepatch: Introduce source code helpers for livepatch modules

Add some helper macros which can be used by livepatch source .patch
files to register callbacks, convert static calls to regular calls where
needed, and patch syscalls.

Acked-by: Petr Mladek <pmladek@suse.com>
Tested-by: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

+77
+77
include/linux/livepatch_helpers.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _LINUX_LIVEPATCH_HELPERS_H 3 + #define _LINUX_LIVEPATCH_HELPERS_H 4 + 5 + /* 6 + * Interfaces for use by livepatch patches 7 + */ 8 + 9 + #include <linux/syscalls.h> 10 + #include <linux/livepatch.h> 11 + 12 + #ifdef MODULE 13 + #define KLP_OBJNAME __KBUILD_MODNAME 14 + #else 15 + #define KLP_OBJNAME vmlinux 16 + #endif 17 + 18 + /* Livepatch callback registration */ 19 + 20 + #define KLP_CALLBACK_PTRS ".discard.klp_callback_ptrs" 21 + 22 + #define KLP_PRE_PATCH_CALLBACK(func) \ 23 + klp_pre_patch_t __used __section(KLP_CALLBACK_PTRS) \ 24 + __PASTE(__KLP_PRE_PATCH_PREFIX, KLP_OBJNAME) = func 25 + 26 + #define KLP_POST_PATCH_CALLBACK(func) \ 27 + klp_post_patch_t __used __section(KLP_CALLBACK_PTRS) \ 28 + __PASTE(__KLP_POST_PATCH_PREFIX, KLP_OBJNAME) = func 29 + 30 + #define KLP_PRE_UNPATCH_CALLBACK(func) \ 31 + klp_pre_unpatch_t __used __section(KLP_CALLBACK_PTRS) \ 32 + __PASTE(__KLP_PRE_UNPATCH_PREFIX, KLP_OBJNAME) = func 33 + 34 + #define KLP_POST_UNPATCH_CALLBACK(func) \ 35 + klp_post_unpatch_t __used __section(KLP_CALLBACK_PTRS) \ 36 + __PASTE(__KLP_POST_UNPATCH_PREFIX, KLP_OBJNAME) = func 37 + 38 + /* 39 + * Replace static_call() usage with this macro when create-diff-object 40 + * recommends it due to the original static call key living in a module. 41 + * 42 + * This converts the static call to a regular indirect call. 43 + */ 44 + #define KLP_STATIC_CALL(name) \ 45 + ((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func)) 46 + 47 + /* Syscall patching */ 48 + 49 + #define KLP_SYSCALL_DEFINE1(name, ...) KLP_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) 50 + #define KLP_SYSCALL_DEFINE2(name, ...) KLP_SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) 51 + #define KLP_SYSCALL_DEFINE3(name, ...) KLP_SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) 52 + #define KLP_SYSCALL_DEFINE4(name, ...) KLP_SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) 53 + #define KLP_SYSCALL_DEFINE5(name, ...) KLP_SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) 54 + #define KLP_SYSCALL_DEFINE6(name, ...) KLP_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) 55 + 56 + #define KLP_SYSCALL_DEFINEx(x, sname, ...) \ 57 + __KLP_SYSCALL_DEFINEx(x, sname, __VA_ARGS__) 58 + 59 + #ifdef CONFIG_X86_64 60 + // TODO move this to arch/x86/include/asm/syscall_wrapper.h and share code 61 + #define __KLP_SYSCALL_DEFINEx(x, name, ...) \ 62 + static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ 63 + static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ 64 + __X64_SYS_STUBx(x, name, __VA_ARGS__) \ 65 + __IA32_SYS_STUBx(x, name, __VA_ARGS__) \ 66 + static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ 67 + { \ 68 + long ret = __klp_do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\ 69 + __MAP(x,__SC_TEST,__VA_ARGS__); \ 70 + __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ 71 + return ret; \ 72 + } \ 73 + static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) 74 + 75 + #endif 76 + 77 + #endif /* _LINUX_LIVEPATCH_HELPERS_H */