91 lines
3.0 KiB
Diff
91 lines
3.0 KiB
Diff
|
From ff963b795b3f93b9d1a3cc5ec0212ebca545259f Mon Sep 17 00:00:00 2001
|
||
|
From: Song Shuai <suagrfillet@gmail.com>
|
||
|
Date: Fri, 4 Aug 2023 17:15:59 +0800
|
||
|
Subject: [PATCH 25/30] RISCV64: Use va_kernel_pa_offset in VTOP()
|
||
|
|
||
|
Since RISC-V Linux v6.4, the commit 3335068f8721 ("riscv: Use
|
||
|
PUD/P4D/PGD pages for the linear mapping") changes phys_ram_base from
|
||
|
the physical start of the kernel to the actual start of the DRAM.
|
||
|
|
||
|
The Crash's VTOP() still uses phys_ram_base and kernel_map.virt_addr
|
||
|
to translate kernel virtual address, that made Crash boot failed with
|
||
|
Linux v6.4 and later version.
|
||
|
|
||
|
Let Linux export kernel_map.va_kernel_pa_offset in v6.5 and backported
|
||
|
v6.4.0 stable, so Crash can use "va_kernel_pa_offset" to translate the
|
||
|
kernel virtual address in VTOP() correctly.
|
||
|
|
||
|
Signed-off-by: Song Shuai <suagrfillet@gmail.com>
|
||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||
|
---
|
||
|
defs.h | 4 ++--
|
||
|
riscv64.c | 23 +++++++++++++++++++++++
|
||
|
2 files changed, 25 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/defs.h b/defs.h
|
||
|
index f784d40c0b17..4883f889f169 100644
|
||
|
--- a/defs.h
|
||
|
+++ b/defs.h
|
||
|
@@ -3663,8 +3663,7 @@ typedef signed int s32;
|
||
|
ulong _X = X; \
|
||
|
(THIS_KERNEL_VERSION >= LINUX(5,13,0) && \
|
||
|
(_X) >= machdep->machspec->kernel_link_addr) ? \
|
||
|
- (((unsigned long)(_X)-(machdep->machspec->kernel_link_addr)) + \
|
||
|
- machdep->machspec->phys_base): \
|
||
|
+ ((unsigned long)(_X)-(machdep->machspec->va_kernel_pa_offset)): \
|
||
|
(((unsigned long)(_X)-(machdep->kvbase)) + \
|
||
|
machdep->machspec->phys_base); \
|
||
|
})
|
||
|
@@ -7022,6 +7021,7 @@ struct machine_specific {
|
||
|
ulong modules_vaddr;
|
||
|
ulong modules_end;
|
||
|
ulong kernel_link_addr;
|
||
|
+ ulong va_kernel_pa_offset;
|
||
|
|
||
|
ulong _page_present;
|
||
|
ulong _page_read;
|
||
|
diff --git a/riscv64.c b/riscv64.c
|
||
|
index 6b9a68840d4c..7b5dd3db7f91 100644
|
||
|
--- a/riscv64.c
|
||
|
+++ b/riscv64.c
|
||
|
@@ -418,6 +418,28 @@ error:
|
||
|
error(FATAL, "cannot get vm layout\n");
|
||
|
}
|
||
|
|
||
|
+static void
|
||
|
+riscv64_get_va_kernel_pa_offset(struct machine_specific *ms)
|
||
|
+{
|
||
|
+ unsigned long kernel_version = riscv64_get_kernel_version();
|
||
|
+
|
||
|
+ /*
|
||
|
+ * Since Linux v6.4 phys_base is not the physical start of the kernel,
|
||
|
+ * trying to use "va_kernel_pa_offset" to determine the offset between
|
||
|
+ * kernel virtual and physical addresses.
|
||
|
+ */
|
||
|
+ if (kernel_version >= LINUX(6,4,0)) {
|
||
|
+ char *string;
|
||
|
+ if ((string = pc->read_vmcoreinfo("NUMBER(va_kernel_pa_offset)"))) {
|
||
|
+ ms->va_kernel_pa_offset = htol(string, QUIET, NULL);
|
||
|
+ free(string);
|
||
|
+ } else
|
||
|
+ error(FATAL, "cannot read va_kernel_pa_offset\n");
|
||
|
+ }
|
||
|
+ else
|
||
|
+ ms->va_kernel_pa_offset = ms->kernel_link_addr - ms->phys_base;
|
||
|
+}
|
||
|
+
|
||
|
static int
|
||
|
riscv64_is_kvaddr(ulong vaddr)
|
||
|
{
|
||
|
@@ -1352,6 +1374,7 @@ riscv64_init(int when)
|
||
|
riscv64_get_struct_page_size(machdep->machspec);
|
||
|
riscv64_get_va_bits(machdep->machspec);
|
||
|
riscv64_get_va_range(machdep->machspec);
|
||
|
+ riscv64_get_va_kernel_pa_offset(machdep->machspec);
|
||
|
|
||
|
pt_level_alloc(&machdep->pgd, "cannot malloc pgd space.");
|
||
|
pt_level_alloc(&machdep->machspec->p4d, "cannot malloc p4d space.");
|
||
|
--
|
||
|
2.37.1
|
||
|
|