From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.214.177 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793021843; b=IQz40MTY5tyOj/tUfv1fNdg57+gQ15jvD1HxnVXza2HBIe0j5LEw7PAxLJHAuJ5hk3II uYMhewDo3WVtnqh/sDzAQOIVNCCoqJ/ZJS68YivnVyn8/XVBDT8tdg2yX233yfqmNz0zp nn8f8dKKWNZzq+X1dqYWXnzNNh+gl5lRZyKez8/V72MYroKhdxG87Y7aOq9h4W0I5hI2S 4UHpF5fQCJ8bDFicw99oxWw9G6NYH8xah5F12dgqqOSJa0z/ICkqBDBnRd22Aw9U1wbX8 sHsBB/JWIchTZwjXNxtYISCcBrriwfkasjDW+lX66yMh7BOfb03ttl4Eo6ckLm8uw6Q== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793021843; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: From:To:Cc:Subject:Date:Message-ID:X-Mailer:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding; bh=VTYcLitAMiXtwWLq5RpovRZ53xkxF5kQKd62tbj7cto=; b=c4h1CiJ7iBZTVMUo5t4ciWuR+yP48zEGUWba/uAt3UKFSWQFOqFRtmaP9LXp1PvRPsP9 5vmdDafSZPxjy2h4t4zKmlcJunIfcm+YLYzw9CI3AD79TGWQOWP4ynOAXBNPPPpxnLmia tmKPlURAties+CalbdRjvs5MmoQq9Qyf9wcxenqVnx7WwA+T0upEdXPFBYVHFIPjwHYiz 1TTM8anZ3/601VWw4xtPcvaRM7qf2Cr8DMenHrXujXdRlRPthShUEzF/CXh63g84INjzt PauJ0Brar68NJCINzAjFry5vlDpzpLEcxFQ1lg/3NUMqLc6D5IS94AlLxuly6PPvZEQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=QMT9vM3X; arc=none smtp.remote-ip=209.85.214.177 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35D92606A32C for ; Mon, 26 Oct 2026 13:37:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 35D92606A32C Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=QMT9vM3X Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-2ea7987517aso16715735ad.0 for ; Mon, 26 Oct 2026 06:37:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1793021842; x=1793626642; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VTYcLitAMiXtwWLq5RpovRZ53xkxF5kQKd62tbj7cto=; b=QMT9vM3XL2pI41yLw+ZH5kjYNq4W5wcfBqKx2Z0+mwfP3B/rVNtqLLhiEezNkd9ycq dfCM0+DI4VIzS7uXYVzUFwp34mRDZGoFyxVqNf+U1Iid6WY4RqOZhWOXT+NjXxUIhHKa UTlM0rPAIS/nJKsVeeFdNol8/oxNCp3BiTyPFhJGncqo+5ERiVFbx7qi/oZgdRore7oK U0lLPLaW+advqP9q3DnTAZ5y14oqRPrJbnb/TMCGnp8hzQ9UYMPqtPURqQkECpQ0NVNU kC3D7Br91b/XRzkqgPs96Yk8jBt6Bcy0P4g5ECj471zgAXBbt4Zwbzi+N8C6nVcPU4O+ BFPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793021842; x=1793626642; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=VTYcLitAMiXtwWLq5RpovRZ53xkxF5kQKd62tbj7cto=; b=liBrxHQDXxA/Bqtrbc5SHtmC3Z/SFudU56qBQXHCFwtwp/Snf0xoblA9cXVXwCcA2Z JQa5K/3awXXxRHA1JIZAHYDdOBZlDFlZeFpSsaG6XFiLHdMs/PUfEaQdC64AEcXvfwYz Pwk3D601pRguWp+TnmD+pgqsIINZKcuj2DnAs32ThxmA4opLGbhHqzVAtzdDPQ71st9v HwbfTW7eX/G1t4euZ16isWljIM9AVVATsk3UjV/92ohptzcBxSg0oIEU03Bc+42LKxQs 7ol4OZj7VCg1nG3ZvM7HK2tdEiiSHQ5sfmRZNlPGvYL8GdNcee9cZI1/OElx4TFQ4rYZ 3HBw== X-Forwarded-Encrypted: i=1; AKwUvBzTDkIX6BHxsW1016OJW+PNo+Hl76jqj2OEC20hFNSK3DxnLaQ5oqmC15NFzGRLT9vM+4fTcZ9fL1rVnSg=@vger.kernel.org X-Gm-Message-State: AFq9FYJbX2ZUetbLf4xqGWnSvwj+rVV7mzNTdD2hD6gM4hPym+5zEprS i1U4ivUUGSn4qKTnQAu8tSSyifEEH8FPalIK9qtXRw75F3xR2uMP0XxC X-Gm-Gg: AYBFou0PZ73Xjwb8FLqkrqDxUnESN9yoXmO8odLXUBDiaz7SDT1ttg7MIIsNQpFiRlj no4FV8Fm3MXnG/TEtC77Zp27SDl0M5eOormQzO7e0pDgEaR2OLnf7Ax43L1n3AWt7a+G4KI4jKt SK11bxazWfi9FYhu8i9Edpcvn2tqUOweclqrc3WoRpi3uOHoYxcuIT3OU4hQKVn1fyz66jF+YJU 02/bwuBfNl/9bh3oy+w1a6jxrzPchxuh3LjxKw9A8ugRMRseTsQiNzkYeVGtM1024XVlaC0UXsA tu6auTOqcxFPvhBkAzH+6iQi9LVb4P0koEVWY6iby/DjHR8d7jexhIehvzQy8pTZ2CezcKp9etg /VFS92+i5rvVRkYccD5feAWbUuR6jIZ+pUZUwotAh3rLtMwwctrsexkI/6Y50h94J6wr/9vLkiR r3QERnaJe/FBFvf/6Om87izvyVxzxJNTeM12kUtZUE7lDioPPL0TxCRKt3JmrK1XWdb7+QM9mLc nIYSJsPa1LJaMcqCvpeeSAlGj/+rpAu8ui2btve3/1l7R2xBa7uDs5noHA5t7mcA1LN7WRJse2i SGOSqBXSwCplXmYzELPQFOZSv4NGV6w56OF+HxNNcbHqVeD+IQqMhP01FOE= X-Received: by 2002:a17:903:1d1:b0:2e9:776c:d52e with SMTP id d9443c01a7336-2ea9c873c48mr57006975ad.52.1793021842362; Mon, 26 Oct 2026 06:37:22 -0700 (PDT) Received: from yafangs-Air ([240e:46d:2600:484d:51ee:4f49:b5a8:aabd]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2ea9b1a5cf0sm17447055ad.52.2026.10.26.06.37.17 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 26 Oct 2026 06:37:21 -0700 (PDT) From: Yafang Shao To: jpoimboe@kernel.org, mbenes@suse.cz, pmladek@suse.com, joe.lawrence@redhat.com, song@kernel.org Cc: live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Yafang Shao Subject: [PATCH v13 2/9] selftests/livepatch: Adapt atomic replace tests to provides/obsoletes Date: Mon, 26 Oct 2026 21:36:44 +0800 Message-ID: <20261026133651.40061-3-laoar.shao@gmail.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20261026133651.40061-1-laoar.shao@gmail.com> References: <20261026133651.40061-1-laoar.shao@gmail.com> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The legacy "replace" field in struct klp_patch will be replaced by the provides/obsoletes mechanism. As a result, the atomic replace selftests fail to build against kernels that only support provides/obsoletes. Adapt the selftests so that they build and run on both old and new kernels. On kernels without the legacy "replace" support, the replace-related test cases are skipped with a SKIP message instead of being run. Also introduce the CONFIG_KLP_HAS_PROVIDES compile-time marker in kernel/livepatch/Kconfig. It defaults to n and will be set to y once the provides/obsoletes support is implemented later in this series. The provides/obsoletes-based selftests will be added later in this series, after the legacy "replace" field has been substituted by the new mechanism. Suggested-by: Petr Mladek Signed-off-by: Yafang Shao Acked-by: Song Liu Reviewed-by: Petr Mladek Tested-by: Petr Mladek Acked-by: Miroslav Benes --- kernel/livepatch/Kconfig | 14 +++ tools/testing/selftests/livepatch/functions.sh | 42 ++++++++- .../testing/selftests/livepatch/test-callbacks.sh | 43 ++++++--- tools/testing/selftests/livepatch/test-kprobe.sh | 3 +- .../testing/selftests/livepatch/test-livepatch.sh | 102 ++++++++++++--------- tools/testing/selftests/livepatch/test-sysfs.sh | 3 +- .../test_modules/test_klp_callbacks_demo2.c | 16 ++++ .../livepatch/test_modules/test_klp_meminfo_lp.c | 16 ++++ .../livepatch/test_modules/test_klp_state.c | 7 ++ .../livepatch/test_modules/test_klp_state2.c | 7 ++ 10 files changed, 189 insertions(+), 64 deletions(-) diff --git a/kernel/livepatch/Kconfig b/kernel/livepatch/Kconfig index 4c0a9c1..d1eb971 100644 --- a/kernel/livepatch/Kconfig +++ b/kernel/livepatch/Kconfig @@ -30,3 +30,17 @@ config KLP_BUILD select OBJTOOL help Enable klp-build support + +config KLP_HAS_PROVIDES + def_bool n + help + Compile-time marker for the livepatch provides/obsoletes support. + It is always set when the kernel is built with the scoped atomic + replace model, i.e. struct klp_patch provides the "provides" and + "obsoletes" fields instead of the legacy "replace" flag. + + The option itself does not enable or add any functionality; it + only serves as a compile-time marker so that out-of-tree modules + and tools (e.g. the livepatch kselftests) can detect kernels that + speak the provides/obsoletes interface and adapt to it with + #ifdef CONFIG_KLP_HAS_PROVIDES. diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh index 429fce1..3d85575 100644 --- a/tools/testing/selftests/livepatch/functions.sh +++ b/tools/testing/selftests/livepatch/functions.sh @@ -27,14 +27,26 @@ function log() { echo "$1" > /dev/kmsg } -# skip(msg) - testing can't proceed +# skip_exit(msg) - testing can't proceed # msg - explanation -function skip() { +function skip_exit() { log "SKIP: $1" echo "SKIP: $1" >&2 exit $ksft_skip } +# skip(test, reason) - skip the test for a specific reason +# test - a test case +# reason - reason to skip it +function skip() { + local test="$1" + local reason="$2" + + echo -n "TEST: $test ... " + echo "SKIP ($reason)" + log "===== TEST: $test SKIPPED: $reason =====" +} + # root test function is_root() { uid=$(id -u) @@ -120,7 +132,7 @@ function set_ftrace_enabled() { return fi - skip "failed to set kernel.ftrace_enabled = $1" + skip_exit "failed to set kernel.ftrace_enabled = $1" fi echo "livepatch: kernel.ftrace_enabled = $result" > /dev/kmsg @@ -371,6 +383,30 @@ function does_sysfs_exist() { [[ -f "$SYSFS_KLP_DIR/$mod/$attr" ]] } +# detect_provides_attr() - detect whether the running kernel supports the +# livepatch "provides" attribute and set HAS_PROVIDES_ATTR accordingly. +# The provides/obsoletes based tests are only run when HAS_PROVIDES_ATTR +# is set. +function detect_provides_attr() { + HAS_PROVIDES_ATTR=0 + + if [[ -r /proc/config.gz ]] && + zgrep -q "CONFIG_KLP_HAS_PROVIDES=y" /proc/config.gz 2>/dev/null; then + HAS_PROVIDES_ATTR=1 + return 0 + fi + + # /proc/config.gz is available only when CONFIG_IKCONFIG_PROC is + # enabled. Fall back to probing the "provides" sysfs attribute, + # which requires loading and unloading a livepatch. + load_lp test_klp_cmdline_lp + if does_sysfs_exist test_klp_cmdline_lp "provides"; then + HAS_PROVIDES_ATTR=1 + fi + disable_lp test_klp_cmdline_lp + unload_lp test_klp_cmdline_lp +} + # check_sysfs_rights(modname, rel_path, expected_rights) - check sysfs # path permissions # modname - livepatch module creating the sysfs interface diff --git a/tools/testing/selftests/livepatch/test-callbacks.sh b/tools/testing/selftests/livepatch/test-callbacks.sh index 2a03deb..210a9f9 100755 --- a/tools/testing/selftests/livepatch/test-callbacks.sh +++ b/tools/testing/selftests/livepatch/test-callbacks.sh @@ -10,6 +10,7 @@ MOD_TARGET=test_klp_callbacks_mod MOD_TARGET_BUSY=test_klp_callbacks_busy setup_config +detect_provides_attr # Test a combination of loading a kernel module and a livepatch that @@ -458,16 +459,17 @@ $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit" # execute as each patch progresses through its (un)patching # transition. -start_test "multiple livepatches" +function test_multiple_livepatches() { + start_test "multiple livepatches" -load_lp $MOD_LIVEPATCH -load_lp $MOD_LIVEPATCH2 -disable_lp $MOD_LIVEPATCH2 -disable_lp $MOD_LIVEPATCH -unload_lp $MOD_LIVEPATCH2 -unload_lp $MOD_LIVEPATCH + load_lp $MOD_LIVEPATCH + load_lp $MOD_LIVEPATCH2 + disable_lp $MOD_LIVEPATCH2 + disable_lp $MOD_LIVEPATCH + unload_lp $MOD_LIVEPATCH2 + unload_lp $MOD_LIVEPATCH -check_result "% insmod test_modules/$MOD_LIVEPATCH.ko + check_result "% insmod test_modules/$MOD_LIVEPATCH.ko livepatch: enabling patch '$MOD_LIVEPATCH' livepatch: '$MOD_LIVEPATCH': initializing patching transition $MOD_LIVEPATCH: pre_patch_callback: vmlinux @@ -499,6 +501,7 @@ $MOD_LIVEPATCH: post_unpatch_callback: vmlinux livepatch: '$MOD_LIVEPATCH': unpatching complete % rmmod $MOD_LIVEPATCH2 % rmmod $MOD_LIVEPATCH" +} # Load multiple livepatches, but the second as an 'atomic-replace' @@ -515,15 +518,16 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete # - Once the atomic replace module is loaded, only its pre and post # unpatch callbacks are executed. -start_test "atomic replace" +function test_atomic_replace() { + start_test "atomic replace" -load_lp $MOD_LIVEPATCH -load_lp $MOD_LIVEPATCH2 replace=1 -disable_lp $MOD_LIVEPATCH2 -unload_lp $MOD_LIVEPATCH2 -unload_lp $MOD_LIVEPATCH + load_lp $MOD_LIVEPATCH + load_lp $MOD_LIVEPATCH2 replace=1 + disable_lp $MOD_LIVEPATCH2 + unload_lp $MOD_LIVEPATCH2 + unload_lp $MOD_LIVEPATCH -check_result "% insmod test_modules/$MOD_LIVEPATCH.ko + check_result "% insmod test_modules/$MOD_LIVEPATCH.ko livepatch: enabling patch '$MOD_LIVEPATCH' livepatch: '$MOD_LIVEPATCH': initializing patching transition $MOD_LIVEPATCH: pre_patch_callback: vmlinux @@ -548,6 +552,15 @@ $MOD_LIVEPATCH2: post_unpatch_callback: vmlinux livepatch: '$MOD_LIVEPATCH2': unpatching complete % rmmod $MOD_LIVEPATCH2 % rmmod $MOD_LIVEPATCH" +} + +if [[ "$HAS_PROVIDES_ATTR" == "1" ]]; then + skip "multiple livepatches" "legacy replace attribute not present" + skip "atomic replace" "legacy replace attribute not present" +else + test_multiple_livepatches + test_atomic_replace +fi exit 0 diff --git a/tools/testing/selftests/livepatch/test-kprobe.sh b/tools/testing/selftests/livepatch/test-kprobe.sh index 81ab6d4..dea62ce 100755 --- a/tools/testing/selftests/livepatch/test-kprobe.sh +++ b/tools/testing/selftests/livepatch/test-kprobe.sh @@ -5,7 +5,8 @@ . $(dirname $0)/functions.sh -grep -q kprobe_ftrace_ops /proc/kallsyms || skip "test-kprobe requires CONFIG_KPROBES_ON_FTRACE" +grep -q kprobe_ftrace_ops /proc/kallsyms || + skip_exit "test-kprobe requires CONFIG_KPROBES_ON_FTRACE" MOD_LIVEPATCH=test_klp_cmdline_lp MOD_KPROBE=test_klp_cmdline_kp diff --git a/tools/testing/selftests/livepatch/test-livepatch.sh b/tools/testing/selftests/livepatch/test-livepatch.sh index 5380b5f..645fa6c 100755 --- a/tools/testing/selftests/livepatch/test-livepatch.sh +++ b/tools/testing/selftests/livepatch/test-livepatch.sh @@ -12,6 +12,7 @@ MOD_TARGET=test_klp_mod_target MOD_TARGET_PATCH=test_klp_mod_patch setup_config +detect_provides_attr # - load a livepatch that modifies the output from /proc/cmdline and @@ -55,31 +56,32 @@ livepatch: '$MOD_LIVEPATCH1': unpatching complete # - unload the second livepatch and verify that the first is still active # - unload the first livepatch and verify none are active -start_test "multiple livepatches" +function test_multiple_livepatches() { + start_test "multiple livepatches" -load_lp $MOD_LIVEPATCH1 + load_lp $MOD_LIVEPATCH1 -grep 'live patched' /proc/cmdline > /dev/kmsg -grep 'live patched' /proc/meminfo > /dev/kmsg + grep 'live patched' /proc/cmdline > /dev/kmsg + grep 'live patched' /proc/meminfo > /dev/kmsg -load_lp $MOD_REPLACE replace=0 + load_lp $MOD_REPLACE replace=0 -grep 'live patched' /proc/cmdline > /dev/kmsg -grep 'live patched' /proc/meminfo > /dev/kmsg + grep 'live patched' /proc/cmdline > /dev/kmsg + grep 'live patched' /proc/meminfo > /dev/kmsg -disable_lp $MOD_REPLACE -unload_lp $MOD_REPLACE + disable_lp $MOD_REPLACE + unload_lp $MOD_REPLACE -grep 'live patched' /proc/cmdline > /dev/kmsg -grep 'live patched' /proc/meminfo > /dev/kmsg + grep 'live patched' /proc/cmdline > /dev/kmsg + grep 'live patched' /proc/meminfo > /dev/kmsg -disable_lp $MOD_LIVEPATCH1 -unload_lp $MOD_LIVEPATCH1 + disable_lp $MOD_LIVEPATCH1 + unload_lp $MOD_LIVEPATCH1 -grep 'live patched' /proc/cmdline > /dev/kmsg -grep 'live patched' /proc/meminfo > /dev/kmsg + grep 'live patched' /proc/cmdline > /dev/kmsg + grep 'live patched' /proc/meminfo > /dev/kmsg -check_result "% insmod test_modules/$MOD_LIVEPATCH1.ko + check_result "% insmod test_modules/$MOD_LIVEPATCH1.ko livepatch: enabling patch '$MOD_LIVEPATCH1' livepatch: '$MOD_LIVEPATCH1': initializing patching transition livepatch: '$MOD_LIVEPATCH1': starting patching transition @@ -107,6 +109,7 @@ livepatch: '$MOD_LIVEPATCH1': starting unpatching transition livepatch: '$MOD_LIVEPATCH1': completing unpatching transition livepatch: '$MOD_LIVEPATCH1': unpatching complete % rmmod $MOD_LIVEPATCH1" +} # - load a livepatch that modifies the output from /proc/cmdline and @@ -119,46 +122,47 @@ livepatch: '$MOD_LIVEPATCH1': unpatching complete # atomic replace livepatch is still active # - remove the atomic replace livepatch and verify that none are active -start_test "atomic replace livepatch" +function test_atomic_replace_livepatch() { + start_test "atomic replace livepatch" -load_lp $MOD_LIVEPATCH1 + load_lp $MOD_LIVEPATCH1 -grep 'live patched' /proc/cmdline > /dev/kmsg -grep 'live patched' /proc/meminfo > /dev/kmsg + grep 'live patched' /proc/cmdline > /dev/kmsg + grep 'live patched' /proc/meminfo > /dev/kmsg -for mod in $MOD_LIVEPATCH2 $MOD_LIVEPATCH3; do - load_lp "$mod" -done + for mod in $MOD_LIVEPATCH2 $MOD_LIVEPATCH3; do + load_lp "$mod" + done -mods=($SYSFS_KLP_DIR/*) -nmods=${#mods[@]} -if [ "$nmods" -ne 3 ]; then - die "Expecting three modules listed, found $nmods" -fi + mods=($SYSFS_KLP_DIR/*) + nmods=${#mods[@]} + if [ "$nmods" -ne 3 ]; then + die "Expecting three modules listed, found $nmods" + fi -load_lp $MOD_REPLACE replace=1 + load_lp $MOD_REPLACE replace=1 -grep 'live patched' /proc/cmdline > /dev/kmsg -grep 'live patched' /proc/meminfo > /dev/kmsg + grep 'live patched' /proc/cmdline > /dev/kmsg + grep 'live patched' /proc/meminfo > /dev/kmsg -loop_until 'mods=($SYSFS_KLP_DIR/*); nmods=${#mods[@]}; [[ "$nmods" -eq 1 ]]' || - die "Expecting only one moduled listed, found $nmods" + loop_until 'mods=($SYSFS_KLP_DIR/*); nmods=${#mods[@]}; [[ "$nmods" -eq 1 ]]' || + die "Expecting only one moduled listed, found $nmods" -# These modules were disabled by the atomic replace -for mod in $MOD_LIVEPATCH3 $MOD_LIVEPATCH2 $MOD_LIVEPATCH1; do - unload_lp "$mod" -done + # These modules were disabled by the atomic replace + for mod in $MOD_LIVEPATCH3 $MOD_LIVEPATCH2 $MOD_LIVEPATCH1; do + unload_lp "$mod" + done -grep 'live patched' /proc/cmdline > /dev/kmsg -grep 'live patched' /proc/meminfo > /dev/kmsg + grep 'live patched' /proc/cmdline > /dev/kmsg + grep 'live patched' /proc/meminfo > /dev/kmsg -disable_lp $MOD_REPLACE -unload_lp $MOD_REPLACE + disable_lp $MOD_REPLACE + unload_lp $MOD_REPLACE -grep 'live patched' /proc/cmdline > /dev/kmsg -grep 'live patched' /proc/meminfo > /dev/kmsg + grep 'live patched' /proc/cmdline > /dev/kmsg + grep 'live patched' /proc/meminfo > /dev/kmsg -check_result "% insmod test_modules/$MOD_LIVEPATCH1.ko + check_result "% insmod test_modules/$MOD_LIVEPATCH1.ko livepatch: enabling patch '$MOD_LIVEPATCH1' livepatch: '$MOD_LIVEPATCH1': initializing patching transition livepatch: '$MOD_LIVEPATCH1': starting patching transition @@ -196,6 +200,16 @@ livepatch: '$MOD_REPLACE': starting unpatching transition livepatch: '$MOD_REPLACE': completing unpatching transition livepatch: '$MOD_REPLACE': unpatching complete % rmmod $MOD_REPLACE" +} + + +if [[ "$HAS_PROVIDES_ATTR" == "1" ]]; then + skip "multiple livepatches" "legacy replace attribute not present" + skip "atomic replace livepatch" "legacy replace attribute not present" +else + test_multiple_livepatches + test_atomic_replace_livepatch +fi # - load a target module that provides /proc/test_klp_mod_target with diff --git a/tools/testing/selftests/livepatch/test-sysfs.sh b/tools/testing/selftests/livepatch/test-sysfs.sh index 32d3af0..e48bf33 100755 --- a/tools/testing/selftests/livepatch/test-sysfs.sh +++ b/tools/testing/selftests/livepatch/test-sysfs.sh @@ -13,6 +13,7 @@ HAS_REPLACE_ATTR=0 HAS_STACK_ORDER_ATTR=0 setup_config +detect_provides_attr # - load a livepatch and verifies the sysfs entries work as expected @@ -154,7 +155,7 @@ livepatch: '$MOD_ATOMIC_REPLACE': unpatching complete % rmmod $MOD_ATOMIC_REPLACE" fi -if [[ "$HAS_STACK_ORDER_ATTR" == "1" ]]; then +if [[ "$HAS_STACK_ORDER_ATTR" == "1" && "$HAS_PROVIDES_ATTR" != "1" ]]; then start_test "sysfs test stack_order value" load_lp $MOD_LIVEPATCH diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_callbacks_demo2.c b/tools/testing/selftests/livepatch/test_modules/test_klp_callbacks_demo2.c index 5417573..6c46ce5 100644 --- a/tools/testing/selftests/livepatch/test_modules/test_klp_callbacks_demo2.c +++ b/tools/testing/selftests/livepatch/test_modules/test_klp_callbacks_demo2.c @@ -7,9 +7,16 @@ #include #include +#ifdef CONFIG_KLP_HAS_PROVIDES +/* + * TODO: Add provides/obsoletes module parameters for the + * provides/obsoletes based tests (to be added later). + */ +#else static int replace; module_param(replace, int, 0644); MODULE_PARM_DESC(replace, "replace (default=0)"); +#endif static const char *const module_state[] = { [MODULE_STATE_LIVE] = "[MODULE_STATE_LIVE] Normal state", @@ -72,12 +79,21 @@ static void post_unpatch_callback(struct klp_object *obj) static struct klp_patch patch = { .mod = THIS_MODULE, .objs = objs, +#ifndef CONFIG_KLP_HAS_PROVIDES /* set .replace in the init function below for demo purposes */ +#endif }; static int test_klp_callbacks_demo2_init(void) { +#ifdef CONFIG_KLP_HAS_PROVIDES + /* + * TODO: Set provides/obsoletes from the module parameters + * for the provides/obsoletes based tests (to be added later). + */ +#else patch.replace = replace; +#endif return klp_enable_patch(&patch); } diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_meminfo_lp.c b/tools/testing/selftests/livepatch/test_modules/test_klp_meminfo_lp.c index f2477b2..0c434a2 100644 --- a/tools/testing/selftests/livepatch/test_modules/test_klp_meminfo_lp.c +++ b/tools/testing/selftests/livepatch/test_modules/test_klp_meminfo_lp.c @@ -7,9 +7,16 @@ #include #include +#ifdef CONFIG_KLP_HAS_PROVIDES +/* + * TODO: Add provides/obsoletes module parameters for the + * provides/obsoletes based tests (to be added later). + */ +#else static int replace; module_param(replace, int, 0644); MODULE_PARM_DESC(replace, "replace (default=0)"); +#endif #include static int livepatch_meminfo_proc_show(struct seq_file *m, void *v) @@ -36,12 +43,21 @@ static int livepatch_meminfo_proc_show(struct seq_file *m, void *v) static struct klp_patch patch = { .mod = THIS_MODULE, .objs = objs, +#ifndef CONFIG_KLP_HAS_PROVIDES /* set .replace in the init function below for demo purposes */ +#endif }; static int test_klp_meminfo_lp_init(void) { +#ifdef CONFIG_KLP_HAS_PROVIDES + /* + * TODO: Set provides/obsoletes from the module parameters + * for the provides/obsoletes based tests (to be added later). + */ +#else patch.replace = replace; +#endif return klp_enable_patch(&patch); } diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_state.c b/tools/testing/selftests/livepatch/test_modules/test_klp_state.c index 57a4253..4d419a5 100644 --- a/tools/testing/selftests/livepatch/test_modules/test_klp_state.c +++ b/tools/testing/selftests/livepatch/test_modules/test_klp_state.c @@ -142,7 +142,14 @@ static void post_unpatch_callback(struct klp_object *obj) .mod = THIS_MODULE, .objs = objs, .states = states, +#ifdef CONFIG_KLP_HAS_PROVIDES + /* + * TODO: Add provides/obsoletes module parameters for the + * provides/obsoletes based tests (to be added later). + */ +#else .replace = true, +#endif }; static int test_klp_callbacks_demo_init(void) diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_state2.c b/tools/testing/selftests/livepatch/test_modules/test_klp_state2.c index c978ea4..4f70f06 100644 --- a/tools/testing/selftests/livepatch/test_modules/test_klp_state2.c +++ b/tools/testing/selftests/livepatch/test_modules/test_klp_state2.c @@ -171,7 +171,14 @@ static void post_unpatch_callback(struct klp_object *obj) .mod = THIS_MODULE, .objs = objs, .states = states, +#ifdef CONFIG_KLP_HAS_PROVIDES + /* + * TODO: Add provides/obsoletes module parameters for the + * provides/obsoletes based tests (to be added later). + */ +#else .replace = true, +#endif }; static int test_klp_callbacks_demo_init(void) -- 1.8.3.1