summaryrefslogtreecommitdiff
path: root/kexec-Quick-kexec-implementation-for-arm64.patch
diff options
context:
space:
mode:
Diffstat (limited to 'kexec-Quick-kexec-implementation-for-arm64.patch')
-rw-r--r--kexec-Quick-kexec-implementation-for-arm64.patch143
1 files changed, 143 insertions, 0 deletions
diff --git a/kexec-Quick-kexec-implementation-for-arm64.patch b/kexec-Quick-kexec-implementation-for-arm64.patch
new file mode 100644
index 0000000..19c6338
--- /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 <snoweay@163.com>
+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 45d7953..f283f50 100644
+--- a/kexec/arch/arm64/iomem.h
++++ b/kexec/arch/arm64/iomem.h
+@@ -7,5 +7,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;
+
+@@ -1050,7 +1050,8 @@ static bool to_be_excluded(char *str, unsigned long long start, unsigned long lo
+
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
+ !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
+- !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)))
++ !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
++ !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
+