[Crash-utility] [PATCH v6] arm64: update the modules/vmalloc/vmemmap ranges

lijiang lijiang at redhat.com
Fri Mar 11 03:28:13 UTC 2022


Hi, ShiJie
Sorry for the late reply.

On Fri, Mar 4, 2022 at 3:21 PM <crash-utility-request at redhat.com> wrote:

> Date: Fri,  4 Mar 2022 15:16:30 +0000
> From: Huang Shijie <shijie at os.amperecomputing.com>
> To: k-hagio-ab at nec.com
> Cc: lijiang at redhat.com, zwang at amperecomputing.com,
>         darren at os.amperecomputing.com, patches at amperecomputing.com,
>         crash-utility at redhat.com
> Subject: [Crash-utility] [PATCH v6] arm64: update the
>         modules/vmalloc/vmemmap ranges
> Message-ID: <20220304151630.2364339-1-shijie at os.amperecomputing.com>
> Content-Type: text/plain
>
> < 1 > The background.
>     The current crash code is still based at kernel v4.20, but the kernel
> is v5.17-rc4(now).
>     The MODULE/VMALLOC/VMEMMAP ranges are not be updated since v4.20.
>
>     I list all the changes from kernel v4.20 to v5.17:
>
>     1.) The current crash code is based at kernel v4.20.
>         The virtual memory layout looks like this:
>
> +--------------------------------------------------------------------+
>         |    KASAN     |   MODULE   |   VMALLOC   | .... |     VMEMMAP
>    |
>
> +--------------------------------------------------------------------+
>
>         The macros are:
>         #define MODULES_VADDR   (VA_START + KASAN_SHADOW_SIZE)
>         #define MODULES_END     (MODULES_VADDR + MODULES_VSIZE)
>
>         #define VMALLOC_START   (MODULES_END)
>         #define VMALLOC_END     (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE -
> SZ_64K)
>
>         #define VMEMMAP_START   (PAGE_OFFSET - VMEMMAP_SIZE)
>
>     2.) In the kernel v5.0, the patch will add a new BFP JIT region:
>        "91fc957c9b1d arm64/bpf: don't allocate BPF JIT programs in module
> memory"
>
>         The virtual memory layout looks like this:
>
> +--------------------------------------------------------------------+
>         | KASAN | BPF_JIT | MODULE | VMALLOC |     ....     | VMEMMAP
>   |
>
> +--------------------------------------------------------------------+
>
>         The macros are:
>         #define MODULES_VADDR   (BPF_JIT_REGION_END)
>         #define MODULES_END     (MODULES_VADDR + MODULES_VSIZE)
>
>         #define VMALLOC_START   (MODULES_END)
>         #define VMALLOC_END     (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE -
> SZ_64K)
>
>         #define VMEMMAP_START   (PAGE_OFFSET - VMEMMAP_SIZE)
>
>         The layout does not changed until v5.4.
>
>     3.) In the kernel v5.4, several patches changes the layout, such as:
>        "ce3aaed87344 arm64: mm: Modify calculation of VMEMMAP_SIZE"
>        "14c127c957c1 arm64: mm: Flip kernel VA space"
>        and the virtual memory layout looks like this:
>
>
> +--------------------------------------------------------------------+
>       | KASAN | BPF_JIT | MODULE | VMALLOC |     ....     | VMEMMAP
> |
>
> +--------------------------------------------------------------------+
>
>       The macros are:
>       #define MODULES_VADDR     (BPF_JIT_REGION_END)
>       #define MODULES_END       (MODULES_VADDR + MODULES_VSIZE)
>
>       #define VMALLOC_START     (MODULES_END)
>       #define VMALLOC_END       (- PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
>
>       #define VMEMMAP_START     (-VMEMMAP_SIZE - SZ_2M)
>
>       In the v5.7, the patch:
>            "bbd6ec605c arm64/mm: Enable memory hot remove"
>       adds the VMEMMAP_END.
>
>     4.) In the kernel v5.11, several patches changes the layout, such as:
>        "9ad7c6d5e75b arm64: mm: tidy up top of kernel VA space"
>        "f4693c2716b3 arm64: mm: extend linear region for 52-bit VA
> configurations"
>       and the virtual memory layout looks like this:
>
>
> +--------------------------------------------------------------------+
>       |   BPF_JIT | MODULE  |  VMALLOC   |    ....    |     VMEMMAP
> |
>
> +--------------------------------------------------------------------+
>
>       The macros are:
>       #define MODULES_VADDR     (BPF_JIT_REGION_END)
>       #define MODULES_END       (MODULES_VADDR + MODULES_VSIZE)
>
>       #define VMALLOC_START     (MODULES_END)
>       #define VMALLOC_END       (VMEMMAP_START - SZ_256M)
>
>       #define VMEMMAP_START     (-(UL(1) << (VA_BITS - VMEMMAP_SHIFT)))
>       #define VMEMMAP_END       (VMEMMAP_START + VMEMMAP_SIZE)
>
>     5.) In the kernel v5.17-rc1, after the patch
>       "b89ddf4cca43 arm64/bpf: Remove 128MB limit for BPF JIT programs"
>       the virtual memory layout looks like this:
>
>
> +--------------------------------------------------------------------+
>       |      MODULE     |   VMALLOC   |     ....     |      VMEMMAP
> |
>
> +--------------------------------------------------------------------+
>
>       The macros are:
>       #define MODULES_VADDR     (_PAGE_END(VA_BITS_MIN))
>       #define MODULES_END       (MODULES_VADDR + MODULES_VSIZE)
>
>       #define VMALLOC_START     (MODULES_END)
>       #define VMALLOC_END       (VMEMMAP_START - SZ_256M)
>
>       #define VMEMMAP_START     (-(UL(1) << (VA_BITS - VMEMMAP_SHIFT)))
>       #define VMEMMAP_END       (VMEMMAP_START + VMEMMAP_SIZE)
>
> < 2 > What does this patch do?
>     1.) Use arm64_get_struct_page_size() to get the size of struct page{}
> in the PRE_GDB.
>
>     2.) If we can succeed in above step, we will try to call
> arm64_get_va_range() to
>         get the proper kernel virtual ranges.
>
>         In the arm64_get_va_range(), we calculate the ranges by the hooks
> of
>         different kernel versions:
>                 get_range: arm64_get_range_v5_17,
>                 get_range: arm64_get_range_v5_11,
>                 get_range: arm64_get_range_v5_4,
>                 get_range: arm64_get_range_v5_0,
>
>     3.) If we can succeed in above steps, the
> arm64_calc_virtual_memory_ranges()
>         will be ignored. If we failed in above steps, the
> arm64_calc_virtual_memory_ranges()
>         will continue to do its work.
>
> < 3 > Test this patch.
>         Tested this patch with a vmcore produced by a 5.4.119 kernel panic.
>         (The CONFIG_KASAN is NOT set for this kernel.)
>
>         Before this patch, we get the wrong output from "help -m":
>           ----------------------------------------------------------
>           vmalloc_start_addr: ffff800048000000
>            vmalloc_end: fffffdffbffeffff
>          modules_vaddr: ffff800040000000
>            modules_end: ffff800047ffffff
>          vmemmap_vaddr: fffffdffffe00000
>            vmemmap_end: ffffffffffffffff
>           ----------------------------------------------------------
>
>         After this patch, we can get the correct output from "help -m":
>          ----------------------------------------------------------
>            vmalloc_start_addr: ffff800010000000
>            vmalloc_end: fffffdffbffeffff
>          modules_vaddr: ffff800008000000
>            modules_end: ffff80000fffffff
>          vmemmap_vaddr: fffffdffffe00000
>            vmemmap_end: ffffffffffffffff
>         ----------------------------------------------------------
>
> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
> ---
> v5 --> v6:
>         1.)
>         Find a bug in the v5:
>          We need to minus 1 for Crash's
> modules_end/vmalloc_end/vmemmap_end.
>
>         2.) Change version limit to LINUX(99, 0, 0)
>         3.) Tested it again.
>
> v4 --> v5:
>         1.) Reset ms->struct_page_size to 0 if arm64_get_va_range() fails,
>             so arm64_calc_virtual_memory_ranges() can continue its work.
>
>         2.) Tested again with the new code.
>
> v3 --> v4:
>         1.) Add struct_page_size to @ms.
>             Change some functions, such as arm64_init() and
> arm64_get_struct_page_size().
>             (Do not use the ASSIGN_SIZE, use the ms->struct_page_size
> instead.)
>
>         2.) Tested again with the new code.
>
> v2 --> v3:
>         Fount two bugs in arm64_get_range_v5_17/arm64_get_range_v5_11:
>         We should use the ms->CONFIG_ARM64_VA_BITS to calculate the
>         vmemmep_vaddr, not use the ms->VA_BITS.
>
> v1 --> v2:
>         The Crash code is based on v4.20 not v4.9.
>         Changed the commit message about it.
> ---
>  arm64.c | 379 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  defs.h  |   1 +
>  2 files changed, 369 insertions(+), 11 deletions(-)
>
> diff --git a/arm64.c b/arm64.c
> index 3ab8489..841016c 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -92,6 +92,14 @@ static void arm64_calc_VA_BITS(void);
>  static int arm64_is_uvaddr(ulong, struct task_context *);
>  static void arm64_calc_KERNELPACMASK(void);
>
> +struct kernel_range {
> +       unsigned long modules_vaddr, modules_end;
> +       unsigned long vmalloc_start_addr, vmalloc_end;
> +       unsigned long vmemmap_vaddr, vmemmap_end;
> +};
> +static struct kernel_range *arm64_get_va_range(struct machine_specific
> *ms);
> +static void arm64_get_struct_page_size(struct machine_specific *ms);
> +
>  static void arm64_calc_kernel_start(void)
>  {
>         struct machine_specific *ms = machdep->machspec;
> @@ -233,9 +241,10 @@ arm64_init(int when)
>                 machdep->pageoffset = machdep->pagesize - 1;
>                 machdep->pagemask = ~((ulonglong)machdep->pageoffset);
>
> +               ms = machdep->machspec;
> +               arm64_get_struct_page_size(ms);
>                 arm64_calc_VA_BITS();
>                 arm64_calc_KERNELPACMASK();
> -               ms = machdep->machspec;
>
>                 /* vabits_actual introduced after mm flip, so it should be
> flipped layout */
>                 if (ms->VA_BITS_ACTUAL) {
> @@ -252,8 +261,15 @@ arm64_init(int when)
>                 }
>                 machdep->is_kvaddr = generic_is_kvaddr;
>                 machdep->kvtop = arm64_kvtop;
> +
> +               /* The defaults */
> +               ms->vmalloc_end = ARM64_VMALLOC_END;
> +               ms->vmemmap_vaddr = ARM64_VMEMMAP_VADDR;
> +               ms->vmemmap_end = ARM64_VMEMMAP_END;
> +
>                 if (machdep->flags & NEW_VMEMMAP) {
>                         struct syment *sp;
> +                       struct kernel_range *r;
>
>                         /* It is finally decided in
> arm64_calc_kernel_start() */
>                         sp = kernel_symbol_search("_text");
> @@ -261,27 +277,36 @@ arm64_init(int when)
>                         sp = kernel_symbol_search("_end");
>                         ms->kimage_end = (sp ? sp->value : 0);
>
> -                       if (ms->VA_BITS_ACTUAL) {
> +                       if (ms->struct_page_size && (r =
> arm64_get_va_range(ms))) {
> +                               /* We can get all the
> MODULES/VMALLOC/VMEMMAP ranges now.*/
> +                               ms->modules_vaddr       = r->modules_vaddr;
> +                               ms->modules_end         = r->modules_end -
> 1;
> +                               ms->vmalloc_start_addr  =
> r->vmalloc_start_addr;
> +                               ms->vmalloc_end         = r->vmalloc_end -
> 1;
> +                               ms->vmemmap_vaddr       = r->vmemmap_vaddr;
> +                               if (THIS_KERNEL_VERSION >= LINUX(5, 7, 0))
> +                                       ms->vmemmap_end         =
> r->vmemmap_end - 1;
> +                               else
> +                                       ms->vmemmap_end         = -1;
> +
> +                       } else if (ms->VA_BITS_ACTUAL) {
>                                 ms->modules_vaddr = (st->_stext_vmlinux &
> TEXT_OFFSET_MASK) - ARM64_MODULES_VSIZE;
>                                 ms->modules_end = ms->modules_vaddr +
> ARM64_MODULES_VSIZE -1;
> +                               ms->vmalloc_start_addr = ms->modules_end +
> 1;
>                         } else {
>                                 ms->modules_vaddr = ARM64_VA_START;
>                                 if (kernel_symbol_exists("kasan_init"))
>                                         ms->modules_vaddr +=
> ARM64_KASAN_SHADOW_SIZE;
>                                 ms->modules_end = ms->modules_vaddr +
> ARM64_MODULES_VSIZE -1;
> +                               ms->vmalloc_start_addr = ms->modules_end +
> 1;
>                         }
>
> -                       ms->vmalloc_start_addr = ms->modules_end + 1;
> -
>                         arm64_calc_kimage_voffset();
>                 } else {
>                         ms->modules_vaddr = ARM64_PAGE_OFFSET -
> MEGABYTES(64);
>                         ms->modules_end = ARM64_PAGE_OFFSET - 1;
>                         ms->vmalloc_start_addr = ARM64_VA_START;
>                 }
> -               ms->vmalloc_end = ARM64_VMALLOC_END;
> -               ms->vmemmap_vaddr = ARM64_VMEMMAP_VADDR;
> -               ms->vmemmap_end = ARM64_VMEMMAP_END;
>
>                 switch (machdep->pagesize)
>                 {
> @@ -404,7 +429,12 @@ arm64_init(int when)
>         case POST_GDB:
>                 /* Rely on kernel version to decide the kernel start
> address */
>                 arm64_calc_kernel_start();
> -               arm64_calc_virtual_memory_ranges();
> +
> +               /*  Can we get the size of struct page before POST_GDB */
> +               ms = machdep->machspec;
> +               if (!ms->struct_page_size)
> +                       arm64_calc_virtual_memory_ranges();
> +
>                 arm64_get_section_size_bits();
>
>                 if (!machdep->max_physmem_bits) {
> @@ -419,8 +449,6 @@ arm64_init(int when)
>                                 machdep->max_physmem_bits =
> _MAX_PHYSMEM_BITS;
>                 }
>
> -               ms = machdep->machspec;
> -
>                 if (CRASHDEBUG(1)) {
>                         if (ms->VA_BITS_ACTUAL) {
>                                 fprintf(fp, "CONFIG_ARM64_VA_BITS: %ld\n",
> ms->CONFIG_ARM64_VA_BITS);
> @@ -511,6 +539,336 @@ arm64_init(int when)
>         }
>  }
>
> +struct kernel_va_range_handler {
> +       unsigned long kernel_versions_start; /* include */
> +       unsigned long kernel_versions_end;   /* exclude */
> +       struct kernel_range *(*get_range)(struct machine_specific *);
> +};
> +
> +static struct kernel_range tmp_range;
> +#define _PAGE_END(va)          (-(1UL << ((va) - 1)))
> +#define SZ_64K                          0x00010000
> +#define SZ_2M                          0x00200000
> +
> +/*
> + * Get the max shift of the size of struct page.
> + * Most of the time, it is 64 bytes, but not sure.
> + */
> +static int arm64_get_struct_page_max_shift(struct machine_specific *ms)
> +{
> +       unsigned long v = ms->struct_page_size;
> +
> +       if (16 < v && v <= 32)
> +               return 5;
> +       if (32 < v && v <= 64)
> +               return 6;
> +       if (64 < v && v <= 128)
> +               return 7;
> +
> +       error(FATAL, "We should not have such struct page size:%d!\n", v);
> +       return 0;
> +}
>

If I understand the above function correctly, can it be replaced
by ceil(log2(v))? That can keep it consistent with the kernel. But the
weakness is to include the header math.h in arm64.c. Do you have any
specific concerns about this?
For example:
return ceil(log2(v));

+
> +/*
> + *  The change is caused by the kernel patch since v5.17-rc1:
> + *    "b89ddf4cca43 arm64/bpf: Remove 128MB limit for BPF JIT programs"
> + */
> +static struct kernel_range *arm64_get_range_v5_17(struct machine_specific
> *ms)
> +{
> +       struct kernel_range *r = &tmp_range;
> +       unsigned long v = ms->CONFIG_ARM64_VA_BITS;
> +       unsigned long vmem_shift, vmemmap_size;
> +
> +       /* Not initialized yet */
> +       if (v == 0)
> +               return NULL;
> +
> +       if (v > 48)
> +               v = 48;
> +
> +       /* Get the MODULES_VADDR ~ MODULES_END */
> +       r->modules_vaddr = _PAGE_END(v);
> +       r->modules_end = r->modules_vaddr + MEGABYTES(128);
> +
> +       /* Get the VMEMMAP_START ~ VMEMMAP_END */
> +       vmem_shift = machdep->pageshift -
> arm64_get_struct_page_max_shift(ms);
> +       vmemmap_size = (_PAGE_END(v) - PAGE_OFFSET) >> vmem_shift;
> +
> +       r->vmemmap_vaddr = (-(1UL << (ms->CONFIG_ARM64_VA_BITS -
> vmem_shift)));
> +       r->vmemmap_end = r->vmemmap_vaddr + vmemmap_size;
> +
> +       /* Get the VMALLOC_START ~ VMALLOC_END */
> +       r->vmalloc_start_addr = r->modules_end;
> +       r->vmalloc_end = r->vmemmap_vaddr - MEGABYTES(256);
> +       return r;
> +}
> +
> +/*
> + *  The change is caused by the kernel patch since v5.11:
> + *    "9ad7c6d5e75b arm64: mm: tidy up top of kernel VA space"
> + */
> +static struct kernel_range *arm64_get_range_v5_11(struct machine_specific
> *ms)
> +{
> +       struct kernel_range *r = &tmp_range;
> +       unsigned long v = ms->CONFIG_ARM64_VA_BITS;
> +       unsigned long vmem_shift, vmemmap_size, bpf_jit_size =
> MEGABYTES(128);
> +
> +       /* Not initialized yet */
> +       if (v == 0)
> +               return NULL;
> +
> +       if (v > 48)
> +               v = 48;
> +
> +       /* Get the MODULES_VADDR ~ MODULES_END */
> +       r->modules_vaddr = _PAGE_END(v) + bpf_jit_size;
> +       r->modules_end = r->modules_vaddr + MEGABYTES(128);
> +
> +       /* Get the VMEMMAP_START ~ VMEMMAP_END */
> +       vmem_shift = machdep->pageshift -
> arm64_get_struct_page_max_shift(ms);
> +       vmemmap_size = (_PAGE_END(v) - PAGE_OFFSET) >> vmem_shift;
> +
> +       r->vmemmap_vaddr = (-(1UL << (ms->CONFIG_ARM64_VA_BITS -
> vmem_shift)));
> +       r->vmemmap_end = r->vmemmap_vaddr + vmemmap_size;
> +
> +       /* Get the VMALLOC_START ~ VMALLOC_END */
> +       r->vmalloc_start_addr = r->modules_end;
> +       r->vmalloc_end = r->vmemmap_vaddr - MEGABYTES(256);
> +       return r;
> +}
> +
> +static unsigned long arm64_get_pud_size(void)
> +{
> +       unsigned long PUD_SIZE = 0;
> +
> +       switch (machdep->pagesize) {
> +       case 4096:
> +               if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L4_4K) {
> +                       PUD_SIZE = PUD_SIZE_L4_4K;
> +               } else {
> +                       PUD_SIZE = PGDIR_SIZE_L3_4K;
> +               }
> +               break;
> +
> +       case 65536:
> +               PUD_SIZE = PGDIR_SIZE_L2_64K;
> +       default:
> +               break;
> +       }
> +       return PUD_SIZE;
> +}
> +
> +/*
> + *  The change is caused by the kernel patches since v5.4, such as:
> + *     "ce3aaed87344 arm64: mm: Modify calculation of VMEMMAP_SIZE"
> + *     "14c127c957c1 arm64: mm: Flip kernel VA space"
> + */
> +static struct kernel_range *arm64_get_range_v5_4(struct machine_specific
> *ms)
> +{
> +       struct kernel_range *r = &tmp_range;
> +       unsigned long v = ms->CONFIG_ARM64_VA_BITS;
> +       unsigned long kasan_shadow_shift, kasan_shadow_offset, PUD_SIZE;
> +       unsigned long vmem_shift, vmemmap_size, bpf_jit_size =
> MEGABYTES(128);
> +       char *string;
> +       int ret;
> +
> +       /* Not initialized yet */
> +       if (v == 0)
> +               return NULL;
> +
> +       if (v > 48)
> +               v = 48;
> +
> +       /* Get the MODULES_VADDR ~ MODULES_END */
> +       if (kernel_symbol_exists("kasan_init")) {
> +               /* See the arch/arm64/Makefile */
> +               ret = get_kernel_config("CONFIG_KASAN_SW_TAGS", NULL);
> +               if (ret == IKCONFIG_N)
> +                       return NULL;
> +               kasan_shadow_shift = (ret == IKCONFIG_Y) ? 4: 3;
> +
> +               /* See the arch/arm64/Kconfig*/
> +               ret = get_kernel_config("CONFIG_KASAN_SHADOW_OFFSET",
> &string);
> +               if (ret != IKCONFIG_STR)
> +                       return NULL;
> +               kasan_shadow_offset = atol(string);
> +
> +               r->modules_vaddr = (1UL << (64 - kasan_shadow_shift)) +
> kasan_shadow_offset
> +                               + bpf_jit_size;
> +       } else {
> +               r->modules_vaddr = _PAGE_END(v) + bpf_jit_size;
> +       }
> +
> +       r->modules_end = r->modules_vaddr + MEGABYTES(128);
> +
> +       /* Get the VMEMMAP_START ~ VMEMMAP_END */
> +       vmem_shift = machdep->pageshift -
> arm64_get_struct_page_max_shift(ms);
> +       vmemmap_size = (_PAGE_END(v) - PAGE_OFFSET) >> vmem_shift;
> +
> +       r->vmemmap_vaddr = (-vmemmap_size - SZ_2M);
> +       if (THIS_KERNEL_VERSION >= LINUX(5, 7, 0)) {
> +               /*
> +                *  In the v5.7, the patch: "bbd6ec605c arm64/mm: Enable
> memory hot remove"
> +                *      adds the VMEMMAP_END.
> +                */
> +               r->vmemmap_end = r->vmemmap_vaddr + vmemmap_size;
> +       } else {
> +               r->vmemmap_end = 0xffffffffffffffffUL;
> +       }
> +
> +       /* Get the VMALLOC_START ~ VMALLOC_END */
> +       PUD_SIZE = arm64_get_pud_size();
> +       r->vmalloc_start_addr = r->modules_end;
> +       r->vmalloc_end = (-PUD_SIZE - vmemmap_size - SZ_64K);
> +       return r;
> +}
> +
> +/*
> + *  The change is caused by the kernel patches since v5.0, such as:
> + *    "91fc957c9b1d arm64/bpf: don't allocate BPF JIT programs in module
> memory"
> + */
> +static struct kernel_range *arm64_get_range_v5_0(struct machine_specific
> *ms)
> +{
> +       struct kernel_range *r = &tmp_range;
> +       unsigned long v = ms->CONFIG_ARM64_VA_BITS;
> +       unsigned long kasan_shadow_shift, PUD_SIZE;
> +       unsigned long vmemmap_size, bpf_jit_size = MEGABYTES(128);
> +       unsigned long va_start, page_offset;
> +       int ret;
> +
> +       /* Not initialized yet */
> +       if (v == 0)
> +               return NULL;
> +
> +       va_start = (0xffffffffffffffffUL - (1UL << v) + 1);
> +       page_offset = (0xffffffffffffffffUL - (1UL << (v - 1)) + 1);
> +
> +       /* Get the MODULES_VADDR ~ MODULES_END */
> +       if (kernel_symbol_exists("kasan_init")) {
> +               /* See the arch/arm64/Makefile */
> +               ret = get_kernel_config("CONFIG_KASAN_SW_TAGS", NULL);
> +               if (ret == IKCONFIG_N)
> +                       return NULL;
> +               kasan_shadow_shift = (ret == IKCONFIG_Y) ? 4: 3;
> +
> +               r->modules_vaddr = va_start + (1UL << (v -
> kasan_shadow_shift)) + bpf_jit_size;
> +       } else {
> +               r->modules_vaddr = va_start  + bpf_jit_size;
> +       }
> +
> +       r->modules_end = r->modules_vaddr + MEGABYTES(128);
> +
> +       /* Get the VMEMMAP_START ~ VMEMMAP_END */
> +       vmemmap_size = (1UL << (v - machdep->pageshift - 1 +
> arm64_get_struct_page_max_shift(ms)));
> +
> +       r->vmemmap_vaddr = page_offset - vmemmap_size;
> +       r->vmemmap_end = 0xffffffffffffffffUL;  /* this kernel does not
> have VMEMMAP_END */
> +
> +       /* Get the VMALLOC_START ~ VMALLOC_END */
> +       PUD_SIZE = arm64_get_pud_size();
> +
> +       r->vmalloc_start_addr = r->modules_end;
> +       r->vmalloc_end = page_offset - PUD_SIZE - vmemmap_size - SZ_64K;
> +       return r;
> +}
> +
> +static struct kernel_va_range_handler kernel_va_range_handlers[] = {
> +       {
> +               LINUX(5,17,0),
> +               LINUX(99,0,0), /* Just a boundary, Change it later */
> +               get_range: arm64_get_range_v5_17,
> +       }, {
> +               LINUX(5,11,0), LINUX(5,17,0),
> +               get_range: arm64_get_range_v5_11,
> +       }, {
> +               LINUX(5,4,0), LINUX(5,11,0),
> +               get_range: arm64_get_range_v5_4,
> +       }, {
> +               LINUX(5,0,0), LINUX(5,4,0),
> +               get_range: arm64_get_range_v5_0,
> +       },
> +};
> +
> +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
> +
> +static unsigned long arm64_get_kernel_version(void)
> +{
> +       char *string;
> +       char buf[BUFSIZE];
> +       char *p1, *p2;
> +
> +       if (THIS_KERNEL_VERSION)
> +               return THIS_KERNEL_VERSION;
> +
> +       string = pc->read_vmcoreinfo("OSRELEASE");
> +       if (string) {
> +               strcpy(buf, string);
> +
> +               p1 = p2 = buf;
> +               while (*p2 != '.')
> +                       p2++;
> +               *p2 = NULLCHAR;
> +               kt->kernel_version[0] = atoi(p1);
> +
> +               p1 = ++p2;
> +               while (*p2 != '.')
> +                       p2++;
> +               *p2 = NULLCHAR;
> +               kt->kernel_version[1] = atoi(p1);
> +
> +               p1 = ++p2;
> +               while ((*p2 >= '0') && (*p2 <= '9'))
> +                       p2++;
> +               *p2 = NULLCHAR;
> +               kt->kernel_version[2] = atoi(p1);
> +       }
> +       free(string);
> +       return THIS_KERNEL_VERSION;
> +}
> +
> +/* Return NULL if we fail. */
> +static struct kernel_range *arm64_get_va_range(struct machine_specific
> *ms)
> +{
> +       struct kernel_va_range_handler *h;
> +       unsigned long kernel_version = arm64_get_kernel_version();
> +       struct kernel_range *r = NULL;
> +       int i;
> +
> +       if (!kernel_version)
> +               goto range_failed;
> +
> +       for (i = 0; i < ARRAY_SIZE(kernel_va_range_handlers); i++) {
> +               h = kernel_va_range_handlers + i;
> +
> +               /* Get the right hook for this kernel version */
> +               if (h->kernel_versions_start <= kernel_version &&
> +                       kernel_version < h->kernel_versions_end) {
> +
> +                       /* Get the correct virtual address ranges */
> +                       r = h->get_range(ms);
> +                       if (!r)
> +                               goto range_failed;
> +                       return r;
> +               }
> +       }
> +
> +range_failed:
> +       /* Reset ms->struct_page_size to 0 for
> arm64_calc_virtual_memory_ranges() */
> +       ms->struct_page_size = 0;
> +       return NULL;
> +}
> +
> +/* Get the size of struct page {} */
> +static void arm64_get_struct_page_size(struct machine_specific *ms)
> +{
> +       char *string;
> +
> +       string = pc->read_vmcoreinfo("SIZE(page)");
> +       if (string)
> +               ms->struct_page_size = atol(string);
> +       free(string);
> +}
> +
>  /*
>   * Accept or reject a symbol from the kernel namelist.
>   */
> @@ -4272,7 +4630,6 @@ arm64_calc_VA_BITS(void)
>  #define ALIGN(x, a) __ALIGN_KERNEL((x), (a))
>  #define __ALIGN_KERNEL(x, a)            __ALIGN_KERNEL_MASK(x,
> (typeof(x))(a) - 1)
>  #define __ALIGN_KERNEL_MASK(x, mask)    (((x) + (mask)) & ~(mask))
> -#define SZ_64K                          0x00010000
>
>  static void
>  arm64_calc_virtual_memory_ranges(void)
> diff --git a/defs.h b/defs.h
> index bf2c59b..81ac049 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -3386,6 +3386,7 @@ struct machine_specific {
>         ulong VA_START;
>         ulong CONFIG_ARM64_KERNELPACMASK;
>         ulong physvirt_offset;
> +       ulong struct_page_size;
>  };
>

Can you add this one to the arm64_dump_machdep_table()?

Thanks.
Lianbo

 struct arm64_stackframe {
> --
> 2.30.2
>
>
>
>
> ------------------------------
>
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://listman.redhat.com/mailman/listinfo/crash-utility
>
> End of Crash-utility Digest, Vol 198, Issue 7
> *********************************************
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/crash-utility/attachments/20220311/f36b2f11/attachment-0001.htm>


More information about the Crash-utility mailing list