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()
This commit is contained in:
@@ -217,16 +217,19 @@ livepatch relocation section refer to their respective symbols with their symbol
|
||||
indices, and the original symbol indices (and thus the symtab ordering) must be
|
||||
preserved in order for apply_relocate_add() to find the right symbol.
|
||||
|
||||
For example, take this particular rela from a livepatch module:::
|
||||
For example, take this particular rela from a livepatch module::
|
||||
|
||||
Relocation section '.klp.rela.btrfs.text.btrfs_feature_attr_show' at offset 0x2ba0 contains 4 entries:
|
||||
Offset Info Type Symbol's Value Symbol's Name + Addend
|
||||
000000000000001f 0000005e00000002 R_X86_64_PC32 0000000000000000 .klp.sym.vmlinux.printk,0 - 4
|
||||
|
||||
This rela refers to the symbol '.klp.sym.vmlinux.printk,0', and the symbol index is encoded
|
||||
in 'Info'. Here its symbol index is 0x5e, which is 94 in decimal, which refers to the
|
||||
symbol index 94.
|
||||
And in this patch module's corresponding symbol table, symbol index 94 refers to that very symbol:
|
||||
This rela refers to the symbol '.klp.sym.vmlinux.printk,0', and the symbol
|
||||
index is encoded in 'Info'. Here its symbol index is 0x5e, which is 94 in
|
||||
decimal, which refers to the symbol index 94.
|
||||
|
||||
And in this patch module's corresponding symbol table, symbol index 94 refers
|
||||
to that very symbol::
|
||||
|
||||
[ snip ]
|
||||
94: 0000000000000000 0 NOTYPE GLOBAL DEFAULT OS [0xff20] .klp.sym.vmlinux.printk,0
|
||||
[ snip ]
|
||||
|
||||
@@ -601,9 +601,12 @@ static int klp_add_object_nops(struct klp_patch *patch,
|
||||
}
|
||||
|
||||
/*
|
||||
* Add 'nop' functions which simply return to the caller to run
|
||||
* the original function. The 'nop' functions are added to a
|
||||
* patch to facilitate a 'replace' mode.
|
||||
* Add 'nop' functions which simply return to the caller to run the
|
||||
* original function.
|
||||
*
|
||||
* They are added only when the atomic replace mode is used and only for
|
||||
* functions which are currently livepatched but are no longer included
|
||||
* in the new livepatch.
|
||||
*/
|
||||
static int klp_add_nops(struct klp_patch *patch)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@ SYSFS_KERNEL_DIR="/sys/kernel"
|
||||
SYSFS_KLP_DIR="$SYSFS_KERNEL_DIR/livepatch"
|
||||
SYSFS_DEBUG_DIR="$SYSFS_KERNEL_DIR/debug"
|
||||
SYSFS_KPROBES_DIR="$SYSFS_DEBUG_DIR/kprobes"
|
||||
SYSFS_TRACING_DIR="$SYSFS_DEBUG_DIR/tracing"
|
||||
|
||||
# Kselftest framework requirement - SKIP code is 4
|
||||
ksft_skip=4
|
||||
@@ -62,6 +63,9 @@ function push_config() {
|
||||
awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}')
|
||||
FTRACE_ENABLED=$(sysctl --values kernel.ftrace_enabled)
|
||||
KPROBE_ENABLED=$(cat "$SYSFS_KPROBES_DIR/enabled")
|
||||
TRACING_ON=$(cat "$SYSFS_TRACING_DIR/tracing_on")
|
||||
CURRENT_TRACER=$(cat "$SYSFS_TRACING_DIR/current_tracer")
|
||||
FTRACE_FILTER=$(cat "$SYSFS_TRACING_DIR/set_ftrace_filter")
|
||||
}
|
||||
|
||||
function pop_config() {
|
||||
@@ -74,6 +78,17 @@ function pop_config() {
|
||||
if [[ -n "$KPROBE_ENABLED" ]]; then
|
||||
echo "$KPROBE_ENABLED" > "$SYSFS_KPROBES_DIR/enabled"
|
||||
fi
|
||||
if [[ -n "$TRACING_ON" ]]; then
|
||||
echo "$TRACING_ON" > "$SYSFS_TRACING_DIR/tracing_on"
|
||||
fi
|
||||
if [[ -n "$CURRENT_TRACER" ]]; then
|
||||
echo "$CURRENT_TRACER" > "$SYSFS_TRACING_DIR/current_tracer"
|
||||
fi
|
||||
if [[ -n "$FTRACE_FILTER" ]]; then
|
||||
echo "$FTRACE_FILTER" \
|
||||
| sed -e "/#### all functions enabled ####/d" \
|
||||
> "$SYSFS_TRACING_DIR/set_ftrace_filter"
|
||||
fi
|
||||
}
|
||||
|
||||
function set_dynamic_debug() {
|
||||
@@ -352,3 +367,37 @@ function check_sysfs_value() {
|
||||
die "Unexpected value in $path: $expected_value vs. $value"
|
||||
fi
|
||||
}
|
||||
|
||||
# cleanup_tracing() - stop and clean up function tracing
|
||||
function cleanup_tracing() {
|
||||
echo 0 > "$SYSFS_TRACING_DIR/tracing_on"
|
||||
echo "" > "$SYSFS_TRACING_DIR/set_ftrace_filter"
|
||||
echo "nop" > "$SYSFS_TRACING_DIR/current_tracer"
|
||||
echo "" > "$SYSFS_TRACING_DIR/trace"
|
||||
}
|
||||
|
||||
# trace_function(function) - start tracing of a function
|
||||
# function - to be traced function
|
||||
function trace_function() {
|
||||
local function="$1"; shift
|
||||
|
||||
cleanup_tracing
|
||||
|
||||
echo "function" > "$SYSFS_TRACING_DIR/current_tracer"
|
||||
echo "$function" > "$SYSFS_TRACING_DIR/set_ftrace_filter"
|
||||
echo 1 > "$SYSFS_TRACING_DIR/tracing_on"
|
||||
}
|
||||
|
||||
# check_traced_functions(functions...) - check whether each function appeared in the trace log
|
||||
# functions - list of functions to be checked
|
||||
function check_traced_functions() {
|
||||
local function
|
||||
|
||||
for function in "$@"; do
|
||||
if ! grep -Fwq "$function" "$SYSFS_TRACING_DIR/trace" ; then
|
||||
die "Function ($function) did not appear in the trace"
|
||||
fi
|
||||
done
|
||||
|
||||
cleanup_tracing
|
||||
}
|
||||
|
||||
@@ -61,4 +61,38 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
|
||||
% rmmod $MOD_LIVEPATCH"
|
||||
|
||||
|
||||
# - verify livepatch can load
|
||||
# - check if traces have a patched function
|
||||
# - reset trace and unload livepatch
|
||||
|
||||
start_test "trace livepatched function and check that the live patch remains in effect"
|
||||
|
||||
FUNCTION_NAME="livepatch_cmdline_proc_show"
|
||||
|
||||
load_lp $MOD_LIVEPATCH
|
||||
trace_function "$FUNCTION_NAME"
|
||||
|
||||
if [[ "$(cat /proc/cmdline)" == "$MOD_LIVEPATCH: this has been live patched" ]] ; then
|
||||
log "livepatch: ok"
|
||||
fi
|
||||
|
||||
check_traced_functions "$FUNCTION_NAME"
|
||||
|
||||
disable_lp $MOD_LIVEPATCH
|
||||
unload_lp $MOD_LIVEPATCH
|
||||
|
||||
check_result "% insmod test_modules/$MOD_LIVEPATCH.ko
|
||||
livepatch: enabling patch '$MOD_LIVEPATCH'
|
||||
livepatch: '$MOD_LIVEPATCH': initializing patching transition
|
||||
livepatch: '$MOD_LIVEPATCH': starting patching transition
|
||||
livepatch: '$MOD_LIVEPATCH': completing patching transition
|
||||
livepatch: '$MOD_LIVEPATCH': patching complete
|
||||
livepatch: ok
|
||||
% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
|
||||
livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
|
||||
livepatch: '$MOD_LIVEPATCH': starting unpatching transition
|
||||
livepatch: '$MOD_LIVEPATCH': completing unpatching transition
|
||||
livepatch: '$MOD_LIVEPATCH': unpatching complete
|
||||
% rmmod $MOD_LIVEPATCH"
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
. $(dirname $0)/functions.sh
|
||||
|
||||
grep -q kprobe_ftrace_ops /proc/kallsyms || skip "test-kprobe requires CONFIG_KPROBES_ON_FTRACE"
|
||||
|
||||
MOD_LIVEPATCH=test_klp_livepatch
|
||||
MOD_KPROBE=test_klp_kprobe
|
||||
|
||||
|
||||
Reference in New Issue
Block a user