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

Merge tag 'livepatching-for-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching

Pull livepatching updates from Petr Mladek:

- Add a selftest for tracing of a livepatched function

- Skip a selftest when kprobes are not using ftrace

- Some documentation clean up

* tag 'livepatching-for-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching:
selftests: livepatch: test if ftrace can trace a livepatched function
selftests: livepatch: add new ftrace helpers functions
selftest/livepatch: Only run test-kprobe with CONFIG_KPROBES_ON_FTRACE
docs: livepatch: move text out of code block
livepatch: Add comment to clarify klp_add_nops()

+99 -8
+8 -5
Documentation/livepatch/module-elf-format.rst
··· 217 217 indices, and the original symbol indices (and thus the symtab ordering) must be 218 218 preserved in order for apply_relocate_add() to find the right symbol. 219 219 220 - For example, take this particular rela from a livepatch module::: 220 + For example, take this particular rela from a livepatch module:: 221 221 222 222 Relocation section '.klp.rela.btrfs.text.btrfs_feature_attr_show' at offset 0x2ba0 contains 4 entries: 223 223 Offset Info Type Symbol's Value Symbol's Name + Addend 224 224 000000000000001f 0000005e00000002 R_X86_64_PC32 0000000000000000 .klp.sym.vmlinux.printk,0 - 4 225 225 226 - This rela refers to the symbol '.klp.sym.vmlinux.printk,0', and the symbol index is encoded 227 - in 'Info'. Here its symbol index is 0x5e, which is 94 in decimal, which refers to the 228 - symbol index 94. 229 - And in this patch module's corresponding symbol table, symbol index 94 refers to that very symbol: 226 + This rela refers to the symbol '.klp.sym.vmlinux.printk,0', and the symbol 227 + index is encoded in 'Info'. Here its symbol index is 0x5e, which is 94 in 228 + decimal, which refers to the symbol index 94. 229 + 230 + And in this patch module's corresponding symbol table, symbol index 94 refers 231 + to that very symbol:: 232 + 230 233 [ snip ] 231 234 94: 0000000000000000 0 NOTYPE GLOBAL DEFAULT OS [0xff20] .klp.sym.vmlinux.printk,0 232 235 [ snip ]
+6 -3
kernel/livepatch/core.c
··· 601 601 } 602 602 603 603 /* 604 - * Add 'nop' functions which simply return to the caller to run 605 - * the original function. The 'nop' functions are added to a 606 - * patch to facilitate a 'replace' mode. 604 + * Add 'nop' functions which simply return to the caller to run the 605 + * original function. 606 + * 607 + * They are added only when the atomic replace mode is used and only for 608 + * functions which are currently livepatched but are no longer included 609 + * in the new livepatch. 607 610 */ 608 611 static int klp_add_nops(struct klp_patch *patch) 609 612 {
+49
tools/testing/selftests/livepatch/functions.sh
··· 10 10 SYSFS_KLP_DIR="$SYSFS_KERNEL_DIR/livepatch" 11 11 SYSFS_DEBUG_DIR="$SYSFS_KERNEL_DIR/debug" 12 12 SYSFS_KPROBES_DIR="$SYSFS_DEBUG_DIR/kprobes" 13 + SYSFS_TRACING_DIR="$SYSFS_DEBUG_DIR/tracing" 13 14 14 15 # Kselftest framework requirement - SKIP code is 4 15 16 ksft_skip=4 ··· 63 62 awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}') 64 63 FTRACE_ENABLED=$(sysctl --values kernel.ftrace_enabled) 65 64 KPROBE_ENABLED=$(cat "$SYSFS_KPROBES_DIR/enabled") 65 + TRACING_ON=$(cat "$SYSFS_TRACING_DIR/tracing_on") 66 + CURRENT_TRACER=$(cat "$SYSFS_TRACING_DIR/current_tracer") 67 + FTRACE_FILTER=$(cat "$SYSFS_TRACING_DIR/set_ftrace_filter") 66 68 } 67 69 68 70 function pop_config() { ··· 77 73 fi 78 74 if [[ -n "$KPROBE_ENABLED" ]]; then 79 75 echo "$KPROBE_ENABLED" > "$SYSFS_KPROBES_DIR/enabled" 76 + fi 77 + if [[ -n "$TRACING_ON" ]]; then 78 + echo "$TRACING_ON" > "$SYSFS_TRACING_DIR/tracing_on" 79 + fi 80 + if [[ -n "$CURRENT_TRACER" ]]; then 81 + echo "$CURRENT_TRACER" > "$SYSFS_TRACING_DIR/current_tracer" 82 + fi 83 + if [[ -n "$FTRACE_FILTER" ]]; then 84 + echo "$FTRACE_FILTER" \ 85 + | sed -e "/#### all functions enabled ####/d" \ 86 + > "$SYSFS_TRACING_DIR/set_ftrace_filter" 80 87 fi 81 88 } 82 89 ··· 366 351 if test "$value" != "$expected_value" ; then 367 352 die "Unexpected value in $path: $expected_value vs. $value" 368 353 fi 354 + } 355 + 356 + # cleanup_tracing() - stop and clean up function tracing 357 + function cleanup_tracing() { 358 + echo 0 > "$SYSFS_TRACING_DIR/tracing_on" 359 + echo "" > "$SYSFS_TRACING_DIR/set_ftrace_filter" 360 + echo "nop" > "$SYSFS_TRACING_DIR/current_tracer" 361 + echo "" > "$SYSFS_TRACING_DIR/trace" 362 + } 363 + 364 + # trace_function(function) - start tracing of a function 365 + # function - to be traced function 366 + function trace_function() { 367 + local function="$1"; shift 368 + 369 + cleanup_tracing 370 + 371 + echo "function" > "$SYSFS_TRACING_DIR/current_tracer" 372 + echo "$function" > "$SYSFS_TRACING_DIR/set_ftrace_filter" 373 + echo 1 > "$SYSFS_TRACING_DIR/tracing_on" 374 + } 375 + 376 + # check_traced_functions(functions...) - check whether each function appeared in the trace log 377 + # functions - list of functions to be checked 378 + function check_traced_functions() { 379 + local function 380 + 381 + for function in "$@"; do 382 + if ! grep -Fwq "$function" "$SYSFS_TRACING_DIR/trace" ; then 383 + die "Function ($function) did not appear in the trace" 384 + fi 385 + done 386 + 387 + cleanup_tracing 369 388 }
+34
tools/testing/selftests/livepatch/test-ftrace.sh
··· 61 61 % rmmod $MOD_LIVEPATCH" 62 62 63 63 64 + # - verify livepatch can load 65 + # - check if traces have a patched function 66 + # - reset trace and unload livepatch 67 + 68 + start_test "trace livepatched function and check that the live patch remains in effect" 69 + 70 + FUNCTION_NAME="livepatch_cmdline_proc_show" 71 + 72 + load_lp $MOD_LIVEPATCH 73 + trace_function "$FUNCTION_NAME" 74 + 75 + if [[ "$(cat /proc/cmdline)" == "$MOD_LIVEPATCH: this has been live patched" ]] ; then 76 + log "livepatch: ok" 77 + fi 78 + 79 + check_traced_functions "$FUNCTION_NAME" 80 + 81 + disable_lp $MOD_LIVEPATCH 82 + unload_lp $MOD_LIVEPATCH 83 + 84 + check_result "% insmod test_modules/$MOD_LIVEPATCH.ko 85 + livepatch: enabling patch '$MOD_LIVEPATCH' 86 + livepatch: '$MOD_LIVEPATCH': initializing patching transition 87 + livepatch: '$MOD_LIVEPATCH': starting patching transition 88 + livepatch: '$MOD_LIVEPATCH': completing patching transition 89 + livepatch: '$MOD_LIVEPATCH': patching complete 90 + livepatch: ok 91 + % echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled 92 + livepatch: '$MOD_LIVEPATCH': initializing unpatching transition 93 + livepatch: '$MOD_LIVEPATCH': starting unpatching transition 94 + livepatch: '$MOD_LIVEPATCH': completing unpatching transition 95 + livepatch: '$MOD_LIVEPATCH': unpatching complete 96 + % rmmod $MOD_LIVEPATCH" 97 + 64 98 exit 0
+2
tools/testing/selftests/livepatch/test-kprobe.sh
··· 5 5 6 6 . $(dirname $0)/functions.sh 7 7 8 + grep -q kprobe_ftrace_ops /proc/kallsyms || skip "test-kprobe requires CONFIG_KPROBES_ON_FTRACE" 9 + 8 10 MOD_LIVEPATCH=test_klp_livepatch 9 11 MOD_KPROBE=test_klp_kprobe 10 12