From 35c9e74cff4c798d0a07830d0d483e6ebe70352f Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Wed, 16 Oct 2019 13:33:14 +0200 Subject: selftests/livepatch: Make dynamic debug setup and restore generic Livepatch selftests currently save the current dynamic debug config and tweak it for the selftests. The config is restored at the end. Make the infrastructure generic, so that more variables can be saved and restored. Link: http://lkml.kernel.org/r/20191016113316.13415-3-mbenes@suse.cz Signed-off-by: Joe Lawrence Signed-off-by: Miroslav Benes Signed-off-by: Steven Rostedt (VMware) --- tools/testing/selftests/livepatch/functions.sh | 22 +++++++++++++--------- .../testing/selftests/livepatch/test-callbacks.sh | 2 +- .../testing/selftests/livepatch/test-livepatch.sh | 2 +- .../selftests/livepatch/test-shadow-vars.sh | 2 +- 4 files changed, 16 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh index 79b0affd21fb..b7e5a67ae434 100644 --- a/tools/testing/selftests/livepatch/functions.sh +++ b/tools/testing/selftests/livepatch/functions.sh @@ -29,29 +29,33 @@ function die() { exit 1 } -function push_dynamic_debug() { - DYNAMIC_DEBUG=$(grep '^kernel/livepatch' /sys/kernel/debug/dynamic_debug/control | \ - awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}') +function push_config() { + DYNAMIC_DEBUG=$(grep '^kernel/livepatch' /sys/kernel/debug/dynamic_debug/control | \ + awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}') } -function pop_dynamic_debug() { +function pop_config() { if [[ -n "$DYNAMIC_DEBUG" ]]; then echo -n "$DYNAMIC_DEBUG" > /sys/kernel/debug/dynamic_debug/control fi } -# set_dynamic_debug() - save the current dynamic debug config and tweak -# it for the self-tests. Set a script exit trap -# that restores the original config. function set_dynamic_debug() { - push_dynamic_debug - trap pop_dynamic_debug EXIT INT TERM HUP cat <<-EOF > /sys/kernel/debug/dynamic_debug/control file kernel/livepatch/* +p func klp_try_switch_task -p EOF } +# setup_config - save the current config and set a script exit trap that +# restores the original config. Setup the dynamic debug +# for verbose livepatching output. +function setup_config() { + push_config + set_dynamic_debug + trap pop_config EXIT INT TERM HUP +} + # loop_until(cmd) - loop a command until it is successful or $MAX_RETRIES, # sleep $RETRY_INTERVAL between attempts # cmd - command and its arguments to run diff --git a/tools/testing/selftests/livepatch/test-callbacks.sh b/tools/testing/selftests/livepatch/test-callbacks.sh index e97a9dcb73c7..a35289b13c9c 100755 --- a/tools/testing/selftests/livepatch/test-callbacks.sh +++ b/tools/testing/selftests/livepatch/test-callbacks.sh @@ -9,7 +9,7 @@ MOD_LIVEPATCH2=test_klp_callbacks_demo2 MOD_TARGET=test_klp_callbacks_mod MOD_TARGET_BUSY=test_klp_callbacks_busy -set_dynamic_debug +setup_config # TEST: target module before livepatch diff --git a/tools/testing/selftests/livepatch/test-livepatch.sh b/tools/testing/selftests/livepatch/test-livepatch.sh index f05268aea859..493e3df415a1 100755 --- a/tools/testing/selftests/livepatch/test-livepatch.sh +++ b/tools/testing/selftests/livepatch/test-livepatch.sh @@ -7,7 +7,7 @@ MOD_LIVEPATCH=test_klp_livepatch MOD_REPLACE=test_klp_atomic_replace -set_dynamic_debug +setup_config # TEST: basic function patching diff --git a/tools/testing/selftests/livepatch/test-shadow-vars.sh b/tools/testing/selftests/livepatch/test-shadow-vars.sh index 04a37831e204..1aae73299114 100755 --- a/tools/testing/selftests/livepatch/test-shadow-vars.sh +++ b/tools/testing/selftests/livepatch/test-shadow-vars.sh @@ -6,7 +6,7 @@ MOD_TEST=test_klp_shadow_vars -set_dynamic_debug +setup_config # TEST: basic shadow variable API -- cgit v1.2.3-59-g8ed1b From 8c666d2ab5762280cb5ef43df4decb2a25450d54 Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Wed, 16 Oct 2019 13:33:15 +0200 Subject: selftests/livepatch: Test interaction with ftrace_enabled Since livepatching depends upon ftrace handlers to implement "patched" code functionality, verify that the ftrace_enabled sysctl value interacts with livepatch registration as expected. At the same time, ensure that ftrace_enabled is set and part of the test environment configuration that is saved and restored when running the selftests. Link: http://lkml.kernel.org/r/20191016113316.13415-4-mbenes@suse.cz Signed-off-by: Joe Lawrence Signed-off-by: Miroslav Benes Signed-off-by: Steven Rostedt (VMware) --- tools/testing/selftests/livepatch/Makefile | 3 +- tools/testing/selftests/livepatch/functions.sh | 14 ++++- tools/testing/selftests/livepatch/test-ftrace.sh | 65 ++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/livepatch/test-ftrace.sh (limited to 'tools') diff --git a/tools/testing/selftests/livepatch/Makefile b/tools/testing/selftests/livepatch/Makefile index fd405402c3ff..1886d9d94b88 100644 --- a/tools/testing/selftests/livepatch/Makefile +++ b/tools/testing/selftests/livepatch/Makefile @@ -4,6 +4,7 @@ TEST_PROGS_EXTENDED := functions.sh TEST_PROGS := \ test-livepatch.sh \ test-callbacks.sh \ - test-shadow-vars.sh + test-shadow-vars.sh \ + test-ftrace.sh include ../lib.mk diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh index b7e5a67ae434..31eb09e38729 100644 --- a/tools/testing/selftests/livepatch/functions.sh +++ b/tools/testing/selftests/livepatch/functions.sh @@ -32,12 +32,16 @@ function die() { function push_config() { DYNAMIC_DEBUG=$(grep '^kernel/livepatch' /sys/kernel/debug/dynamic_debug/control | \ awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}') + FTRACE_ENABLED=$(sysctl --values kernel.ftrace_enabled) } function pop_config() { if [[ -n "$DYNAMIC_DEBUG" ]]; then echo -n "$DYNAMIC_DEBUG" > /sys/kernel/debug/dynamic_debug/control fi + if [[ -n "$FTRACE_ENABLED" ]]; then + sysctl kernel.ftrace_enabled="$FTRACE_ENABLED" &> /dev/null + fi } function set_dynamic_debug() { @@ -47,12 +51,20 @@ function set_dynamic_debug() { EOF } +function set_ftrace_enabled() { + local sysctl="$1" + result=$(sysctl kernel.ftrace_enabled="$1" 2>&1 | paste --serial --delimiters=' ') + echo "livepatch: $result" > /dev/kmsg +} + # setup_config - save the current config and set a script exit trap that # restores the original config. Setup the dynamic debug -# for verbose livepatching output. +# for verbose livepatching output and turn on +# the ftrace_enabled sysctl. function setup_config() { push_config set_dynamic_debug + set_ftrace_enabled 1 trap pop_config EXIT INT TERM HUP } diff --git a/tools/testing/selftests/livepatch/test-ftrace.sh b/tools/testing/selftests/livepatch/test-ftrace.sh new file mode 100755 index 000000000000..e2a76887f40a --- /dev/null +++ b/tools/testing/selftests/livepatch/test-ftrace.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2019 Joe Lawrence + +. $(dirname $0)/functions.sh + +MOD_LIVEPATCH=test_klp_livepatch + +setup_config + + +# TEST: livepatch interaction with ftrace_enabled sysctl +# - turn ftrace_enabled OFF and verify livepatches can't load +# - turn ftrace_enabled ON and verify livepatch can load +# - verify that ftrace_enabled can't be turned OFF while a livepatch is loaded + +echo -n "TEST: livepatch interaction with ftrace_enabled sysctl ... " +dmesg -C + +set_ftrace_enabled 0 +load_failing_mod $MOD_LIVEPATCH + +set_ftrace_enabled 1 +load_lp $MOD_LIVEPATCH +if [[ "$(cat /proc/cmdline)" != "$MOD_LIVEPATCH: this has been live patched" ]] ; then + echo -e "FAIL\n\n" + die "livepatch kselftest(s) failed" +fi + +set_ftrace_enabled 0 +if [[ "$(cat /proc/cmdline)" != "$MOD_LIVEPATCH: this has been live patched" ]] ; then + echo -e "FAIL\n\n" + die "livepatch kselftest(s) failed" +fi +disable_lp $MOD_LIVEPATCH +unload_lp $MOD_LIVEPATCH + +check_result "livepatch: kernel.ftrace_enabled = 0 +% modprobe $MOD_LIVEPATCH +livepatch: enabling patch '$MOD_LIVEPATCH' +livepatch: '$MOD_LIVEPATCH': initializing patching transition +livepatch: failed to register ftrace handler for function 'cmdline_proc_show' (-16) +livepatch: failed to patch object 'vmlinux' +livepatch: failed to enable patch '$MOD_LIVEPATCH' +livepatch: '$MOD_LIVEPATCH': canceling patching transition, going to unpatch +livepatch: '$MOD_LIVEPATCH': completing unpatching transition +livepatch: '$MOD_LIVEPATCH': unpatching complete +modprobe: ERROR: could not insert '$MOD_LIVEPATCH': Device or resource busy +livepatch: kernel.ftrace_enabled = 1 +% modprobe $MOD_LIVEPATCH +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: sysctl: setting key \"kernel.ftrace_enabled\": Device or resource busy kernel.ftrace_enabled = 0 +% echo 0 > /sys/kernel/livepatch/$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 -- cgit v1.2.3-59-g8ed1b From 646f01ccdd59f989f0a1866d2b3503e1855358d8 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Fri, 8 Nov 2019 12:19:14 -0500 Subject: ftrace/selftest: Add tests to test register_ftrace_direct() Add two test cases that test the new ftrace direct functionality if the ftrace-direct sample module is available. One test case tests against each available tracer (function, function_graph, mmiotrace, etc), and the other test tests against a kprobe at the same location as the direct caller. Both tests follow the same pattern of testing combinations: enable test (either the tracer or the kprobe) load direct function module unload direct function module disable test enable test load direct function module disable test unload direct function module load direct function module enable test disable test unload direct function module load direct function module enable test unload direct function module disable test As most the bugs in development happened with various ways of enabling or disabling the direct calls with function tracer in one of these combinations. Signed-off-by: Steven Rostedt (VMware) --- .../ftrace/test.d/direct/ftrace-direct.tc | 53 ++++++++++++++++ .../ftrace/test.d/direct/kprobe-direct.tc | 71 ++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc create mode 100644 tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc b/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc new file mode 100644 index 000000000000..8b8ed3cad51b --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc @@ -0,0 +1,53 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test ftrace direct functions against tracers + +rmmod ftrace-direct ||: +if ! modprobe ftrace-direct ; then + echo "No ftrace-direct sample module - please make CONFIG_SAMPLE_FTRACE_DIRECT=m" + exit_unresolved; +fi + +echo "Let the module run a little" +sleep 1 + +grep -q "my_direct_func: wakeing up" trace + +rmmod ftrace-direct + +test_tracer() { + tracer=$1 + + # tracer -> direct -> no direct > no tracer + echo $tracer > current_tracer + modprobe ftrace-direct + rmmod ftrace-direct + echo nop > current_tracer + + # tracer -> direct -> no tracer > no direct + echo $tracer > current_tracer + modprobe ftrace-direct + echo nop > current_tracer + rmmod ftrace-direct + + # direct -> tracer -> no tracer > no direct + modprobe ftrace-direct + echo $tracer > current_tracer + echo nop > current_tracer + rmmod ftrace-direct + + # direct -> tracer -> no direct > no notracer + modprobe ftrace-direct + echo $tracer > current_tracer + rmmod ftrace-direct + echo nop > current_tracer +} + +for t in `cat available_tracers`; do + if [ "$t" != "nop" ]; then + test_tracer $t + fi +done + +echo nop > current_tracer +rmmod ftrace-direct ||: diff --git a/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc b/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc new file mode 100644 index 000000000000..f030dc80bcde --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc @@ -0,0 +1,71 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test ftrace direct functions against kprobes + +rmmod ftrace-direct ||: +if ! modprobe ftrace-direct ; then + echo "No ftrace-direct sample module - please build with CONFIG_SAMPLE_FTRACE_DIRECT=m" + exit_unresolved; +fi + +if [ ! -f kprobe_events ]; then + echo "No kprobe_events file -please build CONFIG_KPROBE_EVENTS" + exit_unresolved; +fi + +echo "Let the module run a little" +sleep 1 + +grep -q "my_direct_func: wakeing up" trace + +rmmod ftrace-direct + +echo 'p:kwake wake_up_process task=$arg1' > kprobe_events + +start_direct() { + echo > trace + modprobe ftrace-direct + sleep 1 + grep -q "my_direct_func: wakeing up" trace +} + +stop_direct() { + rmmod ftrace-direct +} + +enable_probe() { + echo > trace + echo 1 > events/kprobes/kwake/enable + sleep 1 + grep -q "kwake:" trace +} + +disable_probe() { + echo 0 > events/kprobes/kwake/enable +} + +# probe -> direct -> no direct > no probe +enable_probe +start_direct +stop_direct +disable_probe + +# probe -> direct -> no probe > no direct +enable_probe +start_direct +disable_probe +stop_direct + +# direct -> probe -> no probe > no direct +start_direct +enable_probe +disable_probe +stop_direct + +# direct -> probe -> no direct > no noprobe +start_direct +enable_probe +stop_direct +disable_probe + +echo > kprobe_events -- cgit v1.2.3-59-g8ed1b From ed9dafebce52206382de96bd5bbdff22335930f6 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Fri, 8 Nov 2019 16:08:12 -0500 Subject: ftrace/selftests: Update the direct call selftests to test two direct calls The register_ftrace_direct() takes a different path if there's already a direct call registered, but this was not tested in the self tests. Now that there's a second direct caller test module, we can use this to test not only one direct caller, but two. Signed-off-by: Steven Rostedt (VMware) --- .../ftrace/test.d/direct/ftrace-direct.tc | 16 ++++++ .../ftrace/test.d/direct/kprobe-direct.tc | 59 +++++++++++++--------- 2 files changed, 52 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc b/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc index 8b8ed3cad51b..cbc7a30c2e0f 100644 --- a/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc +++ b/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc @@ -51,3 +51,19 @@ done echo nop > current_tracer rmmod ftrace-direct ||: + +# Now do the same thing with another direct function registered +echo "Running with another ftrace direct function" + +rmmod ftrace-direct-too ||: +modprobe ftrace-direct-too + +for t in `cat available_tracers`; do + if [ "$t" != "nop" ]; then + test_tracer $t + fi +done + +echo nop > current_tracer +rmmod ftrace-direct ||: +rmmod ftrace-direct-too ||: diff --git a/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc b/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc index f030dc80bcde..017a7409b103 100644 --- a/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc +++ b/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc @@ -44,28 +44,41 @@ disable_probe() { echo 0 > events/kprobes/kwake/enable } -# probe -> direct -> no direct > no probe -enable_probe -start_direct -stop_direct -disable_probe - -# probe -> direct -> no probe > no direct -enable_probe -start_direct -disable_probe -stop_direct - -# direct -> probe -> no probe > no direct -start_direct -enable_probe -disable_probe -stop_direct - -# direct -> probe -> no direct > no noprobe -start_direct -enable_probe -stop_direct -disable_probe +test_kprobes() { + # probe -> direct -> no direct > no probe + enable_probe + start_direct + stop_direct + disable_probe + + # probe -> direct -> no probe > no direct + enable_probe + start_direct + disable_probe + stop_direct + + # direct -> probe -> no probe > no direct + start_direct + enable_probe + disable_probe + stop_direct + + # direct -> probe -> no direct > no noprobe + start_direct + enable_probe + stop_direct + disable_probe +} + +test_kprobes + +# Now do this with a second registered direct function +echo "Running with another ftrace direct function" + +modprobe ftrace-direct-too + +test_kprobes + +rmmod ftrace-direct-too echo > kprobe_events -- cgit v1.2.3-59-g8ed1b From b43e78f65b1d35fd3e13c7b23f9b64ea83c9ad3a Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Wed, 13 Nov 2019 11:48:39 -0500 Subject: tracing/selftests: Turn off timeout setting As the ftrace selftests can run for a long period of time, disable the timeout that the general selftests have. If a selftest hangs, then it probably means the machine will hang too. Link: https://lore.kernel.org/r/alpine.LSU.2.21.1911131604170.18679@pobox.suse.cz Suggested-by: Miroslav Benes Tested-by: Miroslav Benes Reviewed-by: Miroslav Benes Signed-off-by: Steven Rostedt (VMware) --- tools/testing/selftests/ftrace/settings | 1 + 1 file changed, 1 insertion(+) create mode 100644 tools/testing/selftests/ftrace/settings (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/settings b/tools/testing/selftests/ftrace/settings new file mode 100644 index 000000000000..e7b9417537fb --- /dev/null +++ b/tools/testing/selftests/ftrace/settings @@ -0,0 +1 @@ +timeout=0 -- cgit v1.2.3-59-g8ed1b From 760f8bc7c89c87bff9c01a8746e85dcc6e771ea8 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 15 Nov 2019 08:59:38 +0000 Subject: ftrace/selftests: Fix spelling mistake "wakeing" -> "waking" There is a spelling mistake in a trace_printk message. As well as in the selftests that search for this string. Link: http://lkml.kernel.org/r/20191115085938.38947-1-colin.king@canonical.com Link: http://lkml.kernel.org/r/20191115090356.39572-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Steven Rostedt (VMware) --- samples/ftrace/ftrace-direct.c | 2 +- tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc | 2 +- tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/samples/ftrace/ftrace-direct.c b/samples/ftrace/ftrace-direct.c index 1483f067b000..a2e3063bd306 100644 --- a/samples/ftrace/ftrace-direct.c +++ b/samples/ftrace/ftrace-direct.c @@ -6,7 +6,7 @@ void my_direct_func(struct task_struct *p) { - trace_printk("wakeing up %s-%d\n", p->comm, p->pid); + trace_printk("waking up %s-%d\n", p->comm, p->pid); } extern void my_tramp(void *); diff --git a/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc b/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc index cbc7a30c2e0f..d75a8695bc21 100644 --- a/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc +++ b/tools/testing/selftests/ftrace/test.d/direct/ftrace-direct.tc @@ -11,7 +11,7 @@ fi echo "Let the module run a little" sleep 1 -grep -q "my_direct_func: wakeing up" trace +grep -q "my_direct_func: waking up" trace rmmod ftrace-direct diff --git a/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc b/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc index 017a7409b103..801ecb63e84c 100644 --- a/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc +++ b/tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc @@ -16,7 +16,7 @@ fi echo "Let the module run a little" sleep 1 -grep -q "my_direct_func: wakeing up" trace +grep -q "my_direct_func: waking up" trace rmmod ftrace-direct @@ -26,7 +26,7 @@ start_direct() { echo > trace modprobe ftrace-direct sleep 1 - grep -q "my_direct_func: wakeing up" trace + grep -q "my_direct_func: waking up" trace } stop_direct() { -- cgit v1.2.3-59-g8ed1b