Compare commits
11 Commits
80dea5ec73
...
007de1dd37
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
007de1dd37 | ||
|
|
95ed002ace | ||
|
|
e568658a70 | ||
|
|
ab2d3de682 | ||
|
|
335b57368f | ||
|
|
3b99781c8c | ||
|
|
74952ea605 | ||
|
|
5e61ef2bf0 | ||
|
|
596f9727a6 | ||
|
|
e6e390cb1b | ||
|
|
0a5923d1d7 |
81
arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch
Normal file
81
arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch
Normal file
@ -0,0 +1,81 @@
|
||||
From d940fc2f069f97226c7ec205a454e4cbf8aff631 Mon Sep 17 00:00:00 2001
|
||||
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
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 <takahiro.akashi@linaro.org>
|
||||
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
kexec/arch/arm64/crashdump-arm64.c | 24 +++++++++---------------
|
||||
1 file changed, 9 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
|
||||
index 158e778..bc7fada 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[CRASH_MAX_RESERVED_RANGES];
|
||||
@@ -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)
|
||||
@@ -139,9 +134,8 @@ static int crash_get_memory_ranges(void)
|
||||
usablemem_rgns.ranges, usablemem_rgns.size);
|
||||
|
||||
for (i = 0; i < usablemem_rgns.size; i++) {
|
||||
- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem[i])) {
|
||||
- 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[i])) {
|
||||
+ fprintf(stderr, "Cannot allocate memory for ranges\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,244 @@
|
||||
From f736104f533290b4ce6fbfbca74abde9ffd3888c Mon Sep 17 00:00:00 2001
|
||||
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
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 <takahiro.akashi@linaro.org>
|
||||
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
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 <inttypes.h>
|
||||
#include <libfdt.h>
|
||||
#include <limits.h>
|
||||
+#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/elf-em.h>
|
||||
#include <elf.h>
|
||||
@@ -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;
|
||||
@ -164,7 +164,7 @@ save_vmcore_dmesg_fs() {
|
||||
_exitcode=$?
|
||||
if [ $_exitcode -eq 0 ]; then
|
||||
mv ${_path}/vmcore-dmesg-incomplete.txt ${_path}/vmcore-dmesg.txt
|
||||
|
||||
chmod 400 ${_path}/vmcore-dmesg.txt
|
||||
# Make sure file is on disk. There have been instances where later
|
||||
# saving vmcore failed and system rebooted without sync and there
|
||||
# was no vmcore-dmesg.txt available.
|
||||
|
||||
101
kexec-Add-quick-kexec-support.patch
Normal file
101
kexec-Add-quick-kexec-support.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From c4fa8f8344a5f7a3147c8bee34d37b6af35d02e7 Mon Sep 17 00:00:00 2001
|
||||
From: snoweay <snoweay@163.com>
|
||||
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
|
||||
|
||||
143
kexec-Quick-kexec-implementation-for-arm64.patch
Normal file
143
kexec-Quick-kexec-implementation-for-arm64.patch
Normal file
@ -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 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
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
From cf977b1af9ec67fabcc6a625589c49c52d07b11d Mon Sep 17 00:00:00 2001
|
||||
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
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 <takahiro.akashi@linaro.org>
|
||||
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
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
|
||||
Binary file not shown.
@ -4,8 +4,8 @@
|
||||
|
||||
Name: kexec-tools
|
||||
Version: 2.0.20
|
||||
Release: 13
|
||||
License: GPLv2
|
||||
Release: 18
|
||||
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
|
||||
@ -69,21 +69,28 @@ 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
|
||||
|
||||
Patch11: kexec-Add-quick-kexec-support.patch
|
||||
%ifarch aarch64
|
||||
Patch12: kexec-Quick-kexec-implementation-for-arm64.patch
|
||||
Patch13: arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch
|
||||
%endif
|
||||
|
||||
%description
|
||||
kexec-tools provides /sbin/kexec binary that facilitates a new
|
||||
@ -106,15 +113,26 @@ 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
|
||||
|
||||
%patch11 -p1
|
||||
%ifarch aarch64
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%endif
|
||||
|
||||
%build
|
||||
autoreconf
|
||||
@ -300,6 +318,26 @@ done
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Aug 3 2022 chenhaixiang <chenhaixiang3@huawei.com> - 2.0.20-18
|
||||
- fix CVE-2021-20269
|
||||
|
||||
* Mon Apr 25 2022 wangbin <wangbin224@huawei.com> - 2.0.20-17
|
||||
- arm64: kdump: deal with a lot of resource entries in /proc/iomem
|
||||
|
||||
* Wed Apr 28 2021 snoweay <snoweay@163.com> - 2.0.20-16
|
||||
- Fix bug of license to GPLv2+
|
||||
|
||||
* Wed Apr 28 2021 snoweay <snoweay@163.com> - 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 <yangzhuangzhuang1@huawei.com> - 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 <buildteam@openeuler.org> - 2.0.20-13
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user