All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/4] kexec-tool:bug fix for crashdump load on riscv
@ 2026-05-21  4:06 luo.haiyang
  2026-05-21  4:08 ` [PATCH v4 1/4] RISC-V: fix crashdump load memory ranges luo.haiyang
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: luo.haiyang @ 2026-05-21  4:06 UTC (permalink / raw)
  To: kexec, horms; +Cc: zhang.run, cai.qu

From: Luo Haiyang <luo.haiyang@zte.com.cn>

This patchset fixes kexec-tool related to crashdump load on riscv

patch 1: crashload should use all system RAM but crash reserved memory.
patch 2: make the phys_to_virt function return the correct value.
patch 3: vmcore-dmesg accesses the address located in the bss segment,
use kernel image to creat kernel text elf header.
patch 4: due to the kernel image being additionally exported in /proc/iomem,
the kernel memory range is not correctly handled by to_be_excluded.

Changes from v3:
- sorry for the incorrect email format in the previous submission.

Changes from v2:
- use kernel image to creat kernel text elf header
- do not exclude kernel memory range
- https://lore.kernel.org/kexec/20260518145742805S2A5Zwk9KwoEtGDh4p3Pl@zte.com.cn/T/#md89827a089395745d3bd361889e4f3c490641732

Changes from v1:
- Add patch 2 and patch 3 to fix other bug
- https://lore.kernel.org/kexec/20260513171150519t11GTC14QEEV4EgIurNHM@zte.com.cn/T/#u

Luo Haiyang (4):
  RISC-V: fix crashdump load memory ranges
  RISCV: Fix incorrect virtual address translation in crashdump load
  RISC-V: use kernel image to creat kernel text elf header
  RISC-V: kernel image memory rang should not be excluded

 kexec/arch/riscv/Makefile          |   2 +
 kexec/arch/riscv/crashdump-riscv.c | 218 +++++++++++++++++++----------
 kexec/arch/riscv/iomem.h           |   3 +-
 kexec/arch/riscv/kexec-riscv.c     |   8 +-
 util_lib/elf_info.c                |  41 ++++--
 util_lib/include/elf_info.h        |   1 +
 6 files changed, 184 insertions(+), 89 deletions(-)

-- 
2.27.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v4 1/4] RISC-V: fix crashdump load memory ranges
  2026-05-21  4:06 [PATCH v4 0/4] kexec-tool:bug fix for crashdump load on riscv luo.haiyang
@ 2026-05-21  4:08 ` luo.haiyang
  2026-05-21  4:09 ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in crashdump load luo.haiyang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: luo.haiyang @ 2026-05-21  4:08 UTC (permalink / raw)
  To: luo.haiyang; +Cc: kexec, horms, zhang.run, cai.qu

From: Luo Haiyang <luo.haiyang@zte.com.cn>

The kdump service reported the following error:

 kdump.sh[338]: readpage_elf: Attempt to read non-existent page at 0x17ee12000.
 kdump.sh[338]: readmem: type_addr: 0, addr:ffffffd6fee12b00, size:8
 kdump.sh[338]: validate_mem_section: Can't read mem_section array.
 kdump.sh[338]: readpage_elf: Attempt to read non-existent page at 0x17ee12000.
 kdump.sh[338]: readmem: type_addr: 0, addr:ffffffd6fee12b00, size:8
 kdump.sh[338]: get_mm_sparsemem: Can't get the address of mem_section.
 kdump.sh[338]: The kernel version is not supported.
 kdump.sh[338]: The makedumpfile operation may be incomplete.

crash_mem_ranges only includes available memory, not all system RAM.
Inspired by the arm64 architecture, use system_mem_ranges in the
load_elfcorehdr function.

Fixes: b3fd54b (RISC-V: Add support for riscv kexec/kdump on kexec-tools)
Signed-off-by: Luo Haiyang <luo.haiyang@zte.com.cn>
---
 kexec/arch/riscv/crashdump-riscv.c | 167 ++++++++++++++++++-----------
 1 file changed, 102 insertions(+), 65 deletions(-)

diff --git a/kexec/arch/riscv/crashdump-riscv.c b/kexec/arch/riscv/crashdump-riscv.c
index 336d7a7..e923a71 100644
--- a/kexec/arch/riscv/crashdump-riscv.c
+++ b/kexec/arch/riscv/crashdump-riscv.c
@@ -6,6 +6,7 @@
 #include "crashdump.h"
 #include "kexec-elf.h"
 #include "mem_regions.h"
