From 596f9727a64b1cd8014cc39e280c223c4174e348 Mon Sep 17 00:00:00 2001 From: yang_zhuang_zhuang <1162011203@qq.com> Date: Fri, 27 Nov 2020 14:26:36 +0800 Subject: [PATCH 1/4] fix issue about iomem file that contains too many contens.As a result,the kdump service failed --- ...mory-space-avoiding-reserved-regions.patch | 244 ++++++++++++++++++ ...unctions-for-handling-memory-regions.patch | 86 ++++++ kexec-tools.spec | 46 ++-- 3 files changed, 359 insertions(+), 17 deletions(-) create mode 100644 arm64-kexec-allocate-memory-space-avoiding-reserved-regions.patch create mode 100644 kexec-add-variant-helper-functions-for-handling-memory-regions.patch diff --git a/arm64-kexec-allocate-memory-space-avoiding-reserved-regions.patch b/arm64-kexec-allocate-memory-space-avoiding-reserved-regions.patch new file mode 100644 index 0000000..de5fd45 --- /dev/null +++ b/arm64-kexec-allocate-memory-space-avoiding-reserved-regions.patch @@ -0,0 +1,244 @@ +From f736104f533290b4ce6fbfbca74abde9ffd3888c Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Wed, 18 Dec 2019 11:42:31 -0500 +Subject: [PATCH] arm64: kexec: allocate memory space avoiding reserved regions + +On UEFI/ACPI-only system, some memory regions, including but not limited +to UEFI memory map and ACPI tables, must be preserved across kexec'ing. +Otherwise, they can be corrupted and result in early failure in booting +a new kernel. + +In recent kernels, /proc/iomem now has an extended file format like: + + 40000000-5871ffff : System RAM + 41800000-426affff : Kernel code + 426b0000-42aaffff : reserved + 42ab0000-42c64fff : Kernel data + 54400000-583fffff : Crash kernel + 58590000-585effff : reserved + 58700000-5871ffff : reserved + 58720000-58b5ffff : reserved + 58b60000-5be3ffff : System RAM + 58b61000-58b61fff : reserved + +where the "reserved" entries at the top level or under System RAM (and +its descendant resources) are ones of such kind and should not be regarded +as usable memory ranges where several free spaces for loading kexec data +will be allocated. + +With this patch, get_memory_ranges() will handle this format of file +correctly. Note that, for safety, unknown regions, in addition to +"reserved" ones, will also be excluded. + +Signed-off-by: AKASHI Takahiro +Tested-by: Bhupesh Sharma +Tested-by: Masayoshi Mizuma +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.c | 153 ++++++++++++++++++++------------- + 1 file changed, 94 insertions(+), 59 deletions(-) + +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index 6ad3b0a..45ebc54 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -10,7 +10,9 @@ + #include + #include + #include ++#include + #include ++#include + #include + #include + #include +@@ -29,6 +31,7 @@ + #include "fs2dt.h" + #include "iomem.h" + #include "kexec-syscall.h" ++#include "mem_regions.h" + #include "arch/options.h" + + #define ROOT_NODE_ADDR_CELLS_DEFAULT 1 +@@ -905,19 +908,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset) + return 0; + } + ++static bool to_be_excluded(char *str) ++{ ++ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) || ++ !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) || ++ !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) || ++ !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL))) ++ return false; ++ else ++ return true; ++} ++ + /** +- * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem. ++ * get_memory_ranges - Try to get the memory ranges from ++ * /proc/iomem. + */ +- +-static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, +- unsigned long long base, unsigned long long length) ++int get_memory_ranges(struct memory_range **range, int *ranges, ++ unsigned long kexec_flags) + { +- int ret; + unsigned long phys_offset = UINT64_MAX; +- struct memory_range *r; +- +- if (nr >= KEXEC_SEGMENT_MAX) +- return -1; ++ FILE *fp; ++ const char *iomem = proc_iomem(); ++ char line[MAX_LINE], *str; ++ unsigned long long start, end; ++ int n, consumed; ++ struct memory_ranges memranges; ++ struct memory_range *last, excl_range; ++ int ret; + + if (!try_read_phys_offset_from_kcore) { + /* Since kernel version 4.19, 'kcore' contains +@@ -951,17 +968,72 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, + try_read_phys_offset_from_kcore = true; + } + +- r = (struct memory_range *)data + nr; ++ fp = fopen(iomem, "r"); ++ if (!fp) ++ die("Cannot open %s\n", iomem); ++ ++ memranges.ranges = NULL; ++ memranges.size = memranges.max_size = 0; ++ ++ while (fgets(line, sizeof(line), fp) != 0) { ++ n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed); ++ if (n != 2) ++ continue; ++ str = line + consumed; ++ ++ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) { ++ ret = mem_regions_alloc_and_add(&memranges, ++ start, end - start + 1, RANGE_RAM); ++ if (ret) { ++ fprintf(stderr, ++ "Cannot allocate memory for ranges\n"); ++ fclose(fp); ++ return -ENOMEM; ++ } + +- if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) +- r->type = RANGE_RAM; +- else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED))) +- r->type = RANGE_RESERVED; +- else +- return 1; ++ dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__, ++ memranges.size - 1, ++ memranges.ranges[memranges.size - 1].start, ++ memranges.ranges[memranges.size - 1].end); ++ } else if (to_be_excluded(str)) { ++ if (!memranges.size) ++ continue; ++ ++ /* ++ * Note: mem_regions_exclude() doesn't guarantee ++ * that the ranges are sorted out, but as long as ++ * we cope with /proc/iomem, we only operate on ++ * the last entry and so it is safe. ++ */ + +- r->start = base; +- r->end = base + length - 1; ++ /* The last System RAM range */ ++ last = &memranges.ranges[memranges.size - 1]; ++ ++ if (last->end < start) ++ /* New resource outside of System RAM */ ++ continue; ++ if (end < last->start) ++ /* Already excluded by parent resource */ ++ continue; ++ ++ excl_range.start = start; ++ excl_range.end = end; ++ ret = mem_regions_alloc_and_exclude(&memranges, &excl_range); ++ if (ret) { ++ fprintf(stderr, ++ "Cannot allocate memory for ranges (exclude)\n"); ++ fclose(fp); ++ return -ENOMEM; ++ } ++ dbgprintf("%s:- %016llx - %016llx\n", ++ __func__, start, end); ++ } ++ } ++ ++ fclose(fp); ++ ++ *range = memranges.ranges; ++ *ranges = memranges.size; + + /* As a fallback option, we can try determining the PHYS_OFFSET + * value from the '/proc/iomem' entries as well. +@@ -982,52 +1054,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, + * between the user-space and kernel space 'PHYS_OFFSET' + * value. + */ +- set_phys_offset(r->start, "iomem"); +- +- dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start, +- r->end, str); +- +- return 0; +-} +- +-/** +- * get_memory_ranges_iomem - Try to get the memory ranges from +- * /proc/iomem. +- */ ++ if (memranges.size) ++ set_phys_offset(memranges.ranges[0].start, "iomem"); + +-static int get_memory_ranges_iomem(struct memory_range *array, +- unsigned int *count) +-{ +- *count = kexec_iomem_for_each_line(NULL, +- get_memory_ranges_iomem_cb, array); +- +- if (!*count) { +- dbgprintf("%s: failed: No RAM found.\n", __func__); +- return EFAILED; +- } ++ dbgprint_mem_range("System RAM ranges;", ++ memranges.ranges, memranges.size); + + return 0; + } + +-/** +- * get_memory_ranges - Try to get the memory ranges some how. +- */ +- +-int get_memory_ranges(struct memory_range **range, int *ranges, +- unsigned long kexec_flags) +-{ +- static struct memory_range array[KEXEC_SEGMENT_MAX]; +- unsigned int count; +- int result; +- +- result = get_memory_ranges_iomem(array, &count); +- +- *range = result ? NULL : array; +- *ranges = result ? 0 : count; +- +- return result; +-} +- + int arch_compat_trampoline(struct kexec_info *info) + { + return 0; diff --git a/kexec-add-variant-helper-functions-for-handling-memory-regions.patch b/kexec-add-variant-helper-functions-for-handling-memory-regions.patch new file mode 100644 index 0000000..74a9e8e --- /dev/null +++ b/kexec-add-variant-helper-functions-for-handling-memory-regions.patch @@ -0,0 +1,86 @@ +From cf977b1af9ec67fabcc6a625589c49c52d07b11d Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Wed, 18 Dec 2019 11:42:30 -0500 +Subject: [PATCH] kexec: add variant helper functions for handling memory + regions + +mem_regions_alloc_and_add() and mem_regions_alloc_and_exclude() are +functionally equivalent to, respectively, mem_regions_add() and +mem_regions_exclude() except the formers will re-allocate memory +dynamically when no more entries are available in 'ranges' array. + +Signed-off-by: AKASHI Takahiro +Tested-by: Bhupesh Sharma +Tested-by: Masayoshi Mizuma +Signed-off-by: Simon Horman +--- + kexec/mem_regions.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + kexec/mem_regions.h | 7 +++++++ + 2 files changed, 49 insertions(+) + +diff --git a/kexec/mem_regions.c b/kexec/mem_regions.c +index 50c8abc..ad7d3f1 100644 +--- a/kexec/mem_regions.c ++++ b/kexec/mem_regions.c +@@ -125,3 +125,45 @@ int mem_regions_exclude(struct memory_ranges *ranges, + } + return 0; + } ++ ++#define KEXEC_MEMORY_RANGES 16 ++ ++int mem_regions_alloc_and_add(struct memory_ranges *ranges, ++ unsigned long long base, ++ unsigned long long length, int type) ++{ ++ void *new_ranges; ++ ++ if (ranges->size >= ranges->max_size) { ++ new_ranges = realloc(ranges->ranges, ++ sizeof(struct memory_range) * ++ (ranges->max_size + KEXEC_MEMORY_RANGES)); ++ if (!new_ranges) ++ return -1; ++ ++ ranges->ranges = new_ranges; ++ ranges->max_size += KEXEC_MEMORY_RANGES; ++ } ++ ++ return mem_regions_add(ranges, base, length, type); ++} ++ ++int mem_regions_alloc_and_exclude(struct memory_ranges *ranges, ++ const struct memory_range *range) ++{ ++ void *new_ranges; ++ ++ /* for safety, we should have at least one free entry in ranges */ ++ if (ranges->size >= ranges->max_size) { ++ new_ranges = realloc(ranges->ranges, ++ sizeof(struct memory_range) * ++ (ranges->max_size + KEXEC_MEMORY_RANGES)); ++ if (!new_ranges) ++ return -1; ++ ++ ranges->ranges = new_ranges; ++ ranges->max_size += KEXEC_MEMORY_RANGES; ++ } ++ ++ return mem_regions_exclude(ranges, range); ++} +diff --git a/kexec/mem_regions.h b/kexec/mem_regions.h +index ae9e972..e306d67 100644 +--- a/kexec/mem_regions.h ++++ b/kexec/mem_regions.h +@@ -12,4 +12,11 @@ int mem_regions_exclude(struct memory_ranges *ranges, + int mem_regions_add(struct memory_ranges *ranges, unsigned long long base, + unsigned long long length, int type); + ++int mem_regions_alloc_and_exclude(struct memory_ranges *ranges, ++ const struct memory_range *range); ++ ++int mem_regions_alloc_and_add(struct memory_ranges *ranges, ++ unsigned long long base, ++ unsigned long long length, int type); ++ + #endif diff --git a/kexec-tools.spec b/kexec-tools.spec index 4cdc094..d6c603b 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -4,7 +4,7 @@ Name: kexec-tools Version: 2.0.20 -Release: 13 +Release: 14 License: GPLv2 Summary: The kexec/kdump userspace component URL: https://www.kernel.org/ @@ -69,21 +69,22 @@ Requires: systemd-udev%{?_isa} %undefine _hardened_build -Patch6000: kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch - -Patch6001: kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch -Patch6002: kexec-tools-2.0.20-makedumpfile-Remove-duplicated-variable-declarations.patch -Patch6003: kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch -Patch6004: kexec-tools-2.0.20-makedumpfile-Introduce-check-params-option.patch +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 %ifarch aarch64 -Patch9000: arm64-support-more-than-one-crash-kernel-regions.patch +Patch7: arm64-support-more-than-one-crash-kernel-regions.patch %endif -Patch9001: add-secure-compile-options-for-makedumpfile.patch +Patch8: add-secure-compile-options-for-makedumpfile.patch -Patch9002: bugfix-get-the-paddr-of-mem_section-return-error-address.patch -Patch9003: fix-header-offset-overflow-when-large-pfn.patch +Patch9: bugfix-get-the-paddr-of-mem_section-return-error-address.patch +Patch10: fix-header-offset-overflow-when-large-pfn.patch %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -106,15 +107,20 @@ mkdir -p -m755 kcp tar -z -x -v -f %{SOURCE9} tar -z -x -v -f %{SOURCE19} -%{lua:for i=0,4 do print(string.format("%%patch600%u -p1\n", i)) end} - +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 %ifarch aarch64 -%patch9000 -p1 +%patch7 -p1 %endif -%patch9001 -p1 -%patch9002 -p1 -%patch9003 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 %build autoreconf @@ -300,6 +306,12 @@ done %endif %changelog +* Fri Nov 27 2020 yangzhuangzhuang - 2.0.20-14 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:fix issue about iomem file that contains too many contens.As a result,the kdump service failed + * Tue May 19 2020 openEuler Buildteam - 2.0.20-13 - Type:enhancement - ID:NA -- Gitee From 74952ea605eb3ca1d487101c5da49a7c378686ac Mon Sep 17 00:00:00 2001 From: snoweay Date: Wed, 28 Apr 2021 18:55:48 +0800 Subject: [PATCH 2/4] kexec: Add support for quick kexec and implement for arm64 Signed-off-by: snoweay --- kexec-Add-quick-kexec-support.patch | 101 +++++++++++++ ...Quick-kexec-implementation-for-arm64.patch | 143 ++++++++++++++++++ kexec-tools.spec | 17 ++- 3 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 kexec-Add-quick-kexec-support.patch create mode 100644 kexec-Quick-kexec-implementation-for-arm64.patch diff --git a/kexec-Add-quick-kexec-support.patch b/kexec-Add-quick-kexec-support.patch new file mode 100644 index 0000000..b587a99 --- /dev/null +++ b/kexec-Add-quick-kexec-support.patch @@ -0,0 +1,101 @@ +From c4fa8f8344a5f7a3147c8bee34d37b6af35d02e7 Mon Sep 17 00:00:00 2001 +From: snoweay +Date: Wed, 12 Aug 2020 07:53:13 -0400 +Subject: [PATCH] kexec: Add quick kexec support + +Add quick kexec option -q and flags. + +In normal kexec, relocating kernel may cost 5 ~ 10 seconds, to +copy all segments from vmalloced memory to kernel boot memory, +because of disabled mmu. + +We introduce quick kexec to save time of copying memory as above, +just like kdump(kexec on crash), by using reserved memory. + +We also add this support in syscall kexec_load of linux kernel +through flags of KEXEC_QUICK. +--- + kexec/kexec-syscall.h | 1 + + kexec/kexec.c | 10 ++++++++++ + kexec/kexec.h | 4 +++- + 3 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h +index dac1c1f..b146b6a 100644 +--- a/kexec/kexec-syscall.h ++++ b/kexec/kexec-syscall.h +@@ -102,6 +102,7 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd, + + #define KEXEC_ON_CRASH 0x00000001 + #define KEXEC_PRESERVE_CONTEXT 0x00000002 ++#define KEXEC_QUICK 0x00000004 + #define KEXEC_ARCH_MASK 0xffff0000 + + /* Flags for kexec file based system call */ +diff --git a/kexec/kexec.c b/kexec/kexec.c +index bc6ab3d..48825af 100644 +--- a/kexec/kexec.c ++++ b/kexec/kexec.c +@@ -997,6 +997,7 @@ void usage(void) + " -l, --load Load the new kernel into the\n" + " current kernel.\n" + " -p, --load-panic Load the new kernel for use on panic.\n" ++ " -q, --load-quick Load the new kernel to quick kexec\n" + " -u, --unload Unload the current kexec target kernel.\n" + " If capture kernel is being unloaded\n" + " specify -p with -u.\n" +@@ -1268,6 +1269,7 @@ int main(int argc, char *argv[]) + { + int do_load = 1; + int do_exec = 0; ++ int do_quick = 0; + int do_load_jump_back_helper = 0; + int do_shutdown = 1; + int do_sync = 1, skip_sync = 0; +@@ -1377,6 +1379,14 @@ int main(int argc, char *argv[]) + kexec_file_flags |= KEXEC_FILE_ON_CRASH; + kexec_flags = KEXEC_ON_CRASH; + break; ++ case OPT_QUICK: ++ do_load = 1; ++ do_exec = 0; ++ do_shutdown = 0; ++ do_quick = 1; ++ kexec_flags = KEXEC_QUICK; ++ skip_checks = 1; ++ break; + case OPT_MEM_MIN: + mem_min = strtoul(optarg, &endptr, 0); + if (*endptr) { +diff --git a/kexec/kexec.h b/kexec/kexec.h +index a97b9ce..e31e4d2 100644 +--- a/kexec/kexec.h ++++ b/kexec/kexec.h +@@ -221,6 +221,7 @@ extern int file_types; + #define OPT_UNLOAD 'u' + #define OPT_TYPE 't' + #define OPT_PANIC 'p' ++#define OPT_QUICK 'q' + #define OPT_KEXEC_FILE_SYSCALL 's' + #define OPT_KEXEC_SYSCALL 'c' + #define OPT_KEXEC_SYSCALL_AUTO 'a' +@@ -248,6 +249,7 @@ extern int file_types; + { "entry", 1, 0, OPT_ENTRY }, \ + { "type", 1, 0, OPT_TYPE }, \ + { "load-panic", 0, 0, OPT_PANIC }, \ ++ { "load-quick", 0, 0, OPT_QUICK }, \ + { "mem-min", 1, 0, OPT_MEM_MIN }, \ + { "mem-max", 1, 0, OPT_MEM_MAX }, \ + { "reuseinitrd", 0, 0, OPT_REUSE_INITRD }, \ +@@ -258,7 +260,7 @@ extern int file_types; + { "status", 0, 0, OPT_STATUS }, \ + { "print-ckr-size", 0, 0, OPT_PRINT_CKR_SIZE }, \ + +-#define KEXEC_OPT_STR "h?vdfixyluet:pscaS" ++#define KEXEC_OPT_STR "h?vdfixyluet:pqscaS" + + extern void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr); + extern void die(const char *fmt, ...) +-- +2.19.1 + diff --git a/kexec-Quick-kexec-implementation-for-arm64.patch b/kexec-Quick-kexec-implementation-for-arm64.patch new file mode 100644 index 0000000..b1329f1 --- /dev/null +++ b/kexec-Quick-kexec-implementation-for-arm64.patch @@ -0,0 +1,143 @@ +From 5a302cd06079a285cb24a74c0f60b26866ae4e4d Mon Sep 17 00:00:00 2001 +From: snoweay +Date: Wed, 12 Aug 2020 07:59:06 -0400 +Subject: [PATCH] kexec: Quick kexec implementation for arm64 + +Implement quick kexec on arch/arm64. + +Locate kernel segments from reserved memory of range "Quick kexec". +--- + kexec/arch/arm64/iomem.h | 1 + + kexec/arch/arm64/kexec-arm64.c | 42 +++++++++++++++++++++++++----------- + kexec/arch/arm64/kexec-image-arm64.c | 11 ++++++++++ + 3 files changed, 41 insertions(+), 13 deletions(-) + +diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h +index d4864bb..108871e 100644 +--- a/kexec/arch/arm64/iomem.h ++++ b/kexec/arch/arm64/iomem.h +@@ -6,5 +6,6 @@ + #define KERNEL_DATA "Kernel data\n" + #define CRASH_KERNEL "Crash kernel\n" + #define IOMEM_RESERVED "reserved\n" ++#define QUICK_KEXEC "Quick kexec\n" + + #endif +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index 219ec49..8a3bb69 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -99,6 +99,9 @@ uint64_t get_vp_offset(void) + return arm64_mem.vp_offset; + } + ++/* Reserved memory for quick kexec. */ ++struct memory_range quick_reserved_mem; ++ + /** + * arm64_process_image_header - Process the arm64 image header. + * +@@ -627,23 +630,33 @@ on_error: + return result; + } + +-unsigned long arm64_locate_kernel_segment(struct kexec_info *info) ++static unsigned long locate_hole_from_range(struct memory_range *range) + { + unsigned long hole; ++ unsigned long hole_end; + +- if (info->kexec_flags & KEXEC_ON_CRASH) { +- unsigned long hole_end; ++ hole = (range->start < mem_min ? mem_min : range->start); ++ hole = _ALIGN_UP(hole, MiB(2)); ++ hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size; + +- 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(2)); +- hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size; ++ if ((hole_end > mem_max) || ++ (hole_end > range->end)) { ++ dbgprintf("%s: Kexec kernel out of range\n", __func__); ++ hole = ULONG_MAX; ++ } + +- if ((hole_end > mem_max) || +- (hole_end > crash_reserved_mem[usablemem_rgns.size - 1].end)) { +- dbgprintf("%s: Crash kernel out of range\n", __func__); +- hole = ULONG_MAX; +- } ++ return hole; ++} ++ ++unsigned long arm64_locate_kernel_segment(struct kexec_info *info) ++{ ++ unsigned long hole; ++ ++ if (info->kexec_flags & KEXEC_ON_CRASH) { ++ hole = locate_hole_from_range( ++ &crash_reserved_mem[usablemem_rgns.size - 1]); ++ } else if (info->kexec_flags & KEXEC_QUICK) { ++ hole = locate_hole_from_range(&quick_reserved_mem); + } else { + hole = locate_hole(info, + arm64_mem.text_offset + arm64_mem.image_size, +@@ -709,6 +722,8 @@ int arm64_load_other_segments(struct kexec_info *info, + hole_min = image_base + arm64_mem.image_size; + if (info->kexec_flags & KEXEC_ON_CRASH) + hole_max = crash_reserved_mem[usablemem_rgns.size - 1].end; ++ else if (info->kexec_flags & KEXEC_QUICK) ++ hole_max = quick_reserved_mem.end; + else + hole_max = ULONG_MAX; + +@@ -944,7 +959,8 @@ static bool to_be_excluded(char *str) + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) || + !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) || + !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) || +- !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL))) ++ !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) || ++ !strncmp(str, QUICK_KEXEC, strlen(QUICK_KEXEC))) + return false; + else + return true; +diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c +index aa8f2e2..f22db62 100644 +--- a/kexec/arch/arm64/kexec-image-arm64.c ++++ b/kexec/arch/arm64/kexec-image-arm64.c +@@ -13,6 +13,9 @@ + #include "kexec-arm64.h" + #include "kexec-syscall.h" + #include "arch/options.h" ++#include "iomem.h" ++ ++extern struct memory_range quick_reserved_mem; + + int image_arm64_probe(const char *kernel_buf, off_t kernel_size) + { +@@ -38,6 +41,7 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf, + { + const struct arm64_image_header *header; + unsigned long kernel_segment; ++ unsigned long start, end; + int result; + + if (info->file_mode) { +@@ -61,6 +65,13 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf, + return 0; + } + ++ if (info->kexec_flags & KEXEC_QUICK) ++ parse_iomem_single(QUICK_KEXEC, &start, &end); ++ dbgprintf("%s: Get Quick kexec reserved mem from 0x%016lx to 0x%016lx\n", ++ __func__, start, end); ++ quick_reserved_mem.start = start; ++ quick_reserved_mem.end = end; ++ + header = (const struct arm64_image_header *)(kernel_buf); + + if (arm64_process_image_header(header)) +-- +2.9.5 + diff --git a/kexec-tools.spec b/kexec-tools.spec index d6c603b..baceb95 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -4,7 +4,7 @@ Name: kexec-tools Version: 2.0.20 -Release: 14 +Release: 15 License: GPLv2 Summary: The kexec/kdump userspace component URL: https://www.kernel.org/ @@ -86,6 +86,11 @@ Patch8: add-secure-compile-options-for-makedumpfile.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 +%endif + %description kexec-tools provides /sbin/kexec binary that facilitates a new kernel to boot using the kernel's kexec feature either on a @@ -122,6 +127,11 @@ tar -z -x -v -f %{SOURCE19} %patch9 -p1 %patch10 -p1 +%patch11 -p1 +%ifarch aarch64 +%patch12 -p1 +%endif + %build autoreconf %configure --sbindir=/usr/sbin \ @@ -306,6 +316,11 @@ done %endif %changelog +* Wed Apr 28 2021 snoweay - 2.0.20-15 +- Add support for quick kexec + kexec: Add quick kexec support + arm64: Quick kexec implementation for arm64 + * Fri Nov 27 2020 yangzhuangzhuang - 2.0.20-14 - Type:bugfix - ID:NA -- Gitee From 3b99781c8c1b7b53976a1232cc2d0a2e376ab94a Mon Sep 17 00:00:00 2001 From: snoweay Date: Wed, 28 Apr 2021 18:51:19 +0800 Subject: [PATCH 3/4] spec: Fix bug of license to GPLv2+ Use correct license "GPLv2+" in spec Signed-off-by: snoweay --- kexec-tools.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kexec-tools.spec b/kexec-tools.spec index baceb95..eaf9385 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -4,8 +4,8 @@ Name: kexec-tools Version: 2.0.20 -Release: 15 -License: GPLv2 +Release: 16 +License: GPLv2+ Summary: The kexec/kdump userspace component URL: https://www.kernel.org/ Source0: http://kernel.org/pub/linux/utils/kernel/kexec/%{name}-%{version}.tar.xz @@ -316,6 +316,9 @@ done %endif %changelog +* Wed Apr 28 2021 snoweay - 2.0.20-16 +- Fix bug of license to GPLv2+ + * Wed Apr 28 2021 snoweay - 2.0.20-15 - Add support for quick kexec kexec: Add quick kexec support -- Gitee From 1a9745858763b1e65ce2d585456a11bd8ea73ee1 Mon Sep 17 00:00:00 2001 From: "fu.lin" Date: Thu, 13 Oct 2022 20:09:07 +0800 Subject: [PATCH 4/4] x86: support quick kexec Signed-off-by: fu.lin --- ...c-Quick-kexec-implementation-for-x86.patch | 106 ++++++++++++++++++ kexec-tools.spec | 6 +- 2 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 kexec-Quick-kexec-implementation-for-x86.patch diff --git a/kexec-Quick-kexec-implementation-for-x86.patch b/kexec-Quick-kexec-implementation-for-x86.patch new file mode 100644 index 0000000..ef4d58c --- /dev/null +++ b/kexec-Quick-kexec-implementation-for-x86.patch @@ -0,0 +1,106 @@ +From aca89e2674901b20f20d9c6f828b3a95fd090a72 Mon Sep 17 00:00:00 2001 +From: Jingxian He +Date: Sat, 20 Feb 2021 03:34:14 +0000 +Subject: [PATCH 1/1] x86: add support for quick kexec + +Supply new command options for kexec tools: +1) Add '-q, --load-quick' for quick upgrade kernel; + +Signed-off-by: Jingxian He +Signed-off-by: fu.lin +--- + kexec/arch/i386/kexec-x86-common.c | 13 ++++++++++++- + kexec/arch/i386/x86-linux-setup.c | 4 ++-- + kexec/kexec.c | 4 +--- + kexec/kexec.h | 1 - + 4 files changed, 15 insertions(+), 7 deletions(-) + +diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c +index 61ea193..877e9e5 100644 +--- a/kexec/arch/i386/kexec-x86-common.c ++++ b/kexec/arch/i386/kexec-x86-common.c +@@ -48,6 +48,10 @@ + #define E820_PRAM 12 + #endif + ++#define QUICK_KEXEC "Quick kexec\n" ++ ++struct memory_range quick_reserved_mem; ++ + static struct memory_range memory_range[MAX_MEMORY_RANGES]; + + /** +@@ -386,8 +390,15 @@ int get_memory_ranges(struct memory_range **range, int *ranges, + mem_min = start; + if (end < mem_max) + mem_max = end; ++ } else if (kexec_flags & KEXEC_QUICK) { ++ parse_iomem_single(QUICK_KEXEC, ++ (uint64_t *)&quick_reserved_mem.start, ++ (uint64_t *)&quick_reserved_mem.end); ++ if (quick_reserved_mem.start > mem_min) ++ mem_min = quick_reserved_mem.start; ++ if (quick_reserved_mem.end < mem_max) ++ mem_max = quick_reserved_mem.end; + } +- + dbgprint_mem_range("MEMORY RANGES", *range, *ranges); + + return ret; +diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c +index 057ee14..fb0c598 100644 +--- a/kexec/arch/i386/x86-linux-setup.c ++++ b/kexec/arch/i386/x86-linux-setup.c +@@ -78,8 +78,8 @@ void setup_linux_bootloader_parameters_high( + /* Load the initrd if we have one */ + if (initrd_buf) { + initrd_base = add_buffer(info, +- initrd_buf, initrd_size, initrd_size, +- 4096, INITRD_BASE, initrd_addr_max, -1); ++ initrd_buf, initrd_size, initrd_size, ++ 4096, INITRD_BASE, initrd_addr_max, -1); + dbgprintf("Loaded initrd at 0x%lx size 0x%lx\n", initrd_base, + initrd_size); + } else { +diff --git a/kexec/kexec.c b/kexec/kexec.c +index 48825af..37db64d 100644 +--- a/kexec/kexec.c ++++ b/kexec/kexec.c +@@ -997,7 +997,7 @@ void usage(void) + " -l, --load Load the new kernel into the\n" + " current kernel.\n" + " -p, --load-panic Load the new kernel for use on panic.\n" +- " -q, --load-quick Load the new kernel to quick kexec\n" ++ " -q, --load-quick Load the new kernel to quick kexec.\n" + " -u, --unload Unload the current kexec target kernel.\n" + " If capture kernel is being unloaded\n" + " specify -p with -u.\n" +@@ -1269,7 +1269,6 @@ int main(int argc, char *argv[]) + { + int do_load = 1; + int do_exec = 0; +- int do_quick = 0; + int do_load_jump_back_helper = 0; + int do_shutdown = 1; + int do_sync = 1, skip_sync = 0; +@@ -1383,7 +1382,6 @@ int main(int argc, char *argv[]) + do_load = 1; + do_exec = 0; + do_shutdown = 0; +- do_quick = 1; + kexec_flags = KEXEC_QUICK; + skip_checks = 1; + break; +diff --git a/kexec/kexec.h b/kexec/kexec.h +index e31e4d2..c7c16a4 100644 +--- a/kexec/kexec.h ++++ b/kexec/kexec.h +@@ -328,5 +328,4 @@ void xen_kexec_exec(void); + int xen_kexec_status(uint64_t kexec_flags); + + extern unsigned long long get_kernel_sym(const char *text); +- + #endif /* KEXEC_H */ +-- +2.27.0 + diff --git a/kexec-tools.spec b/kexec-tools.spec index eaf9385..cdf2332 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -87,9 +87,8 @@ 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 -%endif +Patch13: kexec-Quick-kexec-implementation-for-x86.patch %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -316,6 +315,9 @@ done %endif %changelog +* Thu Oct 13 2021 fu.lin - 2.0.20-17 +* x86: support quick kexec + * Wed Apr 28 2021 snoweay - 2.0.20-16 - Fix bug of license to GPLv2+ -- Gitee