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
next prev parent 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).