Live Patching
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/7] klp-build: OOT module support
@ 2026-08-26 19:49 Joe Lawrence
  2026-08-26 19:49 ` [RFC PATCH v2 1/7] objtool/klp: simplify read_exports file handling Joe Lawrence
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Joe Lawrence @ 2026-08-26 19:49 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Miroslav Benes, Petr Mladek,
	Yafang Shao

This is RFCv2 of out-of-tree (OOT) module support for klp-build,
expanding on the original 4-patch series.  VERY lightly tested and coded
and most likely dangerous.  I'm posting to get feedback on the approach.
Brace for impact, Sashiko.


Motivation
----------

The initial RFC was motivated by stable, repeatable testing of 'objtool
klp diff'.  Standard in-tree drivers undergo frequent refactoring and
API churn, making them unreliable for producing consistent binary
patterns.  Smaller, targeted OOT test modules provide a stable baseline
for faster iteration before committing to an in-tree test case.

Feedback on v1 highlighted several production use cases for OOT in
general:

- Yafang Shao noted a real-world attempt to livepatch an OOT Mellanox
  driver in production that failed due to complex build dependencies.

- Song Liu noted that livepatching OOT modules in production is also a
  real use case at Meta, and that making it easy would likely see
  regular use.

- Song also observed (offlist) that the livepatch replace-set series
  would benefit from OOT support: replace-sets allow vendor and customer
  livepatches to coexist, where vendors patch the core kernel/distro
  modules while customers patch third-party, OOT drivers.

This feedback drove the addition of the "advanced" --orig-dir /
--patched-dir workflow (patches 6-7) for OOT drivers whose build systems
cannot be driven easily via `make M=`.


Series overview
---------------

Patches 1-4 are objtool prerequisites:
1 - Simplify read_exports() error handling (addresses Sashiko review)
2 - Add --symvers option to klp diff for custom Module.symvers paths
3 - Allow special section entry size overrides (allows tests to use
    objtool for cross-target/config processing)
4 - Embed target architecture in usage string (helps tests verify
    cross-target objtool)

Patch 5 provides baseline OOT capability:
5 - Add --oot-dir for simple modules built via 'make M=...'

At this point (patches 1-5), in-tree test and repro modules would be
supported via simple OOT dir builds.

Patches 6-7 extend OOT support for complex, real-world drivers:
6 - Add --orig-dir/--patched-dir for user-supplied pre-built objects
7 - Validate user-supplied objects (compiler match, -ffunction-sections)

The advanced workflow (patches 6-7) delegates the build process entirely
to the user, requiring only that objects are compiled with
-ffunction-sections and -fdata-sections.  klp-build then performs binary
comparison, symbol extraction, and livepatch assembly as usual.

As noted in the commit messages, output correctness depends directly on
the consistency of the inputs.  This is a HUGE footgun-rich space, but
provides flexibility for non-standard vendor build systems.


Changes
-------

RFC -> RFCv2
- Added read_exports() cleanup patch [Sashiko]
- Added pre-built object support for advanced OOT workflows [Song, Yafang]

RFC: https://lore.kernel.org/live-patching/20260512221102.2720763-1-joe.lawrence@redhat.com/

Joe Lawrence (7):
  objtool/klp: simplify read_exports file handling
  objtool/klp: add --symvers option to klp diff
  objtool/klp: allow special section entry size overrides
  objtool: add target architecture to usage
  livepatch/klp-build: add basic out-of-tree module support
  livepatch/klp-build: add pre-built object support for advanced OOT
    workflows
  livepatch/klp-build: add validation for user-supplied OOT objects

 scripts/livepatch/klp-build   | 229 ++++++++++++++++++++++++++++++----
 tools/objtool/Makefile        |   3 +-
 tools/objtool/builtin-check.c |   3 +-
 tools/objtool/klp-diff.c      |  68 ++++++++--
 4 files changed, 263 insertions(+), 40 deletions(-)


base-commit: d8a2860b4a366bfa8acb3d64da2c546ea26d2091
-- 
2.55.0


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [RFC PATCH v2 1/7] objtool/klp: simplify read_exports file handling
  2026-08-26 19:49 [RFC PATCH v2 0/7] klp-build: OOT module support Joe Lawrence
@ 2026-08-26 19:49 ` Joe Lawrence
  2026-08-26 23:31   ` Song Liu
  2026-08-26 19:49 ` [RFC PATCH v2 2/7] objtool/klp: add --symvers option to klp diff Joe Lawrence
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Joe Lawrence @ 2026-08-26 19:49 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Miroslav Benes, Petr Mladek,
	Yafang Shao

Consolidate the Module.symvers handling in klp-diff's read_exports()
with a single error path.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/live-patching/20260514204741.1ECCAC2BCB3@smtp.kernel.org/
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
 tools/objtool/klp-diff.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 16681a76f13d..1726d17f31e5 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -124,16 +124,13 @@ static int read_exports(void)
 	file = fopen(symvers, "r");
 	if (!file) {
 		path = top_level_dir(symvers);
-		if (!path) {
-			ERROR("can't open '%s', \"objtool diff\" should be run from the kernel tree", symvers);
-			return -1;
-		}
-
-		file = fopen(path, "r");
-		if (!file) {
-			ERROR_GLIBC("fopen");
-			return -1;
-		}
+		if (path)
+			file = fopen(path, "r");
+	}
+	if (!file) {
+		ERROR("can't open '%s', \"objtool diff\" should be run from the kernel tree", symvers);
+		free(path);
+		return -1;
 	}
 
 	while (fgets(line, 1024, file)) {
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH v2 2/7] objtool/klp: add --symvers option to klp diff
  2026-08-26 19:49 [RFC PATCH v2 0/7] klp-build: OOT module support Joe Lawrence
  2026-08-26 19:49 ` [RFC PATCH v2 1/7] objtool/klp: simplify read_exports file handling Joe Lawrence
@ 2026-08-26 19:49 ` Joe Lawrence
  2026-08-26 23:31   ` Song Liu
  2026-08-26 19:49 ` [RFC PATCH v2 3/7] objtool/klp: allow special section entry size overrides Joe Lawrence
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Joe Lawrence @ 2026-08-26 19:49 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Miroslav Benes, Petr Mladek,
	Yafang Shao

Add a --symvers (-s) option that accepts a path to Module.symvers.  When
provided, it replaces the default "Module.symvers" filename used by the
auto-detection logic.

This decoupling helps to enable scenarios like out-of-tree module
patching and unit testing of klp-diff, where object files /
Module.symvers live outside the kernel tree.

The existing auto-detection behavior (try cwd, then top_level_dir()
fallback) is preserved regardless of whether --symvers is specified.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
 tools/objtool/klp-diff.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 1726d17f31e5..f40c128fdd49 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -35,6 +35,7 @@ struct export {
 	bool mod_ns;
 };
 
+static const char *symvers_path = "Module.symvers";
 bool debug, debug_correlate, debug_clone;
 int indent;
 
@@ -48,6 +49,7 @@ static const struct option klp_diff_options[] = {
 	OPT_BOOLEAN('d', "debug", &debug, "enable all debug output"),
 	OPT_BOOLEAN(0, "debug-correlate", &debug_correlate, "enable correlation debug output"),
 	OPT_BOOLEAN(0, "debug-clone", &debug_clone, "enable cloning debug output"),
+	OPT_STRING('s', "symvers", &symvers_path, "path", "path to Module.symvers (default: Module.symvers)"),
 	OPT_END(),
 };
 
