diff --git a/Cleanup-move-it-back-from-util_lib-elf_info.c.patch b/Cleanup-move-it-back-from-util_lib-elf_info.c.patch new file mode 100644 index 0000000000000000000000000000000000000000..75b9b95fd4e2e3919d58f2cb02b44041cdefe031 --- /dev/null +++ b/Cleanup-move-it-back-from-util_lib-elf_info.c.patch @@ -0,0 +1,176 @@ +From a7c4cb8e998571cb3dd62e907935a1e052b15d6c Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Fri, 23 Aug 2019 20:05:38 +0800 +Subject: [PATCH] Cleanup: move it back from util_lib/elf_info.c + +Some code related to vmcore-dmesg.c is put into the util_lib, which +is not very reasonable, so lets move it back and tidy up those code. + +In addition, that will also help to limit the size of vmcore-dmesg.txt +in vmcore-dmesg.c instead of elf_info.c. + +Signed-off-by: Lianbo Jiang +Signed-off-by: Simon Horman + +diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c +index 5d0efaa..2bce5cb 100644 +--- a/util_lib/elf_info.c ++++ b/util_lib/elf_info.c +@@ -531,19 +531,7 @@ static int32_t read_file_s32(int fd, uint64_t addr) + return read_file_u32(fd, addr); + } + +-static void write_to_stdout(char *buf, unsigned int nr) +-{ +- ssize_t ret; +- +- ret = write(STDOUT_FILENO, buf, nr); +- if (ret != nr) { +- fprintf(stderr, "Failed to write out the dmesg log buffer!:" +- " %s\n", strerror(errno)); +- exit(54); +- } +-} +- +-static void dump_dmesg_legacy(int fd) ++static void dump_dmesg_legacy(int fd, void (*handler)(char*, unsigned int)) + { + uint64_t log_buf, log_buf_offset; + unsigned log_end, logged_chars, log_end_wrapped; +@@ -604,7 +592,8 @@ static void dump_dmesg_legacy(int fd) + */ + logged_chars = log_end < log_buf_len ? log_end : log_buf_len; + +- write_to_stdout(buf + (log_buf_len - logged_chars), logged_chars); ++ if (handler) ++ handler(buf + (log_buf_len - logged_chars), logged_chars); + } + + static inline uint16_t struct_val_u16(char *ptr, unsigned int offset) +@@ -623,7 +612,7 @@ static inline uint64_t struct_val_u64(char *ptr, unsigned int offset) + } + + /* Read headers of log records and dump accordingly */ +-static void dump_dmesg_structured(int fd) ++static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int)) + { + #define OUT_BUF_SIZE 4096 + uint64_t log_buf, log_buf_offset, ts_nsec; +@@ -733,7 +722,8 @@ static void dump_dmesg_structured(int fd) + out_buf[len++] = c; + + if (len >= OUT_BUF_SIZE - 64) { +- write_to_stdout(out_buf, len); ++ if (handler) ++ handler(out_buf, len); + len = 0; + } + } +@@ -752,16 +742,16 @@ static void dump_dmesg_structured(int fd) + current_idx += loglen; + } + free(buf); +- if (len) +- write_to_stdout(out_buf, len); ++ if (len && handler) ++ handler(out_buf, len); + } + +-static void dump_dmesg(int fd) ++void dump_dmesg(int fd, void (*handler)(char*, unsigned int)) + { + if (log_first_idx_vaddr) +- dump_dmesg_structured(fd); ++ dump_dmesg_structured(fd, handler); + else +- dump_dmesg_legacy(fd); ++ dump_dmesg_legacy(fd, handler); + } + + int read_elf(int fd) +@@ -808,22 +798,6 @@ int read_elf(int fd) + return 0; + } + +-int read_elf_vmcore(int fd) +-{ +- int ret; +- +- ret = read_elf(fd); +- if (ret > 0) { +- fprintf(stderr, "Unable to read ELF information" +- " from vmcore\n"); +- return ret; +- } +- +- dump_dmesg(fd); +- +- return 0; +-} +- + int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off) + { + int ret; +diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h +index c328a1b..4bc9279 100644 +--- a/util_lib/include/elf_info.h ++++ b/util_lib/include/elf_info.h +@@ -30,6 +30,6 @@ int get_pt_load(int idx, + unsigned long long *virt_end); + int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off); + int read_elf(int fd); +-int read_elf_vmcore(int fd); ++void dump_dmesg(int fd, void (*handler)(char*, unsigned int)); + + #endif /* ELF_INFO_H */ +diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c +index bebc348..fe7df8e 100644 +--- a/vmcore-dmesg/vmcore-dmesg.c ++++ b/vmcore-dmesg/vmcore-dmesg.c +@@ -5,6 +5,34 @@ typedef Elf32_Nhdr Elf_Nhdr; + + extern const char *fname; + ++static void write_to_stdout(char *buf, unsigned int nr) ++{ ++ ssize_t ret; ++ ++ ret = write(STDOUT_FILENO, buf, nr); ++ if (ret != nr) { ++ fprintf(stderr, "Failed to write out the dmesg log buffer!:" ++ " %s\n", strerror(errno)); ++ exit(54); ++ } ++} ++ ++static int read_vmcore_dmesg(int fd, void (*handler)(char*, unsigned int)) ++{ ++ int ret; ++ ++ ret = read_elf(fd); ++ if (ret > 0) { ++ fprintf(stderr, "Unable to read ELF information" ++ " from vmcore\n"); ++ return ret; ++ } ++ ++ dump_dmesg(fd, handler); ++ ++ return 0; ++} ++ + int main(int argc, char **argv) + { + ssize_t ret; +@@ -23,7 +51,7 @@ int main(int argc, char **argv) + return 2; + } + +- ret = read_elf_vmcore(fd); ++ ret = read_vmcore_dmesg(fd, write_to_stdout); + + close(fd); + +-- +1.8.3.1 + diff --git a/Cleanup-remove-the-read_elf_kcore.patch b/Cleanup-remove-the-read_elf_kcore.patch new file mode 100644 index 0000000000000000000000000000000000000000..8012051487f36018aa8482b3735401f22bb2f83b --- /dev/null +++ b/Cleanup-remove-the-read_elf_kcore.patch @@ -0,0 +1,79 @@ +From 545c811050a375f79e0fa0e107cb35b9ae3a1599 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Fri, 23 Aug 2019 20:05:36 +0800 +Subject: [PATCH] Cleanup: remove the read_elf_kcore() + +Here, no need to wrap the read_elf() again, lets invoke it directly. +So remove the read_elf_kcore() and clean up redundant code. + +Signed-off-by: Lianbo Jiang +Signed-off-by: Simon Horman + +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index eb3a3a3..6ad3b0a 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -889,7 +889,7 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset) + return EFAILED; + } + +- read_elf_kcore(fd); ++ read_elf(fd); + + for (i = 0; get_pt_load(i, + &phys_start, NULL, &virt_start, NULL); +diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c +index 90a3b21..d9397ec 100644 +--- a/util_lib/elf_info.c ++++ b/util_lib/elf_info.c +@@ -764,7 +764,7 @@ static void dump_dmesg(int fd) + dump_dmesg_legacy(fd); + } + +-static int read_elf(int fd) ++int read_elf(int fd) + { + int ret; + +@@ -824,24 +824,13 @@ int read_elf_vmcore(int fd) + return 0; + } + +-int read_elf_kcore(int fd) +-{ +- int ret; +- +- ret = read_elf(fd); +- if (ret != 0) +- return ret; +- +- return 0; +-} +- + int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off) + { + int ret; + + *phys_off = UINT64_MAX; + +- ret = read_elf_kcore(fd); ++ ret = read_elf(fd); + if (!ret) { + /* If we have a valid 'PHYS_OFFSET' by now, + * return it to the caller now. +diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h +index 1a4debd..c328a1b 100644 +--- a/util_lib/include/elf_info.h ++++ b/util_lib/include/elf_info.h +@@ -29,7 +29,7 @@ int get_pt_load(int idx, + unsigned long long *virt_start, + unsigned long long *virt_end); + int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off); +-int read_elf_kcore(int fd); ++int read_elf(int fd); + int read_elf_vmcore(int fd); + + #endif /* ELF_INFO_H */ +-- +1.8.3.1 + diff --git a/Fix-an-error-definition-about-the-variable-fname.patch b/Fix-an-error-definition-about-the-variable-fname.patch new file mode 100644 index 0000000000000000000000000000000000000000..f541a3e938d971732e5745de143ecea066569dc1 --- /dev/null +++ b/Fix-an-error-definition-about-the-variable-fname.patch @@ -0,0 +1,43 @@ +From 14ad054e7baa788a6629385ffe5e0f1996b7de02 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Fri, 23 Aug 2019 20:05:37 +0800 +Subject: [PATCH] Fix an error definition about the variable 'fname' + +The variable 'fname' is mistakenly defined two twice, the first definition +is in the vmcore-dmesg.c, and the second definition is in the elf_info.c. +That is confused and incorrect although it's a static type, because the +value of variable 'fname' is not assigned(set) in elf_info.c. Anyway, its +value will be always 'null' when printing an error information. + +Signed-off-by: Lianbo Jiang +Signed-off-by: Simon Horman + +diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c +index d9397ec..5d0efaa 100644 +--- a/util_lib/elf_info.c ++++ b/util_lib/elf_info.c +@@ -20,7 +20,7 @@ + /* The 32bit and 64bit note headers make it clear we don't care */ + typedef Elf32_Nhdr Elf_Nhdr; + +-static const char *fname; ++const char *fname; + static Elf64_Ehdr ehdr; + static Elf64_Phdr *phdr; + static int num_pt_loads; +diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c +index 7a386b3..bebc348 100644 +--- a/vmcore-dmesg/vmcore-dmesg.c ++++ b/vmcore-dmesg/vmcore-dmesg.c +@@ -3,7 +3,7 @@ + /* The 32bit and 64bit note headers make it clear we don't care */ + typedef Elf32_Nhdr Elf_Nhdr; + +-static const char *fname; ++extern const char *fname; + + int main(int argc, char **argv) + { +-- +1.8.3.1 + diff --git a/Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch b/Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch new file mode 100644 index 0000000000000000000000000000000000000000..940e595415c4f224094b76a43ace5bd9baed1d1e --- /dev/null +++ b/Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch @@ -0,0 +1,52 @@ +From fa3f0ed47f3e6dbee485722d13713ad495571b7e Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Fri, 23 Aug 2019 20:05:39 +0800 +Subject: [PATCH] Limit the size of vmcore-dmesg.txt to 2G + +With some corrupted vmcore files, the vmcore-dmesg.txt file may grow +forever till the kdump disk becomes full, and also probably causes +the disk error messages as follow: +... +sd 0:0:0:0: [sda] tag#6 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK +sd 0:0:0:0: [sda] tag#6 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00 +blk_update_request: I/O error, dev sda, sector 134630552 +sd 0:0:0:0: [sda] tag#7 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK +sd 0:0:0:0: [sda] tag#7 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00 +blk_update_request: I/O error, dev sda, sector 134630552 +... + +If vmcore-dmesg.txt occupies the whole disk, the vmcore can not be +saved, this is also a problem. + +Lets limit the size of vmcore-dmesg.txt to avoid such problems. + +Signed-off-by: Lianbo Jiang +Signed-off-by: Simon Horman + +diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c +index fe7df8e..81c2a58 100644 +--- a/vmcore-dmesg/vmcore-dmesg.c ++++ b/vmcore-dmesg/vmcore-dmesg.c +@@ -5,9 +5,19 @@ typedef Elf32_Nhdr Elf_Nhdr; + + extern const char *fname; + ++/* stole this macro from kernel printk.c */ ++#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31) ++ + static void write_to_stdout(char *buf, unsigned int nr) + { + ssize_t ret; ++ static uint32_t n_bytes = 0; ++ ++ n_bytes += nr; ++ if (n_bytes > LOG_BUF_LEN_MAX) { ++ fprintf(stderr, "The vmcore-dmesg.txt over 2G in size is not supported.\n"); ++ exit(53); ++ } + + ret = write(STDOUT_FILENO, buf, nr); + if (ret != nr) { +-- +1.8.3.1 + diff --git a/arm64-kdump-deal-with-a-lot-of-resource-entries-in-proc-iomem.patch b/arm64-kdump-deal-with-a-lot-of-resource-entries-in-proc-iomem.patch new file mode 100644 index 0000000000000000000000000000000000000000..447bad0321153b10c9e38f68719986333313f034 --- /dev/null +++ b/arm64-kdump-deal-with-a-lot-of-resource-entries-in-proc-iomem.patch @@ -0,0 +1,79 @@ +From 2572b8d702e452624bdb8d7b7c39f458e7dcf2ce Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Wed, 18 Dec 2019 11:42:32 -0500 +Subject: [PATCH] arm64: kdump: deal with a lot of resource entries in + /proc/iomem + +As described in the commit ("arm64: kexec: allocate memory space avoiding +reserved regions"), /proc/iomem now has a lot of "reserved" entries, and +it's not just enough to have a fixed size of memory range array. + +With this patch, kdump is allowed to handle arbitrary number of memory +ranges, using mem_regions_alloc_and_xxx() functions. + +Signed-off-by: AKASHI Takahiro +Tested-by: Bhupesh Sharma +Tested-by: Masayoshi Mizuma +Signed-off-by: Simon Horman + +diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c +index 4fd7aa8..38d1a0f 100644 +--- a/kexec/arch/arm64/crashdump-arm64.c ++++ b/kexec/arch/arm64/crashdump-arm64.c +@@ -23,13 +23,8 @@ + #include "kexec-elf.h" + #include "mem_regions.h" + +-/* memory ranges on crashed kernel */ +-static struct memory_range system_memory_ranges[CRASH_MAX_MEMORY_RANGES]; +-static struct memory_ranges system_memory_rgns = { +- .size = 0, +- .max_size = CRASH_MAX_MEMORY_RANGES, +- .ranges = system_memory_ranges, +-}; ++/* memory ranges of crashed kernel */ ++static struct memory_ranges system_memory_rgns; + + /* memory range reserved for crashkernel */ + struct memory_range crash_reserved_mem; +@@ -82,7 +77,7 @@ static uint64_t get_kernel_page_offset(void) + * + * This function is called once for each memory region found in /proc/iomem. + * It locates system RAM and crashkernel reserved memory and places these to +- * variables, respectively, system_memory_ranges and crash_reserved_mem. ++ * variables, respectively, system_memory_rgns and usablemem_rgns. + */ + + static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr), +@@ -90,11 +85,11 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr), + unsigned long long length) + { + if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0) +- return mem_regions_add(&usablemem_rgns, +- base, length, RANGE_RAM); ++ return mem_regions_alloc_and_add(&usablemem_rgns, ++ base, length, RANGE_RAM); + else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0) +- return mem_regions_add(&system_memory_rgns, +- base, length, RANGE_RAM); ++ return mem_regions_alloc_and_add(&system_memory_rgns, ++ base, length, RANGE_RAM); + else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0) + elf_info.kern_paddr_start = base; + else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0) +@@ -135,9 +130,9 @@ static int crash_get_memory_ranges(void) + + dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1); + +- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) { +- fprintf(stderr, +- "Error: Number of crash memory ranges excedeed the max limit\n"); ++ if (mem_regions_alloc_and_exclude(&system_memory_rgns, ++ &crash_reserved_mem)) { ++ fprintf(stderr, "Cannot allocate memory for ranges\n"); + return -ENOMEM; + } + +-- +1.8.3.1 + diff --git a/arm64-support-more-than-one-crash-kernel-regions.patch b/arm64-support-more-than-one-crash-kernel-regions.patch index c2cd0c6c14f393a61b52ff1b6f066996bc6a70cb..ab20a18aff248211e822cb6c0905739571a6a2a6 100644 --- a/arm64-support-more-than-one-crash-kernel-regions.patch +++ b/arm64-support-more-than-one-crash-kernel-regions.patch @@ -30,9 +30,9 @@ diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm index 4fd7aa8..158e778 100644 --- a/kexec/arch/arm64/crashdump-arm64.c +++ b/kexec/arch/arm64/crashdump-arm64.c -@@ -32,11 +32,11 @@ static struct memory_ranges system_memory_rgns = { - }; - +@@ -27,11 +27,11 @@ + static struct memory_ranges system_memory_rgns; + /* memory range reserved for crashkernel */ -struct memory_range crash_reserved_mem; +struct memory_range crash_reserved_mem[CRASH_MAX_RESERVED_RANGES]; @@ -63,7 +63,7 @@ index 4fd7aa8..158e778 100644 /* * First read all memory regions that can be considered as * system memory including the crash area. -@@ -129,16 +131,19 @@ static int crash_get_memory_ranges(void) +@@ -124,16 +126,19 @@ static int crash_get_memory_ranges(void) if (!usablemem_rgns.size) kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL); @@ -77,9 +77,9 @@ index 4fd7aa8..158e778 100644 + dbgprint_mem_range("Reserved memory range", + usablemem_rgns.ranges, usablemem_rgns.size); -- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) { -- fprintf(stderr, -- "Error: Number of crash memory ranges excedeed the max limit\n"); +- if (mem_regions_alloc_and_exclude(&system_memory_rgns, +- &crash_reserved_mem)) { +- fprintf(stderr, "Cannot allocate memory for ranges\n"); - return -ENOMEM; + for (i = 0; i < usablemem_rgns.size; i++) { + if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem[i])) { diff --git a/kexec-support-parsing-the-string-Reserved-to-get-the-correct-e820-reserved-region.patch b/kexec-support-parsing-the-string-Reserved-to-get-the-correct-e820-reserved-region.patch new file mode 100644 index 0000000000000000000000000000000000000000..4fa41564287e3bd098fe4ff9aef6b62ce4f20005 --- /dev/null +++ b/kexec-support-parsing-the-string-Reserved-to-get-the-correct-e820-reserved-region.patch @@ -0,0 +1,44 @@ +From 618799e90566e22554584644e496ff95f425ac48 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Mon, 24 Feb 2020 14:36:55 +0800 +Subject: [PATCH] kexec: support parsing the string "Reserved" to get the + correct e820 reserved region + +When loading kernel and initramfs for kexec, kexec-tools could get the +e820 reserved region from "/proc/iomem" in order to rebuild the e820 +ranges for kexec kernel, but there may be the string "Reserved" in the +"/proc/iomem", which caused the failure of parsing. For example: + + #cat /proc/iomem|grep -i reserved +00000000-00000fff : Reserved +7f338000-7f34dfff : Reserved +7f3cd000-8fffffff : Reserved +f17f0000-f17f1fff : Reserved +fe000000-ffffffff : Reserved + +Currently, kexec-tools can not handle the above case because the memcmp() +is case sensitive when comparing the string. + +So, let's fix this corner and make sure that the string "reserved" and +"Reserved" in the "/proc/iomem" are both parsed appropriately. + +Signed-off-by: Lianbo Jiang +Acked-by: Bhupesh Sharma +Signed-off-by: Simon Horman + +diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c +index 61ea193..9303704 100644 +--- a/kexec/arch/i386/kexec-x86-common.c ++++ b/kexec/arch/i386/kexec-x86-common.c +@@ -90,7 +90,7 @@ static int get_memory_ranges_proc_iomem(struct memory_range **range, int *ranges + if (memcmp(str, "System RAM\n", 11) == 0) { + type = RANGE_RAM; + } +- else if (memcmp(str, "reserved\n", 9) == 0) { ++ else if (strncasecmp(str, "reserved\n", 9) == 0) { + type = RANGE_RESERVED; + } + else if (memcmp(str, "ACPI Tables\n", 12) == 0) { +-- +1.8.3.1 + diff --git a/kexec-tools-Fix-kexec_file_load-2-error-handling.patch b/kexec-tools-Fix-kexec_file_load-2-error-handling.patch new file mode 100644 index 0000000000000000000000000000000000000000..85d5284c9f373a7336d02e9546e113ea8a9c0e2d --- /dev/null +++ b/kexec-tools-Fix-kexec_file_load-2-error-handling.patch @@ -0,0 +1,225 @@ +From 4f77da6340356de40af70473d3c3ae6ec663fbdf Mon Sep 17 00:00:00 2001 +From: Petr Tesarik +Date: Fri, 13 Mar 2020 15:09:28 +0100 +Subject: [PATCH] kexec-tools: Fix kexec_file_load(2) error handling + +The handling of kexec_file_load() error conditions needs some +improvement. + +First, on failure, the system call itself returns -1 and sets +errno. It is wrong to check the return value itself. + +Second, do_kexec_file_load() mixes different types of error +codes (-1, return value of a load method, negative kernel error +number). Let it always return one of the reason codes defined in +kexec/kexec.h. + +Third, the caller of do_kexec_file_load() cannot know what exactly +failed inside that function, so it should not check errno directly. +All it needs to know is whether it makes sense to fall back to the +other syscall. Add an error code for that purpose (EFALLBACK), and +let do_kexec_file_load() decide. + +Fourth, do_kexec_file_load() should not print any error message if +it returns EFALLBACK, because the fallback syscall may succeed +later, and the user is confused whether the command failed, or not. +Move the error message towards the end of main(). + +Signed-off-by: Petr Tesarik +Signed-off-by: Simon Horman + +diff --git a/kexec/kexec.c b/kexec/kexec.c +index bc6ab3d..33c1b4b 100644 +--- a/kexec/kexec.c ++++ b/kexec/kexec.c +@@ -836,11 +836,21 @@ static int kexec_file_unload(unsigned long kexec_file_flags) + { + int ret = 0; + ++ if (!is_kexec_file_load_implemented()) ++ return EFALLBACK; ++ + ret = kexec_file_load(-1, -1, 0, NULL, kexec_file_flags); + if (ret != 0) { +- /* The unload failed, print some debugging information */ +- fprintf(stderr, "kexec_file_load(unload) failed\n: %s\n", +- strerror(errno)); ++ if (errno == ENOSYS) { ++ ret = EFALLBACK; ++ } else { ++ /* ++ * The unload failed, print some debugging ++ * information */ ++ fprintf(stderr, "kexec_file_load(unload) failed: %s\n", ++ strerror(errno)); ++ ret = EFAILED; ++ } + } + return ret; + } +@@ -1182,15 +1192,13 @@ static int do_kexec_file_load(int fileind, int argc, char **argv, + info.file_mode = 1; + info.initrd_fd = -1; + +- if (!is_kexec_file_load_implemented()) { +- fprintf(stderr, "syscall kexec_file_load not available.\n"); +- return -ENOSYS; +- } ++ if (!is_kexec_file_load_implemented()) ++ return EFALLBACK; + + if (argc - fileind <= 0) { + fprintf(stderr, "No kernel specified\n"); + usage(); +- return -1; ++ return EFAILED; + } + + kernel = argv[fileind]; +@@ -1199,7 +1207,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv, + if (kernel_fd == -1) { + fprintf(stderr, "Failed to open file %s:%s\n", kernel, + strerror(errno)); +- return -1; ++ return EFAILED; + } + + /* slurp in the input kernel */ +@@ -1225,7 +1233,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv, + if (i == file_types) { + fprintf(stderr, "Cannot determine the file type " "of %s\n", + kernel); +- return -1; ++ return EFAILED; + } + + ret = file_type[i].load(argc, argv, kernel_buf, kernel_size, &info); +@@ -1243,9 +1251,43 @@ static int do_kexec_file_load(int fileind, int argc, char **argv, + + ret = kexec_file_load(kernel_fd, info.initrd_fd, info.command_line_len, + info.command_line, info.kexec_flags); +- if (ret != 0) +- fprintf(stderr, "kexec_file_load failed: %s\n", +- strerror(errno)); ++ if (ret != 0) { ++ switch (errno) { ++ /* ++ * Something failed with signature verification. ++ * Reject the image. ++ */ ++ case ELIBBAD: ++ case EKEYREJECTED: ++ case ENOPKG: ++ case ENOKEY: ++ case EBADMSG: ++ case EMSGSIZE: ++ /* Reject by default. */ ++ default: ++ ret = EFAILED; ++ break; ++ ++ /* Not implemented. */ ++ case ENOSYS: ++ /* ++ * Parsing image or other options failed ++ * The image may be invalid or image ++ * type may not supported by kernel so ++ * retry parsing in kexec-tools. ++ */ ++ case EINVAL: ++ case ENOEXEC: ++ /* ++ * ENOTSUP can be unsupported image ++ * type or unsupported PE signature ++ * wrapper type, duh. ++ */ ++ case ENOTSUP: ++ ret = EFALLBACK; ++ break; ++ } ++ } + + close(kernel_fd); + return ret; +@@ -1496,7 +1538,7 @@ int main(int argc, char *argv[]) + if (do_unload) { + if (do_kexec_file_syscall) { + result = kexec_file_unload(kexec_file_flags); +- if ((result == -ENOSYS) && do_kexec_fallback) ++ if (result == EFALLBACK && do_kexec_fallback) + do_kexec_file_syscall = 0; + } + if (!do_kexec_file_syscall) +@@ -1506,46 +1548,8 @@ int main(int argc, char *argv[]) + if (do_kexec_file_syscall) { + result = do_kexec_file_load(fileind, argc, argv, + kexec_file_flags); +- if (do_kexec_fallback) switch (result) { +- /* +- * Something failed with signature verification. +- * Reject the image. +- */ +- case -ELIBBAD: +- case -EKEYREJECTED: +- case -ENOPKG: +- case -ENOKEY: +- case -EBADMSG: +- case -EMSGSIZE: +- /* +- * By default reject or do nothing if +- * succeded +- */ +- default: break; +- case -ENOSYS: /* not implemented */ +- /* +- * Parsing image or other options failed +- * The image may be invalid or image +- * type may not supported by kernel so +- * retry parsing in kexec-tools. +- */ +- case -EINVAL: +- case -ENOEXEC: +- /* +- * ENOTSUP can be unsupported image +- * type or unsupported PE signature +- * wrapper type, duh +- * +- * The kernel sometimes wrongly +- * returns ENOTSUPP (524) - ignore +- * that. It is not supposed to be seen +- * by userspace so seeing it is a +- * kernel bug +- */ +- case -ENOTSUP: +- do_kexec_file_syscall = 0; +- break; +- } ++ if (result == EFALLBACK && do_kexec_fallback) ++ do_kexec_file_syscall = 0; + } + if (!do_kexec_file_syscall) + result = my_load(type, fileind, argc, argv, +@@ -1570,6 +1574,8 @@ int main(int argc, char *argv[]) + if ((result == 0) && do_load_jump_back_helper) { + result = my_load_jump_back_helper(kexec_flags, entry); + } ++ if (result == EFALLBACK) ++ fputs("syscall kexec_file_load not available.\n", stderr); + + fflush(stdout); + fflush(stderr); +diff --git a/kexec/kexec.h b/kexec/kexec.h +index a97b9ce..28fd129 100644 +--- a/kexec/kexec.h ++++ b/kexec/kexec.h +@@ -63,6 +63,7 @@ + */ + #define EFAILED -1 /* default error code */ + #define ENOCRASHKERNEL -2 /* no memory reserved for crashkernel */ ++#define EFALLBACK -3 /* fallback to kexec_load(2) may work */ + + /* + * This function doesn't actually exist. The idea is that when someone +-- +1.8.3.1 + diff --git a/kexec-tools-Fix-possible-out-of-bounds-access-in-ifdown.patch b/kexec-tools-Fix-possible-out-of-bounds-access-in-ifdown.patch new file mode 100644 index 0000000000000000000000000000000000000000..2c77d7a992336e37e89e73d4a5d2ae4f53b2c24f --- /dev/null +++ b/kexec-tools-Fix-possible-out-of-bounds-access-in-ifdown.patch @@ -0,0 +1,31 @@ +From 775f258fbd1895ba669be22f108faf817247a47a Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 1 Oct 2019 17:06:05 +0200 +Subject: [PATCH] kexec-tools: Fix possible out-of-bounds access in ifdown + +Fix a possible out-of-bounds access in function ifdown(): + +ifdown.c: In function 'ifdown': +ifdown.c:56:4: warning: 'strncpy' specified bound 16 equals destination size [-Wstringop-truncation] + 56 | strncpy(ifr.ifr_name, ifp->if_name, IFNAMSIZ); + +Signed-off-by: Helge Deller +Signed-off-by: Simon Horman + +diff --git a/kexec/ifdown.c b/kexec/ifdown.c +index 9679ad7..3ac19c1 100644 +--- a/kexec/ifdown.c ++++ b/kexec/ifdown.c +@@ -53,7 +53,8 @@ int ifdown(void) + if (strchr(ifp->if_name, ':') != NULL) + continue; + +- strncpy(ifr.ifr_name, ifp->if_name, IFNAMSIZ); ++ strncpy(ifr.ifr_name, ifp->if_name, IFNAMSIZ-1); ++ ifr.ifr_name[IFNAMSIZ-1] = 0; + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + fprintf(stderr, "ifdown: shutdown "); + perror(ifp->if_name); +-- +1.8.3.1 + diff --git a/kexec-tools-Reset-getopt-before-falling-back-to-legacy.patch b/kexec-tools-Reset-getopt-before-falling-back-to-legacy.patch new file mode 100644 index 0000000000000000000000000000000000000000..62dd4c57963973e8b262eb1fe61bacd9438db2a5 --- /dev/null +++ b/kexec-tools-Reset-getopt-before-falling-back-to-legacy.patch @@ -0,0 +1,51 @@ +From 9cf721279f6cb0dec09c8752e471f15fb662406b Mon Sep 17 00:00:00 2001 +From: Petr Tesarik +Date: Fri, 13 Mar 2020 15:09:29 +0100 +Subject: [PATCH] kexec-tools: Reset getopt before falling back to legacy + syscall + +The modules may need to parse the arguments again after +kexec_file_load(2) failed, but getopt is not reset. + +This change fixes the --initrd option on s390x. Without this patch, +it will fail to load the initrd on kernels that do not implement +kexec_file_load(2). + +Signed-off-by: Petr Tesarik +Signed-off-by: Simon Horman + +diff --git a/kexec/kexec.c b/kexec/kexec.c +index 33c1b4b..6601f1f 100644 +--- a/kexec/kexec.c ++++ b/kexec/kexec.c +@@ -1538,8 +1538,12 @@ int main(int argc, char *argv[]) + if (do_unload) { + if (do_kexec_file_syscall) { + result = kexec_file_unload(kexec_file_flags); +- if (result == EFALLBACK && do_kexec_fallback) ++ if (result == EFALLBACK && do_kexec_fallback) { ++ /* Reset getopt for fallback */ ++ opterr = 1; ++ optind = 1; + do_kexec_file_syscall = 0; ++ } + } + if (!do_kexec_file_syscall) + result = k_unload(kexec_flags); +@@ -1548,8 +1552,12 @@ int main(int argc, char *argv[]) + if (do_kexec_file_syscall) { + result = do_kexec_file_load(fileind, argc, argv, + kexec_file_flags); +- if (result == EFALLBACK && do_kexec_fallback) ++ if (result == EFALLBACK && do_kexec_fallback) { ++ /* Reset getopt for fallback */ ++ opterr = 1; ++ optind = 1; + do_kexec_file_syscall = 0; ++ } + } + if (!do_kexec_file_syscall) + result = my_load(type, fileind, argc, argv, +-- +1.8.3.1 + diff --git a/kexec-tools.spec b/kexec-tools.spec index 752e632a5974706284097ef0f47ff9c1ea752c33..3a78295db0823ecff4e4318cdd7735d60feec159 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -4,7 +4,7 @@ Name: kexec-tools Version: 2.0.20 -Release: 3 +Release: 4 License: GPLv2 Summary: The kexec/kdump userspace component URL: https://www.kernel.org/ @@ -70,26 +70,35 @@ Requires: systemd-udev%{?_isa} %undefine _hardened_build Patch0: kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch - Patch1: kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch Patch2: kexec-tools-2.0.20-makedumpfile-Remove-duplicated-variable-declarations.patch Patch3: kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch Patch4: kexec-tools-2.0.20-makedumpfile-Introduce-check-params-option.patch - Patch5: kexec-add-variant-helper-functions-for-handling-memory-regions.patch Patch6: arm64-kexec-allocate-memory-space-avoiding-reserved-regions.patch +Patch7: x86-Fix-PAGE_OFFSET-for-kernels-since-4.20.patch +Patch8: Cleanup-remove-the-read_elf_kcore.patch +Patch9: Fix-an-error-definition-about-the-variable-fname.patch +Patch10: Cleanup-move-it-back-from-util_lib-elf_info.c.patch +Patch11: Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch +Patch12: vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-reported-by-cppcheck.patch +Patch13: kexec-tools-Fix-possible-out-of-bounds-access-in-ifdown.patch +Patch14: kexec-tools-Fix-kexec_file_load-2-error-handling.patch +Patch15: kexec-tools-Reset-getopt-before-falling-back-to-legacy.patch +Patch16: kexec-support-parsing-the-string-Reserved-to-get-the-correct-e820-reserved-region.patch +Patch17: arm64-kdump-deal-with-a-lot-of-resource-entries-in-proc-iomem.patch %ifarch aarch64 -Patch7: arm64-support-more-than-one-crash-kernel-regions.patch +Patch18: arm64-support-more-than-one-crash-kernel-regions.patch %endif -Patch8: add-secure-compile-options-for-makedumpfile.patch +Patch19: add-secure-compile-options-for-makedumpfile.patch +Patch20: bugfix-get-the-paddr-of-mem_section-return-error-address.patch +Patch21: fix-header-offset-overflow-when-large-pfn.patch +Patch22: kexec-Add-quick-kexec-support.patch -Patch9: bugfix-get-the-paddr-of-mem_section-return-error-address.patch -Patch10: fix-header-offset-overflow-when-large-pfn.patch -Patch11: kexec-Add-quick-kexec-support.patch %ifarch aarch64 -Patch12: kexec-Quick-kexec-implementation-for-arm64.patch +Patch23: kexec-Quick-kexec-implementation-for-arm64.patch %endif %description @@ -120,19 +129,30 @@ tar -z -x -v -f %{SOURCE19} %patch4 -p1 %patch5 -p1 %patch6 -p1 - -%ifarch aarch64 %patch7 -p1 -%endif - %patch8 -p1 %patch9 -p1 %patch10 -p1 %patch11 -p1 -%ifarch aarch64 %patch12 -p1 -%endif +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +#%ifarch aarch64 +%patch18 -p1 +#%endif + +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 + +%ifarch aarch64 +%patch23 -p1 +%endif %build autoreconf @@ -318,6 +338,12 @@ done %endif %changelog +* Sat Sep 12 2020 zhangruifang2020 - 2.0.20-4 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:sychronize git patches to enhance quality + * Thu Sep 10 2020 zhangruifang2020 - 2.0.20-3 - Type:bugfix - ID:NA diff --git a/vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-reported-by-cppcheck.patch b/vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-reported-by-cppcheck.patch new file mode 100644 index 0000000000000000000000000000000000000000..cfda16d8cb7cbfc7579685456c94f96eba02e8ca --- /dev/null +++ b/vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-reported-by-cppcheck.patch @@ -0,0 +1,35 @@ +From a46c686f615a86933134c0924c3391ba598a02b8 Mon Sep 17 00:00:00 2001 +From: Bhupesh Sharma +Date: Tue, 10 Sep 2019 15:51:49 +0530 +Subject: [PATCH] vmcore-dmesg/vmcore-dmesg.c: Fix shifting error reported by + cppcheck + +Running 'cppcheck' static code analyzer (see cppcheck(1)) + on 'vmcore-dmesg/vmcore-dmesg.c' shows the following +shifting error: + +$ cppcheck --enable=all vmcore-dmesg/vmcore-dmesg.c +Checking vmcore-dmesg/vmcore-dmesg.c ... +[vmcore-dmesg/vmcore-dmesg.c:17]: (error) Shifting signed 32-bit value by 31 bits is undefined behaviour + +Fix the same via this patch. + +Signed-off-by: Bhupesh Sharma +Signed-off-by: Simon Horman + +diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c +index 81c2a58..122e536 100644 +--- a/vmcore-dmesg/vmcore-dmesg.c ++++ b/vmcore-dmesg/vmcore-dmesg.c +@@ -6,7 +6,7 @@ typedef Elf32_Nhdr Elf_Nhdr; + extern const char *fname; + + /* stole this macro from kernel printk.c */ +-#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31) ++#define LOG_BUF_LEN_MAX (uint32_t)(1U << 31) + + static void write_to_stdout(char *buf, unsigned int nr) + { +-- +1.8.3.1 + diff --git a/x86-Fix-PAGE_OFFSET-for-kernels-since-4.20.patch b/x86-Fix-PAGE_OFFSET-for-kernels-since-4.20.patch new file mode 100644 index 0000000000000000000000000000000000000000..3ef638a346be9c25429e683673df0c45c8c6b4ff --- /dev/null +++ b/x86-Fix-PAGE_OFFSET-for-kernels-since-4.20.patch @@ -0,0 +1,44 @@ +From 23b67f048ddef88e59ffe40f6392aeef92af9066 Mon Sep 17 00:00:00 2001 +From: Donald Buczek +Date: Fri, 30 Aug 2019 11:12:58 +0200 +Subject: [PATCH] x86: Fix PAGE_OFFSET for kernels since 4.20 + +Linux kernel commit d52888aa2753 ("x86/mm: Move LDT remap out of KASLR +region on 5-level paging") changed the base of the direct mapping +from 0xffff880000000000 to 0xffff888000000000. This was merged +into v4.20-rc2. + +Update to new address accordingly. + +Signed-off-by: Simon Horman + +diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c +index a2aea31..c79791f 100644 +--- a/kexec/arch/i386/crashdump-x86.c ++++ b/kexec/arch/i386/crashdump-x86.c +@@ -61,6 +61,8 @@ static int get_kernel_page_offset(struct kexec_info *UNUSED(info), + + if (kv < KERNEL_VERSION(2, 6, 27)) + elf_info->page_offset = X86_64_PAGE_OFFSET_PRE_2_6_27; ++ else if (kv < KERNEL_VERSION(4, 20, 0)) ++ elf_info->page_offset = X86_64_PAGE_OFFSET_PRE_4_20_0; + else + elf_info->page_offset = X86_64_PAGE_OFFSET; + } +diff --git a/kexec/arch/i386/crashdump-x86.h b/kexec/arch/i386/crashdump-x86.h +index ddee19f..e4fdc82 100644 +--- a/kexec/arch/i386/crashdump-x86.h ++++ b/kexec/arch/i386/crashdump-x86.h +@@ -13,7 +13,8 @@ int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline, + + #define X86_64__START_KERNEL_map 0xffffffff80000000ULL + #define X86_64_PAGE_OFFSET_PRE_2_6_27 0xffff810000000000ULL +-#define X86_64_PAGE_OFFSET 0xffff880000000000ULL ++#define X86_64_PAGE_OFFSET_PRE_4_20_0 0xffff880000000000ULL ++#define X86_64_PAGE_OFFSET 0xffff888000000000ULL + + #define X86_64_MAXMEM 0x3fffffffffffUL + +-- +1.8.3.1 +