+#include "iomem.h"

 static struct crash_elf_info elf_info = {
 #if __riscv_xlen == 64
@@ -18,6 +19,7 @@ static struct crash_elf_info elf_info = {
 };

 static struct memory_ranges crash_mem_ranges = {0};
+static struct memory_ranges system_mem_ranges = {0};
 struct memory_range elfcorehdr_mem = {0};

 static unsigned long long get_page_offset(struct kexec_info *info)
@@ -34,86 +36,114 @@ static unsigned long long get_page_offset(struct kexec_info *info)
 	return vaddr_off;
 }

-int load_elfcorehdr(struct kexec_info *info)
+/*
+ * iomem_range_callback() - callback called for each iomem region
+ * @data: not used
+ * @nr: not used
+ * @str: name of the memory region
+ * @base: start address of the memory region
+ * @length: size of the memory region
+ *
+ * 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_rgns and crash_mem_ranges.
+ */
+static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
+				char *str, unsigned long long base,
+				unsigned long long length)
 {
-	struct memory_range crashkern_range = {0};
-	struct memory_range *ranges = NULL;
-	unsigned long start = 0;
-	unsigned long end = 0;
-	unsigned long buf_size = 0;
-	unsigned long elfcorehdr_addr = 0;
-	void* buf = NULL;
-	int i = 0;
-	int ret = 0;
+	if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
+		return mem_regions_alloc_and_add(&crash_mem_ranges,
+						base, length, RANGE_RAM);
+	else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
+		return mem_regions_alloc_and_add(&system_mem_ranges,
+						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;

-	ret = parse_iomem_single("Kernel code\n", &start, NULL);
-	if (ret) {
-		fprintf(stderr, "Cannot determine kernel physical base addr\n");
-		return -EINVAL;
-	}
-	elf_info.kern_paddr_start = start;
+	return 0;
+}
+
+/*
+ * crash_get_memory_ranges() - read system physical memory
+ *
+ * Function reads through system physical memory and stores found memory
+ * regions in system_memory_ranges.
+ * Regions are sorted in ascending order.
+ *
+ * Returns 0 in case of success and a negative value otherwise.
+ */
+static int crash_get_memory_ranges(void)
+{
+	int i;
+
+	if (!crash_mem_ranges.size)
+		kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);

-	ret = parse_iomem_single("Kernel bss\n", NULL, &end);
-	if (ret) {
-		fprintf(stderr, "Cannot determine kernel physical bss addr\n");
+	if (!crash_mem_ranges.size)
 		return -EINVAL;
+
+	dbgprint_mem_range("Reserved memory range",
+			crash_mem_ranges.ranges, crash_mem_ranges.size);
+
+	for (i = 0; i < crash_mem_ranges.size; i++) {
+		if (mem_regions_alloc_and_exclude(&system_mem_ranges,
+					&crash_mem_ranges.ranges[i])) {
+			fprintf(stderr, "Cannot allocate memory for ranges\n");
+			return -ENOMEM;
+		}
 	}
-	elf_info.kern_paddr_start = start;
-	elf_info.kern_size = end - start;

+	/*
+	 * Make sure that the memory regions are sorted.
+	 */
+	mem_regions_sort(&system_mem_ranges);
+
+	dbgprint_mem_range("Coredump memory ranges",
+			   system_mem_ranges.ranges, system_mem_ranges.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) {
+	if (!elf_info.kern_vaddr_start)
 		elf_info.kern_vaddr_start = UINT64_MAX;
-	}

-	elf_info.page_offset = get_page_offset(info);
-	dbgprintf("page_offset:   %016llx\n", elf_info.page_offset);
+	return 0;
+}

-	ret = parse_iomem_single("Crash kernel\n", &start, &end);
-	if (ret) {
-		fprintf(stderr, "Cannot determine kernel physical bss addr\n");
-		return -EINVAL;
-	}
-	crashkern_range.start = start;
-	crashkern_range.end = end;
-	crashkern_range.type = RANGE_RESERVED;
-
-	ranges = info->memory_range;
-	for (i = 0; i < info->memory_ranges; i++) {
-		ret = mem_regions_alloc_and_add(&crash_mem_ranges,
-						ranges[i].start,
-						ranges[i].end - ranges[i].start + 1,
-						ranges[i].type);
-		if (ret ) {
-			fprintf(stderr, "Could not create crash_mem_ranges\n");
-			return ret;
-		}
-	}
+int load_elfcorehdr(struct kexec_info *info)
+{
+	unsigned long buf_size = 0;
+	unsigned long elfcorehdr_addr = 0;
+	void* buf = NULL;

-	ret = mem_regions_alloc_and_exclude(&crash_mem_ranges,
-					    &crashkern_range);
-	if (ret) {
-		fprintf(stderr, "Could not exclude crashkern_range\n");
-		return ret;
-	}
+	if (crash_get_memory_ranges())
+		return EFAILED;
+
+	elf_info.page_offset = get_page_offset(info);
+	dbgprintf("page_offset:   %016llx\n", elf_info.page_offset);

 #if __riscv_xlen == 64
-	crash_create_elf64_headers(info, &elf_info, crash_mem_ranges.ranges,
-				   crash_mem_ranges.size, &buf, &buf_size,
+	crash_create_elf64_headers(info, &elf_info, system_mem_ranges.ranges,
+				   system_mem_ranges.size, &buf, &buf_size,
 				   ELF_CORE_HEADER_ALIGN);

 #else
-	crash_create_elf32_headers(info, &elf_info, crash_mem_ranges.ranges,
-				   crash_mem_ranges.size, &buf, &buf_size,
+	crash_create_elf32_headers(info, &elf_info, system_mem_ranges.ranges,
+				   system_mem_ranges.size, &buf, &buf_size,
 				   ELF_CORE_HEADER_ALIGN);
 #endif


 	elfcorehdr_addr = add_buffer_phys_virt(info, buf, buf_size,
-					       buf_size, 0,
-					       crashkern_range.start,
-					       crashkern_range.end,
-					       -1, 0);
+					    buf_size, 0,
+					    crash_mem_ranges.ranges[crash_mem_ranges.size - 1].start,
+					    crash_mem_ranges.ranges[crash_mem_ranges.size - 1].end,
+					    -1, 0);

 	elfcorehdr_mem.start = elfcorehdr_addr;
 	elfcorehdr_mem.end = elfcorehdr_addr + buf_size - 1;
@@ -126,15 +156,22 @@ int load_elfcorehdr(struct kexec_info *info)

 int is_crashkernel_mem_reserved(void)
 {
-	uint64_t start = 0;
-	uint64_t end = 0;
+	if (!crash_mem_ranges.size)
+		kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);

-	return parse_iomem_single("Crash kernel\n", &start, &end) == 0 ?
-	       (start != end) : 0;
+	return crash_mem_ranges.size;
 }

 int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
 {
-	return parse_iomem_single("Crash kernel\n", start, end);
-}
+	if (!crash_mem_ranges.size)
+		kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
+
+	if (!crash_mem_ranges.size)
+		return -1;
+
+	*start = crash_mem_ranges.ranges[crash_mem_ranges.size - 1].start;
+	*end = crash_mem_ranges.ranges[crash_mem_ranges.size - 1].end;

+	return 0;
+}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in  crashdump load
  2026-05-21  4:06 [PATCH v4 0/4] kexec-tool:bug fix for crashdump load on riscv luo.haiyang
  2026-05-21  4:08 ` [PATCH v4 1/4] RISC-V: fix crashdump load memory ranges luo.haiyang
@ 2026-05-21  4:09 ` luo.haiyang
  2026-05-27  7:27   ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in? " Simon Horman
  2026-05-21  4:12 ` [PATCH v4 3/4] RISC-V: use kernel image to creat kernel text elf header luo.haiyang
  2026-05-21  4:13 ` [PATCH v4 4/4] RISC-V: kernel image memory rang should not be excluded luo.haiyang
  3 siblings, 1 reply; 8+ messages in thread
From: luo.haiyang @ 2026-05-21  4:09 UTC (permalink / raw)
  To: luo.haiyang; +Cc: kexec, horms, zhang.run, cai.qu

From: Luo Haiyang <luo.haiyang@zte.com.cn>

The kexec shows the following crashdump log:

Elf header: p_type = 1, p_offset = 0x80100000 p_paddr = 0x80100000 p_vaddr = 0xcff000 ...
Elf header: p_type = 1, p_offset = 0x100000000 p_paddr = 0x100000000 p_vaddr = 0x80bff000 ...
Elf header: p_type = 1, p_offset = 0x87ffff000 p_paddr = 0x87ffff000 p_vaddr = 0x800bfe000 ...

Obviously, phys_to_virt returns an incorrect virtual address (vaddr). On the RISC-V architecture,
the linear address mapping is defined as:
va = pa + kernel_map.va_pa_offset (kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base)
Both PAGE_OFFSET and phys_ram_base can be read from /proc/kcore.

Signed-off-by: Luo Haiyang <luo.haiyang@zte.com.cn>
---
kexec/arch/riscv/Makefile          |  2 ++
kexec/arch/riscv/crashdump-riscv.c | 55 ++++++++++++++++++++++++------
util_lib/elf_info.c                | 41 +++++++++++++++++-----
util_lib/include/elf_info.h        |  1 +
4 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/kexec/arch/riscv/Makefile b/kexec/arch/riscv/Makefile
index 18a997b..e886770 100644
--- a/kexec/arch/riscv/Makefile
+++ b/kexec/arch/riscv/Makefile
@@ -14,6 +14,8 @@ riscv_ARCH_REUSE_INITRD =
riscv_CPPFLAGS += -I $(srcdir)/kexec/
+riscv_PHYS_TO_VIRT =
+
dist += $(riscv_KEXEC_SRCS)                \
kexec/arch/riscv/image-header.h         \
kexec/arch/riscv/include/arch/options.h     \
diff --git a/kexec/arch/riscv/crashdump-riscv.c b/kexec/arch/riscv/crashdump-riscv.c
index e923a71..6875249 100644
--- a/kexec/arch/riscv/crashdump-riscv.c
+++ b/kexec/arch/riscv/crashdump-riscv.c
@@ -1,5 +1,6 @@
#include <errno.h>
#include <elf.h>
+#include <elf_info.h>
#include <unistd.h>
#include "kexec.h"
@@ -22,18 +23,45 @@ static struct memory_ranges crash_mem_ranges = {0};
static struct memory_ranges system_mem_ranges = {0};
struct memory_range elfcorehdr_mem = {0};
-static unsigned long long get_page_offset(struct kexec_info *info)
+static unsigned long long phys_offset;
+
+static int get_page_offset(unsigned long long *page_offset)
{
-   unsigned long long vaddr_off = 0;
-   unsigned long long page_size = sysconf(_SC_PAGESIZE);
-   unsigned long long init_start = get_kernel_sym("_sinittext");
+   int fd, ret = 0;
-   /*
-    * Begining of init section is aligned to page size
-    */
-   vaddr_off = init_start - page_size;
+   if ((fd = open("/proc/kcore", O_RDONLY)) < 0) {
+       fprintf(stderr, "Can't open (%s).\n", "/proc/kcore");
+       return EFAILED;
+   }
+
+   ret = read_page_offset_elf_kcore(fd, (long *)page_offset);
+   if (ret)
+       fprintf(stderr, "Can't get page_offset from /proc/kcore\n");
+
+   close(fd);
+   return ret;
+}
+
+static int get_phys_offset(unsigned long long *phys_offset)
+{
+   int fd, ret = 0;
+
+   if ((fd = open("/proc/kcore", O_RDONLY)) < 0) {
+       fprintf(stderr, "Can't open (%s).\n", "/proc/kcore");
+       return EFAILED;
+   }
+
+   ret = read_phys_offset_elf_kcore(fd, (long *)phys_offset);
+   if (ret)
+       fprintf(stderr, "Can't get phys_offset from /proc/kcore\n");
-   return vaddr_off;
+   close(fd);
+   return ret;
+}
+
+unsigned long phys_to_virt(struct crash_elf_info *elf_info, unsigned long long p)
+{
+   return elf_info->page_offset - phys_offset + p;
}
/*
@@ -124,7 +152,14 @@ int load_elfcorehdr(struct kexec_info *info)
if (crash_get_memory_ranges())
return EFAILED;
-   elf_info.page_offset = get_page_offset(info);
+   if (get_phys_offset(&phys_offset))
+       return EFAILED;
+
+   dbgprintf("phys_offset:   %016llx\n", phys_offset);
+
+   if (get_page_offset(&elf_info.page_offset))
+       return EFAILED;
+
dbgprintf("page_offset:   %016llx\n", elf_info.page_offset);
#if __riscv_xlen == 64
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index 589bc1a..36eb895 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -1308,16 +1308,39 @@ int read_phys_offset_elf_kcore(int fd, long *phys_off)
*phys_off = ULONG_MAX;
+   if (phys_offset != UINT64_MAX) {
+       *phys_off = phys_offset;
+       return 0;
+   }
+
+   /* If we have a valid 'PHYS_OFFSET' by now,
+    * return it to the caller now.
+    */
ret = read_elf(fd);
-   if (!ret) {
-       /* If we have a valid 'PHYS_OFFSET' by now,
-        * return it to the caller now.
-        */
-       if (phys_offset != UINT64_MAX) {
-           *phys_off = phys_offset;
-           return ret;
-       }
+   if (!ret && phys_offset != UINT64_MAX) {
+       *phys_off = phys_offset;
+       return 0;
+   }
+
+   return -EFAULT;
+}
+
+int read_page_offset_elf_kcore(int fd, long *page_off)
+{
+   int ret;
+
+   *page_off = ULONG_MAX;
+
+   if (page_offset != UINT64_MAX) {
+       *page_off = page_offset;
+       return 0;
+   }
+
+   ret = read_elf(fd);
+   if (!ret && page_offset != UINT64_MAX) {
+       *page_off = page_offset;
+       return 0;
}
-   return 2;
+   return -EFAULT;
}
diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h
index fdf4c3d..3ccc950 100644
--- a/util_lib/include/elf_info.h
+++ b/util_lib/include/elf_info.h
@@ -29,6 +29,7 @@ int get_pt_load(int idx,
unsigned long long *virt_start,
unsigned long long *virt_end);
int read_phys_offset_elf_kcore(int fd, long *phys_off);
+int read_page_offset_elf_kcore(int fd, long *page_off);
int read_elf(int fd);
void dump_dmesg(int fd, void (*handler)(char*, unsigned int));
extern void (*arch_scan_vmcoreinfo)(char *pos);
--
2.27.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 3/4] RISC-V: use kernel image to creat kernel text elf header
  2026-05-21  4:06 [PATCH v4 0/4] kexec-tool:bug fix for crashdump load on riscv luo.haiyang
  2026-05-21  4:08 ` [PATCH v4 1/4] RISC-V: fix crashdump load memory ranges luo.haiyang
  2026-05-21  4:09 ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in crashdump load luo.haiyang
@ 2026-05-21  4:12 ` luo.haiyang
  2026-05-21  4:13 ` [PATCH v4 4/4] RISC-V: kernel image memory rang should not be excluded luo.haiyang
  3 siblings, 0 replies; 8+ messages in thread
From: luo.haiyang @ 2026-05-21  4:12 UTC (permalink / raw)
  To: luo.haiyang; +Cc: kexec, horms, zhang.run, cai.qu

From: Luo Haiyang <luo.haiyang@zte.com.cn>

The kdump service reported the following error:

  No program header covering vaddr 0xffffffff819fa200 found kexec bug?
  saving vmcore-dmesg.txt failed

prb stores the address of printk_rb_dynamic, which resides in the bss segment.
But the PHDR (Program Header) does not contains it. The correct approach is to
use the entire kernel memory range (includs text, rodata, data, bss) to create
the Kernel text Elf header. On RISC-V, we can use the "kernel image" directly,
which can be read from /proc/iomem.

Signed-off-by: Luo Haiyang <luo.haiyang@zte.com.cn>
---
 kexec/arch/riscv/crashdump-riscv.c | 10 +++++-----
 kexec/arch/riscv/iomem.h           |  1 +
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/kexec/arch/riscv/crashdump-riscv.c b/kexec/arch/riscv/crashdump-riscv.c
index 6875249..deb9a49 100644
--- a/kexec/arch/riscv/crashdump-riscv.c
+++ b/kexec/arch/riscv/crashdump-riscv.c
@@ -80,16 +80,16 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
 				char *str, unsigned long long base,
 				unsigned long long length)
 {
-	if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
+	if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0) {
 		return mem_regions_alloc_and_add(&crash_mem_ranges,
 						base, length, RANGE_RAM);
-	else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
+	} else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0) {
 		return mem_regions_alloc_and_add(&system_mem_ranges,
 						base, length, RANGE_RAM);
-	else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0)
+	} else if (strncmp(str, KERNEL_IMAGE, strlen(KERNEL_IMAGE)) == 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;
+		elf_info.kern_size = length;
+	}

 	return 0;
 }
diff --git a/kexec/arch/riscv/iomem.h b/kexec/arch/riscv/iomem.h
index 7671e26..86da971 100644
--- a/kexec/arch/riscv/iomem.h
+++ b/kexec/arch/riscv/iomem.h
@@ -4,6 +4,7 @@
 #define SYSTEM_RAM		"System RAM\n"
 #define KERNEL_CODE		"Kernel code\n"
 #define KERNEL_DATA		"Kernel data\n"
+#define KERNEL_IMAGE		"Kernel image\n"
 #define CRASH_KERNEL		"Crash kernel\n"
 #define IOMEM_RESERVED		"Reserved\n"

-- 
2.27.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 4/4] RISC-V: kernel image memory rang should not be excluded
  2026-05-21  4:06 [PATCH v4 0/4] kexec-tool:bug fix for crashdump load on riscv luo.haiyang
                   ` (2 preceding siblings ...)
  2026-05-21  4:12 ` [PATCH v4 3/4] RISC-V: use kernel image to creat kernel text elf header luo.haiyang
@ 2026-05-21  4:13 ` luo.haiyang
  3 siblings, 0 replies; 8+ messages in thread
