Skip to content

Commit

Permalink
arm64: fix the determination of vmemmap and struct_page_size
Browse files Browse the repository at this point in the history
Currently, the vmemmap ptr addr is determined by the vmcoreinfo of
"SYMBOL(vmemmap)", which leads to an invalid vmemmap addr showed by
"help -m" for dump files without the vmcoreinfo. The value of
vmemmap_end is simply set to -1 for available VA_BITS_ACTUAL case in
arm64_calc_virtual_memory_ranges(), and the struct_page_size value is 0.

  crash> help -m |grep vmem
           vmemmap_vaddr: fffffffeffe00000
             vmemmap_end: ffffffffffffffff
                 vmemmap: 0000000000000000
  crash> help -m |grep struct_page_size
        struct_page_size: 0

Introduce arm64_get_vmemmap_page_ptr() to fix the determination of
vmemmap ptr addr, and fix the determination of vmemmap_end and
struct_page_size in arm64_calc_virtual_memory_ranges().

  crash> help -m |grep vmem
           vmemmap_vaddr: fffffffeffe00000
             vmemmap_end: ffffffffffe00000
                 vmemmap: fffffffefee00000
  crash> help -m |grep struct_page_size
        struct_page_size: 64

Signed-off-by: qiwu.chen <[email protected]>
  • Loading branch information
qiwu.chen authored and lian-bo committed Aug 7, 2024
1 parent f615f8f commit 5cd1c6a
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ arm64_vmemmap_is_page_ptr(ulong addr, physaddr_t *phys)
ulong size = SIZE(page);
ulong pfn, nr;


if (IS_SPARSEMEM() && (machdep->flags & VMEMMAP) &&
(addr >= VMEMMAP_VADDR && addr <= VMEMMAP_END) &&
!((addr - VMEMMAP_VADDR) % size)) {
Expand All @@ -176,6 +175,25 @@ arm64_vmemmap_is_page_ptr(ulong addr, physaddr_t *phys)
return FALSE;
}

static void arm64_get_vmemmap_page_ptr(void)
{
struct machine_specific *ms = machdep->machspec;

/* If vmemmap exists, it means kernel enabled CONFIG_SPARSEMEM_VMEMMAP */
if (arm64_get_vmcoreinfo(&ms->vmemmap, "SYMBOL(vmemmap)", NUM_HEX))
goto out;

/* The global symbol of vmemmap is removed since kernel commit 7bc1a0f9e1765 */
if (kernel_symbol_exists("vmemmap"))
ms->vmemmap = symbol_value("vmemmap");
else
ms->vmemmap = ms->vmemmap_vaddr - ((ms->phys_offset >> machdep->pageshift) * ms->struct_page_size);

out:
if (ms->vmemmap)
machdep->is_page_ptr = arm64_vmemmap_is_page_ptr;
}

/*
* Do all necessary machine-specific setup here. This is called several times
* during initialization.
Expand Down Expand Up @@ -463,10 +481,6 @@ arm64_init(int when)

machdep->stacksize = ARM64_STACK_SIZE;
machdep->flags |= VMEMMAP;
/* If vmemmap exists, it means kernel enabled CONFIG_SPARSEMEM_VMEMMAP */
if (arm64_get_vmcoreinfo(&ms->vmemmap, "SYMBOL(vmemmap)", NUM_HEX))
machdep->is_page_ptr = arm64_vmemmap_is_page_ptr;

machdep->uvtop = arm64_uvtop;
machdep->is_uvaddr = arm64_is_uvaddr;
machdep->eframe_search = arm64_eframe_search;
Expand Down Expand Up @@ -518,6 +532,7 @@ arm64_init(int when)
if (!ms->struct_page_size)
arm64_calc_virtual_memory_ranges();

arm64_get_vmemmap_page_ptr();
arm64_get_section_size_bits();

if (!machdep->max_physmem_bits) {
Expand Down Expand Up @@ -4947,6 +4962,7 @@ arm64_calc_virtual_memory_ranges(void)
return;

STRUCT_SIZE_INIT(page, "page");
ms->struct_page_size = SIZE(page);

switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K))
{
Expand Down Expand Up @@ -4974,7 +4990,8 @@ arm64_calc_virtual_memory_ranges(void)
vmemmap_start = (-vmemmap_size - MEGABYTES(2));
ms->vmalloc_end = vmalloc_end - 1;
ms->vmemmap_vaddr = vmemmap_start;
ms->vmemmap_end = -1;
ms->vmemmap_end = vmemmap_start + vmemmap_size;

return;
}

Expand Down

0 comments on commit 5cd1c6a

Please sign in to comment.