diff --git a/kexec-Add-quick-kexec-support.patch b/kexec-Add-quick-kexec-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..b587a998a2eef3207dde7ac6eb89a9458dbf0a5e --- /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 0000000000000000000000000000000000000000..59c6e18b4152f0e1ea8d437bcdf48661b7e90f28 --- /dev/null +++ b/kexec-Quick-kexec-implementation-for-arm64.patch @@ -0,0 +1,133 @@ +From 7d404ff2549cb9d6d94ec38cee8712cf2feeb39e 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 | 39 +++++++++++++++++++--------- + kexec/arch/arm64/kexec-image-arm64.c | 11 ++++++++ + 3 files changed, 39 insertions(+), 12 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 a3803e3..d12e426 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -96,6 +96,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. + * +@@ -624,23 +627,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, +@@ -706,6 +719,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; + +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.19.1 + diff --git a/kexec-tools.spec b/kexec-tools.spec index 7e30b85a21adc2fea75df93afdffdaa5a021da4e..6148777b542aba9d8cbccc95a9b96ec6cea297e8 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -4,7 +4,7 @@ Name: kexec-tools Version: 2.0.20 -Release: 1 +Release: 2 License: GPLv2 Summary: The kexec/kdump userspace component URL: https://www.kernel.org/ @@ -55,7 +55,7 @@ Requires: dracut >= 047-34.git20180604 Requires: dracut-network >= 044-117 Requires: dracut-squash >= 049-4 Requires: ethtool -BuildRequires: zlib-devel zlib zlib-static elfutils-devel-static glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel +BuildRequires: zlib-devel elfutils-devel-static glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel BuildRequires: pkgconfig intltool gettext BuildRequires: systemd-units BuildRequires: automake autoconf libtool @@ -84,6 +84,10 @@ Patch9001: 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 +Patch9004: kexec-Add-quick-kexec-support.patch +%ifarch aarch64 +Patch9005: kexec-Quick-kexec-implementation-for-arm64.patch +%endif %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -115,6 +119,11 @@ tar -z -x -v -f %{SOURCE19} %patch9001 -p1 %patch9002 -p1 %patch9003 -p1 +%patch9004 -p1 +%ifarch aarch64 +%patch9005 -p1 +%endif + %build autoreconf @@ -300,6 +309,11 @@ done %endif %changelog +* Thu Aug 13 2020 snoweay - 2.0.20-2 +- Add support for quick kexec + kexec: Add quick kexec support + arm64: Quick kexec implementation for arm64 + * Thu Jul 23 2020 zhangxingliang - 2.0.20-1 - Type:update - ID:NA @@ -341,7 +355,7 @@ done kexec/kexec-zlib.h: Add 'is_zlib_file()' helper function kexec/arm64: Add support for handling zlib compressed (Image.gz) image -* Thu Sep 21 2019 openEuler Buildteam - 2.0-17.11 +* Sat Sep 21 2019 openEuler Buildteam - 2.0-17.11 - Package init * Thu Aug 22 2019 Yeqing Peng - 2.0-17.10.h1