Skip to content

Commit dcf9f31

Browse files
committed
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()
2 parents 9605081 + d11f0d1 commit dcf9f31

File tree

5 files changed

+99
-8
lines changed

5 files changed

+99
-8
lines changed

Documentation/livepatch/module-elf-format.rst

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,16 +217,19 @@ livepatch relocation section refer to their respective symbols with their symbol
217217
indices, and the original symbol indices (and thus the symtab ordering) must be
218218
preserved in order for apply_relocate_add() to find the right symbol.
219219

220-
For example, take this particular rela from a livepatch module:::
220+
For example, take this particular rela from a livepatch module::
221221

222222
Relocation section '.klp.rela.btrfs.text.btrfs_feature_attr_show' at offset 0x2ba0 contains 4 entries:
223223
Offset Info Type Symbol's Value Symbol's Name + Addend
224224
000000000000001f 0000005e00000002 R_X86_64_PC32 0000000000000000 .klp.sym.vmlinux.printk,0 - 4
225225

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+
230233
[ snip ]
231234
94: 0000000000000000 0 NOTYPE GLOBAL DEFAULT OS [0xff20] .klp.sym.vmlinux.printk,0
232235
[ snip ]

kernel/livepatch/core.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,12 @@ static int klp_add_object_nops(struct klp_patch *patch,
601601
}
602602

603603
/*
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.
607610
*/
608611
static int klp_add_nops(struct klp_patch *patch)
609612
{

tools/testing/selftests/livepatch/functions.sh

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ SYSFS_KERNEL_DIR="/sys/kernel"
1010
SYSFS_KLP_DIR="$SYSFS_KERNEL_DIR/livepatch"
1111
SYSFS_DEBUG_DIR="$SYSFS_KERNEL_DIR/debug"
1212
SYSFS_KPROBES_DIR="$SYSFS_DEBUG_DIR/kprobes"
13+
SYSFS_TRACING_DIR="$SYSFS_DEBUG_DIR/tracing"
1314

1415
# Kselftest framework requirement - SKIP code is 4
1516
ksft_skip=4
@@ -62,6 +63,9 @@ function push_config() {
6263
awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}')
6364
FTRACE_ENABLED=$(sysctl --values kernel.ftrace_enabled)
6465
KPROBE_ENABLED=$(cat "$SYSFS_KPROBES_DIR/enabled")
66+
TRACING_ON=$(cat "$SYSFS_TRACING_DIR/tracing_on")
67+
CURRENT_TRACER=$(cat "$SYSFS_TRACING_DIR/current_tracer")
68+
FTRACE_FILTER=$(cat "$SYSFS_TRACING_DIR/set_ftrace_filter")
6569
}
6670

6771
function pop_config() {
@@ -74,6 +78,17 @@ function pop_config() {
7478
if [[ -n "$KPROBE_ENABLED" ]]; then
7579
echo "$KPROBE_ENABLED" > "$SYSFS_KPROBES_DIR/enabled"
7680
fi
81+
if [[ -n "$TRACING_ON" ]]; then
82+
echo "$TRACING_ON" > "$SYSFS_TRACING_DIR/tracing_on"
83+
fi
84+
if [[ -n "$CURRENT_TRACER" ]]; then
85+
echo "$CURRENT_TRACER" > "$SYSFS_TRACING_DIR/current_tracer"
86+
fi
87+
if [[ -n "$FTRACE_FILTER" ]]; then
88+
echo "$FTRACE_FILTER" \
89+
| sed -e "/#### all functions enabled ####/d" \
90+
> "$SYSFS_TRACING_DIR/set_ftrace_filter"
91+
fi
7792
}
7893

7994
function set_dynamic_debug() {
@@ -352,3 +367,37 @@ function check_sysfs_value() {
352367
die "Unexpected value in $path: $expected_value vs. $value"
353368
fi
354369
}
370+
371+
# cleanup_tracing() - stop and clean up function tracing
372+
function cleanup_tracing() {
373+
echo 0 > "$SYSFS_TRACING_DIR/tracing_on"
374+
echo "" > "$SYSFS_TRACING_DIR/set_ftrace_filter"
375+
echo "nop" > "$SYSFS_TRACING_DIR/current_tracer"
376+
echo "" > "$SYSFS_TRACING_DIR/trace"
377+
}
378+
379+
# trace_function(function) - start tracing of a function
380+
# function - to be traced function
381+
function trace_function() {
382+
local function="$1"; shift
383+
384+
cleanup_tracing
385+
386+
echo "function" > "$SYSFS_TRACING_DIR/current_tracer"
387+
echo "$function" > "$SYSFS_TRACING_DIR/set_ftrace_filter"
388+
echo 1 > "$SYSFS_TRACING_DIR/tracing_on"
389+
}
390+
391+
# check_traced_functions(functions...) - check whether each function appeared in the trace log
392+
# functions - list of functions to be checked
393+
function check_traced_functions() {
394+
local function
395+
396+
for function in "$@"; do
397+
if ! grep -Fwq "$function" "$SYSFS_TRACING_DIR/trace" ; then
398+
die "Function ($function) did not appear in the trace"
399+
fi
400+
done
401+
402+
cleanup_tracing
403+
}

tools/testing/selftests/livepatch/test-ftrace.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,38 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
6161
% rmmod $MOD_LIVEPATCH"
6262

6363

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+
6498
exit 0

tools/testing/selftests/livepatch/test-kprobe.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
. $(dirname $0)/functions.sh
77

8+
grep -q kprobe_ftrace_ops /proc/kallsyms || skip "test-kprobe requires CONFIG_KPROBES_ON_FTRACE"
9+
810
MOD_LIVEPATCH=test_klp_livepatch
911
MOD_KPROBE=test_klp_kprobe
1012

0 commit comments

Comments
 (0)