[Crash-utility] [PATCHv8 2/4] crash-utility/arm64: store phy_offset and memstart_addr separately
Pingfan Liu
piliu at redhat.com
Wed Jun 30 10:40:56 UTC 2021
On Wed, Jun 30, 2021 at 05:42:27AM +0000, HAGIO KAZUHITO(萩尾 一仁) wrote:
> -----Original Message-----
> > > > > > @@ -1185,8 +1234,20 @@ arm64_VTOP(ulong addr)
> > > > > > return addr - machdep->machspec->kimage_voffset;
> > > > > > }
> > > > > >
> > > > > > - if (addr >= machdep->machspec->page_offset)
> > > > > > - return addr + machdep->machspec->physvirt_offset;
> >
> > I had thought it worked for all versions before commit 5383cc6efed1 (arm64: mm: Introduce vabits_actual).
> > So !(machdep->flags & FLIPPED_VM) branch should use the formula.
> >
> > But it turns out to be wrong. PLS see the comment followed.
> >
> > > > > > + if (addr >= machdep->machspec->page_offset) {
> > > > > > + ulong paddr;
> > > > > > +
> > > > > > + if (!(machdep->flags & FLIPPED_VM) || (machdep->flags & HAS_PHYSVIRT_OFFSET))
> > {
> > > > > > + paddr = addr;
> > > > > > + } else {
> > > > > > + /*
> > > > > > + * #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) +
> > PHYS_OFFSET)
> > > > > > + */
> > > > > > + paddr = addr & ~
> > _PAGE_OFFSET(machdep->machspec->CONFIG_ARM64_VA_BITS);
> > > > > > + }
> > > > > > + paddr += machdep->machspec->physvirt_offset;
> > > > > > + return paddr;
> > > > >
> > > > > Hmm, complex. It should be symmetric to PTOV, why differences?
> > > >
> > [...]
> > >
> > > Yes, it's one of them, and this looks better, but...
> > >
> > > Hmm ok, I summarized these and my question why they're asymmetric emerged:
> > >
> > Thank you for the patient.
> >
> > > if physvirt_offset exists // HAS_PHYSVIRT_OFFSET
> > > ms->physvirt_offset = read physvirt_offset;
> > > else if (machdep->flags & FLIPPED_VM)
> > > ms->physvirt_offset = ms->phys_offset_nominal;
> > > else // !FLIPPED_VM
> > > ms->physvirt_offset = ms->phys_offset - ms->page_offset;
> > >
> > > PTOV:
> > > if (machdep->flags & HAS_PHYSVIRT_OFFSET)
> > > v = paddr - ms->physvirt_offset; // looks ok
> > > else
> > > v = (paddr - ms->physvirt_offset) | PAGE_OFFSET; // Is this ok when !FLIPPED_VM ?
> > >
> > It works for !FLIPPED_VM. But I did make a mistake on VTOP()
> >
> > Flipped mm is introduced by 14c127c957c1 ("arm64: mm: Flip kernel VA space")
> >
> > $ git show 14c127c957c1c6070647c171e72f06e0db275ebf:arch/arm64/include/asm/memory.h | grep "#define
> > __phys_to_virt"
> > #define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
> > $ git show 14c127c957c1c6070647c171e72f06e0db275ebf~1:arch/arm64/include/asm/memory.h | grep "#define
> > __phys_to_virt"
> > #define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
> >
> > So the formula keeps unchange across filpped-mm. The same case for VTOP.
> > And what matters is physvirt_offset introduced by 5383cc6efed1 ("arm64: mm: Introduce vabits_actual")
> >
> > > VTOP:
> > > if (machdep->flags & HAS_PHYSVIRT_OFFSET || !(machdep->flags & FLIPPED_VM))
> > > p = vaddr + ms->physvirt_offset; // looks ok
> > > else
> > > p = (vaddr & ~PAGE_OFFSET) + ms->physvirt_offset; // looks ok
> > >
> >
> > Similar,
> > $git show 14c127c957c1c6070647c171e72f06e0db275ebf:arch/arm64/include/asm/memory.h | grep __lm_to_phys
> > #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
> > __is_lm_address(__x) ? __lm_to_phys(__x) : \
> > $ git show 14c127c957c1c6070647c171e72f06e0db275ebf~1:arch/arm64/include/asm/memory.h | grep __lm_to_phys
> > #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
> > __is_lm_address(__x) ? __lm_to_phys(__x) : \
> >
> > >
> > > When !FLIPPED_VM, PTOV calculates:
> > > v = (paddr - ms->physvirt_offset) | PAGE_OFFSET
> > > = (paddr - ms->physoffset + ms->page_offset) | PAGE_OFFSET
> > >
> > > This might be not wrong in the result value because of the or operation,
> > > but looks wrong formula. So PTOV also needs the !(machdep->flags & FLIPPED_VM)
> > > condition? or I'm missing something?
> > >
> >
> > So I need to drop the !(machdep->flags & FLIPPED_VM) in VTOP(), instead of adding in PTOV().
> > Sorry for the confusion and hope I make it clear.
>
> If you do so, you mean that you will change
> ms->physvirt_offset = ms->phys_offset - ms->page_offset
> to
> ms->physvirt_offset = ms->phys_offset
> if !FLIPPED_VM ?
As you suggested below, just not using physvirt_offset if no such kernel symbol.
And here just keep its semantic, although it is useless in such cases
Either FLIPPED_VM or !FLIPPED_VM without HAS_PHYSVIRT_OFFSET:
ms->physvirt_offset = ms->phys_offset_nominal - ms->page_offset;
>
> For me, it's readable and understandable to match the formulas with kernel's
> one. In this case, use the physvirt_offset only if physvirt_offset exists.
> We can do it now because we are introducing a switchable PTOV/VTOP.
> For example:
>
> ms->phys_offset_nominal = read phys_offset;
> if (ms->phys_offset_nominal < 0)
> ms->phys_offset = ms->phys_offset_nominal + MEMSTART_ADDR_OFFSET;
> else
> ms->phys_offset = ms->phys_offset_nominal
>
> PTOV:
> if (machdep->flags & HAS_PHYSVIRT_OFFSET)
> v = paddr - ms->physvirt_offset;
> else
> v = (paddr - ms->phys_offset_nominal) | PAGE_OFFSET
>
> VTOP:
> if (machdep->flags & HAS_PHYSVIRT_OFFSET)
> p = vaddr + ms->physvirt_offset;
> else
> p = (vaddr & ~PAGE_OFFSET) + ms->phys_offset_nominal;
>
Thanks for this good suggestion. I am composing a new patch based on it.
>
> btw, just to clarify, where is the phys_offset used except for
> PTOV and VTOP? I cannot find it..
>
> > while getting PFN offset in a dumpfile, phys_offset is
> > required.
>
My wrong understanding of the code.
So I think there is only ms->phys_offset needed, and phys_offset_nominal can be abandoned.
Thanks,
Pingfan
More information about the Crash-utility
mailing list