* Re: [PATCH 3/4] selftests: livepatch: Adapt mod_target module to pass on 4.12 kernels
From: Petr Mladek @ 2026-06-05 14:39 UTC (permalink / raw)
To: Marcos Paulo de Souza
Cc: sashiko-reviews, Miroslav Benes, Shuah Khan, Josh Poimboeuf,
Joe Lawrence, Jiri Kosina, live-patching, linux-kselftest,
linux-kernel
In-Reply-To: <0f269520407c8cfc554059ffcba45ef3220ecfea.camel@suse.com>
On Fri 2026-06-05 11:05:32, Marcos Paulo de Souza wrote:
> On Mon, 2026-05-25 at 00:24 +0000, sashiko-bot@kernel.org wrote:
> > Thank you for your contribution! Sashiko AI review found 1 potential
> > issue(s) to consider:
> > - [Medium] The `test_klp_mod_target_ops` structure omits the
> > logically required `.set` callback, exposing the kernel to a NULL
> > pointer dereference during module load.
> > --
> >
> > commit 532c1b8c7438f534fd4e3440716ede6cf83efe1c
> > Author: Marcos Paulo de Souza <mpdesouza@suse.com>
> >
> > selftests: livepatch: Adapt mod_target module to pass on 4.12 kernels
> >
> > Use the stable module_param_cb API instead of proc_fs for exposing
> > module
> > state. This approach is compatible with kernel 4.12 and later.
> >
> > > diff --git
> > > a/tools/testing/selftests/livepatch/test_modules/test_klp_mod_targe
> > > t.c
> > > b/tools/testing/selftests/livepatch/test_modules/test_klp_mod_targe
> > > t.c
> > > index 9643984d24022..1382a266825fb 100644
> > > ---
> > > a/tools/testing/selftests/livepatch/test_modules/test_klp_mod_targe
> > > t.c
> > > +++
> > > b/tools/testing/selftests/livepatch/test_modules/test_klp_mod_targe
> > > t.c
> > > @@ -5,31 +5,29 @@
> > [ ... ]
> > > +static const struct kernel_param_ops test_klp_mod_target_ops = {
> > > + .get = test_klp_mod_target_get,
> > > +};
> > > +
> > > +module_param_cb(klp_mod_arg, &test_klp_mod_target_ops, NULL,
> > > 0444);
> >
> > [Severity: Medium]
> > Does this code need a .set callback in the kernel_param_ops
> > structure?
> >
> > When a module parameter is passed during module load, the kernel
> > parses the
> > arguments using parse_args(), which invokes parse_one() in
> > kernel/params.c.
> > Because parse_one() unconditionally executes the .set callback
> > without
> > verifying if it is actually defined, omitting it here leaves the
> > callback
> > implicitly initialized to NULL.
> >
> > Could this lead to a NULL pointer dereference and a kernel panic if
> > someone
> > attempts to set this parameter during module load?
>
> Indeed! I'll send a v2 addressing the missing argument. Thanks Sachiko
> for spotting it :)
It should be perfectly fine to use NULL for the .set() callback.
It can't be called because of the given permissions 0444.
We should teach Sashiko about this ;-)
Best Regards,
Petr
^ permalink raw reply
* Re: [PATCH 3/4] selftests: livepatch: Adapt mod_target module to pass on 4.12 kernels
From: Petr Mladek @ 2026-06-05 14:36 UTC (permalink / raw)
To: Marcos Paulo de Souza
Cc: Josh Poimboeuf, Jiri Kosina, Miroslav Benes, Joe Lawrence,
Shuah Khan, live-patching, linux-kselftest, linux-kernel, marcos
In-Reply-To: <20260524-livepatch-unload-on-fail-v1-3-7465de7f741d@suse.com>
On Sun 2026-05-24 20:50:32, Marcos Paulo de Souza wrote:
> Use the stable module_param_cb API instead of proc_fs for exposing module
> state. This approach is compatible with kernel 4.12 and later. The end
> result is the same: the module has a function that shows a string, which
> is later livepatched to show a different string. The only difference is
> that the file being checked is now a module parameter instead of a
> procfs entry.
>
> --- a/tools/testing/selftests/livepatch/test-livepatch.sh
> +++ b/tools/testing/selftests/livepatch/test-livepatch.sh
> @@ -198,26 +198,25 @@ 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
> +# - load a target module with module_param_cb get data with original output
> +# - load a livepatch that patches the target module's get function
> +# - verify the parameter get function returns the livepatched output
> # - disable and unload the livepatch
> -# - verify the proc entry returns original output again
> +# - verify the parameter get function returns the 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
> +if [[ "$(cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/klp_mod_arg)" != "$MOD_TARGET: original output" ]] ; then
I would personally call the parameter "test" or something simple.
A better descriptive name was needed in the top-level /proc directory
to prevent conflicts. But the module-specific parameter is
checked module-specific directory...
> echo -e "FAIL\n\n"
> die "livepatch kselftest(s) failed"
> fi
>
> --- a/tools/testing/selftests/livepatch/test_modules/test_klp_mod_patch.c
> +++ b/tools/testing/selftests/livepatch/test_modules/test_klp_mod_patch.c
> @@ -8,17 +8,16 @@
> #include <linux/livepatch.h>
> #include <linux/seq_file.h>
>
> -static int livepatch_mod_target_show(struct seq_file *m, void *v)
> +static int livepatch_mod_target_get(char *buffer, const struct kernel_param *kp)
> {
> - seq_printf(m, "%s: %s\n", THIS_MODULE->name,
> - "this has been live patched");
> - return 0;
> + return sprintf(buffer, "%s: %s\n", THIS_MODULE->name,
> + "this has been live patched");
Please, use sysfs_emit() instead of sprintf(). It is a specifically
designed API for sysfs output. It prevents a potential buffer overflow.
It is less important here. But we should show good examples...
> }
>
> static struct klp_func funcs[] = {
> {
> - .old_name = "test_klp_mod_target_show",
> - .new_func = livepatch_mod_target_show,
> + .old_name = "test_klp_mod_target_get",
> + .new_func = livepatch_mod_target_get,
> },
> {},
> };
Otherwise the change looks good to me.
Best Regards,
Petr
^ permalink raw reply
* Re: [PATCH 2/4] selftests: livepatch: Remove leftover modules when a testcase fails
From: Petr Mladek @ 2026-06-05 14:15 UTC (permalink / raw)
To: sashiko-reviews
Cc: Josh Poimboeuf, Joe Lawrence, Jiri Kosina, Miroslav Benes,
Shuah Khan, Marcos Paulo de Souza, linux-kselftest, marcos,
live-patching, linux-kernel
In-Reply-To: <20260525000622.3D4551F000E9@smtp.kernel.org>
On Mon 2026-05-25 00:06:21, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [Medium] The cleanup loop iterates over the TEST_MODS array in forward order, violating dependency requirements and causing rmmod to fail.
> - [Medium] Functions invoked during cleanup call die() on failure, prematurely aborting the EXIT trap and skipping pop_config().
> --
>
> commit aafb48b2a54fe2209742378f31fb96583598557a
> Author: Marcos Paulo de Souza <mpdesouza@suse.com>
>
> selftests: livepatch: Remove leftover modules when a testcase fails
>
> This commit introduces a cleanup mechanism for livepatch selftests that
> tracks loaded modules and attempts to remove them if a test fails or exits
> prematurely. It uses a TEST_MODS array to keep track of dependencies and
> unloads the remaining modules during an EXIT trap.
>
> > diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh
> > index 3ec0b7962fc5c..25f1370038654 100644
> > --- a/tools/testing/selftests/livepatch/functions.sh
> > +++ b/tools/testing/selftests/livepatch/functions.sh
> [ ... ]
> > @@ -125,6 +127,14 @@ function set_ftrace_enabled() {
> > }
> >
> > function cleanup() {
> > + # Remove leftover modules in reverse order to handle dependencies
> > + for mod_item in "${TEST_MODS[@]}"; do
>
> [Severity: Medium]
> Does this loop actually iterate in reverse order?
>
> The comment states the modules will be removed in reverse order to handle
> dependencies, but ${TEST_MODS[@]} expands the array in ascending index
> order.
>
> Because dependent modules (like livepatches) are loaded after their base
> modules, iterating in forward order will attempt to unload the base modules
> first. This would likely cause rmmod to fail with a module in use error.
The ordering should not be important. It does not matter whether the
livepatch or livepatched module is removed first. And only one
livepatch is enabled when atomic replace is used.
I believe that the ordering does not matter even when more livepatches
are enabled and the atomic replace is not used. Anyway, there is
an idea to make the no-replace livepatches trully independent,
see
https://lore.kernel.org/r/20260529034542.68766-1-laoar.shao@gmail.com
I would personally ignore the ordering here.
Best Regards,
Petr
^ permalink raw reply
* Re: [PATCH 3/4] selftests: livepatch: Adapt mod_target module to pass on 4.12 kernels
From: Marcos Paulo de Souza @ 2026-06-05 14:05 UTC (permalink / raw)
To: sashiko-reviews, Miroslav Benes, Shuah Khan, Petr Mladek,
Josh Poimboeuf, Joe Lawrence, Jiri Kosina
Cc: live-patching, linux-kselftest, linux-kernel
In-Reply-To: <20260525002416.3B3A41F000E9@smtp.kernel.org>
On Mon, 2026-05-25 at 00:24 +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential
> issue(s) to consider:
> - [Medium] The `test_klp_mod_target_ops` structure omits the
> logically required `.set` callback, exposing the kernel to a NULL
> pointer dereference during module load.
> --
>
> commit 532c1b8c7438f534fd4e3440716ede6cf83efe1c
> Author: Marcos Paulo de Souza <mpdesouza@suse.com>
>
> selftests: livepatch: Adapt mod_target module to pass on 4.12 kernels
>
> Use the stable module_param_cb API instead of proc_fs for exposing
> module
> state. This approach is compatible with kernel 4.12 and later.
>
> > diff --git
> > a/tools/testing/selftests/livepatch/test_modules/test_klp_mod_targe
> > t.c
> > b/tools/testing/selftests/livepatch/test_modules/test_klp_mod_targe
> > t.c
> > index 9643984d24022..1382a266825fb 100644
> > ---
> > a/tools/testing/selftests/livepatch/test_modules/test_klp_mod_targe
> > t.c
> > +++
> > b/tools/testing/selftests/livepatch/test_modules/test_klp_mod_targe
> > t.c
> > @@ -5,31 +5,29 @@
> [ ... ]
> > +static const struct kernel_param_ops test_klp_mod_target_ops = {
> > + .get = test_klp_mod_target_get,
> > +};
> > +
> > +module_param_cb(klp_mod_arg, &test_klp_mod_target_ops, NULL,
> > 0444);
>
> [Severity: Medium]
> Does this code need a .set callback in the kernel_param_ops
> structure?
>
> When a module parameter is passed during module load, the kernel
> parses the
> arguments using parse_args(), which invokes parse_one() in
> kernel/params.c.
> Because parse_one() unconditionally executes the .set callback
> without
> verifying if it is actually defined, omitting it here leaves the
> callback
> implicitly initialized to NULL.
>
> Could this lead to a NULL pointer dereference and a kernel panic if
> someone
> attempts to set this parameter during module load?
Indeed! I'll send a v2 addressing the missing argument. Thanks Sachiko
for spotting it :)
^ permalink raw reply
* Re: [PATCH 2/4] selftests: livepatch: Remove leftover modules when a testcase fails
From: Petr Mladek @ 2026-06-05 13:59 UTC (permalink / raw)
To: Marcos Paulo de Souza
Cc: Josh Poimboeuf, Jiri Kosina, Miroslav Benes, Joe Lawrence,
Shuah Khan, live-patching, linux-kselftest, linux-kernel, marcos
In-Reply-To: <20260524-livepatch-unload-on-fail-v1-2-7465de7f741d@suse.com>
On Sun 2026-05-24 20:50:31, Marcos Paulo de Souza wrote:
> The current livepatch selftest scripts load modules, run tests and
> unloads them. If the test fails, it can leave loaded modules behind, and
> in some cases making it impossible to run the next tests.
>
> This approach tracks down the loaded modules, and in case of a test
> failure, or premature exit of the script, the cleanup function will
> be called by the trap installed on setup_config function.
>
> The cleanup function iterates over the list of leftover loaded modules,
> unloading them. The function also checks if the given module is a
> livepatch, properly disabling it before unloading.
>
> Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
> ---
> tools/testing/selftests/livepatch/functions.sh | 23 ++++++++++++++++++++++-
> 1 file changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh
> index 3ec0b7962fc5..25f137003865 100644
> --- a/tools/testing/selftests/livepatch/functions.sh
> +++ b/tools/testing/selftests/livepatch/functions.sh
> @@ -15,6 +15,8 @@ if [[ -e /sys/kernel/tracing/trace ]]; then
> else
> SYSFS_TRACING_DIR="$SYSFS_DEBUG_DIR/tracing"
> fi
> +# List of loaded modules used in tests
> +TEST_MODS=()
>
> # Kselftest framework requirement - SKIP code is 4
> ksft_skip=4
> @@ -125,6 +127,14 @@ function set_ftrace_enabled() {
> }
>
> function cleanup() {
> + # Remove leftover modules in reverse order to handle dependencies
> + for mod_item in "${TEST_MODS[@]}"; do
It would make sense to check here that the module is loaded.
I would add a helper function is_mod_loaded which
would check whether /sys/module/$mod exists.
> + if is_livepatch_mod "$mod_item"; then
It might make sense to 1st check here whether the livepatch is
enabled. Again, I would add a helper function for this.
> + disable_lp "$mod_item"
> + fi
> + _remove_mod "$mod_item"
> + done
I would put this into a helper function, for example,
called remove_test_mods().
> +
> pop_config
> }
>
> @@ -181,6 +191,9 @@ function __load_mod() {
> # Wait for module in sysfs ...
> loop_until '[[ -e "/sys/module/$mod" ]]' ||
> die "failed to load module $mod"
> +
> + # Store the module in the modules list
> + TEST_MODS+=("$mod")
I would put this into a helper function, for example,
called track_test_mod().
> }
>
>
> @@ -262,12 +275,20 @@ function _remove_mod() {
> die "failed to unload module $mod (/sys/module)"
> }
>
> -# unload_mod(modname) - unload a kernel module
> +# unload_mod(modname) - unload a kernel module and remove it from TEST_MODS
> # modname - module name to unload
> function unload_mod() {
> local mod="$1"
>
> _remove_mod "$mod"
> +
> + # Remove from TEST_MODS array
> + for i in "${!TEST_MODS[@]}"; do
> + if [[ "${TEST_MODS[$i]}" == "$mod" ]]; then
> + unset 'TEST_MODS[$i]'
> + break
> + fi
> + done
And this into a helper called, for example, untrack_test_mod().
> }
>
> # unload_lp(modname) - unload a kernel module with a livepatch
Best Regards,
Petr
^ permalink raw reply
* Re: [PATCH 1/4] selftests: livepatch: Introduce _remove_mod function
From: Petr Mladek @ 2026-06-05 13:44 UTC (permalink / raw)
To: Marcos Paulo de Souza
Cc: sashiko-reviews, Jiri Kosina, Joe Lawrence, Shuah Khan,
Miroslav Benes, Josh Poimboeuf, linux-kernel, linux-kselftest,
live-patching
In-Reply-To: <d329f22e75fd01f2250490e4cba87f064a726f52.camel@suse.com>
On Mon 2026-05-25 08:49:10, Marcos Paulo de Souza wrote:
> On Sun, 2026-05-24 at 23:59 +0000, sashiko-bot@kernel.org wrote:
> > Thank you for your contribution! Sashiko AI review found 1 potential
> > issue(s) to consider:
> > - [Medium] `_remove_mod` uses `die()` which will terminate the script
> > during cleanup operations.
> > --
> >
> > commit 7b1591f4e5c3b351136e7fe2821eb2e15ae59ad0
> > Author: Marcos Paulo de Souza <mpdesouza@suse.com>
> >
> > selftests: livepatch: Introduce _remove_mod function
> >
> > This commit introduces the _remove_mod internal function to remove a
> > loaded
> > module, intended to be used during cleanup when a testcase fails. It
> > also
> > refactors unload_mod to use this new helper function.
> >
> > > diff --git a/tools/testing/selftests/livepatch/functions.sh
> > > b/tools/testing/selftests/livepatch/functions.sh
> > > index 2bc50271729c6..3ec0b7962fc5c 100644
> > > --- a/tools/testing/selftests/livepatch/functions.sh
> > > +++ b/tools/testing/selftests/livepatch/functions.sh
> >
> > [ ... ]
> >
> > > @@ -241,9 +241,10 @@ function load_failing_mod() {
> > > log "$ret"
> > > }
> > >
> > > -# unload_mod(modname) - unload a kernel module
> > > +# _remove_mod(modname) - Internal function to remove a loaded
> > > module.
> > > +# Use unload_mod() instead, which also
> > > updates TEST_MODS tracking.
> > > # modname - module name to unload
> > > -function unload_mod() {
> > > +function _remove_mod() {
> > > local mod="$1"
> > >
> > > # Wait for module reference count to clear ...
> > > @@ -261,6 +262,14 @@ function unload_mod() {
> > > die "failed to unload module $mod (/sys/module)"
> >
> > [Severity: Medium]
> > The commit message notes this function will be used to remove loaded
> > modules
> > when a testcase fails. If used in a cleanup path (such as a bash EXIT
> > trap),
> > will calling die() here terminate the script prematurely?
> >
> > If a module fails to unload (for example, if its refcount doesn't
> > drop),
> > die() executes exit 1. Inside a trap, this aborts the rest of the
> > cleanup process. This could skip unloading any remaining modules and
> > prevent final cleanup operations like pop_config() from running,
> > potentially
> > leaving kernel tracing persistently enabled and polluting the system
> > state
> > for subsequent tests.
>
> The system is already polluted when a testcase fails nowadays, since a
> module is kept loaded either way, making the next tests to fail if they
> also try to lead the same modules.
>
> The current approach is trying to make it more reliable.
I believe that Sashiko suggested that the clean up path should not
use "die" or "exit" when something fails. It should try to continue
with the next cleanup task.
I remember that we even used the following in rpm post install scripts:
command || true
It is useful when the script does several independent actions
and we would like to process as many of them as possible.
For example, in our case, if one module can't be unloaded
then we might still try to remove other modules and
call pop_config.
So, we should somehow distinguish when some code paths are
called in the script and when in the clean up part.
I would export some variable in the cleanup() function and
check it in the called code paths, for example:
diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh
index 9c98bbb8b725..eebc7f193d98 100644
--- a/tools/testing/selftests/livepatch/functions.sh
+++ b/tools/testing/selftests/livepatch/functions.sh
@@ -62,7 +62,9 @@ function has_kdir() {
function die() {
log "ERROR: $1"
echo "ERROR: $1" >&2
- exit 1
+ if [ -z "$in_klp_cleanup" ] ; then
+ exit 1
+ fi
}
function push_config() {
@@ -128,6 +130,8 @@ function set_ftrace_enabled() {
}
function cleanup() {
+ export in_klp_cleanup=1
+
# Remove leftover modules in reverse order to handle dependencies
for mod_item in "${TEST_MODS[@]}"; do
if is_livepatch_mod "$mod_item"; then
Finally, I think how to split the changes into patches.
I think that the above changes which add "in_klp_cleanup" might be a
separate patch,
But the original 1st patch looked weird. It did split _remove_mod()
and talked about TEST_MODS tracking but the tracking was added in
2nd patch. I would prefer to split the function and add the tracking
in the same patch so that it is obvious why it is split and what
is the difference.
Best Regards,
Petr
^ permalink raw reply related
* Re: [PATCH 4/8] livepatch/klp-build: disable direct-extern-access for LoongArch to fix kernel panic
From: WangYuli @ 2026-06-05 8:53 UTC (permalink / raw)
To: dongtai.guo
Cc: ardb, chenhuacai, guodongtai, jiaxun.yang, jikos, joe.lawrence,
jpoimboe, kernel, linux-kernel, liukexin, live-patching, llvm,
loongarch, mbenes, nathan, nick.desaulniers+lkml, peterz, pmladek,
rostedt, xry111, yangtiezhu
In-Reply-To: <20260604065317.219777-5-dongtai.guo@linux.dev>
Hi Dongtai,
Just set other issues aside for a moment — you define a variable inside one
function and only use it in another function?...
Thanks,
---
WangYuli
^ permalink raw reply
* Re: [PATCH 3/8] LoongArch: Add special section entry sizes for KLP support
From: WangYuli @ 2026-06-05 8:38 UTC (permalink / raw)
To: dongtai.guo
Cc: ardb, chenhuacai, guodongtai, jiaxun.yang, jikos, joe.lawrence,
jpoimboe, kernel, linux-kernel, liukexin, live-patching, llvm,
loongarch, mbenes, nathan, nick.desaulniers+lkml, peterz, pmladek,
rostedt, xry111, yangtiezhu
In-Reply-To: <20260604065317.219777-4-dongtai.guo@linux.dev>
Hi Dongtai,
Have you actually tested your changes with LLVM?
For example:
asm volatile(
".pushsection .altinstructions, \"aM\", @progbits, "
__stringify(ALT_INSTR_SIZE) "\n\t"
".long 0\n\t"
".popsection\n\t"
);
BTW, "awM" is dangerous, pls see how did x86 do.
And head.S doesn't need to include asm-offsets.h, it seems
stackframe.h has included it.
Thanks,
---
WangYuli
^ permalink raw reply
* Re: [PATCH 5/8] LoongArch: fix kernel panic with -fPIC for same-compilation-unit symbol references
From: Xi Ruoyao @ 2026-06-05 8:10 UTC (permalink / raw)
To: George Guo, chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, liukexin,
loongarch, live-patching, llvm, linux-kernel, George Guo
In-Reply-To: <20260604065317.219777-6-dongtai.guo@linux.dev>
On Thu, 2026-06-04 at 14:53 +0800, George Guo wrote:
> From: George Guo <guodongtai@kylinos.cn>
>
> Add architecture-specific -fPIC compiler flag for LoongArch64 to prevent
> kernel panics when applying livepatches containing references to symbols
> defined in the same compilation unit.
>
> Root cause:
> In the KLP workflow, when a function is livepatched, it's extracted
> from the original object file and compiled into a separate kernel
> module. When the patched function references symbols defined in the
> same compilation unit (like 'uts_sem' in kernel/sys.c), these
> references break if not compiled as position-independent code.
>
> On LoongArch64, without -fPIC, references to same-compilation-unit symbols
> use absolute addressing that assumes fixed memory locations. When the
> function is relocated into the livepatch module, these absolute addresses
> become invalid, causing kernel panics.
This is incorrect.
With GCC and Clang, -fPIC does not mean generating position independent
code. It means generating position independent code *suitable for SVR4-
style shared objects*.
The kernel has nothing to do with SVR4-style shared objects. The kernel
modules are not SVR4 shared objects but relocatable ELF object files.
If you only need position independent code (without the shared object
stuff) you should use -fPIE instead. The kernel is already built with -
fPIE if CONFIG_RELOCATABLE=y.
Thus if you only need position independent code you should make live
patching depend on CONFIG_RELOCATABLE. On the contrary if you really
need to use/abuse something mechanism designed for SVR4 shared object
you 'd at least need to fix the description above.
--
Xi Ruoyao <xry111@xry111.site>
^ permalink raw reply
* Re: [PATCH 0/8] LoongArch: Add livepatch build (KLP) support
From: WangYuli @ 2026-06-05 7:57 UTC (permalink / raw)
To: dongtai.guo
Cc: ardb, chenhuacai, guodongtai, jiaxun.yang, jikos, joe.lawrence,
jpoimboe, kernel, linux-kernel, liukexin, live-patching, llvm,
loongarch, mbenes, nathan, nick.desaulniers+lkml, peterz, pmladek,
rostedt, xry111, yangtiezhu
In-Reply-To: <20260604065317.219777-1-dongtai.guo@linux.dev>
Hi Dongtai,
Patches 1 and 2 should be merged into a single patch and placed at the end of
your patch series rather than at the beginning.
Alternatively, you could simply use patch [1] to replace these two patches, which
might make more sense chronologically.
[1]. https://lore.kernel.org/all/20251203091039.125259-1-wangyuli@aosc.io/
Thanks,
---
WangYuli
^ permalink raw reply
* Re: [PATCH v2] selftests/livepatch: fix resource leak in test_klp_syscall init error path
From: Miroslav Benes @ 2026-06-05 6:51 UTC (permalink / raw)
To: Rui Qi
Cc: mbenes, jpoimboe, jikos, pmladek, joe.lawrence, shuah,
live-patching, linux-kselftest, linux-kernel
In-Reply-To: <20260604083208.1071428-1-qirui.001@bytedance.com>
On 2026-06-04 16:32 +0800, Rui Qi wrote:
> In livepatch_init(), if klp_enable_patch() fails, the previously
> created kobject and sysfs file are never cleaned up, causing a
> resource leak. Capture the return value and add proper cleanup
> on the error path.
>
> Signed-off-by: Rui Qi <qirui.001@bytedance.com>
Acked-by: Miroslav Benes <mbenes@suse.cz>
^ permalink raw reply
* Re: [PATCH v3] killswitch: add per-function short-circuit mitigation primitive
From: Justin Suess @ 2026-06-04 21:18 UTC (permalink / raw)
To: Sasha Levin
Cc: Song Liu, linux-kernel, linux-doc, linux-kselftest, bpf,
live-patching, Greg Kroah-Hartman, Andrew Morton, Jonathan Corbet,
Mathieu Desnoyers, Joshua Peisach, Florian Weimer, Breno Leitao,
Anthony Iliopoulos, Michal Hocko, Jiri Olsa
In-Reply-To: <agsVDqdALBoHEHlv@laps>
On Mon, May 18, 2026 at 09:33:02AM -0400, Sasha Levin wrote:
> On Sun, May 17, 2026 at 11:37:36PM -0700, Song Liu wrote:
> > On Sun, May 17, 2026 at 6:49 AM Sasha Levin <sashal@kernel.org> wrote:
> > > * fail_function (CONFIG_FUNCTION_ERROR_INJECTION) is disabled in
> > > most production kernels. Even where enabled, it only works on
> > > functions pre-annotated with ALLOW_ERROR_INJECTION() in source -
> > > no help for a freshly-disclosed CVE. The debugfs UI is blocked by
> > > lockdown=integrity and the override is probabilistic.
> > >
> > > * BPF override (bpf_override_return) honors the same
> > > ALLOW_ERROR_INJECTION() whitelist, and BPF itself is off in many
> > > production kernels. Even where on, the operator interface is
> > > "load a verified BPF program," not a one-line write.
> >
> > If it is OK for killswitch to attach to any kernel functions, do we still
> > need ALLOW_ERROR_INJECTION() for fail_function and BPF
> > override? Shall we instead also allow fail_function and BPF override
> > to attach to any kernel functions?
>
> I don't think so. ALLOW_ERROR_INJECTION is not a security mechanism, it's an
> integrity/safety mechanism for both bpf and fault injection.
>
> It protects against a "developer or CI script doing legitimate fault injection
> accidentally panics the box" scenario, not an "attacker gets in" one.
>
At that point why not just make this entire killswitch mechanism an expanded
version of the bpf_override_return helper that doesn't care about ALLOW_ERROR_INJECTION?
Then killswitch mitigations are just BPF programs.
This could be paired with a userspace tool for building and
loading the killswitch programs conveniently.
You can make the helper function only succeed if (CONFIG_KILLSWITCH=y
CONFIG_BPF_KPROBE_OVERRIDE=y etc.) and taint the kernel on the first call.
BPF has the crash_kexec kfunc already that can take down the kernel.
Thus it's not crazy in my opinion to add a helper with a similar intentional
intentional footgun in another kfunc/helper.
We can automatically benefit from BPF signing mechanisms to prevent
unauthorized loading of programs. If killswitch is enabled, users can
restrict unauthorized use of it by restricting the loading of all BPF
programs to those signed w/ the key.
Thanks,
Justin
> --
> Thanks,
> Sasha
^ permalink raw reply
* Re: [PATCH v2] selftests/livepatch: fix resource leak in test_klp_syscall init error path
From: Petr Mladek @ 2026-06-04 13:12 UTC (permalink / raw)
To: Rui Qi
Cc: mbenes, jpoimboe, jikos, joe.lawrence, shuah, live-patching,
linux-kselftest, linux-kernel
In-Reply-To: <20260604083208.1071428-1-qirui.001@bytedance.com>
On Thu 2026-06-04 16:32:08, Rui Qi wrote:
> In livepatch_init(), if klp_enable_patch() fails, the previously
> created kobject and sysfs file are never cleaned up, causing a
> resource leak. Capture the return value and add proper cleanup
> on the error path.
>
> Signed-off-by: Rui Qi <qirui.001@bytedance.com>
The patch looks good to me. I would ignore the proble reported by
Sashiko. so:
Reviewed-by: Petr Mladek <pmladek@suse.com>
Best Regards,
Petr
PS: I am going to push this patch early next week if nobody complained
in the meantime.
^ permalink raw reply
* Re: [PATCH v2] selftests/livepatch: fix resource leak in test_klp_syscall init error path
From: Petr Mladek @ 2026-06-04 13:09 UTC (permalink / raw)
To: sashiko-reviews
Cc: mbenes, live-patching, jpoimboe, Rui Qi, joe.lawrence,
linux-kernel, linux-kselftest, jikos, shuah
In-Reply-To: <20260604084214.4F9751F00893@smtp.kernel.org>
On Thu 2026-06-04 08:42:13, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] Relying exclusively on kobject_put() to clean up sysfs attributes backed by module memory introduces a use-after-free window during module unload if CONFIG_DEBUG_KOBJECT_RELEASE is enabled.
> --
>
> commit 89541aa9ecd8e356eaf4884fa2b111bc605a7933
> Author: Rui Qi <qirui.001@bytedance.com>
>
> selftests/livepatch: fix resource leak in test_klp_syscall init error path
>
> This commit attempts to fix a resource leak in livepatch_init() by calling
> kobject_put() on the error path if klp_enable_patch() fails.
>
> > --- a/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
> > +++ b/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
> [ ... ]
> > @@ -98,7 +98,11 @@ static int livepatch_init(void)
> > */
> > npids = npids_pending;
> >
> > - return klp_enable_patch(&patch);
> > + ret = klp_enable_patch(&patch);
> > + if (ret)
> > + kobject_put(klp_kobj);
>
> [Severity: High]
> This isn't a bug introduced by this patch, but it replicates a pre-existing
> issue into the error path.
>
> Does relying exclusively on kobject_put() here create a use-after-free window
> during module unload?
Sigh, I always get lost when looking at kobject-related API.
> If CONFIG_DEBUG_KOBJECT_RELEASE is enabled, kobject_put() drops the refcount
> but schedules kobject_cleanup() (and thus sysfs_remove_dir()) to run
> asynchronously via a workqueue after a 1 to 4 second delay. Because klp_attr
> and its show callback are allocated in the module's memory, returning an error
> here causes the module loader to free that memory immediately.
>
> During this delay, the sysfs file remains fully accessible. If a user reads
> this file, would sysfs_kf_seq_show() dereference the attribute and callback
> that now point to unmapped module memory?
This sounds correct.
> Should kobject_del(klp_kobj) be called prior to kobject_put() to
> synchronously remove the sysfs entries?
I am not sure if this would be a complete solution. I do not see
anywhere that kobject_del() would be synchronous. I think that
the file still might stay opened.
> > +
> > + return ret;
> > }
> >
> > static void livepatch_exit(void)
> > {
> > kobject_put(klp_kobj);
> > }
>
> [Severity: High]
> This is a pre-existing issue, but the exact same vulnerability exists here in
> the unmodified module exit path where kobject_put() is the only cleanup
> mechanism before the module unloads.
>
> Could we also add kobject_del(klp_kobj) before kobject_put() in
> livepatch_exit() to ensure sysfs entries are synchronously removed before
> module memory is freed?
I would ignore this. The same code (just kobject_put()) is used in
samples/kobject/kobject-example.c which is supposed to show how
the API should be used.
It is just a test module. The interface is used only by the selftest.
I believe that this is a problem of the kobject API and should
be fixed there.
Best Regards,
Petr
^ permalink raw reply
* Re: [PATCH v2] selftests/livepatch: fix resource leak in test_klp_syscall init error path
From: sashiko-bot @ 2026-06-04 8:42 UTC (permalink / raw)
To: mbenes
Cc: live-patching, jpoimboe, Rui Qi, joe.lawrence, pmladek,
linux-kernel, linux-kselftest, jikos, shuah
In-Reply-To: <20260604083208.1071428-1-qirui.001@bytedance.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Relying exclusively on kobject_put() to clean up sysfs attributes backed by module memory introduces a use-after-free window during module unload if CONFIG_DEBUG_KOBJECT_RELEASE is enabled.
--
commit 89541aa9ecd8e356eaf4884fa2b111bc605a7933
Author: Rui Qi <qirui.001@bytedance.com>
selftests/livepatch: fix resource leak in test_klp_syscall init error path
This commit attempts to fix a resource leak in livepatch_init() by calling
kobject_put() on the error path if klp_enable_patch() fails.
> --- a/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
> +++ b/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
[ ... ]
> @@ -98,7 +98,11 @@ static int livepatch_init(void)
> */
> npids = npids_pending;
>
> - return klp_enable_patch(&patch);
> + ret = klp_enable_patch(&patch);
> + if (ret)
> + kobject_put(klp_kobj);
[Severity: High]
This isn't a bug introduced by this patch, but it replicates a pre-existing
issue into the error path.
Does relying exclusively on kobject_put() here create a use-after-free window
during module unload?
If CONFIG_DEBUG_KOBJECT_RELEASE is enabled, kobject_put() drops the refcount
but schedules kobject_cleanup() (and thus sysfs_remove_dir()) to run
asynchronously via a workqueue after a 1 to 4 second delay. Because klp_attr
and its show callback are allocated in the module's memory, returning an error
here causes the module loader to free that memory immediately.
During this delay, the sysfs file remains fully accessible. If a user reads
this file, would sysfs_kf_seq_show() dereference the attribute and callback
that now point to unmapped module memory?
Should kobject_del(klp_kobj) be called prior to kobject_put() to
synchronously remove the sysfs entries?
> +
> + return ret;
> }
>
> static void livepatch_exit(void)
> {
> kobject_put(klp_kobj);
> }
[Severity: High]
This is a pre-existing issue, but the exact same vulnerability exists here in
the unmodified module exit path where kobject_put() is the only cleanup
mechanism before the module unloads.
Could we also add kobject_del(klp_kobj) before kobject_put() in
livepatch_exit() to ensure sysfs entries are synchronously removed before
module memory is freed?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260604083208.1071428-1-qirui.001@bytedance.com?part=1
^ permalink raw reply
* [PATCH v2] selftests/livepatch: fix resource leak in test_klp_syscall init error path
From: Rui Qi @ 2026-06-04 8:32 UTC (permalink / raw)
To: mbenes
Cc: jpoimboe, jikos, pmladek, joe.lawrence, shuah, live-patching,
linux-kselftest, linux-kernel, Rui Qi
In-Reply-To: <20260602124509.365996-1-qirui.001@bytedance.com>
In livepatch_init(), if klp_enable_patch() fails, the previously
created kobject and sysfs file are never cleaned up, causing a
resource leak. Capture the return value and add proper cleanup
on the error path.
Signed-off-by: Rui Qi <qirui.001@bytedance.com>
---
Changes in v2:
- Remove sysfs_remove_file() from the error path as suggested by
Miroslav Benes. kobject_put() alone is sufficient because it
eventually calls kobject_cleanup() -> __kobject_del() ->
sysfs_remove_dir(), which removes the entire directory including
all files created under it.
.../selftests/livepatch/test_modules/test_klp_syscall.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c b/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
index 0630ffd9d9a1..08aacc0e14de 100644
--- a/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
@@ -109,7 +109,11 @@ static int livepatch_init(void)
*/
npids = npids_pending;
- return klp_enable_patch(&patch);
+ ret = klp_enable_patch(&patch);
+ if (ret)
+ kobject_put(klp_kobj);
+
+ return ret;
}
static void livepatch_exit(void)
--
2.20.1
^ permalink raw reply related
* Re: [PATCH] selftests/livepatch: fix resource leak in test_klp_syscall init error path
From: Rui Qi @ 2026-06-04 8:10 UTC (permalink / raw)
To: Miroslav Benes
Cc: jpoimboe, jikos, pmladek, joe.lawrence, shuah, live-patching,
linux-kselftest, linux-kernel
In-Reply-To: <178049217756.69035.11980890855635035855.b4-review@b4>
On 6/3/26 9:09 PM, Miroslav Benes wrote:
> On Tue, 02 Jun 2026 20:45:09 +0800, Rui Qi <qirui.001@bytedance.com> wrote:
>> diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c b/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
>> index 0630ffd9d9a1..d631acae48b9 100644
>> --- a/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
>> +++ b/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
>> @@ -109,7 +109,12 @@ static int livepatch_init(void)
>> */
>> npids = npids_pending;
>>
>> - return klp_enable_patch(&patch);
>> + ret = klp_enable_patch(&patch);
>> + if (ret) {
>> + sysfs_remove_file(klp_kobj, &klp_attr.attr);
>> + kobject_put(klp_kobj);
>> + }
>> + return ret;
>
> Is sysfs_remove_file() needed? I think that kobject_put() should remove
> it automatically since the object is bound to sysfs.
>
You are right, the sysfs_remove_file() call is redundant. When
kobject_put() drops the refcount to zero, kobject_cleanup() is
invoked, which calls __kobject_del() -> sysfs_remove_dir(). The
latter removes the entire kobject directory including all files
created under it via sysfs_create_file(). This is also consistent
with the livepatch_exit() cleanup path, which only calls
kobject_put() without an explicit sysfs_remove_file().
I will send v2 with sysfs_remove_file() removed.
Thank you for the review.
^ permalink raw reply
* [PATCH 8/8] klp-build: Add LoongArch syscall patching macro
From: George Guo @ 2026-06-04 6:53 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, xry111, liukexin,
loongarch, live-patching, llvm, linux-kernel, George Guo
In-Reply-To: <20260604065317.219777-1-dongtai.guo@linux.dev>
From: George Guo <guodongtai@kylinos.cn>
Add LoongArch support for KLP_SYSCALL_DEFINEx(), mirroring the generic
__SYSCALL_DEFINEx() pattern from include/linux/syscalls.h.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
include/linux/livepatch_helpers.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/include/linux/livepatch_helpers.h b/include/linux/livepatch_helpers.h
index 4b647b83865f..a8aad067177b 100644
--- a/include/linux/livepatch_helpers.h
+++ b/include/linux/livepatch_helpers.h
@@ -91,6 +91,28 @@
} \
static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
+#elif defined(CONFIG_LOONGARCH)
+
+#define __KLP_SYSCALL_DEFINEx(x, name, ...) \
+ __diag_push(); \
+ __diag_ignore(GCC, 8, "-Wattribute-alias", \
+ "Type aliasing is used to sanitize syscall arguments");\
+ asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
+ __attribute__((alias(__stringify(__se_sys##name)))); \
+ ALLOW_ERROR_INJECTION(sys##name, ERRNO); \
+ static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
+ asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
+ asmlinkage long __attribute__((optimize("-fno-optimize-sibling-calls")))\
+ __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
+ { \
+ long ret = __klp_do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\
+ __MAP(x,__SC_TEST,__VA_ARGS__); \
+ __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
+ return ret; \
+ } \
+ __diag_pop(); \
+ static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
+
#endif
#endif /* _LINUX_LIVEPATCH_HELPERS_H */
--
2.25.1
^ permalink raw reply related
* [PATCH 7/8] objtool/klp: Add LoongArch jump opcode bytes support
From: George Guo @ 2026-06-04 6:53 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, xry111, liukexin,
loongarch, live-patching, llvm, linux-kernel, George Guo
In-Reply-To: <20260604065317.219777-1-dongtai.guo@linux.dev>
From: George Guo <guodongtai@kylinos.cn>
Implement arch_jump_opcode_bytes() for LoongArch so that klp checksums
for jump/call instructions with non-relocated destination offsets are
position-independent, mirroring the x86 and arm64 implementations.
Mask out the embedded branch offset while preserving the opcode and the
register operands, which differ per instruction format:
- B/BL (reg0i26): no regs -> 0xfc000000
- BEQZ/BNEZ/BCEQZ/BCNEZ (reg1i21): keep rj/cj -> 0xfc0003e0
- JIRL/BEQ/BNE/.../BGEU (reg2i16): keep rj/rd -> 0xfc0003ff
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
tools/objtool/arch/loongarch/decode.c | 41 +++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loongarch/decode.c
index 674e4efd138f..12facd0cc8d1 100644
--- a/tools/objtool/arch/loongarch/decode.c
+++ b/tools/objtool/arch/loongarch/decode.c
@@ -432,6 +432,47 @@ unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *tabl
}
}
+size_t arch_jump_opcode_bytes(struct objtool_file *file, struct instruction *insn,
+ unsigned char *buf)
+{
+ union loongarch_instruction *code;
+ u32 insn_word;
+
+ insn_word = le32toh(*(u32 *)(insn->sec->data->d_buf + insn->offset));
+ code = (union loongarch_instruction *)&insn_word;
+
+ switch (code->reg0i26_format.opcode) {
+ case b_op:
+ case bl_op:
+ /* reg0i26: 26-bit offset, no register operands */
+ insn_word &= 0xfc000000;
+ break;
+ case beqz_op:
+ case bnez_op:
+ case bceqz_op: /* == bcnez_op */
+ /* reg1i21: keep opcode + rj/cj at bits[9:5] */
+ insn_word &= 0xfc0003e0;
+ break;
+ case jirl_op:
+ case beq_op:
+ case bne_op:
+ case blt_op:
+ case bge_op:
+ case bltu_op:
+ case bgeu_op:
+ /* reg2i16: keep opcode + rj/rd at bits[9:0] */
+ insn_word &= 0xfc0003ff;
+ break;
+ default:
+ break;
+ }
+
+ insn_word = htole32(insn_word);
+ memcpy(buf, &insn_word, sizeof(insn_word));
+
+ return LOONGARCH_INSN_SIZE;
+}
+
#ifdef DISAS
int arch_disas_info_init(struct disassemble_info *dinfo)
--
2.25.1
^ permalink raw reply related
* [PATCH 6/8] LoongArch: Fix EFI linking with -fdata-sections
From: George Guo @ 2026-06-04 6:53 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, xry111, liukexin,
loongarch, live-patching, llvm, linux-kernel, George Guo
In-Reply-To: <20260604065317.219777-1-dongtai.guo@linux.dev>
From: George Guo <guodongtai@kylinos.cn>
When building with func-fdata-sections, the .init.bss section gets split
up into a bunch of .init.bss.<var> sections. Make sure they get linked
into .init.data.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
arch/loongarch/kernel/vmlinux.lds.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S
index 840d944c2f73..dc5fa017db94 100644
--- a/arch/loongarch/kernel/vmlinux.lds.S
+++ b/arch/loongarch/kernel/vmlinux.lds.S
@@ -96,7 +96,7 @@ SECTIONS
#endif
.init.bss : {
- *(.init.bss)
+ *(.init.bss .init.bss.*)
}
. = ALIGN(PECOFF_SEGMENT_ALIGN);
__initdata_end = .;
--
2.25.1
^ permalink raw reply related
* [PATCH 5/8] LoongArch: fix kernel panic with -fPIC for same-compilation-unit symbol references
From: George Guo @ 2026-06-04 6:53 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, xry111, liukexin,
loongarch, live-patching, llvm, linux-kernel, George Guo
In-Reply-To: <20260604065317.219777-1-dongtai.guo@linux.dev>
From: George Guo <guodongtai@kylinos.cn>
Add architecture-specific -fPIC compiler flag for LoongArch64 to prevent
kernel panics when applying livepatches containing references to symbols
defined in the same compilation unit.
Root cause:
In the KLP workflow, when a function is livepatched, it's extracted
from the original object file and compiled into a separate kernel
module. When the patched function references symbols defined in the
same compilation unit (like 'uts_sem' in kernel/sys.c), these
references break if not compiled as position-independent code.
On LoongArch64, without -fPIC, references to same-compilation-unit symbols
use absolute addressing that assumes fixed memory locations. When the
function is relocated into the livepatch module, these absolute addresses
become invalid, causing kernel panics.
Example failure case:
- SYSCALL_DEFINE1(newuname) references the same-compilation-unit
symbol 'uts_sem'
- When kpatch extracts this function into a module, the reference to
'uts_sem' must be properly relocated
- Without -fPIC, the absolute address reference causes invalid memory
access and kernel panic
Solution:
Force -fPIC compilation for all LoongArch64 KLP builds. This ensures
that references to same-compilation-unit symbols use position-independent
addressing, allowing proper relocation by the kernel module loader and
preventing kernel panics in livepatch scenarios.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
scripts/livepatch/klp-build | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 529437d75346..83a43e0df3b9 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -543,8 +543,10 @@ fix_patches() {
clean_kernel() {
local cmd=()
local ARCH_KBUILD_CFLAGS_KERNEL=""
+ local ARCH_KCFLAGS=""
if [[ -v CONFIG_LOONGARCH && "$CONFIG_LOONGARCH" == "y" ]]; then
+ ARCH_KCFLAGS="-fPIC"
if [[ -n "$CONFIG_CC_IS_CLANG" ]]; then
ARCH_KBUILD_CFLAGS_KERNEL="-fno-direct-access-external-data"
else
@@ -592,7 +594,7 @@ build_kernel() {
cmd+=("-s")
fi
cmd+=("-j$JOBS")
- cmd+=("KCFLAGS=-ffunction-sections -fdata-sections")
+ cmd+=("KCFLAGS=-ffunction-sections -fdata-sections $ARCH_KCFLAGS")
cmd+=("KBUILD_CFLAGS_KERNEL=$ARCH_KBUILD_CFLAGS_KERNEL")
cmd+=("vmlinux")
cmd+=("modules")
--
2.25.1
^ permalink raw reply related
* [PATCH 4/8] livepatch/klp-build: disable direct-extern-access for LoongArch to fix kernel panic
From: George Guo @ 2026-06-04 6:53 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, xry111, liukexin,
loongarch, live-patching, llvm, linux-kernel, George Guo
In-Reply-To: <20260604065317.219777-1-dongtai.guo@linux.dev>
From: George Guo <guodongtai@kylinos.cn>
On LoongArch systems, livepatch modules containing references to
EXTERNAL global variables trigger kernel panics when the core kernel is
built with the -mdirect-extern-access optimization.
Root cause:
The -mdirect-extern-access optimization replaces GOT-based external
symbol access with direct addressing for improved performance. However,
this breaks the kernel module loading mechanism, which relies on GOT
entries for proper relocation of EXTERNAL symbol references. Direct
access to global variables from livepatch modules causes invalid memory
accesses and kernel panics.
Solution:
For LoongArch klp builds, conditionally disable direct-extern-access by
adding:
- -mno-direct-extern-access for GCC builds
- -fno-direct-access-external-data for Clang builds
See also commit 38b10b269d04 ("LoongArch: Tweak CFLAGS for Clang
compatibility"), which added -mdirect-extern-access to the kernel as a
nice-to-have optimization that reduces GOT accesses.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
scripts/livepatch/klp-build | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index e83973567c87..529437d75346 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -542,6 +542,17 @@ fix_patches() {
clean_kernel() {
local cmd=()
+ local ARCH_KBUILD_CFLAGS_KERNEL=""
+
+ if [[ -v CONFIG_LOONGARCH && "$CONFIG_LOONGARCH" == "y" ]]; then
+ if [[ -n "$CONFIG_CC_IS_CLANG" ]]; then
+ ARCH_KBUILD_CFLAGS_KERNEL="-fno-direct-access-external-data"
+ else
+ ARCH_KBUILD_CFLAGS_KERNEL="-mno-direct-extern-access"
+ fi
+
+ status "LoongArch detected: adding $ARCH_KBUILD_CFLAGS_KERNEL to KBUILD_CFLAGS_KERNEL"
+ fi
cmd=("make")
cmd+=("--silent")
@@ -582,6 +593,7 @@ build_kernel() {
fi
cmd+=("-j$JOBS")
cmd+=("KCFLAGS=-ffunction-sections -fdata-sections")
+ cmd+=("KBUILD_CFLAGS_KERNEL=$ARCH_KBUILD_CFLAGS_KERNEL")
cmd+=("vmlinux")
cmd+=("modules")
--
2.25.1
^ permalink raw reply related
* [PATCH 3/8] LoongArch: Add special section entry sizes for KLP support
From: George Guo @ 2026-06-04 6:53 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, xry111, liukexin,
loongarch, live-patching, llvm, linux-kernel, George Guo
In-Reply-To: <20260604065317.219777-1-dongtai.guo@linux.dev>
From: George Guo <guodongtai@kylinos.cn>
Define entry sizes for .altinstructions, __ex_table, __bug_table, and
__jump_table sections to enable objtool to process livepatch modules
on LoongArch.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
arch/loongarch/include/asm/alternative-asm.h | 5 +--
arch/loongarch/include/asm/alternative.h | 6 ++--
arch/loongarch/include/asm/asm-extable.h | 10 ++++--
arch/loongarch/include/asm/bug.h | 15 +++++++-
arch/loongarch/include/asm/jump_label.h | 9 ++++-
arch/loongarch/kernel/asm-offsets.c | 36 ++++++++++++++++++++
arch/loongarch/kernel/head.S | 1 +
7 files changed, 74 insertions(+), 8 deletions(-)
diff --git a/arch/loongarch/include/asm/alternative-asm.h b/arch/loongarch/include/asm/alternative-asm.h
index 7dc29bd9b2f0..d940d9d2c0e1 100644
--- a/arch/loongarch/include/asm/alternative-asm.h
+++ b/arch/loongarch/include/asm/alternative-asm.h
@@ -5,6 +5,7 @@
#ifdef __ASSEMBLER__
#include <asm/asm.h>
+#include <generated/asm-offsets.h>
/*
* Issue one struct alt_instr descriptor entry (need to put it into
@@ -33,7 +34,7 @@
.fill - (((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)) / 4, 4, 0x03400000
142 :
- .pushsection .altinstructions, "a"
+ .pushsection .altinstructions, "aM", @progbits, ALT_INSTR_SIZE
altinstruction_entry 140b, 143f, \feature, 142b-140b, 144f-143f
.popsection
@@ -63,7 +64,7 @@
(alt_max_short(new_len1, new_len2) - (old_len)) / 4, 4, 0x03400000
142 :
- .pushsection .altinstructions, "a"
+ .pushsection .altinstructions, "aM", @progbits, ALT_INSTR_SIZE
altinstruction_entry 140b, 143f, \feature1, 142b-140b, 144f-143f, 142b-141b
altinstruction_entry 140b, 144f, \feature2, 142b-140b, 145f-144f, 142b-141b
.popsection
diff --git a/arch/loongarch/include/asm/alternative.h b/arch/loongarch/include/asm/alternative.h
index b5bae21fb3c8..8f7712ed2f4e 100644
--- a/arch/loongarch/include/asm/alternative.h
+++ b/arch/loongarch/include/asm/alternative.h
@@ -70,7 +70,8 @@ extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
/* alternative assembly primitive: */
#define ALTERNATIVE(oldinstr, newinstr, feature) \
OLDINSTR(oldinstr, 1) \
- ".pushsection .altinstructions,\"a\"\n" \
+ ".pushsection .altinstructions, \"aM\", @progbits, " \
+ __stringify(ALT_INSTR_SIZE) "\n" \
ALTINSTR_ENTRY(feature, 1) \
".popsection\n" \
".subsection 1\n" \
@@ -79,7 +80,8 @@ extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
#define ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2)\
OLDINSTR_2(oldinstr, 1, 2) \
- ".pushsection .altinstructions,\"a\"\n" \
+ ".pushsection .altinstructions, \"aM\", @progbits, " \
+ __stringify(ALT_INSTR_SIZE) "\n" \
ALTINSTR_ENTRY(feature1, 1) \
ALTINSTR_ENTRY(feature2, 2) \
".popsection\n" \
diff --git a/arch/loongarch/include/asm/asm-extable.h b/arch/loongarch/include/asm/asm-extable.h
index d60bdf2e6377..2d7eef7c0b39 100644
--- a/arch/loongarch/include/asm/asm-extable.h
+++ b/arch/loongarch/include/asm/asm-extable.h
@@ -7,10 +7,15 @@
#define EX_TYPE_UACCESS_ERR_ZERO 2
#define EX_TYPE_BPF 3
+#ifndef COMPILE_OFFSETS
+#include <asm/asm-offsets.h>
+#endif
+
#ifdef __ASSEMBLER__
#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
- .pushsection __ex_table, "a"; \
+ .pushsection __ex_table, "aM", @progbits, \
+ EXTABLE_SIZE; \
.balign 4; \
.long ((insn) - .); \
.long ((fixup) - .); \
@@ -29,7 +34,8 @@
#include <asm/gpr-num.h>
#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
- ".pushsection __ex_table, \"a\"\n" \
+ ".pushsection __ex_table, \"aM\", @progbits, "\
+ __stringify(EXTABLE_SIZE) "\n" \
".balign 4\n" \
".long ((" insn ") - .)\n" \
".long ((" fixup ") - .)\n" \
diff --git a/arch/loongarch/include/asm/bug.h b/arch/loongarch/include/asm/bug.h
index d090a5bec5eb..c067c858b918 100644
--- a/arch/loongarch/include/asm/bug.h
+++ b/arch/loongarch/include/asm/bug.h
@@ -22,8 +22,20 @@
#ifndef CONFIG_GENERIC_BUG
#define __BUG_ENTRY(cond_str, flags)
#else
+
+#ifdef COMPILE_OFFSETS
+#define __BUG_ENTRY(cond_str, flags) \
+ .pushsection __bug_table, "awM", @progbits, 0; \
+ .align 2; \
+ 10000: .long 10001f - .; \
+ _BUGVERBOSE_LOCATION(WARN_CONDITION_STR(cond_str) __FILE__, __LINE__) \
+ .short flags; \
+ .popsection; \
+ 10001:
+#else
+#include <generated/asm-offsets.h>
#define __BUG_ENTRY(cond_str, flags) \
- .pushsection __bug_table, "aw"; \
+ .pushsection __bug_table, "awM", @progbits, BUG_ENTRY_SIZE; \
.align 2; \
10000: .long 10001f - .; \
_BUGVERBOSE_LOCATION(WARN_CONDITION_STR(cond_str) __FILE__, __LINE__) \
@@ -31,6 +43,7 @@
.popsection; \
10001:
#endif
+#endif
#define ASM_BUG_FLAGS(cond_str, flags) \
__BUG_ENTRY(cond_str, flags) \
diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/include/asm/jump_label.h
index 7ef4ae3abf08..26ae644755ea 100644
--- a/arch/loongarch/include/asm/jump_label.h
+++ b/arch/loongarch/include/asm/jump_label.h
@@ -23,9 +23,16 @@
#define JUMP_LABEL_TYPE ".quad "
#endif
+#ifdef COMPILE_OFFSETS
+#define JUMP_ENTRY_SIZE 0
+#else
+#include <generated/asm-offsets.h>
+#endif
+
/* This macro is also expanded on the Rust side. */
#define JUMP_TABLE_ENTRY(key, label) \
- ".pushsection __jump_table, \"aw\" \n\t" \
+ ".pushsection __jump_table, \"awM\", @progbits, " \
+ __stringify(JUMP_ENTRY_SIZE) "\n\t" \
".align " __stringify(PTRLOG) " \n\t" \
".long 1b - ., " label " - . \n\t" \
JUMP_LABEL_TYPE key " - . \n\t" \
diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c
index 2cc953f113ac..42f16e5da06d 100644
--- a/arch/loongarch/kernel/asm-offsets.c
+++ b/arch/loongarch/kernel/asm-offsets.c
@@ -18,6 +18,10 @@
#include <asm/ftrace.h>
#include <asm/sigframe.h>
#include <vdso/datapage.h>
+#include <asm/alternative.h>
+#include <asm/extable.h>
+#include <asm/bug.h>
+#include <asm/jump_label.h>
static void __used output_ptreg_defines(void)
{
@@ -323,3 +327,35 @@ static void __used output_vdso_defines(void)
DEFINE(__VDSO_PAGES, VDSO_NR_PAGES);
BLANK();
}
+
+static void __used output_extable_defines(void)
+{
+ COMMENT("LoongArch exception table entry offsets.");
+
+ DEFINE(EXTABLE_SIZE, sizeof(struct exception_table_entry));
+ BLANK();
+}
+
+static void __used output_alt_instr_defines(void)
+{
+ COMMENT("LoongArch alternative instructions offsets.");
+
+ DEFINE(ALT_INSTR_SIZE, sizeof(struct alt_instr));
+ BLANK();
+}
+
+static void __used output_bug_defines(void)
+{
+ COMMENT("LoongArch bug entry offsets.");
+
+ DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
+ BLANK();
+}
+
+static void __used output_jump_label_defines(void)
+{
+ COMMENT("LoongArch jump entry offsets.");
+
+ DEFINE(JUMP_ENTRY_SIZE, sizeof(struct jump_entry));
+ BLANK();
+}
diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index 4eed7bc312a8..a8a2a98e0a5c 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -12,6 +12,7 @@
#include <asm/regdef.h>
#include <asm/loongarch.h>
#include <asm/stackframe.h>
+#include <generated/asm-offsets.h>
#ifdef CONFIG_EFI_STUB
--
2.25.1
^ permalink raw reply related
* [PATCH 2/8] objtool/LoongArch: Add arch_adjusted_addend() for KLP support
From: George Guo @ 2026-06-04 6:53 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, xry111, liukexin,
loongarch, live-patching, llvm, linux-kernel, George Guo
In-Reply-To: <20260604065317.219777-1-dongtai.guo@linux.dev>
From: George Guo <guodongtai@kylinos.cn>
Implement arch_adjusted_addend() to return the relocation addend value.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
tools/objtool/arch/loongarch/decode.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loongarch/decode.c
index 6cd288150f49..674e4efd138f 100644
--- a/tools/objtool/arch/loongarch/decode.c
+++ b/tools/objtool/arch/loongarch/decode.c
@@ -34,6 +34,11 @@ s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *reloc)
return reloc_addend(reloc);
}
+u64 arch_adjusted_addend(struct reloc *reloc)
+{
+ return reloc_addend(reloc);
+}
+
bool arch_pc_relative_reloc(struct reloc *reloc)
{
return false;
--
2.25.1
^ permalink raw reply related
* [PATCH 1/8] LoongArch: Add livepatch build (KLP) support
From: George Guo @ 2026-06-04 6:53 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, xry111, liukexin,
loongarch, live-patching, llvm, linux-kernel, George Guo
In-Reply-To: <20260604065317.219777-1-dongtai.guo@linux.dev>
From: George Guo <guodongtai@kylinos.cn>
This allows automated livepatch module generation using objtool.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
arch/loongarch/Kconfig | 1 +
tools/objtool/Makefile | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 3b042dbb2c41..1dbf51ba9d6a 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -159,6 +159,7 @@ config LOONGARCH
select HAVE_IOREMAP_PROT
select HAVE_IRQ_EXIT_ON_IRQ_STACK
select HAVE_IRQ_TIME_ACCOUNTING
+ select HAVE_KLP_BUILD
select HAVE_KPROBES
select HAVE_KPROBES_ON_FTRACE
select HAVE_KRETPROBES
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 94aabeee9736..83d645675ed9 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -8,7 +8,8 @@ ifeq ($(SRCARCH),x86)
endif
ifeq ($(SRCARCH),loongarch)
- BUILD_ORC := y
+ BUILD_ORC := y
+ ARCH_HAS_KLP := y
endif
ifeq ($(SRCARCH),arm64)
--
2.25.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox