diff --git a/Fix-incorrect-page-exclusion-in-exclude_nodata_pages.patch b/Fix-incorrect-page-exclusion-in-exclude_nodata_pages.patch new file mode 100644 index 0000000000000000000000000000000000000000..4eefd63bc6831d15ebbae489284d926d5bb32775 --- /dev/null +++ b/Fix-incorrect-page-exclusion-in-exclude_nodata_pages.patch @@ -0,0 +1,26 @@ +From fe71ffabcc7e5787b0bcf0b4cfcdab83182b84fd Mon Sep 17 00:00:00 2001 +From: Ming Wang +Date: Mon, 14 Oct 2024 16:23:08 +0800 +Subject: [PATCH] Fix incorrect page exclusion in exclude_nodata_pages() + +Signed-off-by: Ming Wang +--- + makedumpfile-1.7.4/makedumpfile.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/makedumpfile-1.7.4/makedumpfile.c b/makedumpfile-1.7.4/makedumpfile.c +index a6ec9d4..4ddbf4d 100644 +--- a/makedumpfile-1.7.4/makedumpfile.c ++++ b/makedumpfile-1.7.4/makedumpfile.c +@@ -5192,7 +5192,7 @@ exclude_nodata_pages(struct cycle *cycle) + NULL, &file_size)) { + unsigned long long pfn, pfn_end; + +- pfn = paddr_to_pfn(phys_start + file_size); ++ pfn = paddr_to_pfn(roundup(phys_start + file_size, PAGESIZE())); + pfn_end = paddr_to_pfn(roundup(phys_end, PAGESIZE())); + + if (pfn < cycle->start_pfn) +-- +2.41.0 + diff --git a/kdump.sysconfig.loongarch64 b/kdump.sysconfig.loongarch64 old mode 100755 new mode 100644 index 86c6d89d7ef74341ee7bbb4f0bf7e282d615db7a..5fe26bd7a2908d086b5847b8a19acb64e1761249 --- a/kdump.sysconfig.loongarch64 +++ b/kdump.sysconfig.loongarch64 @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len rd_s # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE -KDUMP_COMMANDLINE_APPEND="nr_cpus=1 init 3 irqpoll reset_devices cgroup_disable=memory udev.children-max=2 panic=10 novmcoredd" +KDUMP_COMMANDLINE_APPEND="nr_cpus=1 init 3 irqpoll reset_devices cgroup_disable=memory udev.children-max=2 panic=10 novmcoredd nokaslr" # Any additional kexec arguments required. In most situations, this should # be left empty @@ -34,7 +34,7 @@ KEXEC_ARGS="" #KDUMP_BOOTDIR="/boot" #What is the image type used for kdump -KDUMP_IMG="vmlinux" +KDUMP_IMG="vmlinuz" #Please replace with the capture kernel to be reboot and the #the corresponding initrd only for LoongArch architecture @@ -43,10 +43,10 @@ KDUMP_IMG="vmlinux" # DEFAULT_TARGET_INITRD="/boot/initramfs-4.19.190-4.lns8.loongarch64+kdump.img" # If a DEFAULT_KDUMP_KERNEL is not specified, the default is set to # "/boot/vmlinux-$(uname -r)+kdump" -DEFAULT_KDUMP_KERNEL="" +# DEFAULT_KDUMP_KERNEL="" # If a DEFAULT_TARGET_INITRD is not specified, the default is set to # "/boot/initramfs-$(uname -r)+kdump.img" -DEFAULT_TARGET_INITRD="" +# DEFAULT_TARGET_INITRD="" # Logging is controlled by following variables in the first kernel: # - @var KDUMP_STDLOGLVL - logging level to standard error (console output) diff --git a/kexec-tools.spec b/kexec-tools.spec index e1db2b5a193c1d460024c24e9ed94ea4c3caa8ac..bc7e206a8be43d798800f9436936f691bc714c36 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -4,7 +4,7 @@ Name: kexec-tools Version: 2.0.26 -Release: 9 +Release: 10 License: GPLv2 Summary: The kexec/kdump userspace component URL: https://www.kernel.org/ @@ -86,6 +86,8 @@ Patch0007: kexec-tools-fix-riscv-support.patch %ifarch loongarch64 Patch0008: Add-loongarch-iomem.h.patch +Patch0009: Fix-incorrect-page-exclusion-in-exclude_nodata_pages.patch +Patch0010: loongarch64-fix-kernel-image-size-error.patch %endif %description @@ -295,6 +297,9 @@ done %endif %changelog +* Mon Jan 6 2025 Ming Wang - 2.0.26-10 +- Fix loongarch kdump image size overflow issue. + * Fri Sep 20 2024 chenguokai - 2.0.26-9 - Fix multiple issues of riscv image format & initrd support - Rebase and test by Mingzheng Xing diff --git a/loongarch64-fix-kernel-image-size-error.patch b/loongarch64-fix-kernel-image-size-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..26598150266b63bd26a20e36ca5aec00be70b3a3 --- /dev/null +++ b/loongarch64-fix-kernel-image-size-error.patch @@ -0,0 +1,245 @@ +From 510981a6b810c18d1bc3f5917ad743f3a6c85cf7 Mon Sep 17 00:00:00 2001 +From: Ming Wang +Date: Fri, 17 May 2024 10:39:31 +0800 +Subject: [PATCH] kexec: loongarch: fix some issue. + +Signed-off-by: Hongchen Zhang +Signed-off-by: Ming Wang +--- + kexec/arch/loongarch/crashdump-loongarch.c | 22 ++++++++++++ + kexec/arch/loongarch/crashdump-loongarch.h | 1 + + kexec/arch/loongarch/kexec-elf-loongarch.c | 40 +++++++++++++++++++--- + kexec/arch/loongarch/kexec-loongarch.c | 22 ++++++++---- + kexec/arch/loongarch/kexec-pei-loongarch.c | 7 ++++ + kexec/kexec-syscall.h | 2 +- + 6 files changed, 82 insertions(+), 12 deletions(-) + +diff --git a/kexec/arch/loongarch/crashdump-loongarch.c b/kexec/arch/loongarch/crashdump-loongarch.c +index aaf6cf3..81250e4 100644 +--- a/kexec/arch/loongarch/crashdump-loongarch.c ++++ b/kexec/arch/loongarch/crashdump-loongarch.c +@@ -183,6 +183,28 @@ int load_crashdump_segments(struct kexec_info *info) + return 0; + } + ++/* ++ * e_entry and p_paddr are actually in virtual address space. ++ * Those values will be translated to physcal addresses by using ++ * virt_to_phys() in add_segment(). ++ * So let's fix up those values for later use so the memory base will be ++ * correctly replaced with crash_reserved_mem[usablemem_rgns.size - 1].start. ++ */ ++void fixup_elf_addrs(struct mem_ehdr *ehdr) ++{ ++ struct mem_phdr *phdr; ++ int i; ++ ++ ehdr->e_entry += crash_reserved_mem[usablemem_rgns.size - 1].start; ++ ++ for (i = 0; i < ehdr->e_phnum; i++) { ++ phdr = &ehdr->e_phdr[i]; ++ if (phdr->p_type != PT_LOAD) ++ continue; ++ phdr->p_paddr += crash_reserved_mem[usablemem_rgns.size - 1].start; ++ } ++} ++ + int get_crash_kernel_load_range(uint64_t *start, uint64_t *end) + { + if (!usablemem_rgns.size) +diff --git a/kexec/arch/loongarch/crashdump-loongarch.h b/kexec/arch/loongarch/crashdump-loongarch.h +index 3eb4e0a..25ff24b 100644 +--- a/kexec/arch/loongarch/crashdump-loongarch.h ++++ b/kexec/arch/loongarch/crashdump-loongarch.h +@@ -8,6 +8,7 @@ extern struct memory_range elfcorehdr_mem; + + int load_crashdump_segments(struct kexec_info *info); + int is_crashkernel_mem_reserved(void); ++void fixup_elf_addrs(struct mem_ehdr *ehdr); + int get_crash_kernel_load_range(uint64_t *start, uint64_t *end); + + #define PAGE_OFFSET 0x9000000000000000ULL +diff --git a/kexec/arch/loongarch/kexec-elf-loongarch.c b/kexec/arch/loongarch/kexec-elf-loongarch.c +index 2bf128f..7e84d03 100644 +--- a/kexec/arch/loongarch/kexec-elf-loongarch.c ++++ b/kexec/arch/loongarch/kexec-elf-loongarch.c +@@ -54,6 +54,7 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf, + unsigned long kernel_segment; + struct mem_ehdr ehdr; + int result; ++ int i; + + result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0); + +@@ -62,6 +63,26 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf, + goto exit; + } + ++ /* Find and process the loongarch image header. */ ++ for (i = 0; i < ehdr.e_phnum; i++) { ++ struct mem_phdr *phdr = &ehdr.e_phdr[i]; ++ ++ if (phdr->p_type != PT_LOAD) ++ continue; ++ ++ header = (const struct loongarch_image_header *)( ++ kernel_buf + phdr->p_offset); ++ ++ if (!loongarch_process_image_header(header)) ++ break; ++ } ++ ++ if (i == ehdr.e_phnum) { ++ dbgprintf("%s: Valid loongarch image header not found\n", __func__); ++ result = EFAILED; ++ goto exit; ++ } ++ + kernel_segment = loongarch_locate_kernel_segment(info); + + if (kernel_segment == ULONG_MAX) { +@@ -72,13 +93,12 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf, + + dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment); + dbgprintf("%s: image_size: %016lx\n", __func__, +- kernel_size); ++ loongarch_mem.image_size); + dbgprintf("%s: text_offset: %016lx\n", __func__, + loongarch_mem.text_offset); + dbgprintf("%s: phys_offset: %016lx\n", __func__, + loongarch_mem.phys_offset); +- dbgprintf("%s: PE format: %s\n", __func__, +- (loongarch_header_check_pe_sig(header) ? "yes" : "no")); ++ dbgprintf("%s: PE format: no\n", __func__); + + /* create and initialize elf core header segment */ + if (info->kexec_flags & KEXEC_ON_CRASH) { +@@ -90,6 +110,14 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf, + } + } + ++ /* load the kernel */ ++ if (info->kexec_flags & KEXEC_ON_CRASH) ++ /* ++ * offset addresses in elf header in order to load ++ * vmlinux (elf_exec) into crash kernel's memory. ++ */ ++ fixup_elf_addrs(&ehdr); ++ + info->entry = (void *)virt_to_phys(ehdr.e_entry); + + result = elf_exec_load(&ehdr, info); +@@ -99,8 +127,12 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf, + goto exit; + } + ++ /* for vmlinuz kernel image */ ++ if (kernel_size < MiB(16)) ++ kernel_size = MiB(64); ++ + /* load additional data */ +- result = loongarch_load_other_segments(info, kernel_segment + kernel_size); ++ result = loongarch_load_other_segments(info, kernel_segment + loongarch_mem.image_size); + + exit: + free_elf_info(&ehdr); +diff --git a/kexec/arch/loongarch/kexec-loongarch.c b/kexec/arch/loongarch/kexec-loongarch.c +index 4c7361c..6485080 100644 +--- a/kexec/arch/loongarch/kexec-loongarch.c ++++ b/kexec/arch/loongarch/kexec-loongarch.c +@@ -221,6 +221,10 @@ int arch_process_options(int argc, char **argv) + cmdline = get_command_line(); + remove_parameter(cmdline, "kexec"); + remove_parameter(cmdline, "initrd"); ++ remove_parameter(cmdline, "rd_start"); ++ remove_parameter(cmdline, "rd_size"); ++ remove_parameter(cmdline, "vfio_iommu_type1.allow_unsafe_interrupts"); ++ remove_parameter(cmdline, "nokaslr"); + break; + case OPT_INITRD: + arch_options.initrd_file = optarg; +@@ -253,8 +257,9 @@ unsigned long loongarch_locate_kernel_segment(struct kexec_info *info) + unsigned long hole_end; + + hole = (crash_reserved_mem[usablemem_rgns.size - 1].start < mem_min ? +- mem_min : crash_reserved_mem[usablemem_rgns.size - 1].start); +- hole = _ALIGN_UP(hole, MiB(1)); ++ mem_min : crash_reserved_mem[usablemem_rgns.size - 1].start) + ++ loongarch_mem.text_offset; ++ hole = _ALIGN_UP(hole, MiB(16)); + hole_end = hole + loongarch_mem.text_offset + loongarch_mem.image_size; + + if ((hole_end > mem_max) || +@@ -265,7 +270,7 @@ unsigned long loongarch_locate_kernel_segment(struct kexec_info *info) + } else { + hole = locate_hole(info, + loongarch_mem.text_offset + loongarch_mem.image_size, +- MiB(1), 0, ULONG_MAX, 1); ++ MiB(16), 0, ULONG_MAX, 1); + + if (hole == ULONG_MAX) + dbgprintf("%s: locate_hole failed\n", __func__); +@@ -283,6 +288,7 @@ int loongarch_load_other_segments(struct kexec_info *info, unsigned long hole_mi + unsigned long initrd_min, hole_max; + char *initrd_buf = NULL; + unsigned long pagesize = getpagesize(); ++ int i; + + if (arch_options.command_line) { + if (strlen(arch_options.command_line) > +@@ -320,15 +326,17 @@ int loongarch_load_other_segments(struct kexec_info *info, unsigned long hole_mi + cmdline_add_elfcorehdr(cmdline, elfcorehdr_mem.start, + elfcorehdr_mem.end - elfcorehdr_mem.start + 1); + +- cmdline_add_mem(cmdline, crash_reserved_mem[usablemem_rgns.size - 1].start, +- crash_reserved_mem[usablemem_rgns.size - 1].end - +- crash_reserved_mem[usablemem_rgns.size - 1].start + 1); ++ for(i = 0;i < usablemem_rgns.size; i++) { ++ cmdline_add_mem(cmdline, crash_reserved_mem[i].start, ++ crash_reserved_mem[i].end - ++ crash_reserved_mem[i].start + 1); ++ } + } + + cmdline[sizeof(cmdline) - 1] = 0; + add_buffer(info, cmdline, sizeof(cmdline), sizeof(cmdline), + sizeof(void *), _ALIGN_UP(hole_min, getpagesize()), +- 0xffffffff, 1); ++ hole_max, 1); + + dbgprintf("%s:%d: command_line: %s\n", __func__, __LINE__, cmdline); + +diff --git a/kexec/arch/loongarch/kexec-pei-loongarch.c b/kexec/arch/loongarch/kexec-pei-loongarch.c +index f86ac61..1a11103 100644 +--- a/kexec/arch/loongarch/kexec-pei-loongarch.c ++++ b/kexec/arch/loongarch/kexec-pei-loongarch.c +@@ -66,6 +66,13 @@ int pei_loongarch_load(int argc, char **argv, const char *buf, + + kernel_entry = virt_to_phys(loongarch_header_kernel_entry(header)); + ++ if (info->kexec_flags & KEXEC_ON_CRASH) ++ /* ++ * offset addresses in order to load vmlinux.efi into ++ * crash kernel's memory. ++ */ ++ kernel_entry += crash_reserved_mem[usablemem_rgns.size - 1].start; ++ + dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment); + dbgprintf("%s: kernel_entry: %016lx\n", __func__, kernel_entry); + dbgprintf("%s: image_size: %016lx\n", __func__, +diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h +index e392c01..f18b014 100644 +--- a/kexec/kexec-syscall.h ++++ b/kexec/kexec-syscall.h +@@ -59,7 +59,7 @@ + #endif + #endif /*ifndef __NR_kexec_load*/ + +-#ifdef __arm__ ++#if defined(__arm__) || defined(__loongarch__) + #undef __NR_kexec_file_load + #endif + +-- +2.43.0 +