From: luo.haiyang @ 2026-05-21  4:13 UTC (permalink / raw)
  To: luo.haiyang; +Cc: kexec, horms, zhang.run, cai.qu

From: Luo Haiyang <luo.haiyang@zte.com.cn>

On RISC-V, due to the kernel image being additionally exported
in /proc/iomem, the kernel memory range is not correctly handled
by to_be_excluded.

Signed-off-by: Luo Haiyang <luo.haiyang@zte.com.cn>
---
 kexec/arch/riscv/iomem.h       | 2 --
 kexec/arch/riscv/kexec-riscv.c | 8 +++-----
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/kexec/arch/riscv/iomem.h b/kexec/arch/riscv/iomem.h
index 86da971..1ab704c 100644
--- a/kexec/arch/riscv/iomem.h
+++ b/kexec/arch/riscv/iomem.h
@@ -2,8 +2,6 @@
 #define IOMEM_H

 #define SYSTEM_RAM		"System RAM\n"
-#define KERNEL_CODE		"Kernel code\n"
-#define KERNEL_DATA		"Kernel data\n"
 #define KERNEL_IMAGE		"Kernel image\n"
 #define CRASH_KERNEL		"Crash kernel\n"
 #define IOMEM_RESERVED		"Reserved\n"
diff --git a/kexec/arch/riscv/kexec-riscv.c b/kexec/arch/riscv/kexec-riscv.c
index a5a12a0..72fde08 100644
--- a/kexec/arch/riscv/kexec-riscv.c
+++ b/kexec/arch/riscv/kexec-riscv.c
@@ -417,12 +417,10 @@ static bool to_be_excluded(char *str, unsigned long long start, unsigned long lo
 		return true;
 	}