@@ -116,19 +118,23 @@ static char *normalize_modname(char *name)
 
 static int read_exports(void)
 {
-	const char *symvers = "Module.symvers";
 	char line[1024], *path = NULL;
 	unsigned int line_num = 0;
 	FILE *file;
 
-	file = fopen(symvers, "r");
-	if (!file) {
-		path = top_level_dir(symvers);
+	if (!symvers_path) {
+		ERROR("missing symvers path");
+		return -1;
+	}
+
+	file = fopen(symvers_path, "r");
+	if (!file && symvers_path[0] != '/') {
+		path = top_level_dir(symvers_path);
 		if (path)
 			file = fopen(path, "r");
 	}
 	if (!file) {
-		ERROR("can't open '%s', \"objtool diff\" should be run from the kernel tree", symvers);
+		ERROR("can't open '%s', \"objtool diff\" should be run from the kernel tree", symvers_path);
 		free(path);
 		return -1;
 	}
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH v2 3/7] objtool/klp: allow special section entry size overrides
  2026-08-26 19:49 [RFC PATCH v2 0/7] klp-build: OOT module support Joe Lawrence
  2026-08-26 19:49 ` [RFC PATCH v2 1/7] objtool/klp: simplify read_exports file handling Joe Lawrence
  2026-08-26 19:49 ` [RFC PATCH v2 2/7] objtool/klp: add --symvers option to klp diff Joe Lawrence
@ 2026-08-26 19:49 ` Joe Lawrence
  2026-08-27 19:17   ` Josh Poimboeuf
  2026-08-26 19:49 ` [RFC PATCH v2 4/7] objtool: add target architecture to usage Joe Lawrence
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Joe Lawrence @ 2026-08-26 19:49 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Miroslav Benes, Petr Mladek,
	Yafang Shao

Special section entry sizes (ALT_ENTRY_SIZE, JUMP_ENTRY_SIZE,
EX_ENTRY_SIZE) are built into objtool from arch-specific headers.  When
processing cached unit test objects that were built from a different
kernel version, these compiled-in sizes may not match the objects'
actual entry sizes, causing create_fake_symbols() to incorrectly parse
special sections.

Allow the user to override the compiled-in defaults via environment
variables of the same name.  When unset, behavior is unchanged.  This
will enable a klp-diff unit test runner to pass the correct entry sizes
from test metadata.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
 tools/objtool/klp-diff.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index f40c128fdd49..4195b3ccff15 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -21,6 +21,8 @@
 #include <linux/string.h>
 #include <linux/jhash.h>
 
+#include <arch/special.h>
+
 #define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))
 
 struct elfs {
@@ -1638,6 +1640,22 @@ static int clone_sym_relocs(struct elfs *e, struct symbol *patched_sym)
 
 }
 
+static unsigned int entry_size_from_env(const char *name, unsigned int def)
+{
+	const char *str = getenv(name);
+	char *end;
+	unsigned long val;
+
+	if (!str)
+		return def;
+
+	val = strtoul(str, &end, 10);
+	if (*end || !val)
+		return def;
+
+	return val;
+}
+
 static int create_fake_symbol(struct elf *elf, struct section *sec,
 			      unsigned long offset, size_t size)
 {
@@ -1781,6 +1799,27 @@ static int create_fake_symbols(struct elf *elf)
 		}
 
 		entry_size = sec->sh.sh_entsize;
+
+		/*
+		 * Some special sections have multiple relocs per entry,
+		 * so the reloc-based heuristic below doesn't work.  Use
+		 * the arch-defined entry sizes for known special sections.
+		 */
+		if (!entry_size) {
+			if (!strcmp(sec->name, ".altinstructions"))
+				entry_size = entry_size_from_env("ALT_ENTRY_SIZE", ALT_ENTRY_SIZE);
+			else if (!strcmp(sec->name, "__jump_table"))
+				entry_size = entry_size_from_env("JUMP_ENTRY_SIZE", JUMP_ENTRY_SIZE);
+			else if (!strcmp(sec->name, "__ex_table"))
+				entry_size = entry_size_from_env("EX_ENTRY_SIZE", EX_ENTRY_SIZE);
+
+			if (entry_size && sec_size(sec) % entry_size) {
+				ERROR("%s: entry size %u doesn't divide section size %lu",
+				      sec->name, entry_size, sec_size(sec));
+				return -1;
+			}
+		}
+
 		if (!entry_size) {
 			entry_size = arch_reloc_size(sec->rsec->relocs);
 			if (sec_size(sec) != entry_size * sec_num_entries(sec->rsec)) {
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH v2 4/7] objtool: add target architecture to usage
  2026-08-26 19:49 [RFC PATCH v2 0/7] klp-build: OOT module support Joe Lawrence
                   ` (2 preceding siblings ...)
  2026-08-26 19:49 ` [RFC PATCH v2 3/7] objtool/klp: allow special section entry size overrides Joe Lawrence
@ 2026-08-26 19:49 ` Joe Lawrence
  2026-08-26 19:57   ` sashiko-bot
  2026-08-27 19:23   ` Josh Poimboeuf
  2026-08-26 19:49 ` [RFC PATCH v2 5/7] livepatch/klp-build: add basic out-of-tree module support Joe Lawrence
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 17+ messages in thread
From: Joe Lawrence @ 2026-08-26 19:49 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Miroslav Benes, Petr Mladek,
	Yafang Shao

Display the target architecture in the objtool usage string so that
users can identify which arch variant of objtool they are running.  This
is useful when cross-compiling and automated testing.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
 tools/objtool/Makefile        | 3 ++-
 tools/objtool/builtin-check.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index a4484fd22a96..c73c80af5ef3 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -61,7 +61,8 @@ INCLUDES := -I$(srctree)/tools/include \
 	    -I$(srctree)/tools/lib
 
 OBJTOOL_CFLAGS  := -std=gnu11 -fomit-frame-pointer -O2 -g $(WARNINGS)	\
-		   $(INCLUDES) $(LIBELF_FLAGS) $(LIBXXHASH_CFLAGS) $(HOSTCFLAGS)
+		   $(INCLUDES) $(LIBELF_FLAGS) $(LIBXXHASH_CFLAGS) $(HOSTCFLAGS) \
+		   -DOBJTOOL_TARGET_ARCH=$(SRCARCH)
 
 OBJTOOL_LDFLAGS := $(LIBSUBCMD) $(LIBELF_LIBS) $(LIBXXHASH_LIBS) $(HOSTLDFLAGS)
 
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 75b11dc85010..64651d90986f 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -11,6 +11,7 @@
 #include <errno.h>
 #include <sys/stat.h>
 #include <sys/sendfile.h>
+#include <linux/stringify.h>
 #include <objtool/builtin.h>
 #include <objtool/objtool.h>
 #include <objtool/warn.h>
@@ -23,7 +24,7 @@ const char *objname;
 struct opts opts;
 
 static const char * const check_usage[] = {
-	"objtool <actions> [<options>] file.o",
+	"objtool <actions> [<options>] file-" __stringify(OBJTOOL_TARGET_ARCH) ".o",
 	NULL,
 };
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH v2 5/7] livepatch/klp-build: add basic out-of-tree module support
  2026-08-26 19:49 [RFC PATCH v2 0/7] klp-build: OOT module support Joe Lawrence
                   ` (3 preceding siblings ...)
  2026-08-26 19:49 ` [RFC PATCH v2 4/7] objtool: add target architecture to usage Joe Lawrence
@ 2026-08-26 19:49 ` Joe Lawrence
  2026-08-26 20:00   ` sashiko-bot
  2026-08-27 21:21   ` Josh Poimboeuf
  2026-08-26 19:49 ` [RFC PATCH v2 6/7] livepatch/klp-build: add pre-built object support for advanced OOT workflows Joe Lawrence
  2026-08-26 19:50 ` [RFC PATCH v2 7/7] livepatch/klp-build: add validation for user-supplied OOT objects Joe Lawrence
  6 siblings, 2 replies; 17+ messages in thread
From: Joe Lawrence @ 2026-08-26 19:49 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Miroslav Benes, Petr Mladek,
	Yafang Shao

klp-build is currently limited to patching in-tree kernel modules.
Introduce a --oot-dir option to enable livepatch generation for basic
out-of-tree (OOT) modules.  This requires the associated kernel tree to
be fully built (Module.symvers must exist).

The OOT workflow is as follows:

  cd /path/to/built-kernel
  ./scripts/livepatch/klp-build --oot-dir /path/to/mymodule my-fix.patch

With this option, klp-build performs two builds (original and patched)
of the OOT module via `make M=...` instead of a full kernel rebuild.
The resulting objects are then processed and diffed to produce the final
livepatch .ko.

Note that --oot-dir drives the build via `make M=`, assuming a simple
Kbuild/Makefile layout.  This is suited for small test modules and bug
reproducers rather than full OOT drivers with complex build systems
(which should use --orig-dir/--patched-dir instead).

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
 scripts/livepatch/klp-build | 84 ++++++++++++++++++++++++++++---------
 1 file changed, 64 insertions(+), 20 deletions(-)

diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index b52a8489d9f6..b60f5a5da31e 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -21,6 +21,7 @@ shopt -s lastpipe
 
 unset DEBUG_CLONE DIFF_CHECKSUM SKIP_CLEANUP VERBOSE XTRACE
 
+OOT_DIR=""
 REPLACE=1
 SHORT_CIRCUIT=0
 JOBS="$(getconf _NPROCESSORS_ONLN)"
@@ -137,6 +138,7 @@ Options:
 
 Advanced Options:
    -d, --debug			Show symbol/reloc cloning decisions
+       --oot-dir=<DIR>		Out-of-tree module source directory
    -S, --short-circuit=STEP	Start at build step (requires prior --keep-tmp)
 				   1|orig		Build original kernel (default)
 				   2|patched		Build patched kernel
@@ -160,7 +162,7 @@ process_args() {
 	local patch
 
 	short="hfj:o:vdS:T"
-	long="help,show-first-changed,jobs:,output:,no-replace,verbose,debug,short-circuit:,keep-tmp"
+	long="help,show-first-changed,jobs:,oot-dir:,output:,no-replace,verbose,debug,short-circuit:,keep-tmp"
 
 	args=$(getopt --options "$short" --longoptions "$long" -- "$@") || {
 		echo; usage; exit
@@ -202,6 +204,10 @@ process_args() {
 				keep_tmp=1
 				shift
 				;;
+			--oot-dir)
+				OOT_DIR="$2"
+				shift 2
+				;;
 			-S | --short-circuit)
 				[[ ! -d "$TMP_DIR" ]] && die "--short-circuit requires preserved klp-tmp dir"
 				keep_tmp=1
@@ -364,11 +370,21 @@ check_unsupported_patches() {
 		get_patch_files "$patch" | mapfile -t files
 
 		for file in "${files[@]}"; do
+			# In and out-of-tree paths to reject
 			case "$file" in
-				lib/*|*/vdso/*|*/realmode/rm/*|*.S)
+				*.S)
 					die "${patch}: unsupported patch to $file"
 					;;
 			esac
+
+			# In-tree paths to reject
+			if [[ -z "$OOT_DIR" ]]; then
+				case "$file" in
+					lib/*|*/vdso/*|*/realmode/rm/*)
+						die "${patch}: unsupported patch to $file"
+						;;
+				esac
+			fi
 		done
 	done
 }
@@ -377,13 +393,14 @@ apply_patch() {
 	local patch="$1"
 	shift
 	local extra_args=("$@")
+	local patch_target="${OOT_DIR:-$PWD}"
 	local drift_regex="with fuzz|offset [0-9]+ line"
 	local output
 	local status
 
 	[[ ! -f "$patch" ]] && die "$patch doesn't exist"
 	status=0
-	output=$(patch -p1 --dry-run --no-backup-if-mismatch -r /dev/null "${extra_args[@]}" < "$patch" 2>&1) || status=$?
+	output=$(patch -d "$patch_target" -p1 --dry-run --no-backup-if-mismatch -r /dev/null "${extra_args[@]}" < "$patch" 2>&1) || status=$?
 	if [[ "$status" -ne 0 ]]; then
 		echo "$output" >&2
 		die "$patch did not apply"
@@ -398,9 +415,10 @@ apply_patch() {
 
 revert_patch() {
 	local patch="$1"
+	local patch_target="${OOT_DIR:-$PWD}"
 	local tmp=()
 
-	patch -p1 -R --force --no-backup-if-mismatch -r /dev/null &> /dev/null < "$patch" || true
+	patch -d "$patch_target" -p1 -R --force --no-backup-if-mismatch -r /dev/null &> /dev/null < "$patch" || true
 
 	for p in "${APPLIED_PATCHES[@]}"; do
 		[[ "$p" == "$patch" ]] && continue
@@ -436,10 +454,17 @@ validate_patches() {
 }
 
 do_init() {
-	# We're not yet smart enough to handle anything other than in-tree
-	# builds in pwd.
 	[[ ! "$PWD" -ef "$SCRIPT_DIR/../.." ]] && die "please run from the kernel root directory"
 
+	if [[ -n "$OOT_DIR" ]]; then
+		[[ -d "$OOT_DIR" ]] || die "module directory not found: $OOT_DIR"
+		OOT_DIR="$(realpath "$OOT_DIR")"
+		[[ -f "$OOT_DIR/Kbuild" || -f "$OOT_DIR/Makefile" ]] ||
+			die "no Kbuild or Makefile in $OOT_DIR"
+		[[ -f "$PWD/Module.symvers" ]] ||
+			die "kernel must be built first (no Module.symvers in $PWD)"
+	fi
+
 	if (( SHORT_CIRCUIT >= 2 )); then
 		[[ -f "$ORIG_DIR/.complete" ]] || die "-S $SHORT_CIRCUIT requires completed $ORIG_DIR"
 	fi
@@ -471,6 +496,7 @@ do_init() {
 refresh_patch() {
 	local patch="$1"
 	local tmpdir="$PATCH_TMP_DIR"
+	local patch_target="${OOT_DIR:-$PWD}"
 	local input_files=()
 	local output_files=()
 
@@ -483,11 +509,11 @@ refresh_patch() {
 	get_patch_output_files "$patch" | mapfile -t output_files
 
 	# Copy orig source files to 'a'
-	echo "${input_files[@]}" | xargs cp --parents --target-directory="$tmpdir/a"
+	( cd "$patch_target" && echo "${input_files[@]}" | xargs cp --parents --target-directory="$tmpdir/a" )
 
 	# Copy patched source files to 'b'
 	apply_patch "$patch" "--silent"
-	echo "${output_files[@]}" | xargs cp --parents --target-directory="$tmpdir/b"
+	( cd "$patch_target" && echo "${output_files[@]}" | xargs cp --parents --target-directory="$tmpdir/b" )
 	revert_patch "$patch"
 
 	# Diff 'a' and 'b' to make a clean patch
@@ -529,6 +555,7 @@ clean_kernel() {
 	cmd=("make")
 	cmd+=("--silent")
 	cmd+=("-j$JOBS")
+	[[ -n "$OOT_DIR" ]] && cmd+=("M=$OOT_DIR")
 	cmd+=("clean")
 
 	"${cmd[@]}"
@@ -567,7 +594,11 @@ build_kernel() {
 	fi
 	cmd+=("-j$JOBS")
 	cmd+=("KCFLAGS=-ffunction-sections -fdata-sections")
-	cmd+=("vmlinux")
+	if [[ -z "$OOT_DIR" ]]; then
+		cmd+=("vmlinux")
+	else
+		cmd+=("M=$OOT_DIR")
+	fi
 	cmd+=("modules")
 
 	"${cmd[@]}"							\
@@ -579,13 +610,20 @@ build_kernel() {
 find_objects() {
 	local opts=("$@")
 
-	# Find root-level vmlinux.o and non-root-level .ko files,
-	# excluding klp-tmp/ and hidden directories.
-	find "$PWD" -mindepth 1 \
-		    \( -path "$TMP_DIR" -o -name ".*" -o -regex "$PWD/[^/][^/]*\.ko" \) -prune -o \
-		    -type f "${opts[@]}"				\
-		    \( -name "*.ko" -o -path "$PWD/vmlinux.o" \)	\
-		    -printf '%P\n'
+	if [[ -z "$OOT_DIR" ]]; then
+		# In-tree: find root-level vmlinux.o and non-root-level .ko files,
+		# excluding klp-tmp/ and hidden directories.
+		find "$PWD" -mindepth 1 \
+			    \( -path "$TMP_DIR" -o -name ".*" -o -regex "$PWD/[^/][^/]*\.ko" \) -prune -o \
+			    -type f "${opts[@]}"				\
+			    \( -name "*.ko" -o -path "$PWD/vmlinux.o" \)	\
+			    -printf '%P\n'
+	else
+		# OOT: find .ko at any depth under the module dir
+		find "$OOT_DIR" -path "$OOT_DIR/.git" -prune -o \
+			-type f "${opts[@]}" \
+			-name "*.ko" -printf '%P\n'
+	fi
 }
 
 # Copy all .o archives to $ORIG_DIR
@@ -597,10 +635,11 @@ copy_orig_objects() {
 
 	find_objects | mapfile -t files
 
+	local obj_root="${OOT_DIR:-$PWD}"
 	xtrace_save "copying original objects"
 	for _file in "${files[@]}"; do
 		local rel_file="${_file/.ko/.o}"
-		local file="$PWD/$rel_file"
+		local file="$obj_root/$rel_file"
 		local orig_file="$ORIG_DIR/$rel_file"
 		local orig_dir="$(dirname "$orig_file")"
 
@@ -633,10 +672,11 @@ copy_patched_objects() {
 
 	find_objects "${opts[@]}" | mapfile -t files
 
+	local obj_root="${OOT_DIR:-$PWD}"
 	xtrace_save "copying changed objects"
 	for _file in "${files[@]}"; do
 		local rel_file="${_file/.ko/.o}"
-		local file="$PWD/$rel_file"
+		local file="$obj_root/$rel_file"
 		local orig_file="$ORIG_DIR/$rel_file"
 		local patched_file="$PATCHED_DIR/$rel_file"
 		local patched_dir="$(dirname "$patched_file")"
@@ -717,6 +757,7 @@ diff_objects() {
 		cmd+=("klp")
 		cmd+=("diff")
 		(( ${#opts[@]} > 0 )) && cmd+=("${opts[@]}")
+		[[ -n "$OOT_DIR" ]] && cmd+=("--symvers" "$PWD/Module.symvers")
 		cmd+=("$orig_file")
 		cmd+=("$patched_file")
 		cmd+=("$out_file")
@@ -895,13 +936,16 @@ build_patch_module() {
 process_args "$@"
 do_init
 
+BUILD_TARGET="kernel"
+[[ -n "$OOT_DIR" ]] && BUILD_TARGET="module ${OOT_DIR##*/}"
+
 if (( SHORT_CIRCUIT <= 2 )); then
 	status "Validating patch(es)"
 	validate_patches
 fi
 
 if (( SHORT_CIRCUIT <= 1 )); then
-	status "Building original kernel"
+	status "Building original $BUILD_TARGET"
 	clean_kernel
 	build_kernel "original"
 	status "Copying original object files"
@@ -912,7 +956,7 @@ if (( SHORT_CIRCUIT <= 2 )); then
 	status "Fixing patch(es)"
 	fix_patches
 	apply_patches "--silent"
-	status "Building patched kernel"
+	status "Building patched $BUILD_TARGET"
 	build_kernel "patched"
 	revert_patches
 	status "Copying patched object files"
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH v2 6/7] livepatch/klp-build: add pre-built object support for advanced OOT workflows
  2026-08-26 19:49 [RFC PATCH v2 0/7] klp-build: OOT module support Joe Lawrence
                   ` (4 preceding siblings ...)
  2026-08-26 19:49 ` [RFC PATCH v2 5/7] livepatch/klp-build: add basic out-of-tree module support Joe Lawrence
@ 2026-08-26 19:49 ` Joe Lawrence
  2026-08-26 20:01   ` sashiko-bot
  2026-08-27 21:45   ` Josh Poimboeuf
  2026-08-26 19:50 ` [RFC PATCH v2 7/7] livepatch/klp-build: add validation for user-supplied OOT objects Joe Lawrence
  6 siblings, 2 replies; 17+ messages in thread
From: Joe Lawrence @ 2026-08-26 19:49 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Miroslav Benes, Petr Mladek,
	Yafang Shao

Most real-world out-of-tree drivers use complicated, non-standard build
systems (DKMS, cmake, autoconf, proprietary toolchains) that cannot be
driven by klp-build's internal build stages.  Rather than attempting to
accommodate every third-party build system, let the user handle the
build process and supply the object pairs directly.

Enhance klp-build with --orig-dir and --patched-dir options that accept
directories of pre-built .o files.  The user is responsible for building
original and patched objects externally.  The only hard requirement is
that both builds use -ffunction-sections and -fdata-sections so that
objtool can identify changed functions at the object level.

From there, klp-build performs its binary comparison, symbol extraction,
and livepatch module assembly pipeline used for in-tree patches, only
with the build steps factored out.  External symbol ownership is
determined from the target kernel's Module.symvers (--symvers,
defaulting to $PWD/Module.symvers).

