All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pingfan Liu <piliu@redhat.com>
To: kexec@lists.infradead.org
Subject: [PATCHv4 4/4] arm64: fix PAGE_OFFSET calc for flipped mm
Date: Fri, 21 Jan 2022 09:36:11 +0800	[thread overview]
Message-ID: <CAF+s44QcZ7148G6amQbZefZkZSTwe9aCgp9U0H1bVUFoSP0qWA@mail.gmail.com> (raw)
In-Reply-To: <20220120190856.683a2923@rhtmp>

On Fri, Jan 21, 2022 at 2:09 AM Philipp Rudo <prudo@redhat.com> wrote:
>
> Hi Pingfan,
>
> On Tue, 18 Jan 2022 15:48:12 +0800
> Pingfan Liu <piliu@redhat.com> wrote:
>
> > From: Kairui Song <kasong@tencent.com>
> >
> > Since kernel commit 14c127c957c1 ('arm64: mm: Flip kernel VA space'),
> > the memory layout on arm64 have changed, and kexec-tools can no longer
> > get the the right PAGE_OFFSET based on _text symbol.
> >
> > Prior to that, the kimage (_text) lays above PAGE_END with this layout:
> > 0               -> VA_START                 : Usespace
> > VA_START        -> VA_START + 256M          : BPF JIT, Modules
> > VA_START + 256M -> PAGE_OFFSET - (~GB misc) : Vmalloc (KERNEL _text HERE)
> > PAGE_OFFSET     -> ...                      : * Linear map *
> >
> > And here we have:
> > VA_START    = -1UL << VA_BITS
> > PAGE_OFFSET = -1UL << (VA_BITS - 1)
> > _text < -1UL << (VA_BITS - 1)
> >
> > Kernel image lays somewhere between VA_START and PAGE_OFFSET, so we just
> > calc VA_BITS by getting the highest unset bit of _text symbol address,
> > and shift one less bit of VA_BITS to get page offset. This works as long
> > as KASLR don't put kernel in a too high location (which is commented inline).
> >
> > And after that commit, kernel layout have changed:
> > 0               -> PAGE_OFFSET              : Userspace
> > PAGE_OFFSET     -> PAGE_END                 : * Linear map *
> > PAGE_END        -> PAGE_END + 128M          : bpf jit region
> > PAGE_END + 128M -> PAGE_END + 256MB         : modules
> > PAGE_END + 256M -> ...                      : vmalloc (KERNEL _text HERE)
> >
> > Here we have:
> > PAGE_OFFSET = -1UL << VA_BITS
> > PAGE_END    = -1UL << (VA_BITS - 1)
> > _text > -1UL << (VA_BITS - 1)
> >
> > Kernel image now lays above PAGE_END, so we have to shift one more bit to
> > get the VA_BITS, and shift the exact VA_BITS for PAGE_OFFSET.
> >
> > We can simply check if "_text > -1UL << (VA_BITS - 1)" is true to judge
> > which layout is being used and shift the page offset occordingly.
> >
> > Signed-off-by: Kairui Song <kasong@tencent.com>
> > (rebased and stripped by Pingfan )
> > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > Cc: Simon Horman <horms@verge.net.au>
> > Cc: Philipp Rudo <prudo@redhat.com>
> > To: kexec at lists.infradead.org
> > ---
> >  kexec/arch/arm64/kexec-arm64.c | 14 +++++++++++++-
> >  1 file changed, 13 insertions(+), 1 deletion(-)
> >
> > diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
> > index 793799b..ce7a5bb 100644
> > --- a/kexec/arch/arm64/kexec-arm64.c
> > +++ b/kexec/arch/arm64/kexec-arm64.c
> > @@ -923,13 +923,25 @@ out:
> >
> >  int get_page_offset(unsigned long *page_offset)
> >  {
> > +     unsigned long long text_sym_addr, kernel_va_mid;
> >       int ret;
> >
> > +     text_sym_addr = get_kernel_sym("_text");
> > +     if (text_sym_addr == 0) {
> > +             fprintf(stderr, "Can't get the symbol of _text to calculate page_offset.\n");
> > +             return -1;
> > +     }
> > +
> >       ret = get_va_bits();
> >       if (ret < 0)
> >               return ret;
> >
> > -     if (va_bits < 52)
> > +     /* Since kernel 5.4, kernel image is put above
> > +      * UINT64_MAX << (va_bits - 1)
> > +      */
> > +     kernel_va_mid = UINT64_MAX << (va_bits - 1);
> > +     /* older kernel */
> > +     if (text_sym_addr < kernel_va_mid)
> >               *page_offset = UINT64_MAX << (va_bits - 1);
> >       else
> >               *page_offset = UINT64_MAX << va_bits;
>
> I would drop the kernel_va_mid and simply use
>
>         *page_offset = UINT64_MAX << (va_bits - 1)
>         if (*page_offset > text_sym_addr > *page_offset)
>                 *page_offset = UINT64_MAX << va_bits
>
> but that's more a matter of taste.
>
Ah, I kept kernel_va_mid dedicatedly to illustrate the purpose.

> Reviewed-by: Philipp Rudo <prudo@redhat.com>
>
Thanks for your reviewing.

Regards,

Pingfan



  reply	other threads:[~2022-01-21  1:36 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-18  7:48 [PATCHv4 0/4] arm64: make phys_to_virt() correct Pingfan Liu
2022-01-18  7:48 ` [PATCHv4 1/4] arm64: make phys_offset signed Pingfan Liu
2022-01-20 18:09   ` Philipp Rudo
2022-01-21  1:38     ` Pingfan Liu
2022-01-24  8:58       ` Simon Horman
2022-01-18  7:48 ` [PATCHv4 2/4] arm64/crashdump: unify routine to get page_offset Pingfan Liu
2022-01-20 18:09   ` Philipp Rudo
2022-01-18  7:48 ` [PATCHv4 3/4] arm64: read VA_BITS from kcore for 52-bits VA kernel Pingfan Liu
2022-01-20 18:09   ` Philipp Rudo
2022-01-18  7:48 ` [PATCHv4 4/4] arm64: fix PAGE_OFFSET calc for flipped mm Pingfan Liu
2022-01-20 18:08   ` Philipp Rudo
2022-01-21  1:36     ` Pingfan Liu [this message]
2022-01-24  9:10 ` [PATCHv4 0/4] arm64: make phys_to_virt() correct Simon Horman
2022-01-24  9:53   ` Pingfan Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAF+s44QcZ7148G6amQbZefZkZSTwe9aCgp9U0H1bVUFoSP0qWA@mail.gmail.com \
    --to=piliu@redhat.com \
    --cc=kexec@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.