public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Petr Mladek <pmladek@suse.com>
To: Josh Poimboeuf <jpoimboe@kernel.org>, Miroslav Benes <mbenes@suse.cz>
Cc: Joe Lawrence <joe.lawrence@redhat.com>,
	Nicolai Stange <nstange@suse.de>,
	live-patching@vger.kernel.org, linux-kernel@vger.kernel.org,
	Petr Mladek <pmladek@suse.com>
Subject: [PATCH v1 09/19] selftests/livepatch: Convert testing of multiple target modules
Date: Wed, 15 Jan 2025 09:24:21 +0100	[thread overview]
Message-ID: <20250115082431.5550-10-pmladek@suse.com> (raw)
In-Reply-To: <20250115082431.5550-1-pmladek@suse.com>

The per-object callbacks have been replaced by per-state callbacks and
will be removed soon.

A selftest previously loaded two livepatched modules to ensure that
the per-object callbacks were called for both.

Although per-state callbacks are only invoked when the live patch is
enabled or disabled, it is still important to verify that multiple objects
can be live-patched.

Convert the test into a generic one by reusing the speaker test module
to create the second target module.

In the second variant, speaker_welcome() will only print "(2)" after
the function name to distinguish it, while keeping the real function name
the same to maintain simplicity.

Signed-off-by: Petr Mladek <pmladek@suse.com>
---
 .../selftests/livepatch/test-callbacks.sh     | 59 ----------------
 .../testing/selftests/livepatch/test-order.sh | 69 +++++++++++++++++++
 .../selftests/livepatch/test_modules/Makefile |  1 +
 .../livepatch/test_modules/test_klp_speaker.c |  8 ++-
 .../test_modules/test_klp_speaker2.c          |  8 +++
 .../test_modules/test_klp_speaker_livepatch.c | 26 ++++++-
 6 files changed, 110 insertions(+), 61 deletions(-)
 create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_speaker2.c

diff --git a/tools/testing/selftests/livepatch/test-callbacks.sh b/tools/testing/selftests/livepatch/test-callbacks.sh
index 614ed0aa2e40..a9bb90920c0a 100755
--- a/tools/testing/selftests/livepatch/test-callbacks.sh
+++ b/tools/testing/selftests/livepatch/test-callbacks.sh
@@ -93,65 +93,6 @@ $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
 livepatch: '$MOD_LIVEPATCH': unpatching complete
 % rmmod $MOD_LIVEPATCH"
 
-
-# Test loading multiple targeted kernel modules.  This test-case is
-# mainly for comparing with the next test-case.
-#
-# - Load a target "busy" kernel module which kicks off a worker function
-#   that immediately exits.
-#
-# - Proceed with loading the livepatch and another ordinary target
-#   module.  Post-patch callbacks are executed and the transition
-#   completes quickly.
-
-start_test "multiple target modules"
-
-load_mod $MOD_TARGET_BUSY block_transition=N
-load_lp $MOD_LIVEPATCH
-load_mod $MOD_TARGET
-unload_mod $MOD_TARGET
-disable_lp $MOD_LIVEPATCH
-unload_lp $MOD_LIVEPATCH
-unload_mod $MOD_TARGET_BUSY
-
-check_result "% insmod test_modules/$MOD_TARGET_BUSY.ko block_transition=N
-$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
-$MOD_TARGET_BUSY: busymod_work_func enter
-$MOD_TARGET_BUSY: busymod_work_func exit
-% insmod test_modules/$MOD_LIVEPATCH.ko
-livepatch: enabling patch '$MOD_LIVEPATCH'
-livepatch: '$MOD_LIVEPATCH': initializing patching transition
-$MOD_LIVEPATCH: pre_patch_callback: vmlinux
-$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': starting patching transition
-livepatch: '$MOD_LIVEPATCH': completing patching transition
-$MOD_LIVEPATCH: post_patch_callback: vmlinux
-$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': patching complete
-% insmod test_modules/$MOD_TARGET.ko
-livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
-$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
-$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
-$MOD_TARGET: ${MOD_TARGET}_init
-% rmmod $MOD_TARGET
-$MOD_TARGET: ${MOD_TARGET}_exit
-$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
-livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
-$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
-% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
-livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
-$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
-$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': starting unpatching transition
-livepatch: '$MOD_LIVEPATCH': completing unpatching transition
-$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
-$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': unpatching complete
-% rmmod $MOD_LIVEPATCH
-% rmmod $MOD_TARGET_BUSY
-$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
-
-
 # A similar test as the previous one, but force the "busy" kernel module
 # to block the livepatch transition.
 #
diff --git a/tools/testing/selftests/livepatch/test-order.sh b/tools/testing/selftests/livepatch/test-order.sh
index 869b06605597..189132b01bac 100755
--- a/tools/testing/selftests/livepatch/test-order.sh
+++ b/tools/testing/selftests/livepatch/test-order.sh
@@ -7,6 +7,7 @@
 
 MOD_LIVEPATCH=test_klp_speaker_livepatch
 MOD_TARGET=test_klp_speaker
+MOD_TARGET2=test_klp_speaker2
 
 setup_config
 
@@ -224,3 +225,71 @@ livepatch: '$MOD_LIVEPATCH': starting unpatching transition
 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
 livepatch: '$MOD_LIVEPATCH': unpatching complete
 % rmmod $MOD_LIVEPATCH"
+
+# Test loading multiple targeted kernel modules.
+#
+# Load the first target module before the livepatch and the second one later.
+# Disable and unload them in the opposite order.
+#
+# The module loader hooks should print a message about applying/reverting
+# the livepatch for the 2nd module when it is being loaded/unloaded.
+#
+# The expected state is double-checked by reading "welcome" parameter
+# of both target modules. The livepatched variant should be printed
+# when both the target and livepatch modules are loaded.
+
+start_test "multiple target modules"
+
+load_mod $MOD_TARGET
+read_module_param $MOD_TARGET welcome
+
+load_lp $MOD_LIVEPATCH
+read_module_param $MOD_TARGET welcome
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "1"
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET2 "0"
+
+load_mod $MOD_TARGET2
+read_module_param $MOD_TARGET2 welcome
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "1"
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET2 "1"
+
+unload_mod $MOD_TARGET2
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "1"
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET2 "0"
+
+disable_lp $MOD_LIVEPATCH
+read_module_param $MOD_TARGET welcome
+
+unload_lp $MOD_LIVEPATCH
+unload_mod $MOD_TARGET
+
+check_result "% insmod test_modules/$MOD_TARGET.ko
+$MOD_TARGET: ${MOD_TARGET}_init
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_TARGET: speaker_welcome: Hello, World!
+% 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
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_LIVEPATCH: lp_speaker_welcome: Ladies and gentleman, ...
+% insmod test_modules/$MOD_TARGET2.ko
+livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET2'
+$MOD_TARGET2: ${MOD_TARGET}_init
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET2/parameters/welcome
+$MOD_LIVEPATCH: lp_speaker2_welcome(2): Ladies and gentleman, ...
+% rmmod $MOD_TARGET2
+$MOD_TARGET2: ${MOD_TARGET}_exit
+livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET2'
+% 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
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_TARGET: speaker_welcome: Hello, World!
+% rmmod $MOD_LIVEPATCH
+% rmmod $MOD_TARGET
+$MOD_TARGET: ${MOD_TARGET}_exit"
diff --git a/tools/testing/selftests/livepatch/test_modules/Makefile b/tools/testing/selftests/livepatch/test_modules/Makefile
index 0978c489a67a..72a817d1ddd9 100644
--- a/tools/testing/selftests/livepatch/test_modules/Makefile
+++ b/tools/testing/selftests/livepatch/test_modules/Makefile
@@ -10,6 +10,7 @@ obj-m += test_klp_atomic_replace.o \
 	test_klp_livepatch.o \
 	test_klp_shadow_vars.o \
 	test_klp_speaker.o \
+	test_klp_speaker2.o \
 	test_klp_speaker_livepatch.o \
 	test_klp_state.o \
 	test_klp_state2.o \
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c
index 22f6e5fcb009..92c577addb8e 100644
--- a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c
@@ -6,6 +6,10 @@
 #include <linux/module.h>
 #include <linux/printk.h>
 
+#ifndef SPEAKER_ID
+#define SPEAKER_ID ""
+#endif
+
 /**
  * test_klp_speaker - test module for testing misc livepatching features
  *
@@ -15,12 +19,14 @@
  *
  *    - Log the greeting by reading the "welcome" module parameter, see
  *	welcome_get().
+ *
+ *    - Reuse the module source for more speakers, see SPEAKER_ID.
  */
 
 noinline
 static void speaker_welcome(void)
 {
-	pr_info("%s: Hello, World!\n", __func__);
+	pr_info("%s%s: Hello, World!\n", __func__, SPEAKER_ID);
 }
 
 static int welcome_get(char *buffer, const struct kernel_param *kp)
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker2.c b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker2.c
new file mode 100644
index 000000000000..d38ab51414bf
--- /dev/null
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker2.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2023 SUSE
+
+/* Use versioned function name for livepatched functions */
+#define SPEAKER_ID "(2)"
+
+/* Same module with the same features. */
+#include "test_klp_speaker.c"
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch.c b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch.c
index 26a8dd15f723..8d7e74a69a5d 100644
--- a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch.c
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch.c
@@ -17,11 +17,23 @@
  *
  *    - Improve the speaker's greeting from "Hello, World!" to
  *	"Ladies and gentleman, ..."
