1 Star 0 Fork 46

Ming Wang/kexec-tools-openEuler

forked from src-openEuler/kexec-tools 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
loongarch64-fix-kernel-image-size-error.patch 8.64 KB
一键复制 编辑 原始数据 按行查看 历史
Ming Wang 提交于 2025-01-06 15:08 +08:00 . Fix loongarch64 kdump image size overflow issue.
From 510981a6b810c18d1bc3f5917ad743f3a6c85cf7 Mon Sep 17 00:00:00 2001
From: Ming Wang <wangming01@loongson.cn>
Date: Fri, 17 May 2024 10:39:31 +0800
Subject: [PATCH] kexec: loongarch: fix some issue.
Signed-off-by: Hongchen Zhang <zhanghongchen@loongson.cn>
Signed-off-by: Ming Wang <wangming01@loongson.cn>
---
kexec/arch/loongarch/crashdump-loongarch.c | 22 ++++++++++++
kexec/arch/loongarch/crashdump-loongarch.h | 1 +
kexec/arch/loongarch/kexec-elf-loongarch.c | 40 +++++++++++++++++++---
kexec/arch/loongarch/kexec-loongarch.c | 22 ++++++++----
kexec/arch/loongarch/kexec-pei-loongarch.c | 7 ++++
kexec/kexec-syscall.h | 2 +-
6 files changed, 82 insertions(+), 12 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..7e84d03 100644
--- a/kexec/arch/loongarch/kexec-elf-loongarch.c
+++ b/kexec/arch/loongarch/kexec-elf-loongarch.c
@@ -54,6 +54,7 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf,
unsigned long kernel_segment;
struct mem_ehdr ehdr;
int result;
+ int i;
result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0);
@@ -62,6 +63,26 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf,
goto exit;
}
+ /* Find and process the loongarch image header. */
+ for (i = 0; i < ehdr.e_phnum; i++) {
+ struct mem_phdr *phdr = &ehdr.e_phdr[i];
+
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
+ header = (const struct loongarch_image_header *)(
+ kernel_buf + phdr->p_offset);
+
+ if (!loongarch_process_image_header(header))
+ break;
+ }
+
+ if (i == ehdr.e_phnum) {
+ dbgprintf("%s: Valid loongarch image header not found\n", __func__);
+ result = EFAILED;
+ goto exit;
+ }
+
kernel_segment = loongarch_locate_kernel_segment(info);
if (kernel_segment == ULONG_MAX) {
@@ -72,13 +93,12 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf,
dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment);
dbgprintf("%s: image_size: %016lx\n", __func__,
- kernel_size);
+ loongarch_mem.image_size);
dbgprintf("%s: text_offset: %016lx\n", __func__,
loongarch_mem.text_offset);
dbgprintf("%s: phys_offset: %016lx\n", __func__,
loongarch_mem.phys_offset);
- dbgprintf("%s: PE format: %s\n", __func__,
- (loongarch_header_check_pe_sig(header) ? "yes" : "no"));
+ dbgprintf("%s: PE format: no\n", __func__);
/* create and initialize elf core header segment */
if (info->kexec_flags & KEXEC_ON_CRASH) {
@@ -90,6 +110,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);
@@ -99,8 +127,12 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf,
goto exit;
}
+ /* for vmlinuz kernel image */
+ if (kernel_size < MiB(16))
+ kernel_size = MiB(64);
+
/* load additional data */
- result = loongarch_load_other_segments(info, kernel_segment + kernel_size);
+ result = loongarch_load_other_segments(info, kernel_segment + loongarch_mem.image_size);
exit:
free_elf_info(&ehdr);
diff --git a/kexec/arch/loongarch/kexec-loongarch.c b/kexec/arch/loongarch/kexec-loongarch.c
index 4c7361c..6485080 100644
--- a/kexec/arch/loongarch/kexec-loongarch.c
+++ b/kexec/arch/loongarch/kexec-loongarch.c
@@ -221,6 +221,10 @@ int arch_process_options(int argc, char **argv)
cmdline = get_command_line();
remove_parameter(cmdline, "kexec");
remove_parameter(cmdline, "initrd");
+ remove_parameter(cmdline, "rd_start");
+ remove_parameter(cmdline, "rd_size");
+ remove_parameter(cmdline, "vfio_iommu_type1.allow_unsafe_interrupts");
+ remove_parameter(cmdline, "nokaslr");
break;
case OPT_INITRD:
arch_options.initrd_file = optarg;
@@ -253,8 +257,9 @@ 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);
- hole = _ALIGN_UP(hole, MiB(1));
+ mem_min : crash_reserved_mem[usablemem_rgns.size - 1].start) +
+ loongarch_mem.text_offset;
+ hole = _ALIGN_UP(hole, MiB(16));
hole_end = hole + loongarch_mem.text_offset + loongarch_mem.image_size;
if ((hole_end > mem_max) ||
@@ -265,7 +270,7 @@ unsigned long loongarch_locate_kernel_segment(struct kexec_info *info)
} else {
hole = locate_hole(info,
loongarch_mem.text_offset + loongarch_mem.image_size,
- MiB(1), 0, ULONG_MAX, 1);
+ MiB(16), 0, ULONG_MAX, 1);
if (hole == ULONG_MAX)
dbgprintf("%s: locate_hole failed\n", __func__);
@@ -283,6 +288,7 @@ int loongarch_load_other_segments(struct kexec_info *info, unsigned long hole_mi
unsigned long initrd_min, hole_max;
char *initrd_buf = NULL;
unsigned long pagesize = getpagesize();
+ int i;
if (arch_options.command_line) {
if (strlen(arch_options.command_line) >
@@ -320,15 +326,17 @@ int loongarch_load_other_segments(struct kexec_info *info, unsigned long hole_mi
cmdline_add_elfcorehdr(cmdline, elfcorehdr_mem.start,
elfcorehdr_mem.end - elfcorehdr_mem.start + 1);
- cmdline_add_mem(cmdline, crash_reserved_mem[usablemem_rgns.size - 1].start,
- crash_reserved_mem[usablemem_rgns.size - 1].end -
- crash_reserved_mem[usablemem_rgns.size - 1].start + 1);
+ for(i = 0;i < usablemem_rgns.size; i++) {
+ cmdline_add_mem(cmdline, crash_reserved_mem[i].start,
+ crash_reserved_mem[i].end -
+ crash_reserved_mem[i].start + 1);
+ }
}
cmdline[sizeof(cmdline) - 1] = 0;
add_buffer(info, cmdline, sizeof(cmdline), sizeof(cmdline),
sizeof(void *), _ALIGN_UP(hole_min, getpagesize()),
- 0xffffffff, 1);
+ hole_max, 1);
dbgprintf("%s:%d: command_line: %s\n", __func__, __LINE__, cmdline);
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__,
diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h
index e392c01..f18b014 100644
--- a/kexec/kexec-syscall.h
+++ b/kexec/kexec-syscall.h
@@ -59,7 +59,7 @@
#endif
#endif /*ifndef __NR_kexec_load*/
-#ifdef __arm__
+#if defined(__arm__) || defined(__loongarch__)
#undef __NR_kexec_file_load
#endif
--
2.43.0
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/robinorg/kexec-tools-openEuler.git
git@gitee.com:robinorg/kexec-tools-openEuler.git
robinorg
kexec-tools-openEuler
kexec-tools-openEuler
master

搜索帮助