-----Original Message----- > Hi Kazu, > On Tue, Mar 22, 2022 at 07:29:41AM +0000, HAGIO KAZUHITO(萩尾 一仁) wrote: > > -----Original Message----- > > > 1.) When I tested live system with "crash vmlinux /proc/kcore" in kernel v5.7, > > > I met the following crash issue: > > > ........................................ > > > crash: seek error: kernel virtual address: ffff75e9fffff000 type: "pud page" > > > ........................................ > > > > > > 2.) The root cause is the PTOV does not work correctly for some kernel, > > > and then arm64_vtop_4level_4k() does not work correctly too. > > > > > > Why PTOV does not work? > > > > > > The PHYS_OFFSET is just wrapper of memstart_addr. > > > ............................... > > > #define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; }) > > > ............................... > > > > > > Because memstart_addr is changed after physvirt_offset is initialized. > > > so the NUMBER(PHYS_OFFSET) does not return the correct value. > > > > Hmm, it looks like arm64_PTOV() uses the physvirt_offset if available > > (5.4 <= kernel < 5.10), I'm still not sure why it does not work correctly. > > Would you please explain the issue in more detail? > > In arm64_calc_physvirt_offset(void), we try to read out the > physvirt_offset from the live system, and we call read_proc_kcore(). > > In the read_proc_kcore: > ................................................ > if (paddr == KCORE_USE_VADDR) > kvaddr = addr; > else > kvaddr = PTOV((ulong)paddr); > ................................................ > > We need the PTOV (arm64_PTOV()) to work correctly. > > Unfortunately, arm64_PTOV() uses the ms->phys_offset again.. > ................................................ > ulong arm64_PTOV(ulong paddr) > { > struct machine_specific *ms = machdep->machspec; > > /* > * Either older kernel before kernel has 'physvirt_offset' or newer > * kernel which removes 'physvirt_offset' has the same formula: > * #define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET) > */ > if (!(machdep->flags & HAS_PHYSVIRT_OFFSET)) > return (paddr - ms->phys_offset) | PAGE_OFFSET; > else > return paddr - ms->physvirt_offset; > } > ................................................ > > So the physvirt_offset depends on the NUMBER(PHYS_OFFSET). Thank you for the explanation. So does using symbol_value_from_proc_kallsyms() and KCORE_USE_VADDR work? Several functions in arm64.c already use this way: if (kernel_symbol_exists("vabits_actual")) { if (pc->flags & PROC_KCORE) { vabits_actual = symbol_value_from_proc_kallsyms("vabits_actual"); if ((vabits_actual != BADVAL) && (READMEM(pc->mfd, &value, sizeof(ulong), vabits_actual, KCORE_USE_VADDR) > 0)) { Thanks, Kazu -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki