From: Peter Collingbourne <pcc@google.com>
To: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
clang-built-linux <clang-built-linux@googlegroups.com>,
Linux ARM <linux-arm-kernel@lists.infradead.org>,
Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: Re: [PATCH] arm64: Add support for relocating the kernel with RELR relocations
Date: Fri, 12 Jul 2019 12:40:16 -0700 [thread overview]
Message-ID: <CAMn1gO5FyAUy7VSO4YBNniwjPqEoJVpm+_fEiaF=cp_Du991vw@mail.gmail.com> (raw)
In-Reply-To: <20190710162114.rucn5wyrlwhkifti@willie-the-truck>
On Wed, Jul 10, 2019 at 9:21 AM Will Deacon <will@kernel.org> wrote:
>
> On Fri, Jul 05, 2019 at 01:02:31AM -0700, Peter Collingbourne wrote:
> > RELR is a relocation packing format for relative relocations.
> > The format is described in a generic-abi proposal:
> > https://groups.google.com/d/topic/generic-abi/bX460iggiKg/discussion
> >
> > The LLD linker can be instructed to pack relocations in the RELR
> > format by passing the flag --pack-dyn-relocs=relr.
> >
> > This patch adds a new config option, CONFIG_RELR. Enabling this option
> > instructs the linker to pack vmlinux's relative relocations in the RELR
> > format, and causes the kernel to apply the relocations at startup along
> > with the RELA relocations. RELA relocations still need to be applied
> > because the linker will emit RELA relative relocations if they are
> > unrepresentable in the RELR format (i.e. address not a multiple of 2).
> >
> > Enabling CONFIG_RELR reduces the size of a defconfig kernel image
> > with CONFIG_RANDOMIZE_BASE by 3.5MB/16% uncompressed, or 550KB/5%
> > compressed (lz4).
> >
> > Signed-off-by: Peter Collingbourne <pcc@google.com>
> > ---
> > arch/arm64/Kconfig | 9 +++++
> > arch/arm64/Makefile | 4 ++
> > arch/arm64/kernel/head.S | 70 ++++++++++++++++++++++++++++-----
> > arch/arm64/kernel/vmlinux.lds.S | 9 +++++
> > 4 files changed, 83 insertions(+), 9 deletions(-)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index 697ea05107298..f0cd0d2607e70 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -1447,6 +1447,15 @@ config RELOCATABLE
> > relocation pass at runtime even if the kernel is loaded at the
> > same address it was linked at.
> >
> > +config RELR
> > + bool "Use RELR relocation packing"
> > + depends on RELOCATABLE && $(ld-option,--pack-dyn-relocs=relr)
>
> Do you know if this will also be supported by binutils and, if so, whether
> they've agreed to use the same name for the option?
A number of binutils developers (Cary Coutant, Alan Modra) expressed
support for the format on the generic-abi thread, but I don't know
what the plans of the binutils developers are in terms of
implementation.
> > + help
> > + Store the kernel's dynamic relocations in the RELR relocation packing
> > + format. Requires a compatible linker (currently only LLD supports
> > + this feature), as well as compatible NM and OBJCOPY utilities
> > + (llvm-nm and llvm-objcopy are compatible).
> > +
> > config RANDOMIZE_BASE
> > bool "Randomize the address of the kernel image"
> > select ARM64_MODULE_PLTS if MODULES
> > diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> > index e9d2e578cbe67..16a8636f815c9 100644
> > --- a/arch/arm64/Makefile
> > +++ b/arch/arm64/Makefile
> > @@ -22,6 +22,10 @@ LDFLAGS_vmlinux += -shared -Bsymbolic -z notext -z norelro \
> > $(call ld-option, --no-apply-dynamic-relocs)
> > endif
> >
> > +ifeq ($(CONFIG_RELR),y)
> > + LDFLAGS_vmlinux += --pack-dyn-relocs=relr
> > +endif
> > +
> > ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
> > ifeq ($(call ld-option, --fix-cortex-a53-843419),)
> > $(warning ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum)
> > diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> > index 2cdacd1c141b9..9b27d5e7d8f70 100644
> > --- a/arch/arm64/kernel/head.S
> > +++ b/arch/arm64/kernel/head.S
> > @@ -102,6 +102,7 @@ pe_header:
> > * x23 stext() .. start_kernel() physical misalignment/KASLR offset
> > * x28 __create_page_tables() callee preserved temp register
> > * x19/x20 __primary_switch() callee preserved temp registers
> > + * x24 __primary_switch() current RELR displacement
>
> I think the comment is a bit misleading here, since x24 is used by
> __relocate_kernel(). Maybe make the middle column say:
>
> __primary_switch() .. __relocate_kernel()
>
> it's still not ideal, since the latter can be invoked twice, but oh well.
Done in v2.
> > */
> > ENTRY(stext)
> > bl preserve_boot_args
> > @@ -824,24 +825,63 @@ __relocate_kernel:
> > * Iterate over each entry in the relocation table, and apply the
> > * relocations in place.
> > */
> > - ldr w9, =__rela_offset // offset to reloc table
> > - ldr w10, =__rela_size // size of reloc table
> > -
> > mov_q x11, KIMAGE_VADDR // default virtual offset
> > add x11, x11, x23 // actual virtual offset
> > +
> > + ldr w9, =__rela_offset // offset to reloc table
> > + ldr w10, =__rela_size // size of reloc table
>
> I agree with Nick that I'd prefer to leave these lines alone.
Okay, I've reverted this part in v2.
> > add x9, x9, x11 // __va(.rela)
> > add x10, x9, x10 // __va(.rela) + sizeof(.rela)
> >
> > 0: cmp x9, x10
> > b.hs 1f
> > - ldp x11, x12, [x9], #24
> > - ldr x13, [x9, #-8]
> > - cmp w12, #R_AARCH64_RELATIVE
> > + ldp x12, x13, [x9], #24
> > + ldr x14, [x9, #-8]
> > + cmp w13, #R_AARCH64_RELATIVE
> > b.ne 0b
> > - add x13, x13, x23 // relocate
> > - str x13, [x11, x23]
> > + add x14, x14, x23 // relocate
> > + str x14, [x12, x23]
> > b 0b
> > -1: ret
>
> So the reason you're removing this ret is because we'll end up with both a
> .relr section *and* .rela section, correct?
Right. It's likely that the rela section will be empty when
CONFIG_RELR is enabled, but it isn't guaranteed. There are currently
no relocations at odd addresses in arm64 defconfig, but I've seen a
few in at least one of our Android device kernels.
> > +1:
> > +#ifdef CONFIG_RELR
> > + ldr w9, =__relr_offset // offset to reloc table
> > + ldr w10, =__relr_size // size of reloc table
> > + add x9, x9, x11 // __va(.relr)
> > + add x10, x9, x10 // __va(.relr) + sizeof(.relr)
> > +
> > + sub x15, x23, x24 // delta from previous offset
> > + cbz x15, 7f // nothing to do if unchanged
> > + mov x24, x23 // save new offset
> > +
> > +2: cmp x9, x10
> > + b.hs 7f
> > + ldr x11, [x9], #8
> > + tbnz x11, #0, 3f // branch to handle bitmaps
>
> Can we guarantee that x13 has been initialised at this point?
Yes. x13 will be initialized while processing an address entry, and
the format guarantees that each sequence of bitmap entries will be
preceded with an address entry.
> > + add x13, x11, x23
> > + ldr x12, [x13] // relocate address entry
> > + add x12, x12, x15
> > + str x12, [x13], #8 // adjust to start of bitmap
> > + b 2b
> > +
> > +3: mov x14, x13
> > +4: lsr x11, x11, #1
> > + cbz x11, 6f
> > + tbz x11, #0, 5f // skip bit if not set
> > + ldr x12, [x14] // relocate bit
> > + add x12, x12, x15
> > + str x12, [x14]
> > +
> > +5: add x14, x14, #8 // move to next bit's address
> > + b 4b
> > +
> > +6: add x13, x13, #(8 * 63) // move to next bitmap's address
> > + b 2b
>
> This desparately needs a block comment at the top (immediately after the
> #ifdef CONFIG_RELR) describing the algorithm and the layout of the .relr
> section, please.
Done in v2.
Peter
_______________________________________________
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:[~2019-07-12 19:40 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-05 8:02 [PATCH] arm64: Add support for relocating the kernel with RELR relocations Peter Collingbourne
2019-07-08 18:02 ` Nick Desaulniers
2019-07-09 22:04 ` Peter Collingbourne
2019-07-09 23:13 ` Nick Desaulniers
2019-07-12 19:40 ` Peter Collingbourne
2019-07-10 16:21 ` Will Deacon
2019-07-12 19:40 ` Peter Collingbourne [this message]
2019-07-10 23:14 ` Nick Desaulniers
2019-07-12 19:40 ` Peter Collingbourne
2019-07-12 19:33 ` [PATCH v2] arm64: Add support for relocating the kernel with RELR Peter Collingbourne
2019-07-12 19:38 ` [PATCH v2] arm64: Add support for relocating the kernel with RELR relocations Peter Collingbourne
2019-07-29 20:00 ` Peter Collingbourne
2019-07-31 16:48 ` Will Deacon
2019-08-01 1:19 ` Peter Collingbourne
2019-08-01 1:18 ` [PATCH v3] " Peter Collingbourne
2019-08-01 12:05 ` Will Deacon
2019-08-01 17:51 ` Peter Collingbourne
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='CAMn1gO5FyAUy7VSO4YBNniwjPqEoJVpm+_fEiaF=cp_Du991vw@mail.gmail.com' \
--to=pcc@google.com \
--cc=ard.biesheuvel@linaro.org \
--cc=catalin.marinas@arm.com \
--cc=clang-built-linux@googlegroups.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=mark.rutland@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 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.