The new options are mutually exclusive with --oot-dir (which drives the
build itself) and --short-circuit (which is specific to the standard
build pipeline).

The workflow is as follows:

  # 1. Build OOT objects with -ffunction-sections and -fdata-sections
  mkdir -p /tmp/orig && cp $OOT/my_module.o /tmp/orig/

  # 2. (Optional) leverage the kernel's fix-patch-lines script to "undo"
  #    the effects of line number shift by the patch
  $KDIR/scripts/livepatch/fix-patch-lines $OOT/fix-overflow.patch \
      | recountdiff > /tmp/fixed.patch

  # 3. Apply patch, rebuild
  mkdir -p /tmp/patched && cp $OOT/my_module.o /tmp/patched/

  # 4. Generate the livepatch
  cd $KDIR
  ./scripts/livepatch/klp-build \
      --orig-dir /tmp/orig \
      --patched-dir /tmp/patched \
      --symvers $KDIR/Module.symvers \
      -o livepatch-my_module.ko

NOTE: klp-build does not verify that user-supplied objects were built
against the correct kernel headers or with compatible compiler options.
The resulting livepatch module is only as correct as the inputs
provided.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
 scripts/livepatch/klp-build | 110 +++++++++++++++++++++++++++++++++---
 1 file changed, 102 insertions(+), 8 deletions(-)

diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index b60f5a5da31e..e118f133e923 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -22,6 +22,9 @@ shopt -s lastpipe
 unset DEBUG_CLONE DIFF_CHECKSUM SKIP_CLEANUP VERBOSE XTRACE
 
 OOT_DIR=""
+USER_ORIG_DIR=""
+USER_PATCHED_DIR=""
+SYMVERS_PATH=""
 REPLACE=1
 SHORT_CIRCUIT=0
 JOBS="$(getconf _NPROCESSORS_ONLN)"
@@ -127,6 +130,7 @@ trap trap_err ERR
 __usage() {
 	cat <<EOF
 Usage: $SCRIPT [OPTIONS] PATCH_FILE(s)
+       $SCRIPT --orig-dir=<DIR> --patched-dir=<DIR> [OPTIONS]
 Generate a livepatch module.
 
 Options:
@@ -139,6 +143,9 @@ Options:
 Advanced Options:
    -d, --debug			Show symbol/reloc cloning decisions
        --oot-dir=<DIR>		Out-of-tree module source directory
+       --orig-dir=<DIR>		Directory of pre-built original .o files
+       --patched-dir=<DIR>	Directory of pre-built patched .o files
+       --symvers=<FILE>		Path to Module.symvers [default: \$PWD/Module.symvers]
    -S, --short-circuit=STEP	Start at build step (requires prior --keep-tmp)
 				   1|orig		Build original kernel (default)
 				   2|patched		Build patched kernel
@@ -162,7 +169,7 @@ process_args() {
 	local patch
 
 	short="hfj:o:vdS:T"
-	long="help,show-first-changed,jobs:,oot-dir:,output:,no-replace,verbose,debug,short-circuit:,keep-tmp"
+	long="help,show-first-changed,jobs:,oot-dir:,orig-dir:,patched-dir:,symvers:,output:,no-replace,verbose,debug,short-circuit:,keep-tmp"
 
 	args=$(getopt --options "$short" --longoptions "$long" -- "$@") || {
 		echo; usage; exit
@@ -208,6 +215,18 @@ process_args() {
 				OOT_DIR="$2"
 				shift 2
 				;;
+			--orig-dir)
+				USER_ORIG_DIR="$2"
+				shift 2
+				;;
+			--patched-dir)
+				USER_PATCHED_DIR="$2"
+				shift 2
+				;;
+			--symvers)
+				SYMVERS_PATH="$2"
+				shift 2
+				;;
 			-S | --short-circuit)
 				[[ ! -d "$TMP_DIR" ]] && die "--short-circuit requires preserved klp-tmp dir"
 				keep_tmp=1
