TL;DR: this patch fixes regression. This patch should be backported to all distributions, which packaged v2.0.31, otherwise kexec doesn't work at all at my laptop with pretty common setup with v2.0.31. v2.0.31 is broken without this patch.
Recently I found a bug: kexec doesn't work at my laptop. Here is my setup: * Laptop Dell Precision 7780 * CPU Intel Raptor Lake-S * i915 GPU * x86_64 * UEFI * Linux v6.16-rc5 * linux-firmware 20250708 * kexec-tools v2.0.31 * I do kexec from this kernel to the same kernel * Kernel is UEFI PE image * Secure boot is disabled * Kernel config is minimized Debian config * I use command 'kexec --debug --kexec-syscall -l /disk/vmlinuz --initrd=/disk/initramfs.cpio.gz --append="..."', then I execute 'kexec --debug -e' When I execute "kexec --debug -e", I see black screen instead of proper boot of kexec'd kernel. Okay, why the bug happens? I suspect this is because of "%lux" string specifiers, which are totally wrong. The author meant "print (and scan) in hexademical" here, but this specifier prints (and scans) number in decimal, followed by literal "x". Oops. And this seems to break kexec. Changing this to "%lx" or "%llx" will not work, because uint64_t is defined differently on different architectures. So I use PRIx64 to fix this. I tested on my laptop that this patch actually fixes the bug. Fixes: aecc554e7b ("Correct string specifiers") Signed-off-by: Askar Safin <safinas...@zohomail.com> --- kexec/arch/i386/crashdump-x86.c | 3 ++- kexec/arch/i386/kexec-x86-common.c | 3 ++- kexec/arch/i386/x86-linux-setup.c | 3 ++- util_lib/elf_info.c | 5 +++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c index 770e3f1..0716762 100644 --- a/kexec/arch/i386/crashdump-x86.c +++ b/kexec/arch/i386/crashdump-x86.c @@ -28,6 +28,7 @@ #include <string.h> #include <stdlib.h> #include <errno.h> +#include <inttypes.h> #include <limits.h> #include <elf.h> #include <sys/ioctl.h> @@ -784,7 +785,7 @@ static void cmdline_add_efi(char *cmdline) if (!acpi_rsdp) return; - sprintf(acpi_rsdp_buf, " acpi_rsdp=0x%lux", acpi_rsdp); + sprintf(acpi_rsdp_buf, " acpi_rsdp=0x%" PRIx64, acpi_rsdp); if (strlen(cmdline) + strlen(acpi_rsdp_buf) > (COMMAND_LINE_SIZE - 1)) die("Command line overflow\n"); diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c index acacb45..9ba8b3f 100644 --- a/kexec/arch/i386/kexec-x86-common.c +++ b/kexec/arch/i386/kexec-x86-common.c @@ -30,6 +30,7 @@ #include <limits.h> #include <stdlib.h> #include <stdio.h> +#include <inttypes.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/stat.h> @@ -422,7 +423,7 @@ static uint64_t efi_get_acpi_rsdp(void) { /* ACPI20= always goes before ACPI= */ if ((strstr(line, "ACPI20=")) || (strstr(line, "ACPI="))) { s = strchr(line, '=') + 1; - sscanf(s, "0x%lux", &acpi_rsdp); + sscanf(s, "0x%" PRIx64, &acpi_rsdp); break; } } diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c index 70656e3..c716e1b 100644 --- a/kexec/arch/i386/x86-linux-setup.c +++ b/kexec/arch/i386/x86-linux-setup.c @@ -23,6 +23,7 @@ #include <stddef.h> #include <errno.h> #include <limits.h> +#include <inttypes.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/random.h> @@ -760,7 +761,7 @@ static void add_e820_map_from_mr(struct x86_linux_param_header *real_mode, e820[i].type = E820_RESERVED; break; } - dbgprintf("%016lux-%016lux (%d)\n", + dbgprintf("%016" PRIx64 "-%016" PRIx64 " (%d)\n", e820[i].addr, e820[i].addr + e820[i].size - 1, e820[i].type); diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c index 5cf438c..0f03093 100644 --- a/util_lib/elf_info.c +++ b/util_lib/elf_info.c @@ -15,6 +15,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <inttypes.h> #include <elf_info.h> /* The 32bit and 64bit note headers make it clear we don't care */ @@ -890,7 +891,7 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int)) handler(out_buf, len); fprintf(stderr, "Cycle when parsing dmesg detected.\n"); fprintf(stderr, "The prink log_buf is most likely corrupted.\n"); - fprintf(stderr, "log_buf = 0x%lux, idx = 0x%x\n", + fprintf(stderr, "log_buf = 0x%" PRIx64 ", idx = 0x%x\n", log_buf, current_idx); exit(68); } @@ -904,7 +905,7 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int)) handler(out_buf, len); fprintf(stderr, "Index outside log_buf detected.\n"); fprintf(stderr, "The prink log_buf is most likely corrupted.\n"); - fprintf(stderr, "log_buf = 0x%lux, idx = 0x%x\n", + fprintf(stderr, "log_buf = 0x%" PRIx64 ", idx = 0x%x\n", log_buf, current_idx); exit(69); } -- 2.47.2