Live Patching
 help / color / mirror / Atom feed
* Re: [PATCH v3 09/13] livepatch/klp-build: fix version mismatch when short-circuiting
From: Song Liu @ 2026-02-17 19:25 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <aZSUfFUfpUYIbuiA@redhat.com>

On Tue, Feb 17, 2026 at 8:17 AM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
[...]
> > 2.53.0
> >
> >
>
> Maybe I'm starting to see things, but when running 'S 2' builds, I keep
> getting "vmlinux.o: changed function: override_release".  It could be
> considered benign for quick development work, or confusing.  Seems easy
> enough to stash and avoid.

"-S 2" with a different set of patches is only needed in patch development,
but not used for official releases. Therefore, I agree this is not a real issue.

Thanks,
Song

^ permalink raw reply

* Re: [PATCH v3 11/13] livepatch/klp-build: add terminal color output
From: Song Liu @ 2026-02-17 18:45 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-12-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 8:07 AM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> 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, warnings in yellow, and
> errors in red.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

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

^ permalink raw reply

* Re: [PATCH v3 10/13] livepatch/klp-build: provide friendlier error messages
From: Song Liu @ 2026-02-17 18:32 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-11-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 8:07 AM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> 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.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

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

^ permalink raw reply

* Re: [PATCH v3 07/13] livepatch/klp-build: fix shellcheck complaints
From: Song Liu @ 2026-02-17 18:30 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-8-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 8:07 AM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> 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).
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

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

^ permalink raw reply

* Re: [PATCH v3 08/13] livepatch/klp-build: improve short-circuit validation
From: Song Liu @ 2026-02-17 18:29 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-9-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 8:07 AM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> 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.

Nit: It may make sense to split this into two patches.

> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

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

^ permalink raw reply

* Re: [PATCH v3 06/13] livepatch/klp-build: add Makefile with check target
From: Song Liu @ 2026-02-17 18:26 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-7-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 8:07 AM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> 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.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

I wonder whether we can add logic to "make check" to replace the
grep-override function. But I guess the override function is OK.

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

^ permalink raw reply

* Re: [PATCH v3 05/13] livepatch/klp-build: add grep-override function
From: Song Liu @ 2026-02-17 18:22 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-6-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 8:07 AM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> 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.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

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

^ permalink raw reply

* Re: [PATCH v3 03/13] livepatch/klp-build: support patches that add/remove files
From: Song Liu @ 2026-02-17 17:52 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-4-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 8:06 AM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> 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.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

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

^ permalink raw reply

* Re: [PATCH v3 02/13] objtool/klp: fix mkstemp() failure with long paths
From: Song Liu @ 2026-02-17 17:45 UTC (permalink / raw)
  To: Joe Lawrence
  Cc: live-patching, Josh Poimboeuf, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-3-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 8:06 AM Joe Lawrence <joe.lawrence@redhat.com> wrote:
>
> 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.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>

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

^ permalink raw reply

* Re: [PATCH v3 11/13] livepatch/klp-build: add terminal color output
From: Joe Lawrence @ 2026-02-17 16:20 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-12-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 11:06:42AM -0500, Joe Lawrence wrote:
> 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, warnings in yellow, and
> errors in red.
> 
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
> ---
>  scripts/livepatch/klp-build | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
> index 80703ec4d775..fd104ace29e6 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}warn${COLOR_RESET}: $SCRIPT: $*" >&2
>  }
>  
>  die() {
> -	warn "$@"
> +	echo -e "${COLOR_ERROR}error${COLOR_RESET}: $SCRIPT: $*" >&2
>  	exit 1
>  }
>  
> -- 
> 2.53.0
> 
 
It turned out that modifying the centalized catagory printing functions
resulted in far less code churn than adding a pipes or calls to an
indentation function all over the script.  As an end-user, I would still
prefer the indentation, but I don't think this turned out too bad
either.

--
Joe


^ permalink raw reply

* Re: [PATCH v3 09/13] livepatch/klp-build: fix version mismatch when short-circuiting
From: Joe Lawrence @ 2026-02-17 16:17 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-10-joe.lawrence@redhat.com>

On Tue, Feb 17, 2026 at 11:06:40AM -0500, Joe Lawrence wrote:
> The klp-build script overrides the kernel's setlocalversion script to
> freeze the version string.  This prevents the build system from appending
> "+" or "-dirty" suffixes between original and patched kernel builds.
> 
> However, a version mismatch may still occur when running successive
> klp-build commands using the short-circuit option (-S 2):
> 
> - Initial Run (-T): The real setlocalversion runs once.  It is then
>   replaced by a fixed-string copy.  On exit, the original script is
>   restored.
> - Subsequent Runs (-S 2): The tree contains the original setlocalversion
>   script again.  When set_kernelversion() is called, it may generate a
>   different version string because the tree state has changed (e.g.,
>   include/config/auto.conf now exists).  This causes patched kernel
>   builds to use a version string that differs from the original.
> 
> Fix this by restoring the saved override when SHORT_CIRCUIT >= 2.  This
> ensures that subsequent patched builds reuse the localversion from the
> initial klp-build run.
> 
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
> ---
>  scripts/livepatch/klp-build | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
> index 60c7635e65c1..6d3adadfc394 100755
> --- a/scripts/livepatch/klp-build
> +++ b/scripts/livepatch/klp-build
> @@ -291,17 +291,26 @@ set_module_name() {
>  
>  # Hardcode the value printed by the localversion script to prevent patch
>  # application from appending it with '+' due to a dirty working tree.
> +# When short-circuiting at step 2 or later, restore the saved override from
> +# a prior run instead of recomputing (avoids version mismatch with orig objects).
>  set_kernelversion() {
>  	local file="$SRC/scripts/setlocalversion"
>  	local localversion
>  
>  	stash_file "$file"
> +	if (( SHORT_CIRCUIT >= 2 )); then
> +		[[ ! -f "$TMP_DIR/setlocalversion.override" ]] && \
> +			die "previous setlocalversion.override not found"
> +		cp -f "$TMP_DIR/setlocalversion.override" "$SRC/scripts/setlocalversion"
> +		return 0
> +	fi
>  
>  	localversion="$(cd "$SRC" && make --no-print-directory kernelversion)"
>  	localversion="$(cd "$SRC" && KERNELVERSION="$localversion" ./scripts/setlocalversion)"
>  	[[ -z "$localversion" ]] && die "setlocalversion failed"
>  
>  	sed -i "2i echo $localversion; exit 0" scripts/setlocalversion
> +	cp -f "$SRC/scripts/setlocalversion" "$TMP_DIR/setlocalversion.override"
>  }
>  
>  get_patch_input_files() {
> -- 
> 2.53.0
> 
> 

Maybe I'm starting to see things, but when running 'S 2' builds, I keep
getting "vmlinux.o: changed function: override_release".  It could be
considered benign for quick development work, or confusing.  Seems easy
enough to stash and avoid.

Repro:

Start with a clean source tree, setup some basic configs for klp-build:

  $ make clean && make mrproper
  $ vng --kconfig
  $ ./scripts/config --file .config \
       --set-val CONFIG_FTRACE y \
       --set-val CONFIG_KALLSYMS_ALL y \
       --set-val CONFIG_FUNCTION_TRACER y \
       --set-val CONFIG_DYNAMIC_FTRACE y \
       --set-val CONFIG_DYNAMIC_DEBUG y \
       --set-val CONFIG_LIVEPATCH y
  $ make olddefconfig

Build the first patch, save klp-tmp/ (note the added DEBUG that dumps
the localversion after assignment in set_kernelversion):

  $ ./scripts/livepatch/klp-build -T ~/cmdline-string.patch 
  DEBUG: localversion=6.19.0-gc998cd490c02                           <<
  Validating patch(es)
  Building original kernel
  Copying original object files
  Fixing patch(es)
  Building patched kernel
  Copying patched object files
  Diffing objects
  vmlinux.o: changed function: cmdline_proc_show
  BMuilding patch module: livepatch-cmdline-string.ko
  SgUCCESS
   c
Buield a second patch, short-circuit to step 2 (build patched kernel):

  $ ./scripts/livepatch/klp-build -T -S 2 ~/cmdline-string.patch
  DEBUG: localversion=6.19.0+                                        <<
  Fixing patch(es)
  Building patched kernel
  Copying patched object files
  Diffing objects
  vmlinux.o: changed function: override_release                      <<
  vmlinux.o: changed function: cmdline_proc_show
  Building patch module: livepatch-cmdline-string.ko
  SUCCESS

--
Joe


^ permalink raw reply

* Re: [PATCH v3 01/13] objtool/klp: honor SHF_MERGE entry alignment in elf_add_data()
From: Joe Lawrence @ 2026-02-17 16:14 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-2-joe.lawrence@redhat.com>

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?

Here is the repro:

A simple patch to pr_info a few strings to the kernel buffer:

  diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c
  index a6f76121955f..5b7f43105ea8 100644
  --- a/fs/proc/cmdline.c
  +++ b/fs/proc/cmdline.c
  @@ -7,6 +7,10 @@

   static int cmdline_proc_show(struct seq_file *m, void *v)
   {
  +	pr_info("ABCDEFGHIJKLMN:   message 1 here\n");
  +	pr_info("OPQRSTUVWXYZ12:   message 2 here\n");
  +	pr_info("34567890abcdef:   message 3 here\n");
  +	pr_info("ghijklmnopqrst:   message 4 here\n");
   	seq_puts(m, saved_command_line);
   	seq_putc(m, '\n');
   	return 0;

results in strange dmesg output:

  [ 6179.571413] ABCDEFGHIJKLMN:   message 1 here
  [ 6179.575689] QRSTUVWXYZ12:   message 2 here
  [ 6179.579788] 90abcdef:   message 3 here
  [ 6179.583541] qrst:   message 4 here

patched/vmlinux.o
-----------------

First thing to note, section .rodata.cmdline_proc_show.str1.8 has
entries with an alignment of 8 bytes and the section is SHF_MERGE:

  $ readelf --wide -S klp-tmp/patched/vmlinux.o
  Section Headers:
  [Nr]      Name                              Type      Address           Off      Size    ES  Flg  Lk  Inf  Al
  [132261]  .rodata.cmdline_proc_show.str1.8  PROGBITS  0000000000000000  23b3000  00009c  01  AMS  0   0    8

  $ eu-objdump -r -j .rela.text.unlikely.cmdline_proc_show klp-tmp/patched/vmlinux.o | grep str1.8
  0000000000000020 R_X86_64_32S         .rodata.cmdline_proc_show.str1.8
  000000000000002c R_X86_64_32S         .rodata.cmdline_proc_show.str1.8+0x28
  0000000000000038 R_X86_64_32S         .rodata.cmdline_proc_show.str1.8+0x50
  0000000000000044 R_X86_64_32S         .rodata.cmdline_proc_show.str1.8+0x78

  $ eu-objdump -s -j .rodata.cmdline_proc_show.str1.8 klp-tmp/patched/vmlinux.o
  klp-tmp/patched/vmlinux.o: elf64-elf_x86_64

  Contents of section .rodata.cmdline_proc_show.str1.8:
   0000 01364142 43444546 4748494a 4b4c4d4e  .6ABCDEFGHIJKLMN
        ^ (+0x00)                            ^
   0010 3a202020 6d657373 61676520 31206865  :   message 1 he
   0020 72650a00 00000000 01364f50 51525354  re.......6OPQRST
                          ^ (+0x28)                  ^
   0030 55565758 595a3132 3a202020 6d657373  UVWXYZ12:   mess
   0040 61676520 32206865 72650a00 00000000  age 2 here......
   0050 01363334 35363738 39306162 63646566  .634567890abcdef
        ^ (+0x50)                            ^
   0060 3a202020 6d657373 61676520 33206865  :   message 3 he
   0070 72650a00 00000000 01366768 696a6b6c  re.......6ghijkl
                          ^ (+0x78)                  ^
   0080 6d6e6f70 71727374 3a202020 6d657373  mnopqrst:   mess
   0090 61676520 34206865 72650a00           age 4 here..


diff/vmlinux.o
--------------

Same 8-byte alignment of .rodata.cmdline_proc_show.str1.8:

  $ readelf --wide -S klp-tmp/diff/vmlinux.o | grep str1.8
  Section  Headers:
  [Nr]  Name                              Type      Address           Off     Size    ES  Flg  Lk  Inf  Al
  [6]   .rodata.cmdline_proc_show.str1.8  PROGBITS  0000000000000000  000540  000090  01  AMS  0   0    8

  $ eu-objdump -r klp-tmp/diff/vmlinux.o | grep str1.8
  0000000000000020 R_X86_64_32S         .rodata.cmdline_proc_show.str1.8
  000000000000002c R_X86_64_32S         .rodata.cmdline_proc_show.str1.8+0x28
  0000000000000038 R_X86_64_32S         .rodata.cmdline_proc_show.str1.8+0x50
  0000000000000044 R_X86_64_32S         .rodata.cmdline_proc_show.str1.8+0x78

but notice they do not point to the strings in a now packed section
contents:

  $ eu-objdump -s -j .rodata.cmdline_proc_show.str1.8 klp-tmp/diff/vmlinux.o
  klp-tmp/diff/vmlinux.o: elf64-elf_x86_64

  Contents of section .rodata.cmdline_proc_show.str1.8:
   0000 01364142 43444546 4748494a 4b4c4d4e  .6ABCDEFGHIJKLMN
        ^ (+0x00)                            ^
   0010 3a202020 6d657373 61676520 31206865  :   message 1 he
   0020 72650a00 01364f50 51525354 55565758  re...6OPQRSTUVWX
                          ^ (+0x28)                  ^
   0030 595a3132 3a202020 6d657373 61676520  YZ12:   message
   0040 32206865 72650a00 01363334 35363738  2 here...6345678
   0050 39306162 63646566 3a202020 6d657373  90abcdef:   mess
        ^ (+0x50)                            ^
   0060 61676520 33206865 72650a00 01366768  age 3 here...6gh
   0070 696a6b6c 6d6e6f70 71727374 3a202020  ijklmnopqrst:
                          ^ (+0x78)                  ^
   0080 6d657373 61676520 34206865 72650a00  message 4 here..

--
Joe


^ permalink raw reply

* [PATCH v3 12/13] livepatch/klp-build: report patch validation drift
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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 "drift" 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 fd104ace29e6..5367d573b94b 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -369,11 +369,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"
+		die "$patch did not apply"
+	elif [[ "$output" =~ $drift_regex ]]; then
+		warn "$patch applied with drift"
+		echo "$output"
+	fi
 
+	patch -d "$SRC" -p1 --no-backup-if-mismatch -r /dev/null "${extra_args[@]}" --silent < "$patch"
 	APPLIED_PATCHES+=("$patch")
 }
 
@@ -392,10 +405,11 @@ revert_patch() {
 }
 
 apply_patches() {
+	local extra_args=("$@")
 	local patch
 
 	for patch in "${PATCHES[@]}"; do
-		apply_patch "$patch"
+		apply_patch "$patch" "${extra_args[@]}"
 	done
 }
 
@@ -453,7 +467,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"
 
@@ -826,7 +840,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 v3 13/13] livepatch/klp-build: don't look for changed objects in tools/
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-1-joe.lawrence@redhat.com>

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

diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 5367d573b94b..9bbce09cfb74 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -564,8 +564,8 @@ find_objects() {
 	local opts=("$@")
 
 	# Find root-level vmlinux.o and non-root-level .ko files,
-	# excluding klp-tmp/ and .git/
-	find "$OBJ" \( -path "$TMP_DIR" -o -path "$OBJ/.git" -o	-regex "$OBJ/[^/][^/]*\.ko" \) -prune -o \
+	# excluding klp-tmp/, .git/, and tools/
+	find "$OBJ" \( -path "$TMP_DIR" -o -path "$OBJ/.git" -o -path "$OBJ/tools" -o -regex "$OBJ/[^/][^/]*\.ko" \) -prune -o \
 		    -type f "${opts[@]}"				\
 		    \( -name "*.ko" -o -path "$OBJ/vmlinux.o" \)	\
 		    -printf '%P\n'
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 10/13] livepatch/klp-build: provide friendlier error messages
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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.

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 6d3adadfc394..80703ec4d775 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -351,7 +351,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
@@ -496,6 +496,7 @@ clean_kernel() {
 }
 
 build_kernel() {
+	local build="$1"
 	local log="$TMP_DIR/build.log"
 	local objtool_args=()
 	local cmd=()
@@ -533,7 +534,7 @@ build_kernel() {
 		"${cmd[@]}"							\
 			1> >(tee -a "$log")					\
 			2> >(tee -a "$log" | grep0 -v "modpost.*undefined!" >&2)
-	)
+	) || die "$build kernel build failed"
 }
 
 find_objects() {
@@ -808,7 +809,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
@@ -818,7 +819,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 v3 11/13] livepatch/klp-build: add terminal color output
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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, warnings in yellow, and
errors in red.

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

diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 80703ec4d775..fd104ace29e6 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}warn${COLOR_RESET}: $SCRIPT: $*" >&2
 }
 
 die() {
-	warn "$@"
+	echo -e "${COLOR_ERROR}error${COLOR_RESET}: $SCRIPT: $*" >&2
 	exit 1
 }
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 08/13] livepatch/klp-build: improve short-circuit validation
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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.

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 v3 09/13] livepatch/klp-build: fix version mismatch when short-circuiting
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-1-joe.lawrence@redhat.com>

The klp-build script overrides the kernel's setlocalversion script to
freeze the version string.  This prevents the build system from appending
"+" or "-dirty" suffixes between original and patched kernel builds.

However, a version mismatch may still occur when running successive
klp-build commands using the short-circuit option (-S 2):

- Initial Run (-T): The real setlocalversion runs once.  It is then
  replaced by a fixed-string copy.  On exit, the original script is
  restored.
- Subsequent Runs (-S 2): The tree contains the original setlocalversion
  script again.  When set_kernelversion() is called, it may generate a
  different version string because the tree state has changed (e.g.,
  include/config/auto.conf now exists).  This causes patched kernel
  builds to use a version string that differs from the original.

Fix this by restoring the saved override when SHORT_CIRCUIT >= 2.  This
ensures that subsequent patched builds reuse the localversion from the
initial klp-build run.

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

diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 60c7635e65c1..6d3adadfc394 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -291,17 +291,26 @@ set_module_name() {
 
 # Hardcode the value printed by the localversion script to prevent patch
 # application from appending it with '+' due to a dirty working tree.
+# When short-circuiting at step 2 or later, restore the saved override from
+# a prior run instead of recomputing (avoids version mismatch with orig objects).
 set_kernelversion() {
 	local file="$SRC/scripts/setlocalversion"
 	local localversion
 
 	stash_file "$file"
+	if (( SHORT_CIRCUIT >= 2 )); then
+		[[ ! -f "$TMP_DIR/setlocalversion.override" ]] && \
+			die "previous setlocalversion.override not found"
+		cp -f "$TMP_DIR/setlocalversion.override" "$SRC/scripts/setlocalversion"
+		return 0
+	fi
 
 	localversion="$(cd "$SRC" && make --no-print-directory kernelversion)"
 	localversion="$(cd "$SRC" && KERNELVERSION="$localversion" ./scripts/setlocalversion)"
 	[[ -z "$localversion" ]] && die "setlocalversion failed"
 
 	sed -i "2i echo $localversion; exit 0" scripts/setlocalversion
+	cp -f "$SRC/scripts/setlocalversion" "$TMP_DIR/setlocalversion.override"
 }
 
 get_patch_input_files() {
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 07/13] livepatch/klp-build: fix shellcheck complaints
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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).

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 v3 06/13] livepatch/klp-build: add Makefile with check target
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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.

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 v3 05/13] livepatch/klp-build: add grep-override function
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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.

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 v3 04/13] livepatch/klp-build: switch to GNU patch and recountdiff
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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 v3 03/13] livepatch/klp-build: support patches that add/remove files
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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.

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 v3 02/13] objtool/klp: fix mkstemp() failure with long paths
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-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.

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 bd6502e7bdc0..6f6d1c4cb6af 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 v3 01/13] objtool/klp: honor SHF_MERGE entry alignment in elf_add_data()
From: Joe Lawrence @ 2026-02-17 16:06 UTC (permalink / raw)
  To: live-patching
  Cc: Josh Poimboeuf, Song Liu, Jiri Kosina, Miroslav Benes,
	Petr Mladek
In-Reply-To: <20260217160645.3434685-1-joe.lawrence@redhat.com>

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


^ permalink raw reply related


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