@@ -236,7 +255,18 @@ process_args() {
 		esac
 	done
 
-	if [[ $# -eq 0 ]] && (( SHORT_CIRCUIT <= 2 )); then
+	if [[ -n "$USER_ORIG_DIR" || -n "$USER_PATCHED_DIR" ]]; then
+		[[ -n "$USER_ORIG_DIR" && -n "$USER_PATCHED_DIR" ]] ||
+			die "--orig-dir and --patched-dir must both be specified"
+		[[ -v NAME ]] ||
+			die "--orig-dir/--patched-dir requires -o <output.ko>"
+		[[ -n "$OOT_DIR" ]] &&
+			die "--orig-dir/--patched-dir and --oot-dir are mutually exclusive"
+		(( SHORT_CIRCUIT > 0 )) &&
+			die "--short-circuit is not used with --orig-dir/--patched-dir"
+		[[ $# -gt 0 ]] &&
+			die "patch files are not used with --orig-dir/--patched-dir"
+	elif [[ $# -eq 0 ]] && (( SHORT_CIRCUIT <= 2 )); then
 		usage
 		exit 1
 	fi
@@ -456,7 +486,19 @@ validate_patches() {
 do_init() {
 	[[ ! "$PWD" -ef "$SCRIPT_DIR/../.." ]] && die "please run from the kernel root directory"
 
-	if [[ -n "$OOT_DIR" ]]; then
+	if [[ -n "$USER_ORIG_DIR" ]]; then
+		[[ -d "$USER_ORIG_DIR" ]] || die "directory not found: $USER_ORIG_DIR"
+		[[ -d "$USER_PATCHED_DIR" ]] || die "directory not found: $USER_PATCHED_DIR"
+		USER_ORIG_DIR="$(realpath "$USER_ORIG_DIR")"
+		USER_PATCHED_DIR="$(realpath "$USER_PATCHED_DIR")"
+		if [[ -n "$SYMVERS_PATH" ]]; then
+			SYMVERS_PATH="$(realpath "$SYMVERS_PATH")"
+			[[ -f "$SYMVERS_PATH" ]] || die "Module.symvers not found: $SYMVERS_PATH"
+		else
+			[[ -f "$PWD/Module.symvers" ]] ||
+				die "no Module.symvers in $PWD; use --symvers to specify"
+		fi
+	elif [[ -n "$OOT_DIR" ]]; then
 		[[ -d "$OOT_DIR" ]] || die "module directory not found: $OOT_DIR"
 		OOT_DIR="$(realpath "$OOT_DIR")"
 		[[ -f "$OOT_DIR/Kbuild" || -f "$OOT_DIR/Makefile" ]] ||
@@ -482,14 +524,19 @@ do_init() {
 	(( SHORT_CIRCUIT <= 1 )) && rm -rf "$TMP_DIR"
 	mkdir -p "$TMP_DIR"
 
+	validate_config
+	set_module_name
+	set_kernelversion
+
+	# Pre-built OOT init complete
+	if [[ -n "$USER_ORIG_DIR" ]]; then
+		return 0
+	fi
+
 	APPLIED_PATCHES=()
 
 	[[ -x "$FIX_PATCH_LINES" ]] || die "can't find fix-patch-lines"
 	command -v recountdiff &>/dev/null || die "recountdiff not found (install patchutils)"
-
-	validate_config
-	set_module_name
-	set_kernelversion
 }
 
 # Refresh the patch hunk headers, specifically the line numbers and counts.
@@ -757,7 +804,11 @@ diff_objects() {
 		cmd+=("klp")
 		cmd+=("diff")
 		(( ${#opts[@]} > 0 )) && cmd+=("${opts[@]}")
-		[[ -n "$OOT_DIR" ]] && cmd+=("--symvers" "$PWD/Module.symvers")
+		if [[ -n "$SYMVERS_PATH" ]]; then
+			cmd+=("--symvers" "$SYMVERS_PATH")
+		elif [[ -n "$OOT_DIR" || -n "$USER_ORIG_DIR" ]]; then
+			cmd+=("--symvers" "$PWD/Module.symvers")
+		fi
 		cmd+=("$orig_file")
 		cmd+=("$patched_file")
 		cmd+=("$out_file")
@@ -931,11 +982,54 @@ build_patch_module() {
 }
 
 
+setup_oot() {
+	local files=()
+	local rel
+
+	mkdir -p "$ORIG_DIR" "$PATCHED_DIR"
+
+	find "$USER_ORIG_DIR" -type f -name "*.o" -printf '%P\n' | mapfile -t files
+	[[ ${#files[@]} -gt 0 ]] || die "no .o files found in $USER_ORIG_DIR"
+	for rel in "${files[@]}"; do
+		[[ -f "$USER_PATCHED_DIR/$rel" ]] ||
+			die "$rel found in orig dir but missing from patched dir"
+		mkdir -p "$ORIG_DIR/$(dirname "$rel")"
+		mkdir -p "$PATCHED_DIR/$(dirname "$rel")"
+		cp -f "$USER_ORIG_DIR/$rel" "$ORIG_DIR/$rel"
+		cp -f "$USER_PATCHED_DIR/$rel" "$PATCHED_DIR/$rel"
+	done
+
+	touch "$ORIG_DIR/.complete"
+	touch "$PATCHED_DIR/.complete"
+}
+
+
 ################################################################################
 
 process_args "$@"
 do_init
 
+# User provided OOT original and patched object files can jump straight
+# to checksum + diff + build steps
+if [[ -n "$USER_ORIG_DIR" ]]; then
+	status "Setting up OOT objects"
+	setup_oot
+
+	status "Generating original checksums"
+	generate_checksums "$ORIG_DIR" "$ORIG_CSUM_DIR" "$PATCHED_DIR"
+	status "Generating patched checksums"
+	generate_checksums "$PATCHED_DIR" "$PATCHED_CSUM_DIR"
+
+	status "Diffing objects"
+	diff_objects
+
+	status "Building patch module: $OUTFILE"
+	build_patch_module
+
+	status "SUCCESS"
+	exit 0
+fi
+
 BUILD_TARGET="kernel"
 [[ -n "$OOT_DIR" ]] && BUILD_TARGET="module ${OOT_DIR##*/}"
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH v2 7/7] livepatch/klp-build: add validation for user-supplied OOT objects
  2026-08-26 19:49 [RFC PATCH v2 0/7] klp-build: OOT module support Joe Lawrence
                   ` (5 preceding siblings ...)
  2026-08-26 19:49 ` [RFC PATCH v2 6/7] livepatch/klp-build: add pre-built object support for advanced OOT workflows Joe Lawrence
@ 2026-08-26 19:50 ` Joe Lawrence
  6 siblings, 0 replies; 17+ messages in thread
From: Joe Lawrence @ 2026-08-26 19:50 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Miroslav Benes, Petr Mladek,
	Yafang Shao

With the --orig-dir and --patched-dir options, the user performs the
respective original and patched builds manually.  Therefore it is
important to sanity check the supplied objects to the best of our
ability before entering the diff/extraction pipeline.

Add check_oot_object() and check_oot_objects() to verify:

- Each orig/ object has a matching patched/ counterpart
- At least one .text.<func> section is present, implying
  -ffunction-sections compiler flag was used
- Matching compiler versions

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
 scripts/livepatch/klp-build | 47 ++++++++++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index e118f133e923..fc5d968fe235 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -982,17 +982,58 @@ build_patch_module() {
 }
 
 
+check_oot_object() {
+	local file="$1"
+
+	readelf -S "$file" 2>/dev/null | command grep -q '\.text\.' ||
+		die "$file: no .text.<func> sections found; was -ffunction-sections used?"
+}
+
+check_oot_objects() {
+	local orig_dir="$1"
+	local patched_dir="$2"
+	local -a files
+	local rel
+
+	command -v readelf &>/dev/null ||
+		die "readelf not found (required for OOT object validation)"
+
+	find "$orig_dir" -type f -name "*.o" -printf '%P\n' | mapfile -t files
+	[[ ${#files[@]} -gt 0 ]] || die "no .o files found in $orig_dir"
+
+	for rel in "${files[@]}"; do
+		[[ -f "$patched_dir/$rel" ]] ||
+			die "$rel found in orig dir but missing from patched dir"
+
+		check_oot_object "$orig_dir/$rel"
+		check_oot_object "$patched_dir/$rel"
+
+		local orig_cc patched_cc
+		orig_cc="$(readelf -p .comment "$orig_dir/$rel" 2>/dev/null | sed -n 's/.*\] *//p' | head -1)"
+		patched_cc="$(readelf -p .comment "$patched_dir/$rel" 2>/dev/null | sed -n 's/.*\] *//p' | head -1)"
+		if [[ -n "$orig_cc" && -n "$patched_cc" && "$orig_cc" != "$patched_cc" ]]; then
+			warn "$rel: compiler mismatch between orig and patched"
+			warn "  orig:    $orig_cc"
+			warn "  patched: $patched_cc"
+		fi
+	done
+
+	find "$patched_dir" -type f -name "*.o" -printf '%P\n' | while read -r rel; do
+		[[ -f "$orig_dir/$rel" ]] ||
+			warn "$rel found in patched dir but missing from orig dir"
+	done
+}
+
 setup_oot() {
 	local files=()
 	local rel
 
+	check_oot_objects "$USER_ORIG_DIR" "$USER_PATCHED_DIR"
+
 	mkdir -p "$ORIG_DIR" "$PATCHED_DIR"
 
 	find "$USER_ORIG_DIR" -type f -name "*.o" -printf '%P\n' | mapfile -t files
-	[[ ${#files[@]} -gt 0 ]] || die "no .o files found in $USER_ORIG_DIR"
 	for rel in "${files[@]}"; do
-		[[ -f "$USER_PATCHED_DIR/$rel" ]] ||
-			die "$rel found in orig dir but missing from patched dir"
 		mkdir -p "$ORIG_DIR/$(dirname "$rel")"
 		mkdir -p "$PATCHED_DIR/$(dirname "$rel")"
 		cp -f "$USER_ORIG_DIR/$rel" "$ORIG_DIR/$rel"
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH v2 4/7] objtool: add target architecture to usage
  2026-08-26 19:49 ` [RFC PATCH v2 4/7] objtool: add target architecture to usage Joe Lawrence
@ 2026-08-26 19:57   ` sashiko-bot
  2026-08-27 19:23   ` Josh Poimboeuf
  1 sibling, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-08-26 19:57 UTC (permalink / raw)
  To: Joe Lawrence, live-patching
  Cc: Yafang Shao, Song Liu, Petr Mladek, Josh Poimboeuf,
	Miroslav Benes

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Unintended macro expansion of architecture names during stringification results in an incorrect objtool usage string on certain architectures.
--

commit d81c5c3b288ffe16035a8655c9eb901dce1a358a
Author: Joe Lawrence <joe.lawrence@redhat.com>

objtool: add target architecture to usage
    
Display the target architecture in the objtool usage string so that
users can identify which arch variant of objtool they are running.

> diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
> index a4484fd22a96d..c73c80af5ef3d 100644
> --- a/tools/objtool/Makefile
> +++ b/tools/objtool/Makefile
> @@ -61,7 +61,8 @@ INCLUDES := -I$(srctree)/tools/include \
>  	    -I$(srctree)/tools/lib
>  
>  OBJTOOL_CFLAGS  := -std=gnu11 -fomit-frame-pointer -O2 -g $(WARNINGS)	\
> -		   $(INCLUDES) $(LIBELF_FLAGS) $(LIBXXHASH_CFLAGS) $(HOSTCFLAGS)
> +		   $(INCLUDES) $(LIBELF_FLAGS) $(LIBXXHASH_CFLAGS) $(HOSTCFLAGS) \
> +		   -DOBJTOOL_TARGET_ARCH=$(SRCARCH)

[Severity: Low]
Can passing the architecture name unquoted here cause a regression due to
compiler macro expansion?

For example, on architectures where the target name matches a predefined
compiler macro (like powerpc or sparc), OBJTOOL_TARGET_ARCH becomes an alias
to that predefined macro, which the preprocessor might then expand to a value
like 1.

[ ... ]

> diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
> index 75b11dc85010e..64651d90986fd 100644
> --- a/tools/objtool/builtin-check.c
> +++ b/tools/objtool/builtin-check.c

[ ... ]

> @@ -23,7 +24,7 @@ const char *objname;
>  struct opts opts;
>  
>  static const char * const check_usage[] = {
> -	"objtool <actions> [<options>] file.o",
> +	"objtool <actions> [<options>] file-" __stringify(OBJTOOL_TARGET_ARCH) ".o",

[Severity: Low]
Will this usage of __stringify() introduce a regression where the help string
is incorrect on certain architectures?

The __stringify() macro evaluates and expands its argument before converting it
to a string. If OBJTOOL_TARGET_ARCH evaluates to 1 due to predefined macros
as noted above, the resulting string will be "file-1.o" instead of
"file-powerpc.o".

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260826195000.455905-1-joe.lawrence@redhat.com?part=4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH v2 5/7] livepatch/klp-build: add basic out-of-tree module support
  2026-08-26 19:49 ` [RFC PATCH v2 5/7] livepatch/klp-build: add basic out-of-tree module support Joe Lawrence
@ 2026-08-26 20:00   ` sashiko-bot
  2026-08-27 21:21   ` Josh Poimboeuf
  1 sibling, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-08-26 20:00 UTC (permalink / raw)
  To: Joe Lawrence, live-patching
  Cc: Miroslav Benes, Yafang Shao, Josh Poimboeuf, Song Liu,
	Petr Mladek

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The `apply_patch` function omits the `-d` directory option during the actual patch application, failing to apply patches to out-of-tree modules.
- [Medium] Unconditional requirement for `vmlinux` unnecessarily prevents out-of-tree module livepatching against standard distro kernel headers.
--

commit aa6b14041f6a905023bf4d110f2171d49e9e8c84
Author: Joe Lawrence <joe.lawrence@redhat.com>

livepatch/klp-build: add basic out-of-tree module support

klp-build is currently limited to patching in-tree kernel modules.
Introduce a --oot-dir option to enable livepatch generation for basic
out-of-tree (OOT) modules.  This requires the associated kernel tree to
be fully built (Module.symvers must exist).

> diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
> index b52a8489d9f67..b60f5a5da31e8 100755
> --- a/scripts/livepatch/klp-build
> +++ b/scripts/livepatch/klp-build

[ ... ]

> @@ -377,13 +393,14 @@ apply_patch() {
>  	local patch="$1"
>  	shift
>  	local extra_args=("$@")
> +	local patch_target="${OOT_DIR:-$PWD}"
>  	local drift_regex="with fuzz|offset [0-9]+ line"
>  	local output
>  	local status
>  
>  	[[ ! -f "$patch" ]] && die "$patch doesn't exist"
>  	status=0
> -	output=$(patch -p1 --dry-run --no-backup-if-mismatch -r /dev/null "${extra_args[@]}" < "$patch" 2>&1) || status=$?
> +	output=$(patch -d "$patch_target" -p1 --dry-run --no-backup-if-mismatch -r /dev/null "${extra_args[@]}" < "$patch" 2>&1) || status=$?
>  	if [[ "$status" -ne 0 ]]; then
>  		echo "$output" >&2
>  		die "$patch did not apply"

[Severity: High]
Does this actual patch application omit the -d directory argument?

It looks like the -d "$patch_target" argument was correctly added to the
dry-run here, but not to the real patch application lower down in
apply_patch():

    patch -p1 --no-backup-if-mismatch -r /dev/null "${extra_args[@]}" --silent < "$patch"

When running klp-build --oot-dir <dir> <patch>, won't this attempt to apply
the patch against the kernel root directory instead of the out-of-tree module?
This seems like it would cause the patch application to fail, or erroneously
modify identically-named files in the kernel tree.

[ ... ]

> @@ -597,10 +635,11 @@ copy_orig_objects() {
>  
>  	find_objects | mapfile -t files
>  
> +	local obj_root="${OOT_DIR:-$PWD}"
>  	xtrace_save "copying original objects"
>  	for _file in "${files[@]}"; do
>  		local rel_file="${_file/.ko/.o}"
> -		local file="$PWD/$rel_file"
> +		local file="$obj_root/$rel_file"
>  		local orig_file="$ORIG_DIR/$rel_file"
>  		local orig_dir="$(dirname "$orig_file")"
>  

[Severity: Medium]
Will this script crash for valid out-of-tree module builds against standard
distro kernel headers?

Lower down in copy_orig_objects(), there is an unconditional requirement for
vmlinux to be present:

    cp -f "$PWD/vmlinux" "$ORIG_DIR" || die "missing vmlinux"

A primary use case for out-of-tree modules is building against kernel headers
which provide Module.symvers but do not include vmlinux. Since vmlinux is
unused during the object diffing steps for out-of-tree modules, should this
dependency be skipped when running klp-build --oot-dir <dir> <patch> to avoid
unnecessarily preventing livepatching against headers?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260826195000.455905-1-joe.lawrence@redhat.com?part=5

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH v2 6/7] livepatch/klp-build: add pre-built object support for advanced OOT workflows
  2026-08-26 19:49 ` [RFC PATCH v2 6/7] livepatch/klp-build: add pre-built object support for advanced OOT workflows Joe Lawrence
@ 2026-08-26 20:01   ` sashiko-bot
  2026-08-27 21:45   ` Josh Poimboeuf
  1 sibling, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-08-26 20:01 UTC (permalink / raw)
  To: Joe Lawrence, live-patching
  Cc: Petr Mladek, Josh Poimboeuf, Miroslav Benes, Yafang Shao,
	Song Liu

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [Medium] The newly introduced `--symvers` option breaks standard and `--oot-dir` builds when provided with a relative path, and it fails to override the `$PWD/Module.symvers` validation check for `--oot-dir` builds.
- [Medium] The `--show-first-changed` (`-f`) option is silently ignored in the pre-built object workflow.

Pre-existing issues:
- [High] Arbitrary command execution via maliciously crafted filenames containing Make functions in pre-built object directories.
--

commit f9d7e858a4afcd50869696d974b4dd56100b6cf0
Author: Joe Lawrence <joe.lawrence@redhat.com>
Subject: livepatch/klp-build: add pre-built object support for advanced OOT workflows

This commit introduces `--orig-dir` and `--patched-dir` options to klp-build,
allowing users to supply pre-built original and patched objects directly
rather than relying on internal build stages. It performs binary comparison,
symbol extraction, and livepatch module assembly using these pre-built objects.

> diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
> index b60f5a5da31e8..e118f133e923c 100755
> --- a/scripts/livepatch/klp-build
> +++ b/scripts/livepatch/klp-build

[ ... ]

> @@ -456,7 +486,19 @@ validate_patches() {
>  do_init() {
>  	[[ ! "$PWD" -ef "$SCRIPT_DIR/../.." ]] && die "please run from the kernel root directory"
>  
> -	if [[ -n "$OOT_DIR" ]]; then
> +	if [[ -n "$USER_ORIG_DIR" ]]; then
> +		[[ -d "$USER_ORIG_DIR" ]] || die "directory not found: $USER_ORIG_DIR"
> +		[[ -d "$USER_PATCHED_DIR" ]] || die "directory not found: $USER_PATCHED_DIR"
> +		USER_ORIG_DIR="$(realpath "$USER_ORIG_DIR")"
> +		USER_PATCHED_DIR="$(realpath "$USER_PATCHED_DIR")"
> +		if [[ -n "$SYMVERS_PATH" ]]; then
> +			SYMVERS_PATH="$(realpath "$SYMVERS_PATH")"
> +			[[ -f "$SYMVERS_PATH" ]] || die "Module.symvers not found: $SYMVERS_PATH"
> +		else
> +			[[ -f "$PWD/Module.symvers" ]] ||
> +				die "no Module.symvers in $PWD; use --symvers to specify"
> +		fi
> +	elif [[ -n "$OOT_DIR" ]]; then

[Severity: Medium]
Will this leave `SYMVERS_PATH` as an unexpanded relative path when used with
`--oot-dir` or standard builds, since the `realpath` conversion is nested
inside the `--orig-dir` conditional branch?

Also, in the `elif [[ -n "$OOT_DIR" ]];` branch that follows, there is a check
for `[[ -f "$PWD/Module.symvers" ]]`.

Does this fail to respect the provided `SYMVERS_PATH` during OOT
initialization and enforce validation on the hardcoded `$PWD/Module.symvers`,
preventing alternative paths?

[ ... ]

> @@ -757,7 +804,11 @@ diff_objects() {
>  		cmd+=("klp")
>  		cmd+=("diff")
>  		(( ${#opts[@]} > 0 )) && cmd+=("${opts[@]}")
> -		[[ -n "$OOT_DIR" ]] && cmd+=("--symvers" "$PWD/Module.symvers")
> +		if [[ -n "$SYMVERS_PATH" ]]; then
> +			cmd+=("--symvers" "$SYMVERS_PATH")

[Severity: Medium]
If `SYMVERS_PATH` remains a relative path from the issue above, will this
command fail when it is executed from the `$ORIG_CSUM_DIR` subshell?

[ ... ]

> @@ -931,11 +982,54 @@ build_patch_module() {
>  }
>  
>  
> +setup_oot() {
> +	local files=()
> +	local rel
> +
> +	mkdir -p "$ORIG_DIR" "$PATCHED_DIR"
> +
> +	find "$USER_ORIG_DIR" -type f -name "*.o" -printf '%P\n' | mapfile -t files

[Severity: High]
This is a pre-existing issue, but this pipeline ingests user-supplied
filenames from the pre-built object directories without sanitization.

Later in build_patch_module(), these filenames are written directly into the
generated Kbuild file target list:

    echo -n " $rel_file" >> "$makefile"

Can this allow arbitrary command execution via maliciously crafted filenames
containing Make functions (e.g., `$(shell command).o`) when processing untrusted
pre-built objects?

[ ... ]

> +	status "Building patch module: $OUTFILE"
> +	build_patch_module
> +
> +	status "SUCCESS"
> +	exit 0
> +fi
> +

[Severity: Medium]
Because this block executes the pre-built workflow and exits immediately,
doesn't it fully bypass the `diff_checksums` hook?

Will this silently ignore the `--show-first-changed` (`-f`) option in the
pre-built object workflow?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260826195000.455905-1-joe.lawrence@redhat.com?part=6

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH v2 1/7] objtool/klp: simplify read_exports file handling
  2026-08-26 19:49 ` [RFC PATCH v2 1/7] objtool/klp: simplify read_exports file handling Joe Lawrence
@ 2026-08-26 23:31   ` Song Liu
  0 siblings, 0 replies; 17+ messages in thread
From: Song Liu @ 2026-08-26 23:31 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Miroslav Benes, Petr Mladek,
	Yafang Shao

On Wed, Aug 26, 2026 at 12:50 PM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> Consolidate the Module.symvers handling in klp-diff's read_exports()
> with a single error path.
>
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Link: https://lore.kernel.org/live-patching/20260514204741.1ECCAC2BCB3@smtp.kernel.org/
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

Acked-by: Song Liu <song@kernel.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH v2 2/7] objtool/klp: add --symvers option to klp diff
  2026-08-26 19:49 ` [RFC PATCH v2 2/7] objtool/klp: add --symvers option to klp diff Joe Lawrence
@ 2026-08-26 23:31   ` Song Liu
  0 siblings, 0 replies; 17+ messages in thread
From: Song Liu @ 2026-08-26 23:31 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Miroslav Benes, Petr Mladek,
	Yafang Shao

On Wed, Aug 26, 2026 at 12:50 PM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> Add a --symvers (-s) option that accepts a path to Module.symvers.  When
> provided, it replaces the default "Module.symvers" filename used by the
> auto-detection logic.
>
> This decoupling helps to enable scenarios like out-of-tree module
> patching and unit testing of klp-diff, where object files /
> Module.symvers live outside the kernel tree.
>
> The existing auto-detection behavior (try cwd, then top_level_dir()
> fallback) is preserved regardless of whether --symvers is specified.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

Acked-by: Song Liu <song@kernel.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH v2 3/7] objtool/klp: allow special section entry size overrides
  2026-08-26 19:49 ` [RFC PATCH v2 3/7] objtool/klp: allow special section entry size overrides Joe Lawrence
@ 2026-08-27 19:17   ` Josh Poimboeuf
  0 siblings, 0 replies; 17+ messages in thread
From: Josh Poimboeuf @ 2026-08-27 19:17 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Song Liu, Miroslav Benes, Petr Mladek, Yafang Shao

On Wed, Aug 26, 2026 at 03:49:56PM -0400, Joe Lawrence wrote:
> @@ -1781,6 +1799,27 @@ static int create_fake_symbols(struct elf *elf)
>  		}
>  
>  		entry_size = sec->sh.sh_entsize;
> +
> +		/*
> +		 * Some special sections have multiple relocs per entry,
> +		 * so the reloc-based heuristic below doesn't work.  Use
> +		 * the arch-defined entry sizes for known special sections.
> +		 */

This comment doesn't seem correct: for the special sections with
multiple relocs per entry, the .o file should have annotations for that
(either entsize or ANNOTATE_DATA_SPECIAL).

Also the comment doesn't seem to match the commit log (that this is
needed for unit testing?)

> +		if (!entry_size) {
> +			if (!strcmp(sec->name, ".altinstructions"))
> +				entry_size = entry_size_from_env("ALT_ENTRY_SIZE", ALT_ENTRY_SIZE);
> +			else if (!strcmp(sec->name, "__jump_table"))
> +				entry_size = entry_size_from_env("JUMP_ENTRY_SIZE", JUMP_ENTRY_SIZE);
> +			else if (!strcmp(sec->name, "__ex_table"))
> +				entry_size = entry_size_from_env("EX_ENTRY_SIZE", EX_ENTRY_SIZE);

I really don't like this because it removes klp-diff's hard-earned
agnosticism about these entry sizes.  And they should already be encoded
in the binary anyway.

-- 
Josh

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH v2 4/7] objtool: add target architecture to usage
  2026-08-26 19:49 ` [RFC PATCH v2 4/7] objtool: add target architecture to usage Joe Lawrence
  2026-08-26 19:57   ` sashiko-bot
@ 2026-08-27 19:23   ` Josh Poimboeuf
  1 sibling, 0 replies; 17+ messages in thread
From: Josh Poimboeuf @ 2026-08-27 19:23 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Song Liu, Miroslav Benes, Petr Mladek, Yafang Shao

On Wed, Aug 26, 2026 at 03:49:57PM -0400, Joe Lawrence wrote:
> Display the target architecture in the objtool usage string so that
> users can identify which arch variant of objtool they are running.  This
> is useful when cross-compiling and automated testing.

Can you elaborate on why this is needed?

-- 
Josh

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH v2 5/7] livepatch/klp-build: add basic out-of-tree module support
  2026-08-26 19:49 ` [RFC PATCH v2 5/7] livepatch/klp-build: add basic out-of-tree module support Joe Lawrence
  2026-08-26 20:00   ` sashiko-bot
@ 2026-08-27 21:21   ` Josh Poimboeuf
  1 sibling, 0 replies; 17+ messages in thread
From: Josh Poimboeuf @ 2026-08-27 21:21 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Song Liu, Miroslav Benes, Petr Mladek, Yafang Shao

On Wed, Aug 26, 2026 at 03:49:58PM -0400, Joe Lawrence wrote:
> @@ -579,13 +610,20 @@ build_kernel() {
>  find_objects() {
>  	local opts=("$@")
>  
> -	# Find root-level vmlinux.o and non-root-level .ko files,
> -	# excluding klp-tmp/ and hidden directories.
> -	find "$PWD" -mindepth 1 \
> -		    \( -path "$TMP_DIR" -o -name ".*" -o -regex "$PWD/[^/][^/]*\.ko" \) -prune -o \
> -		    -type f "${opts[@]}"				\
> -		    \( -name "*.ko" -o -path "$PWD/vmlinux.o" \)	\
> -		    -printf '%P\n'
> +	if [[ -z "$OOT_DIR" ]]; then
> +		# In-tree: find root-level vmlinux.o and non-root-level .ko files,
> +		# excluding klp-tmp/ and hidden directories.
> +		find "$PWD" -mindepth 1 \
> +			    \( -path "$TMP_DIR" -o -name ".*" -o -regex "$PWD/[^/][^/]*\.ko" \) -prune -o \
> +			    -type f "${opts[@]}"				\
> +			    \( -name "*.ko" -o -path "$PWD/vmlinux.o" \)	\
> +			    -printf '%P\n'
> +	else
> +		# OOT: find .ko at any depth under the module dir
> +		find "$OOT_DIR" -path "$OOT_DIR/.git" -prune -o \
> +			-type f "${opts[@]}" \
> +			-name "*.ko" -printf '%P\n'

Can these be unified?  Something like:

	if [[ -n "$OOT_DIR ]]; then
		path="$OOT_DIR"
	else
		path="$PWD"
	fi

	find "$path" -mindepth 1 \
		    \( -path "$TMP_DIR" -o -name ".*" -o -regex "$PWD/[^/][^/]*\.ko" \) -prune -o \
		    -type f "${opts[@]}"				\
		    \( -name "*.ko" -o -path "$PWD/vmlinux.o" \)	\
		    -printf '%P\n'

That way we get consistent behavior and the two paths with $PWD would
get silently ignored for the OOT case anyway.

> @@ -717,6 +757,7 @@ diff_objects() {
>  		cmd+=("klp")
>  		cmd+=("diff")
>  		(( ${#opts[@]} > 0 )) && cmd+=("${opts[@]}")
> +		[[ -n "$OOT_DIR" ]] && cmd+=("--symvers" "$PWD/Module.symvers")

Even with OOT_DIR it still runs in the kernel build dir, which is where
objtool looks for this file anyway, so I don't think this line is
needed?

>  		cmd+=("$orig_file")
>  		cmd+=("$patched_file")
>  		cmd+=("$out_file")
> @@ -895,13 +936,16 @@ build_patch_module() {
>  process_args "$@"
>  do_init
>  
> +BUILD_TARGET="kernel"
> +[[ -n "$OOT_DIR" ]] && BUILD_TARGET="module ${OOT_DIR##*/}"
> +
>  if (( SHORT_CIRCUIT <= 2 )); then
>  	status "Validating patch(es)"
>  	validate_patches
>  fi
>  
>  if (( SHORT_CIRCUIT <= 1 )); then
> -	status "Building original kernel"
> +	status "Building original $BUILD_TARGET"

I think we can simplify this to just "Building original objects" or so...

>  	clean_kernel
>  	build_kernel "original"
>  	status "Copying original object files"
> @@ -912,7 +956,7 @@ if (( SHORT_CIRCUIT <= 2 )); then
>  	status "Fixing patch(es)"
>  	fix_patches
>  	apply_patches "--silent"
> -	status "Building patched kernel"
> +	status "Building patched $BUILD_TARGET"

... and "Building patched objects".

-- 
Josh

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH v2 6/7] livepatch/klp-build: add pre-built object support for advanced OOT workflows
  2026-08-26 19:49 ` [RFC PATCH v2 6/7] livepatch/klp-build: add pre-built object support for advanced OOT workflows Joe Lawrence
  2026-08-26 20:01   ` sashiko-bot
@ 2026-08-27 21:45   ` Josh Poimboeuf
  1 sibling, 0 replies; 17+ messages in thread
From: Josh Poimboeuf @ 2026-08-27 21:45 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Song Liu, Miroslav Benes, Petr Mladek, Yafang Shao

On Wed, Aug 26, 2026 at 03:49:59PM -0400, Joe Lawrence wrote:
> +setup_oot() {
> +	local files=()
> +	local rel
> +
> +	mkdir -p "$ORIG_DIR" "$PATCHED_DIR"
> +
> +	find "$USER_ORIG_DIR" -type f -name "*.o" -printf '%P\n' | mapfile -t files
> +	[[ ${#files[@]} -gt 0 ]] || die "no .o files found in $USER_ORIG_DIR"
> +	for rel in "${files[@]}"; do
> +		[[ -f "$USER_PATCHED_DIR/$rel" ]] ||
> +			die "$rel found in orig dir but missing from patched dir"
> +		mkdir -p "$ORIG_DIR/$(dirname "$rel")"
> +		mkdir -p "$PATCHED_DIR/$(dirname "$rel")"
> +		cp -f "$USER_ORIG_DIR/$rel" "$ORIG_DIR/$rel"
> +		cp -f "$USER_PATCHED_DIR/$rel" "$PATCHED_DIR/$rel"
> +	done
> +
> +	touch "$ORIG_DIR/.complete"
> +	touch "$PATCHED_DIR/.complete"
> +}

This is basically reimplementing copy_orig_objects() and copy_patched_objects().

>  ################################################################################
>  
>  process_args "$@"
>  do_init
>  
> +# User provided OOT original and patched object files can jump straight
> +# to checksum + diff + build steps
> +if [[ -n "$USER_ORIG_DIR" ]]; then
> +	status "Setting up OOT objects"
> +	setup_oot
> +
> +	status "Generating original checksums"
> +	generate_checksums "$ORIG_DIR" "$ORIG_CSUM_DIR" "$PATCHED_DIR"
> +	status "Generating patched checksums"
> +	generate_checksums "$PATCHED_DIR" "$PATCHED_CSUM_DIR"
> +
> +	status "Diffing objects"
> +	diff_objects
> +
> +	status "Building patch module: $OUTFILE"
> +	build_patch_module
> +
> +	status "SUCCESS"
> +	exit 0
> +fi

This is basically reimplementing --short-circuit=3.

Instead of --orig-dir and --patched-dir, I wonder if we could just have
--oot-build-cmd (combined with --oot-dir), so the user can specify
whatever make command is needed?

Then do_init() could have something like SRC_DIR="${OOT_DIR:-$PWD}" so
almost all the code for all the steps gets shared, except for the build
command.

The klp-specific build-isms like KCFLAGS could be exported instead of
added to the cmdline.

And then that would be easier for the user too, they wouldn't have to do
the building/copying of objects, filtering the patch, etc.

-- 
Josh

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2026-08-27 21:45 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-26 19:49 [RFC PATCH v2 0/7] klp-build: OOT module support Joe Lawrence
2026-08-26 19:49 ` [RFC PATCH v2 1/7] objtool/klp: simplify read_exports file handling Joe Lawrence
2026-08-26 23:31   ` Song Liu
2026-08-26 19:49 ` [RFC PATCH v2 2/7] objtool/klp: add --symvers option to klp diff Joe Lawrence
2026-08-26 23:31   ` Song Liu
2026-08-26 19:49 ` [RFC PATCH v2 3/7] objtool/klp: allow special section entry size overrides Joe Lawrence
2026-08-27 19:17   ` Josh Poimboeuf
2026-08-26 19:49 ` [RFC PATCH v2 4/7] objtool: add target architecture to usage Joe Lawrence
2026-08-26 19:57   ` sashiko-bot
2026-08-27 19:23   ` Josh Poimboeuf
2026-08-26 19:49 ` [RFC PATCH v2 5/7] livepatch/klp-build: add basic out-of-tree module support Joe Lawrence
2026-08-26 20:00   ` sashiko-bot
2026-08-27 21:21   ` Josh Poimboeuf
2026-08-26 19:49 ` [RFC PATCH v2 6/7] livepatch/klp-build: add pre-built object support for advanced OOT workflows Joe Lawrence
2026-08-26 20:01   ` sashiko-bot
2026-08-27 21:45   ` Josh Poimboeuf
2026-08-26 19:50 ` [RFC PATCH v2 7/7] livepatch/klp-build: add validation for user-supplied OOT objects Joe Lawrence

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox