Register an architecture-specific get_kvaddr_ranges callback so that
the search command can properly enumerate all kernel virtual address
regions including modules and vmemmap.
Without this callback, riscv64 falls back to generic_get_kvaddr_ranges()
which only knows about KVADDR_UNITY_MAP and KVADDR_VMALLOC, missing
the modules and vmemmap regions. While the generic VMALLOC range covers
these addresses (its end is -1), the type information is lost, making
it impossible for consumers to distinguish between different kernel
address space regions.
Signed-off-by: Rui Qi <qirui.001(a)bytedance.com>
---
riscv64.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/riscv64.c b/riscv64.c
index 02210267862f..4dcecc2f6b2c 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -62,6 +62,7 @@ static void riscv64_set_process_stack(struct bt_info *);
static void riscv64_set_irq_stack(struct bt_info *);
static int riscv64_on_overflow_stack(int, ulong);
static void riscv64_set_overflow_stack(struct bt_info *);
+static int riscv64_get_kvaddr_ranges(struct vaddr_range *);
#define REG_FMT "%016lx"
#define SZ_2G 0x80000000
@@ -1757,6 +1758,7 @@ riscv64_init(int when)
if (machdep->machspec->vmemmap_vaddr)
machdep->flags |= VMEMMAP;
+ machdep->get_kvaddr_ranges = riscv64_get_kvaddr_ranges;
break;
case POST_GDB:
@@ -2018,6 +2020,52 @@ riscv64_eframe_search(struct bt_info *bt)
return count;
}
+static int
+compare_kvaddr(const void *v1, const void *v2)
+{
+ struct vaddr_range *r1, *r2;
+
+ r1 = (struct vaddr_range *)v1;
+ r2 = (struct vaddr_range *)v2;
+
+ return (r1->start < r2->start ? -1 :
+ r1->start == r2->start ? 0 : 1);
+}
+
+static int
+riscv64_get_kvaddr_ranges(struct vaddr_range *vrp)
+{
+ int cnt;
+
+ cnt = 0;
+
+ vrp[cnt].type = KVADDR_UNITY_MAP;
+ vrp[cnt].start = machdep->machspec->page_offset;
+ vrp[cnt++].end = vt->high_memory;
+
+ vrp[cnt].type = KVADDR_VMALLOC;
+ vrp[cnt].start = machdep->machspec->vmalloc_start_addr;
+ vrp[cnt++].end = last_vmalloc_address();
+
+ if (st->mods_installed) {
+ vrp[cnt].type = KVADDR_MODULES;
+ vrp[cnt].start = lowest_module_address();
+ vrp[cnt++].end = roundup(highest_module_address(),
+ PAGESIZE());
+ }
+
+ if (machdep->flags & VMEMMAP) {
+ vrp[cnt].type = KVADDR_VMEMMAP;
+ vrp[cnt].start = machdep->machspec->vmemmap_vaddr;
+ vrp[cnt++].end = vt->node_table[vt->numnodes-1].mem_map +
+ (vt->node_table[vt->numnodes-1].size * SIZE(page));
+ }
+
+ qsort(vrp, cnt, sizeof(struct vaddr_range), compare_kvaddr);
+
+ return cnt;
+}
+
#else /* !RISCV64 */
void
--
2.20.1