* Re: [PATCH v4 09/12] livepatch/klp-build: Fix inconsistent kernel version
From: Song Liu @ 2026-03-11 22:23 UTC (permalink / raw)
To: Joe Lawrence
Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-10-joe.lawrence@redhat.com>
On Tue, Mar 10, 2026 at 1:38 PM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> From: Josh Poimboeuf <jpoimboe@kernel.org>
>
> If .config hasn't been synced with auto.conf, any recent changes to
> CONFIG_LOCALVERSION* may not get reflected in the kernel version name.
>
> Use "make syncconfig" to force them to sync, and "make -s kernelrelease"
> to get the version instead of having to construct it manually.
>
> Fixes: 24ebfcd65a87 ("livepatch/klp-build: Introduce klp-build script for generating livepatch modules")
> Closes: https://lore.kernel.org/20260217160645.3434685-10-joe.lawrence@redhat.com
> Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> [add -s to make kernelrelease]
Acked-by: Song Liu <song@kernel.org>
^ permalink raw reply
* Re: [PATCH v4 12/12] livepatch/klp-build: report patch validation fuzz
From: Song Liu @ 2026-03-11 22:22 UTC (permalink / raw)
To: Joe Lawrence
Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-13-joe.lawrence@redhat.com>
On Tue, Mar 10, 2026 at 1:38 PM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> Capture the output of the patch command to detect when a patch applies
> with fuzz or line offsets.
>
> If such "fuzz" is detected during the validation phase, warn the user
> and display the details. This helps identify input patches that may
> need refreshing against the target source tree.
>
> Ensure that internal patch operations (such as those in refresh_patch or
> during the final build phase) can still run quietly.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Song Liu <song@kernel.org>
^ permalink raw reply
* Re: [PATCH v4 04/12] livepatch/klp-build: switch to GNU patch and recountdiff
From: Song Liu @ 2026-03-11 22:20 UTC (permalink / raw)
To: Joe Lawrence
Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-5-joe.lawrence@redhat.com>
On Tue, Mar 10, 2026 at 1:38 PM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> The klp-build script is currently very strict with input patches,
> requiring them to apply cleanly via `git apply --recount`. This
> prevents the use of patches with minor contextual fuzz relative to the
> target kernel sources.
>
> To allow users to reuse a patch across similar kernel streams, switch to
> using GNU patch and patchutils for intermediate patch manipulation.
> Update the logic for applying, reverting, and regenerating patches:
>
> - Use 'patch -p1' for better handling of context fuzz.
> - Use 'recountdiff' to update line counts after FIX_PATCH_LINES.
> - Drop git_refresh() and related git-specific logic.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Song Liu <song@kernel.org>
^ permalink raw reply
* Re: [PATCH 07/14] objtool: Extricate checksum calculation from validate_branch()
From: Miroslav Benes @ 2026-03-11 8:24 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
In-Reply-To: <ssvxqrraejznlambdt3yunuteguhu22yef236ngtqnpyhxruc6@bx2dhcbpzrbq>
On Tue, 10 Mar 2026, Josh Poimboeuf wrote:
> On Tue, Mar 10, 2026 at 11:47:41AM +0100, Miroslav Benes wrote:
> > Hi,
> >
> > > @@ -3691,9 +3691,30 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
> > > struct instruction *insn)
> > > {
> > > struct reloc *reloc = insn_reloc(file, insn);
> > > + struct alternative *alt;
> > > unsigned long offset;
> > > struct symbol *sym;
> > >
> > > + for (alt = insn->alts; alt; alt = alt->next) {
> > > + struct alt_group *alt_group = alt->insn->alt_group;
> > > +
> > > + checksum_update(func, insn, &alt->type, sizeof(alt->type));
> > > +
> > > + if (alt_group && alt_group->orig_group) {
> > > + struct instruction *alt_insn;
> > > +
> > > + checksum_update(func, insn, &alt_group->feature, sizeof(alt_group->feature));
> > > +
> > > + for (alt_insn = alt->insn; alt_insn; alt_insn = next_insn_same_sec(file, alt_insn)) {
> > > + checksum_update_insn(file, func, alt_insn);
> > > + if (alt_insn == alt_group->last_insn)
> > > + break;
> > > + }
> > > + } else {
> > > + checksum_update(func, insn, &alt->insn->offset, sizeof(alt->insn->offset));
> > > + }
> > > + }
> > > +
> >
> > does this hunk belong to the patch? Unless I am missing something, it
> > might be worth a separate one.
>
> It belongs, but I should have clarified that in the patch description.
>
> This hunk wasn't needed before because validate_branch() already
> iterates all the alternatives, so it was calling checksum_update_insn()
> for every instruction in the function, including the alternatives.
>
> Now that it's no longer called by validate_branch(),
> checksum_update_insn() has to manually iterate the alternatives.
After writing the email I had a suspicion it must have been something like
above but failed to find it. Now I see that next_insn_to_validate() called
in do_validate_branch() handles exactly that. Thanks for the pointer. The
patch looks good to me then (and the rest as well as far as I can judge).
I must admit that objtool has gotten so complex that I have a hard time to
track everything in the code :).
Regards
Miroslav
^ permalink raw reply
* [PATCH v4 12/12] livepatch/klp-build: report patch validation fuzz
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
Capture the output of the patch command to detect when a patch applies
with fuzz or line offsets.
If such "fuzz" is detected during the validation phase, warn the user
and display the details. This helps identify input patches that may
need refreshing against the target source tree.
Ensure that internal patch operations (such as those in refresh_patch or
during the final build phase) can still run quietly.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
scripts/livepatch/klp-build | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 325dc4601bba..0ad7e6631314 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -359,11 +359,24 @@ check_unsupported_patches() {
apply_patch() {
local patch="$1"
+ shift
+ local extra_args=("$@")
+ local drift_regex="with fuzz|offset [0-9]+ line"
+ local output
+ local status
[[ ! -f "$patch" ]] && die "$patch doesn't exist"
- patch -d "$SRC" -p1 --dry-run --silent --no-backup-if-mismatch -r /dev/null < "$patch"
- patch -d "$SRC" -p1 --silent --no-backup-if-mismatch -r /dev/null < "$patch"
+ status=0
+ output=$(patch -d "$SRC" -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"
+ elif [[ "$output" =~ $drift_regex ]]; then
+ echo "$output" >&2
+ warn "${patch} applied with fuzz"
+ fi
+ patch -d "$SRC" -p1 --no-backup-if-mismatch -r /dev/null "${extra_args[@]}" --silent < "$patch"
APPLIED_PATCHES+=("$patch")
}
@@ -382,10 +395,11 @@ revert_patch() {
}
apply_patches() {
+ local extra_args=("$@")
local patch
for patch in "${PATCHES[@]}"; do
- apply_patch "$patch"
+ apply_patch "$patch" "${extra_args[@]}"
done
}
@@ -443,7 +457,7 @@ refresh_patch() {
( cd "$SRC" && echo "${input_files[@]}" | xargs cp --parents --target-directory="$tmpdir/a" )
# Copy patched source files to 'b'
- apply_patch "$patch"
+ apply_patch "$patch" "--silent"
( cd "$SRC" && echo "${output_files[@]}" | xargs cp --parents --target-directory="$tmpdir/b" )
revert_patch "$patch"
@@ -816,7 +830,7 @@ fi
if (( SHORT_CIRCUIT <= 2 )); then
status "Fixing patch(es)"
fix_patches
- apply_patches
+ apply_patches "--silent"
status "Building patched kernel"
build_kernel "patched"
revert_patches
--
2.53.0
^ permalink raw reply related
* [PATCH v4 10/12] livepatch/klp-build: provide friendlier error messages
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
Provide more context for common klp-build failure modes. Clarify which
user-provided patch is unsupported or failed to apply, and explicitly
identify which kernel build (original or patched) failed.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
scripts/livepatch/klp-build | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 7f4041a0eefb..cf36555330b3 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -341,7 +341,7 @@ check_unsupported_patches() {
for file in "${files[@]}"; do
case "$file" in
lib/*|*.S)
- die "unsupported patch to $file"
+ die "${patch}: unsupported patch to $file"
;;
esac
done
@@ -486,6 +486,7 @@ clean_kernel() {
}
build_kernel() {
+ local build="$1"
local log="$TMP_DIR/build.log"
local objtool_args=()
local cmd=()
@@ -523,7 +524,7 @@ build_kernel() {
"${cmd[@]}" \
1> >(tee -a "$log") \
2> >(tee -a "$log" | grep0 -v "modpost.*undefined!" >&2)
- )
+ ) || die "$build kernel build failed"
}
find_objects() {
@@ -798,7 +799,7 @@ fi
if (( SHORT_CIRCUIT <= 1 )); then
status "Building original kernel"
clean_kernel
- build_kernel
+ build_kernel "original"
status "Copying original object files"
copy_orig_objects
fi
@@ -808,7 +809,7 @@ if (( SHORT_CIRCUIT <= 2 )); then
fix_patches
apply_patches
status "Building patched kernel"
- build_kernel
+ build_kernel "patched"
revert_patches
status "Copying patched object files"
copy_patched_objects
--
2.53.0
^ permalink raw reply related
* [PATCH v4 11/12] livepatch/klp-build: add terminal color output
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
Improve the readability of klp-build output by implementing a basic
color scheme. When the standard output and error are connected to a
terminal, highlight status messages in bold and warning/error prefixes
in yellow/red.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
scripts/livepatch/klp-build | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index cf36555330b3..325dc4601bba 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -52,6 +52,15 @@ PATCH_TMP_DIR="$TMP_DIR/tmp"
KLP_DIFF_LOG="$DIFF_DIR/diff.log"
+# Terminal output colors
+read -r COLOR_RESET COLOR_BOLD COLOR_ERROR COLOR_WARN <<< ""
+if [[ -t 1 && -t 2 ]]; then
+ COLOR_RESET="\033[0m"
+ COLOR_BOLD="\033[1m"
+ COLOR_ERROR="\033[0;31m"
+ COLOR_WARN="\033[0;33m"
+fi
+
grep0() {
# shellcheck disable=SC2317
command grep "$@" || true
@@ -65,15 +74,15 @@ grep() {
}
status() {
- echo "$*"
+ echo -e "${COLOR_BOLD}$*${COLOR_RESET}"
}
warn() {
- echo "error: $SCRIPT: $*" >&2
+ echo -e "${COLOR_WARN}warning${COLOR_RESET}: $SCRIPT: $*" >&2
}
die() {
- warn "$@"
+ echo -e "${COLOR_ERROR}error${COLOR_RESET}: $SCRIPT: $*" >&2
exit 1
}
@@ -110,7 +119,7 @@ cleanup() {
}
trap_err() {
- warn "line ${BASH_LINENO[0]}: '$BASH_COMMAND'"
+ die "line ${BASH_LINENO[0]}: '$BASH_COMMAND'"
}
trap cleanup EXIT INT TERM HUP
--
2.53.0
^ permalink raw reply related
* [PATCH v4 08/12] livepatch/klp-build: improve short-circuit validation
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
Update SHORT_CIRCUIT behavior to better handle patch validation and
argument processing in later klp-build steps.
Perform patch validation for both step 1 (building original kernel) and
step 2 (building patched kernel) to ensure patches are verified before
any compilation occurs.
Additionally, allow the user to omit input patches when skipping past
step 2.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
scripts/livepatch/klp-build | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 374e1261fd7a..60c7635e65c1 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -220,7 +220,7 @@ process_args() {
esac
done
- if [[ $# -eq 0 ]]; then
+ if [[ $# -eq 0 ]] && (( SHORT_CIRCUIT <= 2 )); then
usage
exit 1
fi
@@ -791,9 +791,12 @@ build_patch_module() {
process_args "$@"
do_init
-if (( SHORT_CIRCUIT <= 1 )); then
+if (( SHORT_CIRCUIT <= 2 )); then
status "Validating patch(es)"
validate_patches
+fi
+
+if (( SHORT_CIRCUIT <= 1 )); then
status "Building original kernel"
clean_kernel
build_kernel
--
2.53.0
^ permalink raw reply related
* [PATCH v4 09/12] livepatch/klp-build: Fix inconsistent kernel version
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
From: Josh Poimboeuf <jpoimboe@kernel.org>
If .config hasn't been synced with auto.conf, any recent changes to
CONFIG_LOCALVERSION* may not get reflected in the kernel version name.
Use "make syncconfig" to force them to sync, and "make -s kernelrelease"
to get the version instead of having to construct it manually.
Fixes: 24ebfcd65a87 ("livepatch/klp-build: Introduce klp-build script for generating livepatch modules")
Closes: https://lore.kernel.org/20260217160645.3434685-10-joe.lawrence@redhat.com
Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> [add -s to make kernelrelease]
---
scripts/livepatch/klp-build | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 60c7635e65c1..7f4041a0eefb 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -293,15 +293,14 @@ set_module_name() {
# application from appending it with '+' due to a dirty working tree.
set_kernelversion() {
local file="$SRC/scripts/setlocalversion"
- local localversion
+ local kernelrelease
stash_file "$file"
- localversion="$(cd "$SRC" && make --no-print-directory kernelversion)"
- localversion="$(cd "$SRC" && KERNELVERSION="$localversion" ./scripts/setlocalversion)"
- [[ -z "$localversion" ]] && die "setlocalversion failed"
+ kernelrelease="$(cd "$SRC" && make syncconfig &>/dev/null && make -s kernelrelease)"
+ [[ -z "$kernelrelease" ]] && die "failed to get kernel version"
- sed -i "2i echo $localversion; exit 0" scripts/setlocalversion
+ sed -i "2i echo $kernelrelease; exit 0" scripts/setlocalversion
}
get_patch_input_files() {
--
2.53.0
^ permalink raw reply related
* [PATCH v4 07/12] livepatch/klp-build: fix shellcheck complaints
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
Fix or suppress the following shellcheck warnings:
In klp-build line 57:
command grep "$@" || true
^--^ SC2317 (info): Command appears to be unreachable. Check usage (or ignore if invoked indirectly).
Fix the following warning:
In klp-build line 565:
local file_dir="$(dirname "$file")"
^------^ SC2034 (warning): file_dir appears unused. Verify use (or export if used externally).
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
scripts/livepatch/klp-build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index cf6c2bf694aa..374e1261fd7a 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -53,6 +53,7 @@ PATCH_TMP_DIR="$TMP_DIR/tmp"
KLP_DIFF_LOG="$DIFF_DIR/diff.log"
grep0() {
+ # shellcheck disable=SC2317
command grep "$@" || true
}
@@ -550,7 +551,6 @@ copy_orig_objects() {
for _file in "${files[@]}"; do
local rel_file="${_file/.ko/.o}"
local file="$OBJ/$rel_file"
- local file_dir="$(dirname "$file")"
local orig_file="$ORIG_DIR/$rel_file"
local orig_dir="$(dirname "$orig_file")"
--
2.53.0
^ permalink raw reply related
* [PATCH v4 06/12] livepatch/klp-build: add Makefile with check target
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
Add a standalone Makefile with a 'check' target that runs static code
analysis (shellcheck) on the klp-build script(s). This is intended
strictly as a development aid.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
scripts/livepatch/Makefile | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 scripts/livepatch/Makefile
diff --git a/scripts/livepatch/Makefile b/scripts/livepatch/Makefile
new file mode 100644
index 000000000000..17b590213740
--- /dev/null
+++ b/scripts/livepatch/Makefile
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0
+# Standalone Makefile for developer tooling (not part of kbuild).
+
+SHELLCHECK := $(shell which shellcheck 2> /dev/null)
+
+SRCS := \
+ klp-build
+
+.DEFAULT_GOAL := help
+.PHONY: help
+help:
+ @echo " check - Run shellcheck on $(SRCS)"
+ @echo " help - Show this help message"
+
+.PHONY: check
+check:
+ifndef SHELLCHECK
+ $(error shellcheck is not installed. Please install it to run checks)
+endif
+ @$(SHELLCHECK) $(SHELLCHECK_OPTIONS) $(SRCS)
--
2.53.0
^ permalink raw reply related
* [PATCH v4 05/12] livepatch/klp-build: add grep-override function
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
Provide a custom grep() function to catch direct usage of the command.
Bare grep calls are generally incompatible with pipefail and
errexit behavior (where a failed match causes the script to exit).
Developers can still call grep via command grep if that behavior is
explicitly desired.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
scripts/livepatch/klp-build | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 564985a1588a..cf6c2bf694aa 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -56,6 +56,13 @@ grep0() {
command grep "$@" || true
}
+# Because pipefail is enabled, the grep0 helper should be used instead of
+# grep, otherwise a failed match can propagate to an error.
+grep() {
+ echo "error: $SCRIPT: use grep0 or 'command grep' instead of bare grep" >&2
+ exit 1
+}
+
status() {
echo "$*"
}
--
2.53.0
^ permalink raw reply related
* [PATCH v4 04/12] livepatch/klp-build: switch to GNU patch and recountdiff
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
The klp-build script is currently very strict with input patches,
requiring them to apply cleanly via `git apply --recount`. This
prevents the use of patches with minor contextual fuzz relative to the
target kernel sources.
To allow users to reuse a patch across similar kernel streams, switch to
using GNU patch and patchutils for intermediate patch manipulation.
Update the logic for applying, reverting, and regenerating patches:
- Use 'patch -p1' for better handling of context fuzz.
- Use 'recountdiff' to update line counts after FIX_PATCH_LINES.
- Drop git_refresh() and related git-specific logic.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
scripts/livepatch/klp-build | 59 ++++++++-----------------------------
1 file changed, 13 insertions(+), 46 deletions(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 94ed3b4a91d8..564985a1588a 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -95,7 +95,7 @@ restore_files() {
cleanup() {
set +o nounset
- revert_patches "--recount"
+ revert_patches
restore_files
[[ "$KEEP_TMP" -eq 0 ]] && rm -rf "$TMP_DIR"
return 0
@@ -282,7 +282,7 @@ set_module_name() {
}
# Hardcode the value printed by the localversion script to prevent patch
-# application from appending it with '+' due to a dirty git working tree.
+# application from appending it with '+' due to a dirty working tree.
set_kernelversion() {
local file="$SRC/scripts/setlocalversion"
local localversion
@@ -300,8 +300,8 @@ get_patch_input_files() {
local patch="$1"
grep0 -E '^--- ' "$patch" \
+ | grep0 -v -e '/dev/null' -e '1969-12-31' -e '1970-01-01' \
| gawk '{print $2}' \
- | grep0 -v '^/dev/null$' \
| sed 's|^[^/]*/||' \
| sort -u
}
@@ -310,8 +310,8 @@ get_patch_output_files() {
local patch="$1"
grep0 -E '^\+\+\+ ' "$patch" \
+ | grep0 -v -e '/dev/null' -e '1969-12-31' -e '1970-01-01' \
| gawk '{print $2}' \
- | grep0 -v '^/dev/null$' \
| sed 's|^[^/]*/||' \
| sort -u
}
@@ -323,21 +323,6 @@ get_patch_files() {
| sort -u
}
-# Make sure git re-stats the changed files
-git_refresh() {
- local patch="$1"
- local files=()
-
- [[ ! -e "$SRC/.git" ]] && return
-
- get_patch_input_files "$patch" | mapfile -t files
-
- (
- cd "$SRC"
- git update-index -q --refresh -- "${files[@]}"
- )
-}
-
check_unsupported_patches() {
local patch
@@ -358,36 +343,19 @@ check_unsupported_patches() {
apply_patch() {
local patch="$1"
- shift
- local extra_args=("$@")
[[ ! -f "$patch" ]] && die "$patch doesn't exist"
-
- (
- cd "$SRC"
-
- # The sed strips the version signature from 'git format-patch',
- # otherwise 'git apply --recount' warns.
- sed -n '/^-- /q;p' "$patch" |
- git apply "${extra_args[@]}"
- )
+ patch -d "$SRC" -p1 --dry-run --silent --no-backup-if-mismatch -r /dev/null < "$patch"
+ patch -d "$SRC" -p1 --silent --no-backup-if-mismatch -r /dev/null < "$patch"
APPLIED_PATCHES+=("$patch")
}
revert_patch() {
local patch="$1"
- shift
- local extra_args=("$@")
local tmp=()
- (
- cd "$SRC"
-
- sed -n '/^-- /q;p' "$patch" |
- git apply --reverse "${extra_args[@]}"
- )
- git_refresh "$patch"
+ patch -d "$SRC" -p1 -R --silent --no-backup-if-mismatch -r /dev/null < "$patch"
for p in "${APPLIED_PATCHES[@]}"; do
[[ "$p" == "$patch" ]] && continue
@@ -406,11 +374,10 @@ apply_patches() {
}
revert_patches() {
- local extra_args=("$@")
local patches=("${APPLIED_PATCHES[@]}")
for (( i=${#patches[@]}-1 ; i>=0 ; i-- )) ; do
- revert_patch "${patches[$i]}" "${extra_args[@]}"
+ revert_patch "${patches[$i]}"
done
APPLIED_PATCHES=()
@@ -434,6 +401,7 @@ do_init() {
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
@@ -459,12 +427,12 @@ refresh_patch() {
( cd "$SRC" && echo "${input_files[@]}" | xargs cp --parents --target-directory="$tmpdir/a" )
# Copy patched source files to 'b'
- apply_patch "$patch" --recount
+ apply_patch "$patch"
( cd "$SRC" && echo "${output_files[@]}" | xargs cp --parents --target-directory="$tmpdir/b" )
- revert_patch "$patch" --recount
+ revert_patch "$patch"
# Diff 'a' and 'b' to make a clean patch
- ( cd "$tmpdir" && git diff --no-index --no-prefix a b > "$patch" ) || true
+ ( cd "$tmpdir" && diff -Nupr a b > "$patch" ) || true
}
# Copy the patches to a temporary directory, fix their lines so as not to
@@ -487,8 +455,7 @@ fix_patches() {
cp -f "$old_patch" "$tmp_patch"
refresh_patch "$tmp_patch"
- "$FIX_PATCH_LINES" "$tmp_patch" > "$new_patch"
- refresh_patch "$new_patch"
+ "$FIX_PATCH_LINES" "$tmp_patch" | recountdiff > "$new_patch"
PATCHES[i]="$new_patch"
--
2.53.0
^ permalink raw reply related
* [PATCH v4 03/12] livepatch/klp-build: support patches that add/remove files
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
The klp-build script prepares a clean patch by populating two temporary
directories ('a' and 'b') with source files and diffing the result.
However, this process fails when a patch introduces a new source file,
as the script attempts to copy files that do not yet exist in the
original source tree. Likewise, it fails when a patch removes a source
file and the script attempts to copy a file that no longer exists.
Refactor the file-gathering logic to distinguish between original input
files and patched output files:
- Split get_patch_files() into get_patch_input_files() and
get_patch_output_files() to identify which files exist before and
after patch application.
- Filter out "/dev/null" from both to handle file creation/deletion.
- Update refresh_patch() to only copy existing input files to the 'a'
directory and the resulting output files to the 'b' directory.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
scripts/livepatch/klp-build | 34 +++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 809e198a561d..94ed3b4a91d8 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -296,15 +296,33 @@ set_kernelversion() {
sed -i "2i echo $localversion; exit 0" scripts/setlocalversion
}
-get_patch_files() {
+get_patch_input_files() {
+ local patch="$1"
+
+ grep0 -E '^--- ' "$patch" \
+ | gawk '{print $2}' \
+ | grep0 -v '^/dev/null$' \
+ | sed 's|^[^/]*/||' \
+ | sort -u
+}
+
+get_patch_output_files() {
local patch="$1"
- grep0 -E '^(--- |\+\+\+ )' "$patch" \
+ grep0 -E '^\+\+\+ ' "$patch" \
| gawk '{print $2}' \
+ | grep0 -v '^/dev/null$' \
| sed 's|^[^/]*/||' \
| sort -u
}
+get_patch_files() {
+ local patch="$1"
+
+ { get_patch_input_files "$patch"; get_patch_output_files "$patch"; } \
+ | sort -u
+}
+
# Make sure git re-stats the changed files
git_refresh() {
local patch="$1"
@@ -312,7 +330,7 @@ git_refresh() {
[[ ! -e "$SRC/.git" ]] && return
- get_patch_files "$patch" | mapfile -t files
+ get_patch_input_files "$patch" | mapfile -t files
(
cd "$SRC"
@@ -426,21 +444,23 @@ do_init() {
refresh_patch() {
local patch="$1"
local tmpdir="$PATCH_TMP_DIR"
- local files=()
+ local input_files=()
+ local output_files=()
rm -rf "$tmpdir"
mkdir -p "$tmpdir/a"
mkdir -p "$tmpdir/b"
# Get all source files affected by the patch
- get_patch_files "$patch" | mapfile -t files
+ get_patch_input_files "$patch" | mapfile -t input_files
+ get_patch_output_files "$patch" | mapfile -t output_files
# Copy orig source files to 'a'
- ( cd "$SRC" && echo "${files[@]}" | xargs cp --parents --target-directory="$tmpdir/a" )
+ ( cd "$SRC" && echo "${input_files[@]}" | xargs cp --parents --target-directory="$tmpdir/a" )
# Copy patched source files to 'b'
apply_patch "$patch" --recount
- ( cd "$SRC" && echo "${files[@]}" | xargs cp --parents --target-directory="$tmpdir/b" )
+ ( cd "$SRC" && echo "${output_files[@]}" | xargs cp --parents --target-directory="$tmpdir/b" )
revert_patch "$patch" --recount
# Diff 'a' and 'b' to make a clean patch
--
2.53.0
^ permalink raw reply related
* [PATCH v4 02/12] objtool/klp: fix mkstemp() failure with long paths
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
The elf_create_file() function fails with EINVAL when the build directory
path is long enough to truncate the "XXXXXX" suffix in the 256-byte
tmp_name buffer.
Simplify the code to remove the unnecessary dirname()/basename() split
and concatenation. Instead, allocate the exact number of bytes needed for
the path.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
tools/objtool/elf.c | 23 +++--------------------
1 file changed, 3 insertions(+), 20 deletions(-)
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 3da90686350d..2ffe3ebfbe37 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -16,7 +16,6 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
-#include <libgen.h>
#include <ctype.h>
#include <linux/align.h>
#include <linux/kernel.h>
@@ -1189,7 +1188,7 @@ struct elf *elf_open_read(const char *name, int flags)
struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name)
{
struct section *null, *symtab, *strtab, *shstrtab;
- char *dir, *base, *tmp_name;
+ char *tmp_name;
struct symbol *sym;
struct elf *elf;
@@ -1203,29 +1202,13 @@ struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name)
INIT_LIST_HEAD(&elf->sections);
- dir = strdup(name);
- if (!dir) {
- ERROR_GLIBC("strdup");
- return NULL;
- }
-
- dir = dirname(dir);
-
- base = strdup(name);
- if (!base) {
- ERROR_GLIBC("strdup");
- return NULL;
- }
-
- base = basename(base);
-
- tmp_name = malloc(256);
+ tmp_name = malloc(strlen(name) + 8);
if (!tmp_name) {
ERROR_GLIBC("malloc");
return NULL;
}
- snprintf(tmp_name, 256, "%s/%s.XXXXXX", dir, base);
+ sprintf(tmp_name, "%s.XXXXXX", name);
elf->fd = mkstemp(tmp_name);
if (elf->fd == -1) {
--
2.53.0
^ permalink raw reply related
* [PATCH v4 01/12] objtool/klp: fix data alignment in __clone_symbol()
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
In-Reply-To: <20260310203751.1479229-1-joe.lawrence@redhat.com>
Commit 356e4b2f5b80 ("objtool: Fix data alignment in elf_add_data()")
corrected the alignment of data within a section (honoring the section's
sh_addralign). Apply the same alignment when klp-diff mode clones a
symbol, adjusting the new symbol's offset for the output section's
sh_addralign.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
tools/objtool/klp-diff.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index a3198a63c2f0..c2c4e4968bc2 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -14,6 +14,7 @@
#include <objtool/util.h>
#include <arch/special.h>
+#include <linux/align.h>
#include <linux/objtool_types.h>
#include <linux/livepatch_external.h>
#include <linux/stringify.h>
@@ -560,7 +561,7 @@ static struct symbol *__clone_symbol(struct elf *elf, struct symbol *patched_sym
}
if (!is_sec_sym(patched_sym))
- offset = sec_size(out_sec);
+ offset = ALIGN(sec_size(out_sec), out_sec->sh.sh_addralign);
if (patched_sym->len || is_sec_sym(patched_sym)) {
void *data = NULL;
--
2.53.0
^ permalink raw reply related
* [PATCH v4 00/12] livepatch-klp-build: small fixups and enhancements
From: Joe Lawrence @ 2026-03-10 20:37 UTC (permalink / raw)
To: live-patching
Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
Petr Mladek
v4:
- Rebased on 9a73f085dc91 (tip/objtool/urgent)
- Dropped elf_add_data() fix, added __clone_symbol() align fix [Josh]
- Adopted Josh's kernel version fix [Josh]
- Updated friendly msg, "foo.patch: unsupported patch to bar.c" [Josh]
- s/warn:/warning:/, trap_err -> die, and commit msg clarification on
colorization commit [Josh]
- Use "fuzz" instead of "drift", adjust output ordering, and send patch
cmd errors to stderr [Josh]
- Dropped ("livepatch/klp-build: don't look for changed objects in
tools/") for now
- Added Song's Acks [Song]
v3: https://lore.kernel.org/live-patching/20260217160645.3434685-1-joe.lawrence@redhat.com/T/#t
- Added a patch to objtool ELF code to fix packed string section alignment
- Simplified the mkstemp() patch and surrounding code [Josh]
- Added patches to catch grep use, add Makefile shellcheck, and fix
current shellcheck warnings [Josh]
- Simplified the short-circuit validation patch [Josh]
- Added a patch to fix short-circuit version mismatch
- Pretty-print output in color [Josh]
- Reduce 'patch' chatter to fuzz/offset warning during patch validation
- Prune tools/ from paths that find_objects() looks for changed objects
v2: https://lore.kernel.org/live-patching/20260204025140.2023382-1-joe.lawrence@redhat.com/
- Update patch subject prefixes accordingly [Josh]
- Added a small objtool/klp patch. Test systems setup crazy long
pathnames :D
- Removed patch ("limit parent .git directory search") as this version
replaces the use of git apply --recount with patch and recountdiff.
A side effect of this simplification was no longer needing this weird
hack. [Josh]
- Updated the patch that handles input patches that add files to also
support removing files, implement this by directly inspecting the
.patch +++ and --- header lines via two file lists [Josh]
- Implement two short-circuiting updates: validate patches for steps 1
and 2, and allow the user to omit patches for steps 3 and 4. This
combines the original 'fail-fast' patch and some related notes on the
v1 thread. [Josh]
- Since v2 replaces git apply with patch and recountdiff, there is no
need for a -z/--fuzz argument, it comes with GNU patch for free.
v1: https://lore.kernel.org/live-patching/CAPhsuW5qrueccM123YbTo2ZvP-Rf+0UT-goG6c5A8gXw7BsF3w@mail.gmail.com/T/#t
Joe Lawrence (11):
objtool/klp: fix data alignment in __clone_symbol()
objtool/klp: fix mkstemp() failure with long paths
livepatch/klp-build: support patches that add/remove files
livepatch/klp-build: switch to GNU patch and recountdiff
livepatch/klp-build: add grep-override function
livepatch/klp-build: add Makefile with check target
livepatch/klp-build: fix shellcheck complaints
livepatch/klp-build: improve short-circuit validation
livepatch/klp-build: provide friendlier error messages
livepatch/klp-build: add terminal color output
livepatch/klp-build: report patch validation fuzz
Josh Poimboeuf (1):
livepatch/klp-build: Fix inconsistent kernel version
scripts/livepatch/Makefile | 20 ++++++
scripts/livepatch/klp-build | 140 ++++++++++++++++++++----------------
tools/objtool/elf.c | 23 +-----
tools/objtool/klp-diff.c | 3 +-
4 files changed, 105 insertions(+), 81 deletions(-)
create mode 100644 scripts/livepatch/Makefile
--
2.53.0
^ permalink raw reply
* Re: [PATCH v3 01/13] objtool/klp: honor SHF_MERGE entry alignment in elf_add_data()
From: Josh Poimboeuf @ 2026-03-10 16:34 UTC (permalink / raw)
To: Joe Lawrence
Cc: live-patching, Song Liu, Jiri Kosina, Miroslav Benes, Petr Mladek
In-Reply-To: <abAkkrWoTao_tIi7@redhat.com>
On Tue, Mar 10, 2026 at 10:02:58AM -0400, Joe Lawrence wrote:
> LMK if you want me to update the patch in this set, or drop it here so
> you can update in ("objtool/arm64: Port klp-build to arm64").
I actually already merged that one into tip/objtool/urgent (356e4b2f5b80
("objtool: Fix data alignment in elf_add_data()")), so please create a
separate fix based on tip/objtool/urgent, and make it the first patch of
your series so I can easily grab it.
Also, FYI, I'm starting PTO today, so I may be slow to respond the rest
of the week.
--
Josh
^ permalink raw reply
* Re: [PATCH] klp-build: Fix inconsistent kernel version
From: Josh Poimboeuf @ 2026-03-10 16:30 UTC (permalink / raw)
To: Joe Lawrence
Cc: live-patching, Song Liu, Jiri Kosina, Miroslav Benes, Petr Mladek
In-Reply-To: <abAghiWvh3BeJNp9@redhat.com>
On Tue, Mar 10, 2026 at 09:45:42AM -0400, Joe Lawrence wrote:
> On Thu, Mar 05, 2026 at 02:52:46PM -0800, Josh Poimboeuf wrote:
> > If .config hasn't been synced with auto.conf, any recent changes to
> > CONFIG_LOCALVERSION* may not get reflected in the kernel version name.
> >
> > Use "make syncconfig" to force them to sync, and "make kernelrelease" to
> > get the version instead of having to construct it manually.
> >
> > Fixes: 24ebfcd65a87 ("livepatch/klp-build: Introduce klp-build script for generating livepatch modules")
> > Closes: https://lore.kernel.org/20260217160645.3434685-10-joe.lawrence@redhat.com
> > Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
> > Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> > ---
> > scripts/livepatch/klp-build | 9 ++++-----
> > 1 file changed, 4 insertions(+), 5 deletions(-)
> >
> > diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
> > index 809e198a561d..72f05c40b9f8 100755
> > --- a/scripts/livepatch/klp-build
> > +++ b/scripts/livepatch/klp-build
> > @@ -285,15 +285,14 @@ set_module_name() {
> > # application from appending it with '+' due to a dirty git working tree.
> > set_kernelversion() {
> > local file="$SRC/scripts/setlocalversion"
> > - local localversion
> > + local kernelrelease
> >
> > stash_file "$file"
> >
> > - localversion="$(cd "$SRC" && make --no-print-directory kernelversion)"
> > - localversion="$(cd "$SRC" && KERNELVERSION="$localversion" ./scripts/setlocalversion)"
> > - [[ -z "$localversion" ]] && die "setlocalversion failed"
> > + kernelrelease="$(cd "$SRC" && make syncconfig &>/dev/null && make kernelrelease)"
>
> Almost, I needed to add '-s' to the kernelversion target to silence the
> make "entering / leaving directory" msgs and then this worked for me.
>
> There's some makefile voodoo going on here where when I manually run
> `make kernelrelease` I don't see the verbose msgs, but I printed
> "$kernelrelease" here in klp-build and on my machine (make v4.4.1), that
> extra output derailed the script.
>
> Anyway, `make help` says:
>
> kernelrelease - Output the release version string (use with make -s)
>
> so we should probably use '-s' regardless.
>
> With that, shall I drop my ("livepatch/klp-build: fix version mismatch
> when short-circuiting") and carry yours in its place?
Yes, I think so. Thanks!
--
Josh
^ permalink raw reply
* Re: [PATCH 07/14] objtool: Extricate checksum calculation from validate_branch()
From: Josh Poimboeuf @ 2026-03-10 16:27 UTC (permalink / raw)
To: Miroslav Benes
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
In-Reply-To: <alpine.LSU.2.21.2603101144410.14672@pobox.suse.cz>
On Tue, Mar 10, 2026 at 11:47:41AM +0100, Miroslav Benes wrote:
> Hi,
>
> > @@ -3691,9 +3691,30 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
> > struct instruction *insn)
> > {
> > struct reloc *reloc = insn_reloc(file, insn);
> > + struct alternative *alt;
> > unsigned long offset;
> > struct symbol *sym;
> >
> > + for (alt = insn->alts; alt; alt = alt->next) {
> > + struct alt_group *alt_group = alt->insn->alt_group;
> > +
> > + checksum_update(func, insn, &alt->type, sizeof(alt->type));
> > +
> > + if (alt_group && alt_group->orig_group) {
> > + struct instruction *alt_insn;
> > +
> > + checksum_update(func, insn, &alt_group->feature, sizeof(alt_group->feature));
> > +
> > + for (alt_insn = alt->insn; alt_insn; alt_insn = next_insn_same_sec(file, alt_insn)) {
> > + checksum_update_insn(file, func, alt_insn);
> > + if (alt_insn == alt_group->last_insn)
> > + break;
> > + }
> > + } else {
> > + checksum_update(func, insn, &alt->insn->offset, sizeof(alt->insn->offset));
> > + }
> > + }
> > +
>
> does this hunk belong to the patch? Unless I am missing something, it
> might be worth a separate one.
It belongs, but I should have clarified that in the patch description.
This hunk wasn't needed before because validate_branch() already
iterates all the alternatives, so it was calling checksum_update_insn()
for every instruction in the function, including the alternatives.
Now that it's no longer called by validate_branch(),
checksum_update_insn() has to manually iterate the alternatives.
--
Josh
^ permalink raw reply
* Re: [PATCH v3 01/13] objtool/klp: honor SHF_MERGE entry alignment in elf_add_data()
From: Joe Lawrence @ 2026-03-10 14:02 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: live-patching, Song Liu, Jiri Kosina, Miroslav Benes, Petr Mladek
In-Reply-To: <p67ixebt5ufjed44j6wrufwihmsh3ufhbdog7767ro6tygleaw@lvp55v6brjxw>
On Wed, Mar 04, 2026 at 06:33:47PM -0800, Josh Poimboeuf wrote:
> On Tue, Feb 17, 2026 at 11:14:17AM -0500, Joe Lawrence wrote:
> > On Tue, Feb 17, 2026 at 11:06:32AM -0500, Joe Lawrence wrote:
> > > When adding data to an SHF_MERGE section, set the Elf_Data d_align to
> > > the section's sh_addralign so libelf aligns entries within the section.
> > > This ensures that entry offsets are consistent with previously calculated
> > > relocation addends.
> > >
> > > Fixes: 431dbabf2d9d ("objtool: Add elf_create_data()")
> > > Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
> > > ---
> > > tools/objtool/elf.c | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
> > > index 2c02c7b49265..bd6502e7bdc0 100644
> > > --- a/tools/objtool/elf.c
> > > +++ b/tools/objtool/elf.c
> > > @@ -1375,7 +1375,7 @@ void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_
> > > memcpy(sec->data->d_buf, data, size);
> > >
> > > sec->data->d_size = size;
> > > - sec->data->d_align = 1;
> > > + sec->data->d_align = (sec->sh.sh_flags & SHF_MERGE) ? sec->sh.sh_addralign : 1;
> > >
> > > offset = ALIGN(sec->sh.sh_size, sec->sh.sh_addralign);
> > > sec->sh.sh_size = offset + size;
> > > --
> > > 2.53.0
> > >
> > >
> >
> > This one stretches my ELF internals knowledge a bit, is ^^ true or
> > should we rely on the section ".str1.8" suffix to indicate internal
> > alignment?
>
> I hit the same issue in my testing for the klp-build arm64 port, I think
> it can be simplified to the below?
>
> diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
> @@ -1375,7 +1382,7 @@ void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_
> memcpy(sec->data->d_buf, data, size);
>
> sec->data->d_size = size;
> - sec->data->d_align = 1;
> + sec->data->d_align = sec->sh.sh_addralign;
>
> offset = ALIGN(sec->sh.sh_size, sec->sh.sh_addralign);
> sec->sh.sh_size = offset + size;
>
Yeah that make sense, but I think we both missed the second half of the
fix in the symbol table. This patch fails with your version:
-->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8--
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
--- a/fs/proc/stat.c
+++ b/fs/proc/stat.c
@@ -54,6 +54,13 @@ static u64 get_iowait_time(struct kernel_cpustat *kcs, int cpu)
return iowait;
}
+static void klp_test_stat_accessed(void)
+{
+ static atomic_t call_count = ATOMIC_INIT(0);
+ atomic_inc(&call_count);
+ pr_info("klp-build-test: stat accessed %d times\n", atomic_read(&call_count));
+}
+
static int show_stat(struct seq_file *p, void *v)
{
int i, j;
@@ -92,6 +99,7 @@ static int show_stat(struct seq_file *p, void *v)
user = nice = system = idle = iowait =
irq = softirq = steal = 0;
guest = guest_nice = 0;
+ klp_test_stat_accessed();
getboottime64(&boottime);
/* shift boot timestamp according to the timens offset */
timens_sub_boottime(&boottime);
-->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8--
Confused on instruction decoding?
livepatch-test.o: warning: objtool: show_stat+0x696: can't find jump dest instruction at .rodata.show_stat.str1.1+0x38
make[3]: *** [/root/linux/scripts/Makefile.build:505: livepatch-test.o] Error 255
make[3]: *** Deleting file 'livepatch-test.o'
make[2]: *** [/root/linux/Makefile:2064: .] Error 2
make[1]: *** [/root/linux/Makefile:248: __sub-make] Error 2
make: *** [Makefile:248: __sub-make] Error 2
error: klp-build: line 793: '"${cmd[@]}" > >(tee -a "$log") 2> >(tee -a "$log" 1>&2)'
error: klp-build: line 795: '( cd "$SRC"; "${cmd[@]}" > >(tee -a "$log") 2> >(tee -a "$log" 1>&2) )'
Notice the 0x10 section offset value for show_stat in the generated
vmlinux.o diff object symbol table:
$ readelf --wide --symbols klp-tmp/diff/vmlinux.o | grep -E 'Ndx|\.text\.show_stat$|show_stat$|pfx_show_stat$'
Num: Value Size Type Bind Vis Ndx Name
1: 0000000000000000 16 FUNC LOCAL DEFAULT 4 __pfx_show_stat
2: 0000000000000010 2126 FUNC LOCAL DEFAULT 4 show_stat
5: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .text.show_stat
but then in the disassembly, show_stat() starts 0x20 bytes into the
section:
$ objdump -d -j .text.show_stat --start-address=0x0 --stop-address=0x24 klp-tmp/diff/vmlinux.o
klp-tmp/diff/vmlinux.o: file format elf64-x86-64
Disassembly of section .text.show_stat:
0000000000000000 <__pfx_show_stat>:
0: 90 nop
1: 90 nop
2: 90 nop
3: 90 nop
4: 90 nop
5: 90 nop
6: 90 nop
7: 90 nop
8: 90 nop
9: 90 nop
a: 90 nop
b: 90 nop
c: 90 nop
d: 90 nop
e: 90 nop
f: 90 nop
0000000000000010 <show_stat>:
...
20: f3 0f 1e fa endbr64
When cloning the symbol, if we ensure the symbol's offset aligns
with the sh_addralign (as elf_add_data() does now):
-->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8--
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index a3198a63c2..c2c4e4968b 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -14,6 +14,7 @@
#include <objtool/util.h>
#include <arch/special.h>
+#include <linux/align.h>
#include <linux/objtool_types.h>
#include <linux/livepatch_external.h>
#include <linux/stringify.h>
@@ -560,7 +561,7 @@ static struct symbol *__clone_symbol(struct elf *elf, struct symbol *patched_sym
}
if (!is_sec_sym(patched_sym))
- offset = sec_size(out_sec);
+ offset = ALIGN(sec_size(out_sec), out_sec->sh.sh_addralign);
if (patched_sym->len || is_sec_sym(patched_sym)) {
void *data = NULL;
-->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8--
Results are as expected:
$ readelf --wide --symbols klp-tmp/diff/vmlinux.o | grep -E 'Ndx|\.text\.show_stat$|show_stat$|pfx_show_stat$'
Num: Value Size Type Bind Vis Ndx Name
1: 0000000000000000 16 FUNC LOCAL DEFAULT 4 __pfx_show_stat
2: 0000000000000020 2126 FUNC LOCAL DEFAULT 4 show_stat
5: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .text.show_stat
$ objdump -d -j .text.show_stat --start-address=0x0 --stop-address=0x24 klp-tmp/diff/vmlinux.o
klp-tmp/diff/vmlinux.o: file format elf64-x86-64
Disassembly of section .text.show_stat:
0000000000000000 <__pfx_show_stat>:
0: 90 nop
1: 90 nop
2: 90 nop
3: 90 nop
4: 90 nop
5: 90 nop
6: 90 nop
7: 90 nop
8: 90 nop
9: 90 nop
a: 90 nop
b: 90 nop
c: 90 nop
d: 90 nop
e: 90 nop
f: 90 nop
...
0000000000000020 <show_stat>:
20: f3 0f 1e fa endbr64
LMK if you want me to update the patch in this set, or drop it here so
you can update in ("objtool/arm64: Port klp-build to arm64").
Thanks,
--
Joe
^ permalink raw reply related
* Re: [PATCH] klp-build: Fix inconsistent kernel version
From: Joe Lawrence @ 2026-03-10 13:45 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: live-patching, Song Liu, Jiri Kosina, Miroslav Benes, Petr Mladek
In-Reply-To: <noyyhysipjm6aw4td6q4mg6n4c637unfgmkn35otopu3rbqugj@ekzuix6lsb6p>
On Thu, Mar 05, 2026 at 02:52:46PM -0800, Josh Poimboeuf wrote:
> If .config hasn't been synced with auto.conf, any recent changes to
> CONFIG_LOCALVERSION* may not get reflected in the kernel version name.
>
> Use "make syncconfig" to force them to sync, and "make kernelrelease" to
> get the version instead of having to construct it manually.
>
> Fixes: 24ebfcd65a87 ("livepatch/klp-build: Introduce klp-build script for generating livepatch modules")
> Closes: https://lore.kernel.org/20260217160645.3434685-10-joe.lawrence@redhat.com
> Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> ---
> scripts/livepatch/klp-build | 9 ++++-----
> 1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
> index 809e198a561d..72f05c40b9f8 100755
> --- a/scripts/livepatch/klp-build
> +++ b/scripts/livepatch/klp-build
> @@ -285,15 +285,14 @@ set_module_name() {
> # application from appending it with '+' due to a dirty git working tree.
> set_kernelversion() {
> local file="$SRC/scripts/setlocalversion"
> - local localversion
> + local kernelrelease
>
> stash_file "$file"
>
> - localversion="$(cd "$SRC" && make --no-print-directory kernelversion)"
> - localversion="$(cd "$SRC" && KERNELVERSION="$localversion" ./scripts/setlocalversion)"
> - [[ -z "$localversion" ]] && die "setlocalversion failed"
> + kernelrelease="$(cd "$SRC" && make syncconfig &>/dev/null && make kernelrelease)"
Almost, I needed to add '-s' to the kernelversion target to silence the
make "entering / leaving directory" msgs and then this worked for me.
There's some makefile voodoo going on here where when I manually run
`make kernelrelease` I don't see the verbose msgs, but I printed
"$kernelrelease" here in klp-build and on my machine (make v4.4.1), that
extra output derailed the script.
Anyway, `make help` says:
kernelrelease - Output the release version string (use with make -s)
so we should probably use '-s' regardless.
With that, shall I drop my ("livepatch/klp-build: fix version mismatch
when short-circuiting") and carry yours in its place?
--
Joe
^ permalink raw reply
* Re: [PATCH 07/14] objtool: Extricate checksum calculation from validate_branch()
From: Miroslav Benes @ 2026-03-10 10:47 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
In-Reply-To: <7a1e22454a3fd1d968775c24aa0529a4ec7c5886.1772681234.git.jpoimboe@kernel.org>
Hi,
> @@ -3691,9 +3691,30 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
> struct instruction *insn)
> {
> struct reloc *reloc = insn_reloc(file, insn);
> + struct alternative *alt;
> unsigned long offset;
> struct symbol *sym;
>
> + for (alt = insn->alts; alt; alt = alt->next) {
> + struct alt_group *alt_group = alt->insn->alt_group;
> +
> + checksum_update(func, insn, &alt->type, sizeof(alt->type));
> +
> + if (alt_group && alt_group->orig_group) {
> + struct instruction *alt_insn;
> +
> + checksum_update(func, insn, &alt_group->feature, sizeof(alt_group->feature));
> +
> + for (alt_insn = alt->insn; alt_insn; alt_insn = next_insn_same_sec(file, alt_insn)) {
> + checksum_update_insn(file, func, alt_insn);
> + if (alt_insn == alt_group->last_insn)
> + break;
> + }
> + } else {
> + checksum_update(func, insn, &alt->insn->offset, sizeof(alt->insn->offset));
> + }
> + }
> +
does this hunk belong to the patch? Unless I am missing something, it
might be worth a separate one.
Miroslav
^ permalink raw reply
* Re: [PATCH kbuild v2] kbuild: Reduce the number of compiler-generated suffixes for clang thin-lto build
From: Josh Poimboeuf @ 2026-03-10 3:49 UTC (permalink / raw)
To: Yonghong Song
Cc: linux-kbuild, live-patching, kernel-team, Nathan Chancellor,
Nicolas Schier, Song Liu
In-Reply-To: <20260307050250.3767489-1-yonghong.song@linux.dev>
On Fri, Mar 06, 2026 at 09:02:50PM -0800, Yonghong Song wrote:
> The current clang thin-lto build often produces lots of symbols with
> suffix. The following is a partial list of such function call symbols:
> ...
> ethnl_module_fw_flash_ntf.llvm.7631589765585346066
> __nf_conntrack_alloc.llvm.6438426151906658917
> tcp_can_early_drop.llvm.11937612064648250727
> tcp_print_conntrack.llvm.11937612064648250727
> ...
>
> In my particular build with current bpf-next, the number of '*.llvm.<hash>'
> function calls is 1212. As the side effect of cross-file inlining,
> some static variables may be promoted with '*.llvm.<hash>' as well.
> In my same setup, the number of variables with such suffixes is 9.
>
> Such symbols make kernel live patching difficult since
> - a minor code change will change the hash and then the '*.llvm.<hash>'
> symbol becomes another one with a different hash. Sometimes, maybe
> the suffix is gone.
> - a previous source-level symbol may become a one with suffix after live
> patching code.
>
> In [1], Song Liu suggested to reduce the number of '*.llvm.<hash>' functions
> to make live patch easier. In respond of this, I implemented this
> in llvm ([2]). The same thin-lto build with [2] only has two symbols with
> suffix:
> m_stop.llvm.14460341347352036579
> m_next.llvm.14460341347352036579
> This should make live patch much easier.
>
> To support suffix symbol reduction, two lld flags are necessary to enable
> this feature in kernel:
> - Flag '--lto-whole-program-visibility' is needed as it ensures that all
> non-assembly files are available in the same thin-lto lld, which is true
> for kernel.
> - Flag '-mllvm -always-rename-promoted-locals=false' is needed to enable
> suffix reduction. Currently in llvm [1], only process mode is supported.
> There is another distributed mode (across different processes or even
> different machines) which is not supported yet ([2]). The kernel uses
> process mode so it should work.
>
> The assembly files may have some global functions/data which may potentially
> conflict with thin-lto global symbols after the above two flags. But such assembly
> global symbols are limited and tend to be uniquely named for its context.
> Hence the conflict with globals in non-assembly codes is rare. If indeed the
> conflict happens, we can rename either of them to avoid conflicts.
>
> Nathan Chancellor suggested the following under thin-lto:
> KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)
> The '-mllvm -always-rename-promoted-locals=false' flag is only available for llvm23.
> So for llvm22 or earlier, the above KBUILD_LDFLAGS will ignore those two flags.
> For llvm23 and later, two flags will be added to KBUILD_LDFLAGS.
>
> [1] https://lpc.events/event/19/contributions/2212
> [2] https://github.com/llvm/llvm-project/pull/178587
>
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> ---
> Makefile | 1 +
> 1 file changed, 1 insertion(+)
>
> Changelog:
> v1 -> v2:
> - v1: https://lore.kernel.org/linux-kbuild/20260306034325.3605301-1-yonghong.song@linux.dev/
> - Removed the new config option and use ld-option to check whether new flags
> will be used or not.
>
> diff --git a/Makefile b/Makefile
> index e944c6e71e81..e4385af16985 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1034,6 +1034,7 @@ endif
> ifdef CONFIG_LTO_CLANG
> ifdef CONFIG_LTO_CLANG_THIN
> CC_FLAGS_LTO := -flto=thin -fsplit-lto-unit
> +KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)
> else
> CC_FLAGS_LTO := -flto
> endif
Thanks, this will help a lot with livepatch module generation.
Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
--
Josh
^ permalink raw reply
* Re: [PATCH kbuild v2] kbuild: Reduce the number of compiler-generated suffixes for clang thin-lto build
From: Nathan Chancellor @ 2026-03-10 3:14 UTC (permalink / raw)
To: Yonghong Song
Cc: linux-kbuild, live-patching, Josh Poimboeuf, kernel-team,
Nicolas Schier, Song Liu
In-Reply-To: <20260307050250.3767489-1-yonghong.song@linux.dev>
On Fri, Mar 06, 2026 at 09:02:50PM -0800, Yonghong Song wrote:
> The current clang thin-lto build often produces lots of symbols with
> suffix. The following is a partial list of such function call symbols:
> ...
> ethnl_module_fw_flash_ntf.llvm.7631589765585346066
> __nf_conntrack_alloc.llvm.6438426151906658917
> tcp_can_early_drop.llvm.11937612064648250727
> tcp_print_conntrack.llvm.11937612064648250727
> ...
>
> In my particular build with current bpf-next, the number of '*.llvm.<hash>'
> function calls is 1212. As the side effect of cross-file inlining,
> some static variables may be promoted with '*.llvm.<hash>' as well.
> In my same setup, the number of variables with such suffixes is 9.
>
> Such symbols make kernel live patching difficult since
> - a minor code change will change the hash and then the '*.llvm.<hash>'
> symbol becomes another one with a different hash. Sometimes, maybe
> the suffix is gone.
> - a previous source-level symbol may become a one with suffix after live
> patching code.
>
> In [1], Song Liu suggested to reduce the number of '*.llvm.<hash>' functions
> to make live patch easier. In respond of this, I implemented this
> in llvm ([2]). The same thin-lto build with [2] only has two symbols with
> suffix:
> m_stop.llvm.14460341347352036579
> m_next.llvm.14460341347352036579
> This should make live patch much easier.
>
> To support suffix symbol reduction, two lld flags are necessary to enable
> this feature in kernel:
> - Flag '--lto-whole-program-visibility' is needed as it ensures that all
> non-assembly files are available in the same thin-lto lld, which is true
> for kernel.
> - Flag '-mllvm -always-rename-promoted-locals=false' is needed to enable
> suffix reduction. Currently in llvm [1], only process mode is supported.
> There is another distributed mode (across different processes or even
> different machines) which is not supported yet ([2]). The kernel uses
> process mode so it should work.
>
> The assembly files may have some global functions/data which may potentially
> conflict with thin-lto global symbols after the above two flags. But such assembly
> global symbols are limited and tend to be uniquely named for its context.
> Hence the conflict with globals in non-assembly codes is rare. If indeed the
> conflict happens, we can rename either of them to avoid conflicts.
>
> Nathan Chancellor suggested the following under thin-lto:
> KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)
> The '-mllvm -always-rename-promoted-locals=false' flag is only available for llvm23.
> So for llvm22 or earlier, the above KBUILD_LDFLAGS will ignore those two flags.
> For llvm23 and later, two flags will be added to KBUILD_LDFLAGS.
>
> [1] https://lpc.events/event/19/contributions/2212
> [2] https://github.com/llvm/llvm-project/pull/178587
>
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nathan Chancellor <nathan@kernel.org> # build
Thanks!
> ---
> Makefile | 1 +
> 1 file changed, 1 insertion(+)
>
> Changelog:
> v1 -> v2:
> - v1: https://lore.kernel.org/linux-kbuild/20260306034325.3605301-1-yonghong.song@linux.dev/
> - Removed the new config option and use ld-option to check whether new flags
> will be used or not.
>
> diff --git a/Makefile b/Makefile
> index e944c6e71e81..e4385af16985 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1034,6 +1034,7 @@ endif
> ifdef CONFIG_LTO_CLANG
> ifdef CONFIG_LTO_CLANG_THIN
> CC_FLAGS_LTO := -flto=thin -fsplit-lto-unit
> +KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)
> else
> CC_FLAGS_LTO := -flto
> endif
> --
> 2.47.3
>
^ permalink raw reply
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