On Fri 2026-03-20 17:11:17, Pablo Hugen wrote:
> From: Pablo Alessandro Santos Hugen <[email protected]>
> 
> Add a target module and livepatch pair that verify module function
> patching via a proc entry. Two test cases cover both the
> klp_enable_patch path (target loaded before livepatch) and the
> klp_module_coming path (livepatch loaded before target).

First, thanks for the test.

Second, I am a bit biased because I am working on a patchset which would
obsolete this patch, see
https://lore.kernel.org/all/[email protected]/

That said, I have sent an RFC a year ago. I worked on v1 when time
permitted but it is still not ready. And it might take another
many months or year to finish it.

Your test might be perfectly fine in the meantime. Just see few
notes below.

> --- a/tools/testing/selftests/livepatch/test-livepatch.sh
> +++ b/tools/testing/selftests/livepatch/test-livepatch.sh
> @@ -8,6 +8,8 @@ MOD_LIVEPATCH1=test_klp_livepatch
>  MOD_LIVEPATCH2=test_klp_syscall
>  MOD_LIVEPATCH3=test_klp_callbacks_demo
>  MOD_REPLACE=test_klp_atomic_replace
> +MOD_TARGET=test_klp_mod_target
> +MOD_TARGET_PATCH=test_klp_mod_patch
>  
>  setup_config
>  
> @@ -196,4 +198,102 @@ livepatch: '$MOD_REPLACE': unpatching complete
>  % rmmod $MOD_REPLACE"
>  
>  
> +# - load a target module that provides /proc/test_klp_mod_target with
> +#   original output
> +# - load a livepatch that patches the target module's show function
> +# - verify the proc entry returns livepatched output
> +# - disable and unload the livepatch
> +# - verify the proc entry returns original output again
> +# - unload the target module
> +
> +start_test "module function patching"
> +
> +load_mod $MOD_TARGET
> +
> +if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
> +     echo -e "FAIL\n\n"
> +     die "livepatch kselftest(s) failed"
> +fi

This code is repeated several times. It might be worth creating a
helper function in tools/testing/selftests/livepatch/functions.sh.

> +load_lp $MOD_TARGET_PATCH
> +
> +if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET_PATCH: this has been live 
> patched" ]] ; then
> +     echo -e "FAIL\n\n"
> +     die "livepatch kselftest(s) failed"
> +fi

When I was working on the above mentioned patchset, I realized that
"die" in the middle of the test was not practical because it
did not do any clean up. As a result, "make run_tests"
continued with other tests but they typically failed as well.
And I had to manually remove the test modules to be able to
try "fixed" tests again.

I thought about two solutions:

1. Remember loaded modules and try to remove them in a clean up code.

2. Report the failure into the kernel log but keep the test
   running so that they calls the disable_lp/unload_lp/unload_mod
   functions. The test will do the clean up and will fail
   later in check_result().


While the 1st approach might be easier in the end, I choose
the 2nd approach in my RFC, see below.


> +disable_lp $MOD_TARGET_PATCH
> +unload_lp $MOD_TARGET_PATCH
> +
> +if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
> +     echo -e "FAIL\n\n"
> +     die "livepatch kselftest(s) failed"
> +fi
> +
> +unload_mod $MOD_TARGET
> +
> +check_result "% insmod test_modules/$MOD_TARGET.ko
> +$MOD_TARGET: test_klp_mod_target_init
> +% insmod test_modules/$MOD_TARGET_PATCH.ko

Note that the existing helper functions log the userspace commands
in the kernel log. It helps to understand the kernel logs.

In my RFC, I created a helper module which implemented a person
(speaker) which would come on the stage and welcome the audience.
I am not sure if it was a good idea. But it became a bit confusing
when everything (module name, sysfs interface, function name, message)
included the same strings like (livepatch, callback, shadow_var).

Anyway, my tests produced messages like these:

+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_TARGET: speaker_welcome: Hello, World!

, see https://lore.kernel.org/all/[email protected]/


There were even tests which blocked the transition. They tested shadow
variables which added an applause to the message. They did something like:

<paste>
All four callbacks are used as follows:

  + pre_patch() allocates a shadow variable with a string and fills
                it with "[]".
  + post_patch() fills the string with "[APPLAUSE]".
  + pre_unpatch() reverts the string back to "[]".
  + post_unpatch() releases the shadow variable.

The welcome message printed by the livepatched function allows us to
distinguish between the transition and the completed transition.
Specifically, the speaker's welcome message appears as:

  + Not patched system:          "Hello, World!"
  + Transition (unpatched task): "[] Hello, World!"
  + Transition (patched task):   "[] Ladies and gentlemen, ..."
  + Patched system:              "[APPLAUSE] Ladies and gentlemen, ..."
</paste>

, see https://lore.kernel.org/all/[email protected]/

Sigh, I have done many changes in the tests for v1. But they still
need some love (and rebasing) for sending.

> +livepatch: enabling patch '$MOD_TARGET_PATCH'
> +livepatch: '$MOD_TARGET_PATCH': initializing patching transition
> +livepatch: '$MOD_TARGET_PATCH': starting patching transition
> +livepatch: '$MOD_TARGET_PATCH': completing patching transition
> +livepatch: '$MOD_TARGET_PATCH': patching complete
> +% echo 0 > $SYSFS_KLP_DIR/$MOD_TARGET_PATCH/enabled
> +livepatch: '$MOD_TARGET_PATCH': initializing unpatching transition
> +livepatch: '$MOD_TARGET_PATCH': starting unpatching transition
> +livepatch: '$MOD_TARGET_PATCH': completing unpatching transition
> +livepatch: '$MOD_TARGET_PATCH': unpatching complete
> +% rmmod $MOD_TARGET_PATCH
> +% rmmod $MOD_TARGET
> +$MOD_TARGET: test_klp_mod_target_exit"

Summary:

IMHO, this patch is perfectly fine as is if we accept that it will get
eventually obsoleted by my patchset (hopefully in a year or two).

On the other hand, this patch would deserve some clean up,
(helper functions, don't die in the middle of the test) if
you planned to work on more tests. It would help to maintain
the tests.

Best Regards,
Petr

Reply via email to