[PATCH v3 1/2] selftests/livepatch: build test modules against the selected kernel
From: Sasha Levin
Date: Tue Nov 03 2026 - 17:27:53 EST
The livepatch test modules are built against /lib/modules/$(uname -r)/build
unless KDIR is set, and they are built unconditionally. This has three
problems:
- When the selftests are built for a kernel in an output directory
(make O=...), the modules are still built against the running host
kernel, or fail when the host has no build directory.
- The top-level selftests Makefile passes O to every suite, and the
test_modules Makefile hands it on to the kernel build. Even an empty
O= on the command line overrides the KBUILD_OUTPUT set by the
Makefile of a kernel build directory, so the build fails against
output directories and distribution headers such as Debian's:
"make -C tools/testing/selftests TARGETS=livepatch" builds no
modules at all.
- A kernel configured without CONFIG_LIVEPATCH cannot build the
modules, although the installed scripts would correctly skip.
Select KDIR from O or KBUILD_OUTPUT when it is a prepared kernel build
directory containing Module.symvers, then from the source tree when the
kernel was built in place, and otherwise from the running kernel. An
explicit KDIR still takes precedence. Pass KDIR to test_modules as an
absolute path, also when it was given on the command line, and stop
forwarding O and KBUILD_OUTPUT to the kernel build, including when the
selftests are built through the kernel's kselftest targets, since KDIR
already names the output directory.
Read CONFIG_LIVEPATCH from the selected .config and skip the modules
only when the configuration is readable and the option is not enabled. A
KDIR without a readable configuration still attempts the build, so that
a directory that is not a prepared kernel tree fails the build instead
of silently producing an installation without modules. A KDIR that does
not exist keeps being skipped, as before.
Always clean test_modules, through the kernel source tree that contains
them. Cleaning external modules needs neither a configuration nor
Module.symvers, and unlike the build targets, the clean target of the
selftests Makefile does not pass the absolute O on, so the kernel the
modules were built against cannot always be found at that point.
Have the scripts report a skip after the root check when the running
kernel does not provide livepatch.
Fixes: c4bbe83d27c2 ("livepatch: Move tests from lib/livepatch to selftests/livepatch")
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
tools/testing/selftests/livepatch/Makefile | 28 +++++++++++++++++++
.../testing/selftests/livepatch/functions.sh | 1 +
.../selftests/livepatch/test_modules/Makefile | 11 ++++----
3 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/livepatch/Makefile b/tools/testing/selftests/livepatch/Makefile
index a080eb54a215d..5c631812575dc 100644
--- a/tools/testing/selftests/livepatch/Makefile
+++ b/tools/testing/selftests/livepatch/Makefile
@@ -1,7 +1,26 @@
# SPDX-License-Identifier: GPL-2.0
+ifndef KDIR
+LIVEPATCH_OBJTREE := $(firstword $(O) $(KBUILD_OUTPUT))
+ifneq ($(and $(LIVEPATCH_OBJTREE),$(wildcard $(LIVEPATCH_OBJTREE)/Module.symvers)),)
+KDIR := $(LIVEPATCH_OBJTREE)
+else ifneq ($(wildcard ../../../../Module.symvers),)
+KDIR := ../../../..
+else
+KDIR := /lib/modules/$(shell uname -r)/build
+endif
+endif
+override KDIR := $(abspath $(KDIR))
+export KDIR
+MAKEOVERRIDES := $(filter-out KDIR=%,$(MAKEOVERRIDES))
+
+LIVEPATCH_CONFIG := $(shell if [ -r "$(KDIR)/.config" ]; then \
+ grep -qx 'CONFIG_LIVEPATCH=y' "$(KDIR)/.config" && echo y || echo n; fi)
+
TEST_GEN_FILES := test_klp-call_getpid
+ifneq ($(LIVEPATCH_CONFIG),n)
TEST_GEN_MODS_DIR := test_modules
+endif
TEST_PROGS_EXTENDED := functions.sh
TEST_PROGS := \
test-livepatch.sh \
@@ -16,3 +35,12 @@ TEST_PROGS := \
TEST_FILES := settings
include ../lib.mk
+
+ifeq ($(LIVEPATCH_CONFIG),n)
+clean: clean_livepatch_mods
+
+clean_livepatch_mods:
+ $(Q)$(MAKE) -C test_modules clean
+
+.PHONY: clean_livepatch_mods
+endif
diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh
index 429fce1f31431..8b26b70f92d8c 100644
--- a/tools/testing/selftests/livepatch/functions.sh
+++ b/tools/testing/selftests/livepatch/functions.sh
@@ -150,6 +150,7 @@ function cleanup() {
# the ftrace_enabled sysctl.
function setup_config() {
is_root
+ [[ -d "$SYSFS_KLP_DIR" ]] || skip "livepatch is not available"
has_kdir
push_config
set_dynamic_debug
diff --git a/tools/testing/selftests/livepatch/test_modules/Makefile b/tools/testing/selftests/livepatch/test_modules/Makefile
index a13d398585dcb..62cb724c6b333 100644
--- a/tools/testing/selftests/livepatch/test_modules/Makefile
+++ b/tools/testing/selftests/livepatch/test_modules/Makefile
@@ -16,14 +16,15 @@ obj-m += test_klp_atomic_replace.o \
test_klp_state3.o \
test_klp_syscall.o
+modules clean: MAKEOVERRIDES := $(filter-out O=% KBUILD_OUTPUT=%,$(MAKEOVERRIDES))
+
# Ensure that KDIR exists, otherwise skip the compilation
modules:
ifneq ("$(wildcard $(KDIR))", "")
- $(Q)$(MAKE) -C $(KDIR) modules KBUILD_EXTMOD=$(TESTMODS_DIR)
+ $(Q)env -u KBUILD_OUTPUT $(MAKE) -C $(KDIR) modules KBUILD_EXTMOD=$(TESTMODS_DIR)
endif
-# Ensure that KDIR exists, otherwise skip the clean target
+# Any kernel tree can clean the test modules, so use the one containing them
clean:
-ifneq ("$(wildcard $(KDIR))", "")
- $(Q)$(MAKE) -C $(KDIR) clean KBUILD_EXTMOD=$(TESTMODS_DIR)
-endif
+ $(Q)env -u KBUILD_OUTPUT $(MAKE) -C $(TESTMODS_DIR)/../../../../.. \
+ clean KBUILD_EXTMOD=$(TESTMODS_DIR)
--
2.53.0