Skip to content

Conversation

@pfliu
Copy link
Owner

@pfliu pfliu commented Jan 14, 2026

No description provided.

ii4gsp and others added 11 commits December 30, 2025 10:34
lkkbd_interrupt() schedules lk->tq via schedule_work(), and the work
handler lkkbd_reinit() dereferences the lkkbd structure and its
serio/input_dev fields.

lkkbd_disconnect() and error paths in lkkbd_connect() free the lkkbd
structure without preventing the reinit work from being queued again
until serio_close() returns. This can allow the work handler to run
after the structure has been freed, leading to a potential use-after-free.

Use disable_work_sync() instead of cancel_work_sync() to ensure the
reinit work cannot be re-queued, and call it both in lkkbd_disconnect()
and in lkkbd_connect() error paths after serio_open().

Signed-off-by: Minseong Kim <ii4gsp@gmail.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20251212052314.16139-1-ii4gsp@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
After commit 9cf6e24 ("Input: atkbd -
do not skip atkbd_deactivate() when skipping ATKBD_CMD_GETID"), HONOR
FMB-P, aka HONOR MagicBook Pro 14 2025's internal keyboard stops
working. Adding the atkbd_deactivate_fixup quirk fixes it.

DMI: HONOR FMB-P/FMB-P-PCB, BIOS 1.13 05/08/2025

Fixes: 9cf6e24 ("Input: atkbd - do not skip atkbd_deactivate() when skipping ATKBD_CMD_GETID")
Reported-by: Mikura Kyouka <mikurakyouka@aosc.io>
Reported-by: foad.elkhattabi <foad.elkhattabi@gmail.com>
Signed-off-by: Cryolitia PukNgae <cryolitia.pukngae@linux.dev>
Reviewed-by: Hans de Goede <hansg@kernel.org>
Link: https://patch.msgid.link/20251022-honor-v1-1-ff894ed271a9@linux.dev
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
…able

The device occasionally wakes up from suspend with missing input on the
internal keyboard and the following suspend attempt results in an instant
wake-up. The quirks fix both issues for this device.

Signed-off-by: Christoffer Sandberg <cs@tuxedo.de>
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20251124203336.64072-1-wse@tuxedocomputers.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
The dev3_register_work delayed work item is initialized within
alps_reconnect() and scheduled upon receipt of the first bare
PS/2 packet from an external PS/2 device connected to the ALPS
touchpad. During device detachment, the original implementation
calls flush_workqueue() in psmouse_disconnect() to ensure
completion of dev3_register_work. However, the flush_workqueue()
in psmouse_disconnect() only blocks and waits for work items that
were already queued to the workqueue prior to its invocation. Any
work items submitted after flush_workqueue() is called are not
included in the set of tasks that the flush operation awaits.
This means that after flush_workqueue() has finished executing,
the dev3_register_work could still be scheduled. Although the
psmouse state is set to PSMOUSE_CMD_MODE in psmouse_disconnect(),
the scheduling of dev3_register_work remains unaffected.

The race condition can occur as follows:

CPU 0 (cleanup path)     | CPU 1 (delayed work)
psmouse_disconnect()     |
  psmouse_set_state()    |
  flush_workqueue()      | alps_report_bare_ps2_packet()
  alps_disconnect()      |   psmouse_queue_work()
    kfree(priv); // FREE | alps_register_bare_ps2_mouse()
                         |   priv = container_of(work...); // USE
                         |   priv->dev3 // USE

Add disable_delayed_work_sync() in alps_disconnect() to ensure
that dev3_register_work is properly canceled and prevented from
executing after the alps_data structure has been deallocated.

This bug is identified by static analysis.

Fixes: 04aae28 ("Input: ALPS - do not mix trackstick and external PS/2 mouse data")
Cc: stable@kernel.org
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Link: https://patch.msgid.link/b57b0a9ccca51a3f06be141bfc02b9ffe69d1845.1765939397.git.duoming@zju.edu.cn
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Under certain conditions (more prevalent after a suspend/resume cycle),
the touchscreen controller can send the "boot complete" interrupt before
it actually finished booting. In those cases, attempting to read touch
data resuls in a stream of "not ready" messages being read and
interpreted as a touch report. Check that the response is in fact a
touch report and discard it otherwise.

Reported-by: pitust <piotr@stelmaszek.com>
Closes: https://oftc.catirclogs.org/asahi/2025-12-17#34878715;
Fixes: 471a92f ("Input: apple_z2 - add a driver for Apple Z2 touchscreens")
Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Link: https://patch.msgid.link/20251218-z2-init-fix-v1-1-48e3aa239caf@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
ABS_SND_PROFILE used to describe the state of a multi-value sound profile
switch. This will be used for the alert-slider on OnePlus phones or other
phones.

Profile values added as SND_PROFLE_(SILENT|VIBRATE|RING) identifiers
to input-event-codes.h so they can be used from DTS.

Signed-off-by: Gergo Koteles <soyer@irl.hu>
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
Tested-by: Guido Günther <agx@sigxcpu.org> # oneplus,fajita & oneplus,enchilada
Reviewed-by: Guido Günther <agx@sigxcpu.org>
Signed-off-by: David Heidelberg <david@ixit.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Link: https://patch.msgid.link/20251113-op6-tri-state-v8-1-54073f3874bc@ixit.cz
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Add support for various CRKD Guitar Controllers.

Signed-off-by: Sanjay Govind <sanjay.govind9@gmail.com>
Link: https://patch.msgid.link/20251129073720.2750-2-sanjay.govind9@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
The current validation 'wire_order[i] > ARRAY_SIZE(config_pins)' allows
wire_order[i] to equal ARRAY_SIZE(config_pins), which causes out-of-bounds
access when used as index in 'config_pins[wire_order[i]]'.

Since config_pins has 4 elements (indices 0-3), the valid range for
wire_order should be 0-3. Fix the off-by-one error by using >= instead
of > in the validation check.

Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Link: https://patch.msgid.link/20251114062817.852698-1-junjie.cao@intel.com
Fixes: bb76dc0 ("input: ti_am33x_tsc: Order of TSC wires, made configurable")
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Enhance the coccicheck script to filter *.cocci files based on the
specified MODE (e.g., report, patch). This ensures that only compatible
semantic patch files are executed, preventing errors such as:

    "virtual rule report not supported"

This error occurs when a .cocci file does not define a 'virtual <MODE>'
rule, yet is executed in that mode.

For example:

    make coccicheck M=drivers/hwtracing/coresight/ MODE=report

In this case, running "secs_to_jiffies.cocci" would trigger the error
because it lacks support for 'report' mode. With this change, such files
are skipped automatically, improving robustness and developer
experience.

Signed-off-by: Songwei Chai <quic_songchai@quicinc.com>
Reviewed-by: Julia Lawall <Julia.Lawall@inria.fr>
s/Unecessary/Unnecessary/

Reviewed-by: Julia Lawall <julia.lawall@inria.fr>
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
@gemini-code-assist
Copy link

Summary of Changes

Hello @pfliu, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the kernel's kexec capabilities by integrating BPF programs for parsing kexec image files, allowing for more flexible and dynamic boot processes. This major feature required extensive additions to the BPF and kexec subsystems, including new configuration options, source files, and build system modifications. In addition to this core functionality, the PR also broadens input device support by incorporating new CRKD controllers, introduces a new input event code for sound profiles, and includes several minor but important fixes across various input drivers and kernel infrastructure. The kernel's release candidate version has also been updated.

Highlights

  • Kexec BPF Integration: Introduced Kexec BPF functionality, enabling BPF programs to parse kexec image files. This involves new Kconfig options, build system changes, and new C files (bpf_buffer_parser.c, kexec_bpf_loader.c, kexec_uefi_app.c) to facilitate dynamic image processing during kexec boot.
  • New Input Device Support: Added support for several new CRKD controllers (Blueberry Burst Pro, Black Tribal Edition, SG) to the xpad joystick driver, expanding compatibility for gaming peripherals.
  • New Input Event Code: Defined a new input event code, ABS_SND_PROFILE, for handling multi-value sound profile switches, along with its documentation and mapping in the HID debug driver.
  • DMI Quirk for HONOR Laptops: Added a DMI quirk for 'HONOR FMB-P' laptops to address specific keyboard issues by applying the atkbd_deactivate_fixup.
  • Driver Stability Improvements: Implemented fixes in lkkbd, alps, and ti_am335x_tsc drivers, primarily focusing on proper workqueue synchronization during disconnect/error paths and correcting an array bounds check in touchscreen configuration.
  • Decompressor Persistence Option: Added CONFIG_KEEP_DECOMPRESSOR to allow decompressor routines to remain in memory after kernel initialization, a necessary dependency for the new Kexec BPF feature.
  • Kernel Version Update: The kernel's EXTRAVERSION was incremented from -rc1 to -rc2.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant new feature to kexec, allowing a BPF program embedded in a kexec image to parse the image. This is a powerful mechanism for supporting complex image formats. The implementation is extensive, touching core kexec, BPF infrastructure, and adding new tools.

My review has found several issues, including a build-breaking change, a few bugs that could lead to memory leaks or incorrect behavior, and some issues in the new tooling. These should be addressed to ensure the feature is robust.

  • In kernel/Kconfig.kexec, there's a typo in a dependency.
  • In kernel/bpf/bpf_buffer_parser.c, the return value of copy_from_kernel_nofault is checked incorrectly.
  • In kernel/bpf/helpers.c, a new kfunc is added unconditionally, which will break builds where the feature is disabled.
  • In kernel/kexec_bpf_loader.c, there's a memory leak in an error path and a portability issue in a memory allocation calculation.
  • The new user-space tool tools/kexec/zboot_image_builder.c has a couple of bugs that will prevent it from compiling or cause it to crash.

Overall, this is a promising feature, but the identified issues need to be fixed.

#ifdef CONFIG_CRASH_DUMP
BTF_ID_FLAGS(func, crash_kexec, KF_DESTRUCTIVE)
#endif
BTF_ID_FLAGS(func, bpf_buffer_parser, KF_TRUSTED_ARGS | KF_SLEEPABLE)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This unconditional BTF_ID_FLAGS for bpf_buffer_parser will cause a linker error when the kernel is built with CONFIG_KEXEC_FILE=n, because the function bpf_buffer_parser is defined in kernel/bpf/bpf_buffer_parser.c which is only compiled when CONFIG_KEXEC_FILE=y. This should be wrapped in an #ifdef to make it conditional on CONFIG_KEXEC_BPF being enabled.

#if IS_ENABLED(CONFIG_KEXEC_BPF)
BTF_ID_FLAGS(func, bpf_buffer_parser, KF_TRUSTED_ARGS | KF_SLEEPABLE)
#endif

munmap(base_start_addr, sb.st_size);
close(base_fd);
close(out_fd);
close(bpf_fd);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This line will cause a compilation error. The file descriptor bpf_fd is not declared or opened. You probably meant to close bin_fp, which was opened with fopen(). It should be closed with fclose(bin_fp).

fclose(bin_fp);

config KEXEC_BPF
bool "Enable bpf-prog to parse the kexec image"
depends on KEXEC_FILE
depends on DEBUG_INFO_BTF && BPF_SYSCALL && KEEP_COMPRESSOR

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There appears to be a typo in the dependency. KEEP_COMPRESSOR should be KEEP_DECOMPRESSOR. The new Kconfig option added in lib/Kconfig is KEEP_DECOMPRESSOR.

depends on DEBUG_INFO_BTF && BPF_SYSCALL && KEEP_DECOMPRESSOR

if (!b)
return -ENOMEM;
ret = copy_from_kernel_nofault(b, buf, buf_sz);
if (ret < 0) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The return value of copy_from_kernel_nofault() is the number of bytes that could not be copied (0 on success). Therefore, the check for an error should be if (ret != 0) instead of if (ret < 0), as it does not return negative error codes.

if (ret) {

Comment on lines 395 to 399
if (ret) {
pr_err("Fail to load .bpf section\n");
goto err;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There is a resource leak in this error path. If arm_bpf_prog() fails, the function jumps to err: without releasing the bpf_parser_context allocated earlier. You should call put_bpf_parser_context(bpf) before the goto to prevent the leak.

if (ret) {
				pr_err("Fail to load .bpf section\n");
				put_bpf_parser_context(bpf);
				goto err;
			}

perror("Failed to read binary data");
free(bin_data);
free(base_sections);
free(new_sections);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

base_sections is a pointer into a memory-mapped region (base_start_addr) and was not allocated with malloc/calloc. Calling free(base_sections) will lead to a crash or undefined behavior. This line should be removed.

Comment on lines 59 to 61
ifeq ($(CONFIG_KEXEC_FILE),y)
obj-$(CONFIG_BPF_SYSCALL) += bpf_buffer_parser.o
endif

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The compilation of bpf_buffer_parser.o is conditioned on CONFIG_KEXEC_FILE. It would be more precise to condition this on CONFIG_KEXEC_BPF, as the functionality in bpf_buffer_parser.c is specific to the kexec BPF feature. While CONFIG_KEXEC_BPF depends on CONFIG_KEXEC_FILE, this change would avoid compiling the file unnecessarily if KEXEC_FILE is enabled but KEXEC_BPF is not.

ifeq ($(CONFIG_KEXEC_BPF),y)
obj-$(CONFIG_BPF_SYSCALL) += bpf_buffer_parser.o
endif

struct decompress_mem_allocator *a,
unsigned int chunk_size)
{
unsigned long sz = (MAX_UNCOMPRESSED_BUF_SIZE / chunk_size) * sizeof(unsigned long *);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The size of a pointer is being calculated using sizeof(unsigned long *). While this may work on many 64-bit systems, it's not portable. The type of chunk_base_addr is char **, so you should use sizeof(char *) or sizeof(void *) for portability.

unsigned long sz = (MAX_UNCOMPRESSED_BUF_SIZE / chunk_size) * sizeof(char *);

Pingfan Liu added 14 commits January 15, 2026 09:04
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Pingfan Liu <piliu@redhat.com>
As UEFI becomes popular, a few architectures support to boot a PE format
kernel image directly. But the internal of PE format varies, which means
each parser for each format.

This patch (with the rest in this series) introduces a common skeleton
to all parsers, and leave the format parsing in
bpf-prog, so the kernel code can keep relative stable.

History, the syscall
SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
                unsigned long, cmdline_len, const char __user *, cmdline_ptr,
                unsigned long, flags)
is intend for kexec boot protocol: bootable kernel, initramfs, cmdline.

But
The functionality can be re-organized as two stages, for the first
stage, the passed in image is broken down to bootable image. For the
second stage, the tranditional image loader, which faces the
tranditional kexec boot protocol

There are some place holder function in this patch. (They will take
effect after the introduction of kexec bpf light skeleton and bpf
helpers). Overall the parsing progress is a pipeline, the current
bpf-prog parser is attached to bpf_handle_pefile(), and detatched at the
end of the current stage 'disarm_bpf_prog()' the current parsed result
by the current bpf-prog will be buffered in kernel 'prepare_nested_pe()'
, and deliver to the next stage.  For each stage, the bpf bytecode is
extracted from the '.bpf' section in the PE file.

Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philipp Rudo <prudo@redhat.com>
To: kexec@lists.infradead.org
The KEXE PE format parser needs the kernel built-in decompressor to
decompress the kernel image. So moving the decompressor out of __init
sections.

Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
To: linux-kernel@vger.kernel.org
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Analague to kernel/bpf/preload/iterators/Makefile,
this Makefile is not invoked by the Kbuild system. It needs to be
invoked manually when kexec_pe_parser_bpf.c is changed so that
kexec_pe_parser_bpf.lskel.h can be re-generated by the command "bpftool
gen skeleton -L kexec_pe_parser_bpf.o".

kexec_pe_parser_bpf.lskel.h is used directly by the kernel kexec code in
later patch. For this patch, there are bpf bytecode contained in
opts_data[] and opts_insn[] in kexec_pe_parser_bpf.lskel.h, but in the
following patch, they will be removed and only the function API in
kexec_pe_parser_bpf.lskel.h left.

As exposed in kexec_pe_parser_bpf.lskel.h, the interface between
bpf-prog and the kernel are constituted by:

four maps:
                struct bpf_map_desc ringbuf_1;
                struct bpf_map_desc ringbuf_2;
                struct bpf_map_desc ringbuf_3;
                struct bpf_map_desc ringbuf_4;
four sections:
                struct bpf_map_desc rodata;
                struct bpf_map_desc data;
                struct bpf_map_desc bss;
                struct bpf_map_desc rodata_str1_1;

one prog:
	SEC("fentry.s/kexec_image_parser_anchor")

They are fixed and provided for all kinds of bpf-prog which interacts
with the kexec kernel component.

Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philipp Rudo <prudo@redhat.com>
Cc: bpf@vger.kernel.org
To: kexec@lists.infradead.org
The routine to search a symbol in ELF can be shared, so split it out.

Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philipp Rudo <prudo@redhat.com>
To: kexec@lists.infradead.org
All kexec PE bpf prog should align with the interface exposed by the
light skeleton
    four maps:
                    struct bpf_map_desc ringbuf_1;
                    struct bpf_map_desc ringbuf_2;
                    struct bpf_map_desc ringbuf_3;
                    struct bpf_map_desc ringbuf_4;
    four sections:
                    struct bpf_map_desc rodata;
                    struct bpf_map_desc data;
                    struct bpf_map_desc rodata_str1_1;
                    struct bpf_map_desc bss;
    two progs:
            SEC("fentry.s/bpf_handle_pefile")

With the above presumption, the integration consists of two parts:
  -1. Call API exposed by light skeleton from kexec
  -2. The opts_insn[] and opts_data[] are bpf-prog dependent and
      can be extracted and passed in from the user space. In the
      kexec_file_load design, a PE file has a .bpf section, which data
      content is a ELF, and the ELF contains opts_insn[] opts_data[].
      As a bonus, BPF bytecode can be placed under the protection of the
      entire PE signature.
      (Note, since opts_insn[] contains the information of the ringbuf
       size, the bpf-prog writer can change its proper size according to
       the kernel image size without modifying the kernel code)

Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philipp Rudo <prudo@redhat.com>
Cc: bpf@vger.kernel.org
To: kexec@lists.infradead.org
Now everything is ready for kexec PE image parser. Select it on arm64
for zboot and UKI image support.

Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
To: linux-arm-kernel@lists.infradead.org
This BPF program aligns with the convention defined in the kernel file
kexec_pe_parser_bpf.lskel.h, where the interface between the BPF program
and the kernel is established, and is composed of:
    four maps:
                    struct bpf_map_desc ringbuf_1;
                    struct bpf_map_desc ringbuf_2;
                    struct bpf_map_desc ringbuf_3;
                    struct bpf_map_desc ringbuf_4;
    four sections:
                    struct bpf_map_desc rodata;
                    struct bpf_map_desc data;
                    struct bpf_map_desc bss;
                    struct bpf_map_desc rodata_str1_1;

    two progs:
            SEC("fentry.s/bpf_handle_pefile")
            SEC("fentry.s/bpf_post_handle_pefile")

This BPF program only uses ringbuf_1, so it minimizes the size of the
other three ringbufs to one byte.  The size of ringbuf_1 is deduced from
the size of the uncompressed file 'vmlinux.bin', which is usually less
than 64MB. With the help of a group of bpf kfuncs: bpf_decompress(),
bpf_copy_to_kernel(), bpf_mem_range_result_put(), this bpf-prog stores
the uncompressed kernel image inside the kernel space.

Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philipp Rudo <prudo@redhat.com>
Cc: bpf@vger.kernel.org
To: kexec@lists.infradead.org
The objcopy binary can append an section into PE file, but it disregards
the DOS header. While the zboot format carries important information:
payload offset and size in the DOS header.

In order to keep track and update such information, here introducing a
dedicated binary tool to build zboot image. The payload offset is
determined by the fact that its offset inside the .data section is
unchanged. Hence the offset of .data section in the new PE file plus the
payload offset within section renders the offset within the new PE file.

The objcopy binary can append a section to a PE file, but it disregards
the DOS header. However, the zboot format carries important information
in the DOS header: payload offset and size.

To track this information and append a new PE section, here a dedicated
binary tool is introduced to build zboot images. The payload's relative
offset within the .data section remains unchanged.  Therefore, the .data
section offset in the new PE file, plus the payload offset within that
section, yields the payload offset within the new PE file.

Finally, the new PE file 'zboot.efi' can be got by the command:
  make -C tools/kexec zboot

Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philipp Rudo <prudo@redhat.com>
Cc: bpf@vger.kernel.org
To: kexec@lists.infradead.org
@pfliu
Copy link
Owner Author

pfliu commented Jan 15, 2026

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant new feature enabling the use of BPF programs to parse kexec images, particularly PE files containing a .bpf section. This allows for more flexible image handling, such as on-the-fly decompression. The changes are extensive, touching the kexec and BPF subsystems, and adding new user-space tooling for image preparation. My review has identified a high-severity issue in the new user-space image builder tool related to an uninitialized variable, which could lead to a crash. I have also provided several medium-severity comments regarding non-idiomatic C code (unnecessary use of the !! operator) that deviates from the Linux kernel coding style, and a minor string formatting issue in a driver file. The overall architecture of this feature appears robust and well-designed.

{
uint32_t payload_new_offset, payload_sect_off;
uint32_t payload_size;
uint32_t payload_sect_idx;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The variable payload_sect_idx is used on line 203 without being initialized if the loop on lines 129-136 does not find a matching section for zheader->payload_offset. This can lead to undefined behavior.

To fix this, you should initialize payload_sect_idx to an invalid value (e.g., (uint32_t)-1), and then add a check after the loop to handle the error case where no section is found. For example:

// after the loop on line 136
if (payload_sect_idx == (uint32_t)-1) {
    fprintf(stderr, "Failed to find section for payload offset 0x%x\n", zheader->payload_offset);
    ret = -1;
    goto err;
}

Also, consider adding a break inside the if block in the loop to make it more efficient.

 uint32_t payload_sect_idx = -1;

/* Please keep this list sorted by vendor and product ID. */
{ 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 },
{ 0x0351, 0x1000, "CRKD LP Blueberry Burst Pro Edition (Xbox)", 0, XTYPE_XBOX360 },
{ 0x0351, 0x2000, "CRKD LP Black Tribal Edition (Xbox) ", 0, XTYPE_XBOX360 },

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is a trailing space in the device name string "CRKD LP Black Tribal Edition (Xbox) ". This should be removed for consistency and to avoid potential issues with string handling in userspace.

 0x0351, 0x2000, "CRKD LP Black Tribal Edition (Xbox)", 0, XTYPE_XBOX360 },

{
struct bpf_parser_context *ctx = container_of(kref, struct bpf_parser_context, ref);

if (!!ctx->buf) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of double negation !! on a pointer is unnecessary. The Linux kernel coding style prefers a direct check for non-NULL pointers. Using if (ctx->buf) is more idiomatic and readable.

 if (ctx->buf) {

if (!b)
return -ENOMEM;
ret = copy_from_kernel_nofault(b, buf, buf_sz);
if (!!ret) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of double negation !! on an integer return value is unnecessary. The Linux kernel coding style prefers checking against zero explicitly (e.g., if (ret != 0)) or simply if (ret) for error codes where any non-zero value is an error. In this context, if (ret) is sufficient and more idiomatic.

 if (ret) {

name, image_gz_sz);
ret = decompressor(compressed_data, image_gz_sz, NULL, flush,
NULL, NULL, NULL);
if (!!ret)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of double negation !! on an integer return value is unnecessary. A direct check if (ret) is sufficient and more idiomatic according to Linux kernel coding style.

 if (ret)

if (!bpf)
return -ENOMEM;
file_get_section((const char *)kernel_start, ".bpf", &bpf_start, &bpf_sz);
if (!!bpf_sz) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of double negation !! on a size variable is unnecessary. A direct check if (bpf_sz) is sufficient and more idiomatic.

  if (bpf_sz) {

Comment on lines +62 to +63
if (!!__builtin_memcmp(&zboot_header->image_type, "zimg",
sizeof(zboot_header->image_type))) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of double negation !! on the result of __builtin_memcmp is unnecessary and not idiomatic. A direct comparison with 0 is clearer and preferred: if (__builtin_memcmp(...) != 0).

 if (__builtin_memcmp(&zboot_header->image_type, "zimg",
   sizeof(zboot_header->image_type)) != 0) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.