+ *
+ *    - Support more speaker modules, see __lp_speaker_welcome().
  */
 
+static void __lp_speaker_welcome(const char *caller_func, const char *speaker_id)
+{
+	pr_info("%s%s: Ladies and gentleman, ...\n", caller_func, speaker_id);
+}
+
 static void lp_speaker_welcome(void)
 {
-	pr_info("%s: Ladies and gentleman, ...\n", __func__);
+	__lp_speaker_welcome(__func__, "");
+}
+
+static void lp_speaker2_welcome(void)
+{
+	__lp_speaker_welcome(__func__, "(2)");
 }
 
 static struct klp_func test_klp_speaker_funcs[] = {
@@ -32,11 +44,23 @@ static struct klp_func test_klp_speaker_funcs[] = {
 	{ }
 };
 
+static struct klp_func test_klp_speaker2_funcs[] = {
+	{
+		.old_name = "speaker_welcome",
+		.new_func = lp_speaker2_welcome,
+	},
+	{ }
+};
+
 static struct klp_object objs[] = {
 	{
 		.name = "test_klp_speaker",
 		.funcs = test_klp_speaker_funcs,
 	},
+	{
+		.name = "test_klp_speaker2",
+		.funcs = test_klp_speaker2_funcs,
+	},
 	{ }
 };
 
-- 
2.47.1


  parent reply	other threads:[~2025-01-15  8:26 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-15  8:24 [PATCH v1 00/19] livepatch: Better integrate callbacks and shadow variables with the states API Petr Mladek
2025-01-15  8:24 ` [PATCH v1 01/19] livepatch: Add callbacks for introducing and removing states Petr Mladek
2025-01-15  8:24 ` [PATCH v1 02/19] livepatch: Allow to handle lifetime of shadow variables using the livepatch state Petr Mladek
2025-01-15  8:24 ` [PATCH v1 03/19] selftests/livepatch: Use per-state callbacks in state API tests Petr Mladek
2025-01-15  8:24 ` [PATCH v1 04/19] livepatch: Add "block_disable" flag to per-state API and remove versioning Petr Mladek
2025-01-15  8:24 ` [PATCH v1 05/19] livepatch: Remove "data" from struct klp_state Petr Mladek
2025-01-15  8:24 ` [PATCH v1 06/19] selftests/livepatch: Remove callbacks from sysfs interface testing Petr Mladek
2025-01-15  8:24 ` [PATCH v1 07/19] selftests/livepatch: Substitute hard-coded /sys/module path Petr Mladek
2025-01-15  8:24 ` [PATCH v1 08/19] selftests/livepatch: Move basic tests for livepatching modules Petr Mladek
2025-01-15  8:24 ` Petr Mladek [this message]
2025-01-15  8:24 ` [PATCH v1 10/19] selftests/livepatch: Create a simple selftest for state callbacks Petr Mladek
2025-01-15  8:24 ` [PATCH v1 11/19] selftests/livepatch: Convert selftests for failing pre_patch callback Petr Mladek
2025-01-15  8:24 ` [PATCH v1 12/19] selftests/livepatch: Convert selftest with blocked transition Petr Mladek
2025-01-15  8:24 ` [PATCH v1 13/19] selftests/livepatch: Add more tests for state callbacks with blocked transitions Petr Mladek
2025-01-15  8:24 ` [PATCH v1 14/19] selftests/livepatch: Convert selftests for testing callbacks with more livepatches Petr Mladek
2025-01-15  8:24 ` [PATCH v1 15/19] selftests/livepatch: Do not use a livepatch with the obsolete per-object callbacks in the basic selftests Petr Mladek
2025-01-15  8:24 ` [PATCH v1 16/19] selftests/livepatch: Remove obsolete test modules for per-object callbacks Petr Mladek
2025-01-15  8:24 ` [PATCH v1 17/19] samples/livepatch: Replace sample module with obsolete " Petr Mladek
2025-01-15  8:24 ` [PATCH v1 18/19] Documentation/livepatch: Update documentation for state, callbacks, and shadow variables Petr Mladek
2025-03-06 22:54   ` Joe Lawrence
2025-03-07 12:26     ` Petr Mladek
2025-03-07 15:50       ` Joe Lawrence
2025-03-17 11:17         ` Petr Mladek
2025-01-15  8:24 ` [PATCH v1 19/19] livepatch: Remove obsolete per-object callbacks Petr Mladek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250115082431.5550-10-pmladek@suse.com \
    --to=pmladek@suse.com \
    --cc=joe.lawrence@redhat.com \
    --cc=jpoimboe@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    --cc=nstange@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox