linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb@kernel.org>
To: Dave P Martin <dave.martin@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
	Anders Roxell <anders.roxell@linaro.org>,
	Arnd Bergmann <arnd@arndb.de>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Mark Brown <broonie@kernel.org>,
	James Morse <james.morse@arm.com>,
	Andre Przywara <andre.przywara@arm.com>,
	Will Deacon <will@kernel.org>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH] arm64/alternatives: use subsections for replacement sequences
Date: Wed, 1 Jul 2020 19:32:07 +0200	[thread overview]
Message-ID: <CAMj1kXFGnaPRyagKwELDApjx=Fb+m5r4pBoQg5PGcK5GsSr-Kw@mail.gmail.com> (raw)
In-Reply-To: <CAMj1kXFGy2xtqKL4ZexswvUPSg9kNW6hi54N5uz_W1jm=ixGVw@mail.gmail.com>

On Wed, 1 Jul 2020 at 19:30, Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Wed, 1 Jul 2020 at 19:01, Dave P Martin <dave.martin@arm.com> wrote:
> >
> > On Tue, Jun 30, 2020 at 10:19:21AM +0200, Ard Biesheuvel wrote:
> > > When building very large kernels, the logic that emits replacement
> > > sequences for alternatives fails when relative branches are present
> > > in the code that is emitted into the .altinstr_replacement section
> > > and patched in at the original site and fixed up. The reason is that
> > > the linker will insert veneers if relative branches go out of range,
> > > and due to the relative distance of the .altinstr_replacement from
> > > the .text section where its branch targets usually live, veneers
> > > may be emitted at the end of the .altinstr_replacement section, with
> > > the relative branches in the sequence pointed at the veneers instead
> > > of the actual target.
> > >
> > > The alternatives patching logic will attempt to fix up the branch to
> > > point to its original target, which will be the veneer in this case,
> > > but given that the patch site is likely to be far away as well, it
> > > will be out of range and so patching will fail. There are other cases
> > > where these veneers are problematic, e.g., when the target of the
> > > branch is in .text while the patch site is in .init.text, in which
> > > case putting the replacement sequence inside .text may not help either.
> > >
> > > So let's use subsections to emit the replacement code as closely as
> > > possible to the patch site, to ensure that veneers are only likely to
> > > be emitted if they are required at the patch site as well, in which
> > > case they will be in range for the replacement sequence both before
> > > and after it is transported to the patch site.
> > >
> > > This will prevent alternative sequences in non-init code from being
> > > released from memory after boot, but this is tolerable given that the
> > > entire section is only 512 KB on an allyesconfig build (which weighs in
> > > at 500+ MB for the entire Image). Also, note that modules today carry
> > > the replacement sequences in non-init sections as well, and any of
> > > those that target init code will be emitted into init sections after
> > > this change.
> > >
> > > This fixes an early crash when booting an allyesconfig kernel on a
> > > system where any of the alternatives sequences containing relative
> > > branches are activated at boot (e.g., ARM64_HAS_PAN on TX2)
> > >
> > > Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > Cc: James Morse <james.morse@arm.com>
> > > Cc: Andre Przywara <andre.przywara@arm.com>
> > > Cc: Dave P Martin <dave.martin@arm.com>
> > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > > ---
> > >  arch/arm64/include/asm/alternative.h | 16 ++++++++--------
> > >  arch/arm64/kernel/vmlinux.lds.S      |  3 ---
> > >  2 files changed, 8 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h
> > > index 5e5dc05d63a0..12f0eb56a1cc 100644
> > > --- a/arch/arm64/include/asm/alternative.h
> > > +++ b/arch/arm64/include/asm/alternative.h
> > > @@ -73,11 +73,11 @@ static inline void apply_alternatives_module(void *start, size_t length) { }
> > >       ".pushsection .altinstructions,\"a\"\n"                         \
> > >       ALTINSTR_ENTRY(feature)                                         \
> > >       ".popsection\n"                                                 \
> > > -     ".pushsection .altinstr_replacement, \"a\"\n"                   \
> > > +     ".subsection 1\n"                                               \
> >
> > This uses subsections in existing sections.  Could that interfere with
> > existing (or future) uses of subsections?  (I've not checked whether
> > there actually are such uses.  I'm also assuming that clobbering the
> > invoker's idea of what section is .previous doesn't matter.)
> >
>
> It shouldn't matter, really. You can use different indexes for the
> subsection, but since the execution never flows from one subsection
> into the next, all that matters is that they are 'somewhere else'
>
> As for the use of .previous - the idea is that this does not affect
> the contents of the section stack, which I think makes sense. We could
> use '.pushsection .text, 1' as well to enter another subsection in
> .text, but that means we keep the .text vs .init.text issue that this
> patch solves.
>
> > Another wrinkle: the replacement code now becomes executable, whereas
> > I think it was previously in rodata.  I'm not sure how much this
> > matters, but it might be a source of gadgets.
> >
>
> True. Perhaps we need to get rid of relative branches in alternative
> sequences entirely - see below.
>
> >
> > A different option would be to add an explicitly veneered branch macro
> > for use in alternatives, maybe adrp+add+br.  For BTI compatility, we'd
> > need a bti j or equivalent at the destination, which might or might not
> > be easy to achieve -- mind you, I think we theoretically need that
> > anyway for veneers to work properly in all cases.
> >
> > Because we would define the exact instruction sequence, the
> > alternatives code could probably replace it with a direct branch if the
> > actual destination is close enough.  The downside is that it wouldn't
> > be a single instruction any more, and there would be some overhead for
> > conditional branches if we replace the unneeded insns with NOPs.
> >
>
> Yeah, this becomes quite hairy very quickly, especially because now
> you need to allocate a spare register each time you do this.
>
> One other option is to simply disallow branches in the alternative
> sequences: I spotted three occurrences [0] that are quite easily
> fixed, by inverting the condition so that the relative branch is
> emitted in place, and the alternative sequence is just NOPs.

[0] https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=arm64-alt-branches

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2020-07-01 17:34 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-30  8:19 [PATCH] arm64/alternatives: use subsections for replacement sequences Ard Biesheuvel
2020-07-01 17:00 ` Dave P Martin
2020-07-01 17:30   ` Ard Biesheuvel
2020-07-01 17:32     ` Ard Biesheuvel [this message]
2020-07-06 15:50       ` Dave Martin
2020-07-06 16:04         ` Ard Biesheuvel
2020-07-07 10:35           ` Dave Martin
2020-07-02 11:56 ` Will Deacon
2020-07-02 13:54 ` Will Deacon
2020-07-09 10:57 ` Alexandru Elisei
2020-07-09 11:12   ` Alexandru Elisei
2020-07-09 12:31     ` Ard Biesheuvel
2020-07-09 12:39       ` Ard Biesheuvel
2020-07-09 12:43         ` Will Deacon
2020-07-09 12:48         ` Alexandru Elisei

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='CAMj1kXFGnaPRyagKwELDApjx=Fb+m5r4pBoQg5PGcK5GsSr-Kw@mail.gmail.com' \
    --to=ardb@kernel.org \
    --cc=anders.roxell@linaro.org \
    --cc=andre.przywara@arm.com \
    --cc=arnd@arndb.de \
    --cc=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=dave.martin@arm.com \
    --cc=james.morse@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).