SHA256
1
0
forked from pool/kexec-tools
kexec-tools/0040-arm64-kdump-add-elf-core-header-segment.patch

203 lines
6.0 KiB
Diff
Raw Normal View History

Accepting request 500203 from home:tiwai:branches:Kernel:kdump - Update to version 2.0.14 (bsc#1039937, FATE#320672, FATE#320671) Changelog: http://git.kernel.org/cgit/utils/kernel/kexec/kexec-tools.git/log/?id=refs/tags/v2.0.13..v2.0.14 - Backport upstream fixes (bsc#1039937, FATE#320672, FATE#320671) 0001-kexec-tools-2.0.14.git.patch 0002-ppc64-Reduce-number-of-ELF-LOAD-segments.patch 0003-kexec-Increase-the-upper-limit-for-RAM-segments.patch 0004-alpha-add-missing-__NR_kexec_load-definition.patch 0005-kexec-implemented-XEN-KEXEC-STATUS-to-determine-if-a.patch 0006-kexec-Remove-redundant-space-from-help-message.patch 0007-purgatory-Add-purgatory.map-and-purgatory.ro.sym-to-.patch 0008-kexec-Add-option-to-get-crash-kernel-region-size.patch 0009-crashdump-arm-Add-get_crash_kernel_load_range-functi.patch 0010-crashdump-arm64-Add-get_crash_kernel_load_range-func.patch 0011-crashdump-cris-Add-get_crash_kernel_load_range-funct.patch 0012-crashdump-ia64-Add-get_crash_kernel_load_range-funct.patch 0013-crashdump-m68k-Add-get_crash_kernel_load_range-funct.patch 0014-crashdump-mips-Add-get_crash_kernel_load_range-funct.patch 0015-crashdump-ppc-Add-get_crash_kernel_load_range-functi.patch 0016-crashdump-ppc64-Add-get_crash_kernel_load_range-func.patch 0017-crashdump-s390-Add-get_crash_kernel_load_range-funct.patch 0018-crashdump-sh-Add-get_crash_kernel_load_range-functio.patch 0019-gitignore-add-two-generated-files-in-purgatory.patch 0020-Only-print-debug-message-when-failed-to-serach-for-k.patch 0021-build_mem_phdrs-check-if-p_paddr-is-invalid.patch 0022-uImage-fix-realloc-pointer-confusion.patch 0023-uImage-Fix-uImage_load-for-little-endian-machines.patch 0024-uImage-Add-new-IH_ARCH_xxx-definitions.patch 0025-uImage-use-char-instead-of-unsigned-char-for-uImage_.patch 0026-uImage-use-char-instead-of-unsigned-char-for-uImage_.patch 0027-arm64-add-uImage-support.patch OBS-URL: https://build.opensuse.org/request/show/500203 OBS-URL: https://build.opensuse.org/package/show/Kernel:kdump/kexec-tools?expand=0&rev=83
2017-05-31 22:00:34 +02:00
From 0bd5219da953639276cd17e067c030ac97feca97 Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Wed, 17 May 2017 14:51:46 +0900
Subject: [PATCH 40/45] arm64: kdump: add elf core header segment
Elf core header contains the information necessary for the coredump of
the 1st kernel, including its physcal memory layout as well as cpu register
states at the panic.
The segment is allocated inside the reserved memory of crash dump kernel.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Tested-by: David Woodhouse <dwmw@amazon.co.uk>
Tested-by: Pratyush Anand <panand@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/crashdump-arm64.c | 98 ++++++++++++++++++++++++++++++++++++++
kexec/arch/arm64/crashdump-arm64.h | 3 ++
kexec/arch/arm64/iomem.h | 2 +
kexec/arch/arm64/kexec-elf-arm64.c | 11 +++++
4 files changed, 114 insertions(+)
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
index 9267c9add291..d142435fa933 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -39,6 +39,39 @@ struct memory_ranges usablemem_rgns = {
.ranges = &crash_reserved_mem,
};
+struct memory_range elfcorehdr_mem;
+
+static struct crash_elf_info elf_info = {
+ .class = ELFCLASS64,
+#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+ .data = ELFDATA2LSB,
+#else
+ .data = ELFDATA2MSB,
+#endif
+ .machine = EM_AARCH64,
+};
+
+/*
+ * Note: The returned value is correct only if !CONFIG_RANDOMIZE_BASE.
+ */
+static uint64_t get_kernel_page_offset(void)
+{
+ int i;
+
+ if (elf_info.kern_vaddr_start == UINT64_MAX)
+ return UINT64_MAX;
+
+ /* Current max virtual memory range is 48-bits. */
+ for (i = 48; i > 0; i--)
+ if (!(elf_info.kern_vaddr_start & (1UL << i)))
+ break;
+
+ if (i <= 0)
+ return UINT64_MAX;
+ else
+ return UINT64_MAX << i;
+}
+
/*
* iomem_range_callback() - callback called for each iomem region
* @data: not used
@@ -62,6 +95,10 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
return mem_regions_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)
+ elf_info.kern_size = base + length - elf_info.kern_paddr_start;
return 0;
}
@@ -111,6 +148,67 @@ static int crash_get_memory_ranges(void)
dbgprint_mem_range("Coredump memory ranges",
system_memory_rgns.ranges, system_memory_rgns.size);
+
+ /*
+ * For additional kernel code/data segment.
+ * kern_paddr_start/kern_size are determined in iomem_range_callback
+ */
+ elf_info.kern_vaddr_start = get_kernel_sym("_text");
+ if (!elf_info.kern_vaddr_start)
+ elf_info.kern_vaddr_start = UINT64_MAX;
+
+ return 0;
+}
+
+/*
+ * load_crashdump_segments() - load the elf core header
+ * @info: kexec info structure
+ *
+ * This function creates and loads an additional segment of elf core header
+ : which is used to construct /proc/vmcore on crash dump kernel.
+ *
+ * Return 0 in case of success and -1 in case of error.
+ */
+
+int load_crashdump_segments(struct kexec_info *info)
+{
+ unsigned long elfcorehdr;
+ unsigned long bufsz;
+ void *buf;
+ int err;
+
+ /*
+ * First fetch all the memory (RAM) ranges that we are going to
+ * pass to the crash dump kernel during panic.
+ */
+
+ err = crash_get_memory_ranges();
+
+ if (err)
+ return EFAILED;
+
+ elf_info.page_offset = get_kernel_page_offset();
+ dbgprintf("%s: page_offset: %016llx\n", __func__,
+ elf_info.page_offset);
+
+ err = crash_create_elf64_headers(info, &elf_info,
+ system_memory_rgns.ranges, system_memory_rgns.size,
+ &buf, &bufsz, ELF_CORE_HEADER_ALIGN);
+
+ if (err)
+ return EFAILED;
+
+ elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 0,
+ crash_reserved_mem.start, crash_reserved_mem.end,
+ -1, 0);
+
+ elfcorehdr_mem.start = elfcorehdr;
+ elfcorehdr_mem.end = elfcorehdr + bufsz - 1;
+
+ dbgprintf("%s: elfcorehdr 0x%llx-0x%llx\n", __func__,
+ elfcorehdr_mem.start, elfcorehdr_mem.end);
+
+ return 0;
}
int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h
index ce9881eba67e..64c677d2fce1 100644
--- a/kexec/arch/arm64/crashdump-arm64.h
+++ b/kexec/arch/arm64/crashdump-arm64.h
@@ -18,5 +18,8 @@
extern struct memory_ranges usablemem_rgns;
extern struct memory_range crash_reserved_mem;
+extern struct memory_range elfcorehdr_mem;
+
+extern int load_crashdump_segments(struct kexec_info *info);
#endif /* CRASHDUMP_ARM64_H */
diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
index 20cda87dbd02..d4864bb44922 100644
--- a/kexec/arch/arm64/iomem.h
+++ b/kexec/arch/arm64/iomem.h
@@ -2,6 +2,8 @@
#define IOMEM_H
#define SYSTEM_RAM "System RAM\n"
+#define KERNEL_CODE "Kernel code\n"
+#define KERNEL_DATA "Kernel data\n"
#define CRASH_KERNEL "Crash kernel\n"
#define IOMEM_RESERVED "reserved\n"
diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
index 2b6c127ebc92..900c6939ab62 100644
--- a/kexec/arch/arm64/kexec-elf-arm64.c
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -119,6 +119,16 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
dbgprintf("%s: PE format: %s\n", __func__,
(arm64_header_check_pe_sig(header) ? "yes" : "no"));
+ /* create and initialize elf core header segment */
+ if (info->kexec_flags & KEXEC_ON_CRASH) {
+ result = load_crashdump_segments(info);
+ if (result) {
+ dbgprintf("%s: Creating eflcorehdr failed.\n",
+ __func__);
+ goto exit;
+ }
+ }
+
/* load the kernel */
result = elf_exec_load(&ehdr, info);
@@ -127,6 +137,7 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
goto exit;
}
+ /* load additional data */
result = arm64_load_other_segments(info, kernel_segment
+ arm64_mem.text_offset);
--
2.13.0