-	if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
-	    !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
-	    !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)))
-		return false;
-	else
+	if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
 		return true;
+
+	return false;
 }

 int get_memory_ranges(struct memory_range **range, int *num_ranges,
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in? crashdump load
  2026-05-21  4:09 ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in crashdump load luo.haiyang
@ 2026-05-27  7:27   ` Simon Horman
  2026-05-27  8:18     ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in " luo.haiyang
  2026-05-27  8:30     ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in? " luo.haiyang
  0 siblings, 2 replies; 8+ messages in thread
From: Simon Horman @ 2026-05-27  7:27 UTC (permalink / raw)
  To: luo.haiyang; +Cc: kexec, zhang.run, cai.qu

On Thu, May 21, 2026 at 12:09:46PM +0800, luo.haiyang@zte.com.cn wrote:
> From: Luo Haiyang <luo.haiyang@zte.com.cn>
> 
> The kexec shows the following crashdump log:
> 
> Elf header: p_type = 1, p_offset = 0x80100000 p_paddr = 0x80100000 p_vaddr = 0xcff000 ...
> Elf header: p_type = 1, p_offset = 0x100000000 p_paddr = 0x100000000 p_vaddr = 0x80bff000 ...
> Elf header: p_type = 1, p_offset = 0x87ffff000 p_paddr = 0x87ffff000 p_vaddr = 0x800bfe000 ...
> 
> Obviously, phys_to_virt returns an incorrect virtual address (vaddr). On the RISC-V architecture,
> the linear address mapping is defined as:
> va = pa + kernel_map.va_pa_offset (kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base)
> Both PAGE_OFFSET and phys_ram_base can be read from /proc/kcore.
> 
> Signed-off-by: Luo Haiyang <luo.haiyang@zte.com.cn>

Hi,

Unfortunately this patch seems to be somewhat mangled
and does not apply. Could you look into that?




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in crashdump load
  2026-05-27  7:27   ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in? " Simon Horman
@ 2026-05-27  8:18     ` luo.haiyang
  2026-05-27  8:30     ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in? " luo.haiyang
  1 sibling, 0 replies; 8+ messages in thread
From: luo.haiyang @ 2026-05-27  8:18 UTC (permalink / raw)
  To: horms; +Cc: kexec, zhang.run, cai.qu

From: Luo Haiyang <luo.haiyang@zte.com.cn>

The kexec shows the following crashdump log:

  Elf header: p_type = 1, p_offset = 0x80100000 p_paddr = 0x80100000 p_vaddr = 0xcff000 ...
  Elf header: p_type = 1, p_offset = 0x100000000 p_paddr = 0x100000000 p_vaddr = 0x80bff000 ...
  Elf header: p_type = 1, p_offset = 0x87ffff000 p_paddr = 0x87ffff000 p_vaddr = 0x800bfe000 ...

Obviously, phys_to_virt returns an incorrect virtual address (vaddr). On the RISC-V architecture,
the linear address mapping is defined as:
  va = pa + kernel_map.va_pa_offset (kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base)
Both PAGE_OFFSET and phys_ram_base can be read from /proc/kcore.

Signed-off-by: Luo Haiyang <luo.haiyang@zte.com.cn>
---
 kexec/arch/riscv/Makefile          |  2 ++
 kexec/arch/riscv/crashdump-riscv.c | 55 ++++++++++++++++++++++++------
 util_lib/elf_info.c                | 41 +++++++++++++++++-----
 util_lib/include/elf_info.h        |  1 +
 4 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/kexec/arch/riscv/Makefile b/kexec/arch/riscv/Makefile
index 18a997b..e886770 100644
--- a/kexec/arch/riscv/Makefile
+++ b/kexec/arch/riscv/Makefile
@@ -14,6 +14,8 @@ riscv_ARCH_REUSE_INITRD =

 riscv_CPPFLAGS += -I $(srcdir)/kexec/

+riscv_PHYS_TO_VIRT =
+
 dist += $(riscv_KEXEC_SRCS)				\
 	kexec/arch/riscv/image-header.h			\
 	kexec/arch/riscv/include/arch/options.h		\
diff --git a/kexec/arch/riscv/crashdump-riscv.c b/kexec/arch/riscv/crashdump-riscv.c
index e923a71..6875249 100644
--- a/kexec/arch/riscv/crashdump-riscv.c
+++ b/kexec/arch/riscv/crashdump-riscv.c
@@ -1,5 +1,6 @@
 #include <errno.h>
 #include <elf.h>
+#include <elf_info.h>
 #include <unistd.h>

 #include "kexec.h"
@@ -22,18 +23,45 @@ static struct memory_ranges crash_mem_ranges = {0};
 static struct memory_ranges system_mem_ranges = {0};
 struct memory_range elfcorehdr_mem = {0};

-static unsigned long long get_page_offset(struct kexec_info *info)
+static unsigned long long phys_offset;
+
+static int get_page_offset(unsigned long long *page_offset)
 {
-	unsigned long long vaddr_off = 0;
-	unsigned long long page_size = sysconf(_SC_PAGESIZE);
-	unsigned long long init_start = get_kernel_sym("_sinittext");
+	int fd, ret = 0;

-	/*
-	 * Begining of init section is aligned to page size
-	 */
-	vaddr_off = init_start - page_size;
+	if ((fd = open("/proc/kcore", O_RDONLY)) < 0) {
+		fprintf(stderr, "Can't open (%s).\n", "/proc/kcore");
+		return EFAILED;
+	}
+
+	ret = read_page_offset_elf_kcore(fd, (long *)page_offset);
+	if (ret)
+		fprintf(stderr, "Can't get page_offset from /proc/kcore\n");
+
+	close(fd);
+	return ret;
+}
+
+static int get_phys_offset(unsigned long long *phys_offset)
+{
+	int fd, ret = 0;
+
+	if ((fd = open("/proc/kcore", O_RDONLY)) < 0) {
+		fprintf(stderr, "Can't open (%s).\n", "/proc/kcore");
+		return EFAILED;
+	}
+
+	ret = read_phys_offset_elf_kcore(fd, (long *)phys_offset);
+	if (ret)
+		fprintf(stderr, "Can't get phys_offset from /proc/kcore\n");

-	return vaddr_off;
+	close(fd);
+	return ret;
+}
+
+unsigned long phys_to_virt(struct crash_elf_info *elf_info, unsigned long long p)
+{
+	return elf_info->page_offset - phys_offset + p;
 }

 /*
@@ -124,7 +152,14 @@ int load_elfcorehdr(struct kexec_info *info)
 	if (crash_get_memory_ranges())
 		return EFAILED;

-	elf_info.page_offset = get_page_offset(info);
+	if (get_phys_offset(&phys_offset))
+		return EFAILED;
+
+	dbgprintf("phys_offset:   %016llx\n", phys_offset);
+
+	if (get_page_offset(&elf_info.page_offset))
+		return EFAILED;
+
 	dbgprintf("page_offset:   %016llx\n", elf_info.page_offset);

 #if __riscv_xlen == 64
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index 589bc1a..36eb895 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -1308,16 +1308,39 @@ int read_phys_offset_elf_kcore(int fd, long *phys_off)

 	*phys_off = ULONG_MAX;

+	if (phys_offset != UINT64_MAX) {
+		*phys_off = phys_offset;
+		return 0;
+	}
+
+	/* If we have a valid 'PHYS_OFFSET' by now,
+	 * return it to the caller now.
+	 */
 	ret = read_elf(fd);
-	if (!ret) {
-		/* If we have a valid 'PHYS_OFFSET' by now,
-		 * return it to the caller now.
-		 */
-		if (phys_offset != UINT64_MAX) {
-			*phys_off = phys_offset;
-			return ret;
-		}
+	if (!ret && phys_offset != UINT64_MAX) {
+		*phys_off = phys_offset;
+		return 0;
+	}
+
+	return -EFAULT;
+}
+
+int read_page_offset_elf_kcore(int fd, long *page_off)
+{
+	int ret;
+
+	*page_off = ULONG_MAX;
+
+	if (page_offset != UINT64_MAX) {
+		*page_off = page_offset;
+		return 0;
+	}
+
+	ret = read_elf(fd);
+	if (!ret && page_offset != UINT64_MAX) {
+		*page_off = page_offset;
+		return 0;
 	}

-	return 2;
+	return -EFAULT;
 }
diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h
index fdf4c3d..3ccc950 100644
--- a/util_lib/include/elf_info.h
+++ b/util_lib/include/elf_info.h
@@ -29,6 +29,7 @@ int get_pt_load(int idx,
 	unsigned long long *virt_start,
 	unsigned long long *virt_end);
 int read_phys_offset_elf_kcore(int fd, long *phys_off);
+int read_page_offset_elf_kcore(int fd, long *page_off);
 int read_elf(int fd);
 void dump_dmesg(int fd, void (*handler)(char*, unsigned int));
 extern void (*arch_scan_vmcoreinfo)(char *pos);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in? crashdump load
  2026-05-27  7:27   ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in? " Simon Horman
  2026-05-27  8:18     ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in " luo.haiyang
@ 2026-05-27  8:30     ` luo.haiyang
  1 sibling, 0 replies; 8+ messages in thread
From: luo.haiyang @ 2026-05-27  8:30 UTC (permalink / raw)
  To: horms; +Cc: kexec, zhang.run, cai.qu

SimonHorman <horms@kernel.org> wrote:
>On Thu, May 21, 2026 at 12:09:46PM +0800, luo.haiyang@zte.com.cn wrote:
>> From: Luo Haiyang <luo.haiyang@zte.com.cn>
>> 
>> The kexec shows the following crashdump log:
>> 
>> Elf header: p_type = 1, p_offset = 0x80100000 p_paddr = 0x80100000 p_vaddr = 0xcff000 ...
>> Elf header: p_type = 1, p_offset = 0x100000000 p_paddr = 0x100000000 p_vaddr = 0x80bff000 ...
>> Elf header: p_type = 1, p_offset = 0x87ffff000 p_paddr = 0x87ffff000 p_vaddr = 0x800bfe000 ...
>> 
>> Obviously, phys_to_virt returns an incorrect virtual address (vaddr). On the RISC-V architecture,
>> the linear address mapping is defined as:
>> va = pa + kernel_map.va_pa_offset (kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base)
>> Both PAGE_OFFSET and phys_ram_base can be read from /proc/kcore.
>> 
>> Signed-off-by: Luo Haiyang <luo.haiyang@zte.com.cn>
>
>Hi,
>
>Unfortunately this patch seems to be somewhat mangled
>and does not apply. Could you look into that?

Seems something got broken, I've resent the patch. Could you please see if it works?

Thanks
Luo haiyang


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-05-27  8:31 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-21  4:06 [PATCH v4 0/4] kexec-tool:bug fix for crashdump load on riscv luo.haiyang
2026-05-21  4:08 ` [PATCH v4 1/4] RISC-V: fix crashdump load memory ranges luo.haiyang
2026-05-21  4:09 ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in crashdump load luo.haiyang
2026-05-27  7:27   ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in? " Simon Horman
2026-05-27  8:18     ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in " luo.haiyang
2026-05-27  8:30     ` [PATCH v4 2/4] RISCV: Fix incorrect virtual address translation in? " luo.haiyang
2026-05-21  4:12 ` [PATCH v4 3/4] RISC-V: use kernel image to creat kernel text elf header luo.haiyang
2026-05-21  4:13 ` [PATCH v4 4/4] RISC-V: kernel image memory rang should not be excluded luo.haiyang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.