On Tue, Aug 15, 2023 at 10:40 AM Song Shuai <suagrfillet@gmail.com> wrote:

在 2023/8/14 16:27, lijiang 写道:
>     +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)) {
>
> Is it possible to detect the existence of the symbol
> 'linear_mapping_va_to_pa' or 'linear_mapping_pa_to_va' to decide reading
> the value of 'va_kernel_pa_offset'? For example:
> kernel_symbol_exists()/symbol_exists()
>
> if (kernel_symbol_exists("linear_mapping_va_to_pa") ||
> kernel_symbol_exists("linear_mapping_pa_to_va")) {
>      string = pc->read_vmcoreinfo("NUMBER(va_kernel_pa_offset)");
>      ...
> }

The `linear_mapping_va_to_pa` and `linear_mapping_pa_to_va` symbols will
only be exported when the debug option -- CONFIG_DEBUG_VIRTUAL is
enabled, otherwise they will expanded as macros. As the kernel Makefile

That is really problematic. If so, I tend to read the vmcoreinfo directly as below. I haven't tested it , just an idea.

string = pc->read_vmcoreinfo("NUMBER(va_kernel_pa_offset)");
if (string) {
    ms->va_kernel_pa_offset = htol(string, QUIET, NULL);
    free(string);
    if (CRASHDEBUG(1))
        fprintf(fp, "NUMBER(va_kernel_pa_offset): %lx\n", ms->va_kernel_pa_offset);
} else
    ms->va_kernel_pa_offset = ms->kernel_link_addr - ms->phys_base;

But that depends on how you and Kazu think about it.
 

says:

obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o

Actually, it's hard to extract some explicit infomation from the commit
3335068f8721 and use them as the first `if` condition, so the kernel
version checking was the final choice.

 
The kernel version checking is not very good, although it has some similar code in crash-utility. Once the related kernel code is backported to the old kernel(such as a stable branch), crash won't work well on these vmcore. As you mentioned, the kernel version checking is the last resort if there is no better way.

Thanks.
Lianbo
 
>
> I saw the commit 3335068f8721 exported two symbols:
>
> +phys_addr_t linear_mapping_va_to_pa(unsigned long x)
> +{
> +       BUG_ON(!kernel_map.va_pa_offset);
> +
> +       return ((unsigned long)(x) - kernel_map.va_pa_offset);
> +}
> +EXPORT_SYMBOL(linear_mapping_va_to_pa);
> +
> +void *linear_mapping_pa_to_va(unsigned long x)
> +{
> +       BUG_ON(!kernel_map.va_pa_offset);
> +
> +       return ((void *)((unsigned long)(x) + kernel_map.va_pa_offset));
> +}
> +EXPORT_SYMBOL(linear_mapping_pa_to_va);