summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYouling Tang <tangyouling@loongson.cn>2023-03-04 11:09:11 +0800
committerSimon Horman <horms@kernel.org>2023-03-08 11:49:45 +0100
commita8de94e5f033afc1424dc37933c9d1ecb3dc1b9f (patch)
treead9f1134e6e9dc5f042fddbccc542eb3e0c2a7e5
parent4203eaccfa925dd11019163560297a5353b01638 (diff)
downloadkexec-tools-master.tar.gz
LoongArch: kdump: Set up kernel image segmentHEADmastermain
On LoongArch, we can use the same kernel image as 1st kernel when 3f89765d622 ("LoongArch: kdump: Add single kernel image implementation") is merged, but we have to modify the entry point as well as segments addresses in the kernel elf header (or PE format vmlinux.efi) in order to load them into correct places. Signed-off-by: Youling Tang <tangyouling@loongson.cn> Signed-off-by: Simon Horman <horms@kernel.org>
-rw-r--r--kexec/arch/loongarch/crashdump-loongarch.c22
-rw-r--r--kexec/arch/loongarch/crashdump-loongarch.h1
-rw-r--r--kexec/arch/loongarch/kexec-elf-loongarch.c8
-rw-r--r--kexec/arch/loongarch/kexec-loongarch.c3
-rw-r--r--kexec/arch/loongarch/kexec-pei-loongarch.c7
5 files changed, 40 insertions, 1 deletions
diff --git a/kexec/arch/loongarch/crashdump-loongarch.c b/kexec/arch/loongarch/crashdump-loongarch.c
index aaf6cf3..81250e4 100644
--- a/kexec/arch/loongarch/crashdump-loongarch.c
+++ b/kexec/arch/loongarch/crashdump-loongarch.c
@@ -183,6 +183,28 @@ int load_crashdump_segments(struct kexec_info *info)
return 0;
}
+/*
+ * e_entry and p_paddr are actually in virtual address space.
+ * Those values will be translated to physcal addresses by using
+ * virt_to_phys() in add_segment().
+ * So let's fix up those values for later use so the memory base will be
+ * correctly replaced with crash_reserved_mem[usablemem_rgns.size - 1].start.
+ */
+void fixup_elf_addrs(struct mem_ehdr *ehdr)
+{
+ struct mem_phdr *phdr;
+ int i;
+
+ ehdr->e_entry += crash_reserved_mem[usablemem_rgns.size - 1].start;
+
+ for (i = 0; i < ehdr->e_phnum; i++) {
+ phdr = &ehdr->e_phdr[i];
+ if (phdr->p_type != PT_LOAD)
+ continue;
+ phdr->p_paddr += crash_reserved_mem[usablemem_rgns.size - 1].start;
+ }
+}
+
int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
{
if (!usablemem_rgns.size)
diff --git a/kexec/arch/loongarch/crashdump-loongarch.h b/kexec/arch/loongarch/crashdump-loongarch.h
index 3eb4e0a..25ff24b 100644
--- a/kexec/arch/loongarch/crashdump-loongarch.h
+++ b/kexec/arch/loongarch/crashdump-loongarch.h
@@ -8,6 +8,7 @@ extern struct memory_range elfcorehdr_mem;
int load_crashdump_segments(struct kexec_info *info);
int is_crashkernel_mem_reserved(void);
+void fixup_elf_addrs(struct mem_ehdr *ehdr);
int get_crash_kernel_load_range(uint64_t *start, uint64_t *end);
#define PAGE_OFFSET 0x9000000000000000ULL
diff --git a/kexec/arch/loongarch/kexec-elf-loongarch.c b/kexec/arch/loongarch/kexec-elf-loongarch.c
index 2bf128f..45387ca 100644
--- a/kexec/arch/loongarch/kexec-elf-loongarch.c
+++ b/kexec/arch/loongarch/kexec-elf-loongarch.c
@@ -90,6 +90,14 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf,
}
}
+ /* load the kernel */
+ if (info->kexec_flags & KEXEC_ON_CRASH)
+ /*
+ * offset addresses in elf header in order to load
+ * vmlinux (elf_exec) into crash kernel's memory.
+ */
+ fixup_elf_addrs(&ehdr);
+
info->entry = (void *)virt_to_phys(ehdr.e_entry);
result = elf_exec_load(&ehdr, info);
diff --git a/kexec/arch/loongarch/kexec-loongarch.c b/kexec/arch/loongarch/kexec-loongarch.c
index 4c7361c..f47c998 100644
--- a/kexec/arch/loongarch/kexec-loongarch.c
+++ b/kexec/arch/loongarch/kexec-loongarch.c
@@ -253,7 +253,8 @@ unsigned long loongarch_locate_kernel_segment(struct kexec_info *info)
unsigned long hole_end;
hole = (crash_reserved_mem[usablemem_rgns.size - 1].start < mem_min ?
- mem_min : crash_reserved_mem[usablemem_rgns.size - 1].start);
+ mem_min : crash_reserved_mem[usablemem_rgns.size - 1].start) +
+ loongarch_mem.text_offset;
hole = _ALIGN_UP(hole, MiB(1));
hole_end = hole + loongarch_mem.text_offset + loongarch_mem.image_size;
diff --git a/kexec/arch/loongarch/kexec-pei-loongarch.c b/kexec/arch/loongarch/kexec-pei-loongarch.c
index f86ac61..1a11103 100644
--- a/kexec/arch/loongarch/kexec-pei-loongarch.c
+++ b/kexec/arch/loongarch/kexec-pei-loongarch.c
@@ -66,6 +66,13 @@ int pei_loongarch_load(int argc, char **argv, const char *buf,
kernel_entry = virt_to_phys(loongarch_header_kernel_entry(header));
+ if (info->kexec_flags & KEXEC_ON_CRASH)
+ /*
+ * offset addresses in order to load vmlinux.efi into
+ * crash kernel's memory.
+ */
+ kernel_entry += crash_reserved_mem[usablemem_rgns.size - 1].start;
+
dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment);
dbgprintf("%s: kernel_entry: %016lx\n", __func__, kernel_entry);
dbgprintf("%s: image_size: %016lx\n", __func__,