Re: [PATCH 2/2] arm64: fix the "pud page" crash for live system

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----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




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux