From: Song Liu <song@kernel.org>
To: live-patching@vger.kernel.org, linux-kselftest@vger.kernel.org
Cc: jpoimboe@kernel.org, jikos@kernel.org, mbenes@suse.cz,
pmladek@suse.com, joe.lawrence@redhat.com, shuah@kernel.org,
linux-kernel@vger.kernel.org, Song Liu <song@kernel.org>
Subject: [PATCH 01/11] klp-build: Fix dependent patches in a series
Date: Fri, 16 Oct 2026 17:24:31 -0700 [thread overview]
Message-ID: <20261017002441.716615-2-song@kernel.org> (raw)
In-Reply-To: <20261017002441.716615-1-song@kernel.org>
fix_patches() refreshes each patch on its own against the original
source: it applies the patch, copies the patched files, and reverts it.
If a later patch in the series depends on an earlier one, it doesn't
apply to the original source, and klp-build fails even though
validate_patches(), which applies the patches in order, accepted the
series:
$ ./scripts/livepatch/klp-build 0001-dummy.patch 0002-Revert-dummy.patch
Validating patch(es)
Building original kernel
Copying original object files
Fixing patch(es)
Reversed (or previously applied) patch detected! Assume -R? [n]
Apply anyway? [n]
1 out of 1 hunk ignored
error: klp-build: .../klp-tmp/tmp.patch did not apply
Refreshing each patch on top of the previous ones wouldn't work either.
fix-patch-lines adds #line directives to each fixed patch, so the next
patch's context wouldn't match. The #line numbers in later patches
would also refer to the intermediate source rather than the original
source, which defeats the purpose of preserving __LINE__.
Instead, apply all the patches in order and diff the result against the
original source to get a single combined patch, then run fix-patch-lines
on that. If the patches have no net effect, fail early with "no changes
detected" instead of building the patched kernel for nothing.
Fixes: 24ebfcd65a87 ("livepatch/klp-build: Introduce klp-build script for generating livepatch modules")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Song Liu <song@kernel.org>
---
scripts/livepatch/klp-build | 93 +++++++++++++++++++++----------------
1 file changed, 54 insertions(+), 39 deletions(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index b52a8489d9f6..6cdc36e97c21 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -467,60 +467,75 @@ do_init() {
set_kernelversion
}
-# Refresh the patch hunk headers, specifically the line numbers and counts.
-refresh_patch() {
- local patch="$1"
+# Combine the patches into a single patch against the original source, with
+# refreshed hunk headers. The patches may depend on each other, so they can't
+# be refreshed individually.
+combine_patches() {
+ local outfile="$1"
local tmpdir="$PATCH_TMP_DIR"
- local input_files=()
- local output_files=()
+ local files=()
+ local patch
+ local file
rm -rf "$tmpdir"
- mkdir -p "$tmpdir/a"
- mkdir -p "$tmpdir/b"
+ mkdir -p "$tmpdir"
- # Get all source files affected by the patch
- get_patch_input_files "$patch" | mapfile -t input_files
- get_patch_output_files "$patch" | mapfile -t output_files
+ # Get all source files affected by the patches
+ for patch in "${PATCHES[@]}"; do
+ get_patch_files "$patch"
+ done | sort -u | mapfile -t files
- # Copy orig source files to 'a'
- echo "${input_files[@]}" | xargs cp --parents --target-directory="$tmpdir/a"
+ # Copy orig source files to $tmpdir
+ for file in "${files[@]}"; do
+ if [[ -e "$file" ]]; then
+ cp --parents "$file" "$tmpdir"
+ fi
+ done
- # Copy patched source files to 'b'
- apply_patch "$patch" "--silent"
- echo "${output_files[@]}" | xargs cp --parents --target-directory="$tmpdir/b"
- revert_patch "$patch"
+ # Diff the orig source files against the patched ones in place to make a
+ # clean patch. Use /dev/null for created and deleted files.
+ : > "$outfile"
+ apply_patches "--silent"
+ for file in "${files[@]}"; do
+ local old="$tmpdir/$file"
+ local new="$file"
+ local old_label="a/$file"
+ local new_label="b/$file"
+ local status=0
+
+ if [[ ! -e "$old" ]]; then
+ old=/dev/null
+ old_label=/dev/null
+ fi
+ if [[ ! -e "$new" ]]; then
+ new=/dev/null
+ new_label=/dev/null
+ fi
- # Diff 'a' and 'b' to make a clean patch
- ( cd "$tmpdir" && diff -Nupr a b > "$patch" ) || true
+ diff -up --label "$old_label" --label "$new_label" "$old" "$new" >> "$outfile" || status=$?
+ if (( status > 1 )); then
+ die "diff failed for $file"
+ fi
+ done
+ revert_patches
}
-# Copy the patches to a temporary directory, fix their lines so as not to
-# affect the __LINE__ macro for otherwise unchanged functions further down the
-# file, and update $PATCHES to point to the fixed patches.
+# Combine the patches into a single patch, fix its lines so as not to affect
+# the __LINE__ macro for otherwise unchanged functions further down the file,
+# and update $PATCHES to point to the fixed patch.
fix_patches() {
- local idx
- local i
+ local tmp_patch="$TMP_DIR/tmp.patch"
+ local new_patch="$TMP_DIR/fixed.patch"
rm -f "$TMP_DIR"/*.patch
- idx=0001
- for i in "${!PATCHES[@]}"; do
- local old_patch="${PATCHES[$i]}"
- local tmp_patch="$TMP_DIR/tmp.patch"
- local patch="${PATCHES[$i]}"
- local new_patch
-
- new_patch="$TMP_DIR/$idx-fixed-$(basename "$patch")"
+ combine_patches "$tmp_patch"
+ [[ ! -s "$tmp_patch" ]] && die "no changes detected"
- cp -f "$old_patch" "$tmp_patch"
- refresh_patch "$tmp_patch"
- "$FIX_PATCH_LINES" "$tmp_patch" | recountdiff > "$new_patch"
+ "$FIX_PATCH_LINES" "$tmp_patch" | recountdiff > "$new_patch"
+ PATCHES=("$new_patch")
- PATCHES[i]="$new_patch"
-
- rm -f "$tmp_patch"
- idx=$(printf "%04d" $(( 10#$idx + 1 )))
- done
+ rm -f "$tmp_patch"
}
clean_kernel() {
--
2.53.0-Meta
next prev parent reply other threads:[~2026-10-17 0:24 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 0:24 [PATCH 00/11] klp-build: Fix dependent patches, add selftests Song Liu
2026-10-17 0:24 ` Song Liu [this message]
2026-10-17 0:24 ` [PATCH 02/11] klp-build: Add --patch-only option Song Liu
2026-10-17 0:24 ` [PATCH 03/11] selftests/livepatch: Add tests for klp-build's patch handling Song Liu
2026-10-17 0:24 ` [PATCH 04/11] selftests/livepatch: Test klp-build with dependent patches Song Liu
2026-10-17 0:30 ` sashiko-bot
2026-10-17 0:24 ` [PATCH 05/11] selftests/livepatch: Test klp-build with patches to different functions Song Liu
2026-10-17 0:24 ` [PATCH 06/11] selftests/livepatch: Test klp-build with patches which cancel out Song Liu
2026-10-17 0:24 ` [PATCH 07/11] selftests/livepatch: Test klp-build with created and deleted files Song Liu
2026-10-17 0:24 ` [PATCH 08/11] selftests/livepatch: Test where klp-build adds #line directives Song Liu
2026-10-17 0:24 ` [PATCH 09/11] selftests/livepatch: Test klp-build's rejection of unsupported files Song Liu
2026-10-17 0:24 ` [PATCH 10/11] selftests/livepatch: Test klp-build with patches which don't apply Song Liu
2026-10-17 0:24 ` [PATCH 11/11] selftests/livepatch: Test klp-build with patches which need offset or fuzz Song Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261017002441.716615-2-song@kernel.org \
--to=song@kernel.org \
--cc=jikos@kernel.org \
--cc=joe.lawrence@redhat.com \
--cc=jpoimboe@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=pmladek@suse.com \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.