diff options
Diffstat (limited to 'meta/recipes-kernel/kexec/kexec-tools/0006-arm64-kdump-set-up-kernel-image-segment.patch')
-rw-r--r-- | meta/recipes-kernel/kexec/kexec-tools/0006-arm64-kdump-set-up-kernel-image-segment.patch | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/meta/recipes-kernel/kexec/kexec-tools/0006-arm64-kdump-set-up-kernel-image-segment.patch b/meta/recipes-kernel/kexec/kexec-tools/0006-arm64-kdump-set-up-kernel-image-segment.patch new file mode 100644 index 0000000000..414955107a --- /dev/null +++ b/meta/recipes-kernel/kexec/kexec-tools/0006-arm64-kdump-set-up-kernel-image-segment.patch | |||
@@ -0,0 +1,137 @@ | |||
1 | From 4079c93ac5453ef5f7889ab64920c1e9427690ef Mon Sep 17 00:00:00 2001 | ||
2 | From: AKASHI Takahiro <takahiro.akashi@linaro.org> | ||
3 | Date: Tue, 17 Feb 2015 16:06:55 +0900 | ||
4 | Subject: [PATCH 6/9] arm64: kdump: set up kernel image segment | ||
5 | |||
6 | On arm64, we can use the same kernel image as 1st kernel, but | ||
7 | we have to modify the entry point as well as segments' addresses | ||
8 | in the kernel's elf header in order to load them into correct places. | ||
9 | |||
10 | Upstream-Status: Backport [https://git.linaro.org/people/takahiro.akashi/kexec-tools.git] | ||
11 | |||
12 | Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> | ||
13 | Signed-off-by: He Zhe <zhe.he@windriver.com> | ||
14 | --- | ||
15 | kexec/arch/arm64/crashdump-arm64.c | 23 +++++++++++++++++++++++ | ||
16 | kexec/arch/arm64/crashdump-arm64.h | 1 + | ||
17 | kexec/arch/arm64/kexec-arm64.c | 25 ++++++++++++++++++++----- | ||
18 | kexec/arch/arm64/kexec-elf-arm64.c | 10 +++++++++- | ||
19 | 4 files changed, 53 insertions(+), 6 deletions(-) | ||
20 | |||
21 | diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c | ||
22 | index 8346131..9517329 100644 | ||
23 | --- a/kexec/arch/arm64/crashdump-arm64.c | ||
24 | +++ b/kexec/arch/arm64/crashdump-arm64.c | ||
25 | @@ -213,3 +213,26 @@ int load_crashdump_segments(struct kexec_info *info) | ||
26 | |||
27 | return 0; | ||
28 | } | ||
29 | + | ||
30 | +/* | ||
31 | + * e_entry and p_paddr are actually in virtual address space. | ||
32 | + * Those values will be translated to physcal addresses by | ||
33 | + * using virt_to_phys(). | ||
34 | + * So let's get ready for later use so the memory base (phys_offset) | ||
35 | + * will be correctly replaced with crash_reserved_mem.start. | ||
36 | + */ | ||
37 | +void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr) | ||
38 | +{ | ||
39 | + struct mem_phdr *phdr; | ||
40 | + int i; | ||
41 | + | ||
42 | + ehdr->e_entry += - arm64_mem.phys_offset + crash_reserved_mem.start; | ||
43 | + | ||
44 | + for (i = 0; i < ehdr->e_phnum; i++) { | ||
45 | + phdr = &ehdr->e_phdr[i]; | ||
46 | + if (phdr->p_type != PT_LOAD) | ||
47 | + continue; | ||
48 | + phdr->p_paddr += | ||
49 | + (-arm64_mem.phys_offset + crash_reserved_mem.start); | ||
50 | + } | ||
51 | +} | ||
52 | diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h | ||
53 | index da75a2d..382f571 100644 | ||
54 | --- a/kexec/arch/arm64/crashdump-arm64.h | ||
55 | +++ b/kexec/arch/arm64/crashdump-arm64.h | ||
56 | @@ -21,5 +21,6 @@ extern struct memory_range crash_reserved_mem; | ||
57 | extern struct memory_range elfcorehdr_mem; | ||
58 | |||
59 | extern int load_crashdump_segments(struct kexec_info *info); | ||
60 | +extern void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr); | ||
61 | |||
62 | #endif /* CRASHDUMP_ARM64_H */ | ||
63 | diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c | ||
64 | index 8ac811d..cec4e41 100644 | ||
65 | --- a/kexec/arch/arm64/kexec-arm64.c | ||
66 | +++ b/kexec/arch/arm64/kexec-arm64.c | ||
67 | @@ -307,12 +307,27 @@ unsigned long arm64_locate_kernel_segment(struct kexec_info *info) | ||
68 | { | ||
69 | unsigned long hole; | ||
70 | |||
71 | - hole = locate_hole(info, | ||
72 | - arm64_mem.text_offset + arm64_mem.image_size, | ||
73 | - MiB(2), 0, ULONG_MAX, 1); | ||
74 | + if (info->kexec_flags & KEXEC_ON_CRASH) { | ||
75 | + unsigned long hole_end; | ||
76 | + | ||
77 | + hole = (crash_reserved_mem.start < mem_min ? | ||
78 | + mem_min : crash_reserved_mem.start); | ||
79 | + hole = _ALIGN_UP(hole, MiB(2)); | ||
80 | + hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size; | ||
81 | + | ||
82 | + if ((hole_end > mem_max) || | ||
83 | + (hole_end > crash_reserved_mem.end)) { | ||
84 | + dbgprintf("%s: Crash kernel out of range\n", __func__); | ||
85 | + hole = ULONG_MAX; | ||
86 | + } | ||
87 | + } else { | ||
88 | + hole = locate_hole(info, | ||
89 | + arm64_mem.text_offset + arm64_mem.image_size, | ||
90 | + MiB(2), 0, ULONG_MAX, 1); | ||
91 | |||
92 | - if (hole == ULONG_MAX) | ||
93 | - dbgprintf("%s: locate_hole failed\n", __func__); | ||
94 | + if (hole == ULONG_MAX) | ||
95 | + dbgprintf("%s: locate_hole failed\n", __func__); | ||
96 | + } | ||
97 | |||
98 | return hole; | ||
99 | } | ||
100 | diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c | ||
101 | index c70a37a..842ce21 100644 | ||
102 | --- a/kexec/arch/arm64/kexec-elf-arm64.c | ||
103 | +++ b/kexec/arch/arm64/kexec-elf-arm64.c | ||
104 | @@ -9,6 +9,7 @@ | ||
105 | #include <stdlib.h> | ||
106 | #include <linux/elf.h> | ||
107 | |||
108 | +#include "crashdump-arm64.h" | ||
109 | #include "kexec-arm64.h" | ||
110 | #include "kexec-elf.h" | ||
111 | #include "kexec-syscall.h" | ||
112 | @@ -105,7 +106,8 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, | ||
113 | } | ||
114 | |||
115 | arm64_mem.vp_offset = _ALIGN_DOWN(ehdr.e_entry, MiB(2)); | ||
116 | - arm64_mem.vp_offset -= kernel_segment - get_phys_offset(); | ||
117 | + if (!(info->kexec_flags & KEXEC_ON_CRASH)) | ||
118 | + arm64_mem.vp_offset -= kernel_segment - get_phys_offset(); | ||
119 | |||
120 | dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment); | ||
121 | dbgprintf("%s: text_offset: %016lx\n", __func__, | ||
122 | @@ -127,6 +129,12 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, | ||
123 | __func__); | ||
124 | goto exit; | ||
125 | } | ||
126 | + | ||
127 | + /* | ||
128 | + * offset addresses in order to fit vmlinux | ||
129 | + * (elf_exec) into crash kernel's memory | ||
130 | + */ | ||
131 | + modify_ehdr_for_crashdump(&ehdr); | ||
132 | } | ||
133 | |||
134 | /* load the kernel */ | ||
135 | -- | ||
136 | 1.9.1 | ||
137 | |||