diff mbox

arm64: errata: add module build workaround for erratum #843419

Message ID 1442402197-20306-1-git-send-email-will.deacon@arm.com
State Accepted
Commit df057cc7b4fa59e9b55f07ffdb6c62bf02e99a00
Headers show

Commit Message

Will Deacon Sept. 16, 2015, 11:16 a.m. UTC
Cortex-A53 processors <= r0p4 are affected by erratum #843419 which can
lead to a memory access using an incorrect address in certain sequences
headed by an ADRP instruction.

There is a linker fix to generate veneers for ADRP instructions, but
this doesn't work for kernel modules which are built as unlinked ELF
objects.

This patch adds a new config option for the erratum which, when enabled,
builds kernel modules with the mcmodel=large flag. This uses absolute
addressing for all kernel symbols, thereby removing the use of ADRP as
a PC-relative form of addressing. The ADRP relocs are removed from the
module loader so that we fail to load any potentially affected modules.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig         | 16 ++++++++++++++++
 arch/arm64/Makefile        |  4 ++++
 arch/arm64/kernel/module.c |  2 ++
 3 files changed, 22 insertions(+)

Comments

Catalin Marinas Sept. 16, 2015, 3:54 p.m. UTC | #1
On Wed, Sep 16, 2015 at 12:16:37PM +0100, Will Deacon wrote:
> Cortex-A53 processors <= r0p4 are affected by erratum #843419 which can
> lead to a memory access using an incorrect address in certain sequences
> headed by an ADRP instruction.
> 
> There is a linker fix to generate veneers for ADRP instructions, but
> this doesn't work for kernel modules which are built as unlinked ELF
> objects.
> 
> This patch adds a new config option for the erratum which, when enabled,
> builds kernel modules with the mcmodel=large flag. This uses absolute
> addressing for all kernel symbols, thereby removing the use of ADRP as
> a PC-relative form of addressing. The ADRP relocs are removed from the
> module loader so that we fail to load any potentially affected modules.
> 
> Signed-off-by: Will Deacon <will.deacon@arm.com>

I don't particularly like but, well...

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Ard Biesheuvel Sept. 17, 2015, 2:24 p.m. UTC | #2
Hi Will,

On 16 September 2015 at 13:16, Will Deacon <will.deacon@arm.com> wrote:
> Cortex-A53 processors <= r0p4 are affected by erratum #843419 which can
> lead to a memory access using an incorrect address in certain sequences
> headed by an ADRP instruction.
>
> There is a linker fix to generate veneers for ADRP instructions, but
> this doesn't work for kernel modules which are built as unlinked ELF
> objects.
>

Considering that the kernel is built without -fpic but still appears
at a different offset when the MMU is off, those veneers had better be
position independent.

> This patch adds a new config option for the erratum which, when enabled,
> builds kernel modules with the mcmodel=large flag. This uses absolute
> addressing for all kernel symbols, thereby removing the use of ADRP as
> a PC-relative form of addressing. The ADRP relocs are removed from the
> module loader so that we fail to load any potentially affected modules.
>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm64/Kconfig         | 16 ++++++++++++++++
>  arch/arm64/Makefile        |  4 ++++
>  arch/arm64/kernel/module.c |  2 ++
>  3 files changed, 22 insertions(+)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 7d95663c0160..11ff4d57c92a 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -331,6 +331,22 @@ config ARM64_ERRATUM_845719
>
>           If unsure, say Y.
>
> +config ARM64_ERRATUM_843419
> +       bool "Cortex-A53: 843419: A load or store might access an incorrect address"
> +       depends on MODULES
> +       default y
> +       help
> +         This option builds kernel modules using the large memory model in
> +         order to avoid the use of the ADRP instruction, which can cause
> +         a subsequent memory access to use an incorrect address on Cortex-A53
> +         parts up to r0p4.
> +
> +         Note that the kernel itself must be linked with a version of ld
> +         which fixes potentially affected ADRP instructions through the
> +         use of veneers.
> +
> +         If unsure, say Y.
> +
>  endmenu
>
>
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index 15ff5b4156fd..f9914d7c1bb0 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -41,6 +41,10 @@ endif
>
>  CHECKFLAGS     += -D__aarch64__
>
> +ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
> +CFLAGS_MODULE  += -mcmodel=large
> +endif
> +

Ouch.

Couldn't we handle this at runtime? According to the erratum, the
problem only occurs when the adrp is in either of the last two
instruction slots of a 4 KB page, and we could easily turn adrp
instructions into adr if the symbol is within 1 MB of the place (which
would typically cover all internal references in the module), and emit
a veneer otherwise?

I'm happy to hack something up

>  # Default value
>  head-y         := arch/arm64/kernel/head.o
>
> diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
> index 67bf4107f6ef..876eb8df50bf 100644
> --- a/arch/arm64/kernel/module.c
> +++ b/arch/arm64/kernel/module.c
> @@ -332,12 +332,14 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
>                         ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 0, 21,
>                                              AARCH64_INSN_IMM_ADR);
>                         break;
> +#ifndef CONFIG_ARM64_ERRATUM_843419
>                 case R_AARCH64_ADR_PREL_PG_HI21_NC:
>                         overflow_check = false;
>                 case R_AARCH64_ADR_PREL_PG_HI21:
>                         ovf = reloc_insn_imm(RELOC_OP_PAGE, loc, val, 12, 21,
>                                              AARCH64_INSN_IMM_ADR);
>                         break;
> +#endif
>                 case R_AARCH64_ADD_ABS_LO12_NC:
>                 case R_AARCH64_LDST8_ABS_LO12_NC:
>                         overflow_check = false;
> --
> 2.1.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon Sept. 17, 2015, 2:48 p.m. UTC | #3
On Thu, Sep 17, 2015 at 03:24:01PM +0100, Ard Biesheuvel wrote:
> Hi Will,

Hi Ard,

> On 16 September 2015 at 13:16, Will Deacon <will.deacon@arm.com> wrote:
> > Cortex-A53 processors <= r0p4 are affected by erratum #843419 which can
> > lead to a memory access using an incorrect address in certain sequences
> > headed by an ADRP instruction.
> >
> > There is a linker fix to generate veneers for ADRP instructions, but
> > this doesn't work for kernel modules which are built as unlinked ELF
> > objects.
> >
> 
> Considering that the kernel is built without -fpic but still appears
> at a different offset when the MMU is off, those veneers had better be
> position independent.

They seem to be ok, from what I've tested. You should also be able to
take a recent ld and see for yourself what it gets up to.

> > This patch adds a new config option for the erratum which, when enabled,
> > builds kernel modules with the mcmodel=large flag. This uses absolute
> > addressing for all kernel symbols, thereby removing the use of ADRP as
> > a PC-relative form of addressing. The ADRP relocs are removed from the
> > module loader so that we fail to load any potentially affected modules.
> >
> > Signed-off-by: Will Deacon <will.deacon@arm.com>
> > ---
> >  arch/arm64/Kconfig         | 16 ++++++++++++++++
> >  arch/arm64/Makefile        |  4 ++++
> >  arch/arm64/kernel/module.c |  2 ++
> >  3 files changed, 22 insertions(+)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index 7d95663c0160..11ff4d57c92a 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -331,6 +331,22 @@ config ARM64_ERRATUM_845719
> >
> >           If unsure, say Y.
> >
> > +config ARM64_ERRATUM_843419
> > +       bool "Cortex-A53: 843419: A load or store might access an incorrect address"
> > +       depends on MODULES
> > +       default y
> > +       help
> > +         This option builds kernel modules using the large memory model in
> > +         order to avoid the use of the ADRP instruction, which can cause
> > +         a subsequent memory access to use an incorrect address on Cortex-A53
> > +         parts up to r0p4.
> > +
> > +         Note that the kernel itself must be linked with a version of ld
> > +         which fixes potentially affected ADRP instructions through the
> > +         use of veneers.
> > +
> > +         If unsure, say Y.
> > +
> >  endmenu
> >
> >
> > diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> > index 15ff5b4156fd..f9914d7c1bb0 100644
> > --- a/arch/arm64/Makefile
> > +++ b/arch/arm64/Makefile
> > @@ -41,6 +41,10 @@ endif
> >
> >  CHECKFLAGS     += -D__aarch64__
> >
> > +ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
> > +CFLAGS_MODULE  += -mcmodel=large
> > +endif
> > +
> 
> Ouch.
> 
> Couldn't we handle this at runtime? According to the erratum, the
> problem only occurs when the adrp is in either of the last two
> instruction slots of a 4 KB page, and we could easily turn adrp
> instructions into adr if the symbol is within 1 MB of the place (which
> would typically cover all internal references in the module), and emit
> a veneer otherwise?

I'd have thought the internal references would already be using smaller
relocs if they could get away with it, but it's worth looking at.

> I'm happy to hack something up

Sure, fill your boots! I just wanted something simple for stable and I
have limited patience in working around these kind of things. I think
there are some testcases in the binutils tree if you want to adapt them
for the module loader [1].

Will

[1]
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=ld/testsuite/ld-aarch64/erratum843419.s;h=35c21ae95a65913050dafc857abe35d8ee6fe9ed;hb=HEAD
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=ld/testsuite/ld-aarch64/erratum843419.d;h=4be8f9e585095898dae9a8677d565edb4089e97a;hb=HEAD
dann frazier Oct. 6, 2015, 9:44 p.m. UTC | #4
On Wed, Sep 16, 2015 at 5:16 AM, Will Deacon <will.deacon@arm.com> wrote:
> Cortex-A53 processors <= r0p4 are affected by erratum #843419 which can
> lead to a memory access using an incorrect address in certain sequences
> headed by an ADRP instruction.

Just a heads up that we're seeing a regression in the Ubuntu 4.2 kernel on
X-Gene after this patch is applied and the CONFIG enabled.

Modules loads fail with messages like:

[ 2.192721] module gpio_xgene_sb: unsupported RELA relocation: 275
[ 2.193609] module xgene_enet: unsupported RELA relocation: 275
[ 2.249402] module libahci: unsupported RELA relocation: 275
[ 2.249628] module xgene_enet: unsupported RELA relocation: 275
[ 2.359451] module xgene_enet: unsupported RELA relocation: 275
[ 2.389444] module xgene_enet: unsupported RELA relocation: 275
[ 3.473766] module linear: unsupported RELA relocation: 275
[ 3.543252] module multipath: unsupported RELA relocation: 275
[ 3.593268] module raid0: unsupported RELA relocation: 275
[ 3.663695] module raid1: unsupported RELA relocation: 275
[ 3.713964] module raid6_pq: unsupported RELA relocation: 275
[ 3.763983] module raid6_pq: unsupported RELA relocation: 275
[ 3.803975] module raid6_pq: unsupported RELA relocation: 275
[ 3.853881] module raid10: unsupported RELA relocation: 275
[ 3.924962] module raid6_pq: unsupported RELA relocation: 275

I haven't attempted to reproduce with a pure upstream kernel yet.

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1502946

   -dann

> There is a linker fix to generate veneers for ADRP instructions, but
> this doesn't work for kernel modules which are built as unlinked ELF
> objects.
>
> This patch adds a new config option for the erratum which, when enabled,
> builds kernel modules with the mcmodel=large flag. This uses absolute
> addressing for all kernel symbols, thereby removing the use of ADRP as
> a PC-relative form of addressing. The ADRP relocs are removed from the
> module loader so that we fail to load any potentially affected modules.
>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm64/Kconfig         | 16 ++++++++++++++++
>  arch/arm64/Makefile        |  4 ++++
>  arch/arm64/kernel/module.c |  2 ++
>  3 files changed, 22 insertions(+)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 7d95663c0160..11ff4d57c92a 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -331,6 +331,22 @@ config ARM64_ERRATUM_845719
>
>           If unsure, say Y.
>
> +config ARM64_ERRATUM_843419
> +       bool "Cortex-A53: 843419: A load or store might access an incorrect address"
> +       depends on MODULES
> +       default y
> +       help
> +         This option builds kernel modules using the large memory model in
> +         order to avoid the use of the ADRP instruction, which can cause
> +         a subsequent memory access to use an incorrect address on Cortex-A53
> +         parts up to r0p4.
> +
> +         Note that the kernel itself must be linked with a version of ld
> +         which fixes potentially affected ADRP instructions through the
> +         use of veneers.
> +
> +         If unsure, say Y.
> +
>  endmenu
>
>
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index 15ff5b4156fd..f9914d7c1bb0 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -41,6 +41,10 @@ endif
>
>  CHECKFLAGS     += -D__aarch64__
>
> +ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
> +CFLAGS_MODULE  += -mcmodel=large
> +endif
> +
>  # Default value
>  head-y         := arch/arm64/kernel/head.o
>
> diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
> index 67bf4107f6ef..876eb8df50bf 100644
> --- a/arch/arm64/kernel/module.c
> +++ b/arch/arm64/kernel/module.c
> @@ -332,12 +332,14 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
>                         ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 0, 21,
>                                              AARCH64_INSN_IMM_ADR);
>                         break;
> +#ifndef CONFIG_ARM64_ERRATUM_843419
>                 case R_AARCH64_ADR_PREL_PG_HI21_NC:
>                         overflow_check = false;
>                 case R_AARCH64_ADR_PREL_PG_HI21:
>                         ovf = reloc_insn_imm(RELOC_OP_PAGE, loc, val, 12, 21,
>                                              AARCH64_INSN_IMM_ADR);
>                         break;
> +#endif
>                 case R_AARCH64_ADD_ABS_LO12_NC:
>                 case R_AARCH64_LDST8_ABS_LO12_NC:
>                         overflow_check = false;
> --
> 2.1.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Ard Biesheuvel Oct. 6, 2015, 10:29 p.m. UTC | #5
On 6 October 2015 at 22:44, Dann Frazier <dann.frazier@canonical.com> wrote:
> On Wed, Sep 16, 2015 at 5:16 AM, Will Deacon <will.deacon@arm.com> wrote:
>> Cortex-A53 processors <= r0p4 are affected by erratum #843419 which can
>> lead to a memory access using an incorrect address in certain sequences
>> headed by an ADRP instruction.
>
> Just a heads up that we're seeing a regression in the Ubuntu 4.2 kernel on
> X-Gene after this patch is applied and the CONFIG enabled.
>
> Modules loads fail with messages like:
>
> [ 2.192721] module gpio_xgene_sb: unsupported RELA relocation: 275
> [ 2.193609] module xgene_enet: unsupported RELA relocation: 275
> [ 2.249402] module libahci: unsupported RELA relocation: 275
> [ 2.249628] module xgene_enet: unsupported RELA relocation: 275
> [ 2.359451] module xgene_enet: unsupported RELA relocation: 275
> [ 2.389444] module xgene_enet: unsupported RELA relocation: 275
> [ 3.473766] module linear: unsupported RELA relocation: 275
> [ 3.543252] module multipath: unsupported RELA relocation: 275
> [ 3.593268] module raid0: unsupported RELA relocation: 275
> [ 3.663695] module raid1: unsupported RELA relocation: 275
> [ 3.713964] module raid6_pq: unsupported RELA relocation: 275
> [ 3.763983] module raid6_pq: unsupported RELA relocation: 275
> [ 3.803975] module raid6_pq: unsupported RELA relocation: 275
> [ 3.853881] module raid10: unsupported RELA relocation: 275
> [ 3.924962] module raid6_pq: unsupported RELA relocation: 275
>

RELA #275 is the relocation against ADRP instructions, which GCC
should not emit anymore when -mcmodel=large is in effect.

Can you confirm that the modules have been rebuilt with this config as
well? Can you double check the GCC command line (with V=1) when doing
'make modules' to ensure that '-mcmodel=large' is being passed? Can
you check with 'readelf -r' which objects still contain
R_AARCH64_ADR_PREL_PG_HI21 relocations?



> I haven't attempted to reproduce with a pure upstream kernel yet.
>
> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1502946
>
>    -dann
>
>> There is a linker fix to generate veneers for ADRP instructions, but
>> this doesn't work for kernel modules which are built as unlinked ELF
>> objects.
>>
>> This patch adds a new config option for the erratum which, when enabled,
>> builds kernel modules with the mcmodel=large flag. This uses absolute
>> addressing for all kernel symbols, thereby removing the use of ADRP as
>> a PC-relative form of addressing. The ADRP relocs are removed from the
>> module loader so that we fail to load any potentially affected modules.
>>
>> Signed-off-by: Will Deacon <will.deacon@arm.com>
>> ---
>>  arch/arm64/Kconfig         | 16 ++++++++++++++++
>>  arch/arm64/Makefile        |  4 ++++
>>  arch/arm64/kernel/module.c |  2 ++
>>  3 files changed, 22 insertions(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 7d95663c0160..11ff4d57c92a 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -331,6 +331,22 @@ config ARM64_ERRATUM_845719
>>
>>           If unsure, say Y.
>>
>> +config ARM64_ERRATUM_843419
>> +       bool "Cortex-A53: 843419: A load or store might access an incorrect address"
>> +       depends on MODULES
>> +       default y
>> +       help
>> +         This option builds kernel modules using the large memory model in
>> +         order to avoid the use of the ADRP instruction, which can cause
>> +         a subsequent memory access to use an incorrect address on Cortex-A53
>> +         parts up to r0p4.
>> +
>> +         Note that the kernel itself must be linked with a version of ld
>> +         which fixes potentially affected ADRP instructions through the
>> +         use of veneers.
>> +
>> +         If unsure, say Y.
>> +
>>  endmenu
>>
>>
>> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
>> index 15ff5b4156fd..f9914d7c1bb0 100644
>> --- a/arch/arm64/Makefile
>> +++ b/arch/arm64/Makefile
>> @@ -41,6 +41,10 @@ endif
>>
>>  CHECKFLAGS     += -D__aarch64__
>>
>> +ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
>> +CFLAGS_MODULE  += -mcmodel=large
>> +endif
>> +
>>  # Default value
>>  head-y         := arch/arm64/kernel/head.o
>>
>> diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
>> index 67bf4107f6ef..876eb8df50bf 100644
>> --- a/arch/arm64/kernel/module.c
>> +++ b/arch/arm64/kernel/module.c
>> @@ -332,12 +332,14 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
>>                         ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 0, 21,
>>                                              AARCH64_INSN_IMM_ADR);
>>                         break;
>> +#ifndef CONFIG_ARM64_ERRATUM_843419
>>                 case R_AARCH64_ADR_PREL_PG_HI21_NC:
>>                         overflow_check = false;
>>                 case R_AARCH64_ADR_PREL_PG_HI21:
>>                         ovf = reloc_insn_imm(RELOC_OP_PAGE, loc, val, 12, 21,
>>                                              AARCH64_INSN_IMM_ADR);
>>                         break;
>> +#endif
>>                 case R_AARCH64_ADD_ABS_LO12_NC:
>>                 case R_AARCH64_LDST8_ABS_LO12_NC:
>>                         overflow_check = false;
>> --
>> 2.1.4
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
dann frazier Oct. 8, 2015, 6:07 a.m. UTC | #6
On Tue, Oct 6, 2015 at 4:29 PM, Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
> On 6 October 2015 at 22:44, Dann Frazier <dann.frazier@canonical.com> wrote:
>> On Wed, Sep 16, 2015 at 5:16 AM, Will Deacon <will.deacon@arm.com> wrote:
>>> Cortex-A53 processors <= r0p4 are affected by erratum #843419 which can
>>> lead to a memory access using an incorrect address in certain sequences
>>> headed by an ADRP instruction.
>>
>> Just a heads up that we're seeing a regression in the Ubuntu 4.2 kernel on
>> X-Gene after this patch is applied and the CONFIG enabled.
>>
>> Modules loads fail with messages like:
>>
>> [ 2.192721] module gpio_xgene_sb: unsupported RELA relocation: 275
>> [ 2.193609] module xgene_enet: unsupported RELA relocation: 275
>> [ 2.249402] module libahci: unsupported RELA relocation: 275
>> [ 2.249628] module xgene_enet: unsupported RELA relocation: 275
>> [ 2.359451] module xgene_enet: unsupported RELA relocation: 275
>> [ 2.389444] module xgene_enet: unsupported RELA relocation: 275
>> [ 3.473766] module linear: unsupported RELA relocation: 275
>> [ 3.543252] module multipath: unsupported RELA relocation: 275
>> [ 3.593268] module raid0: unsupported RELA relocation: 275
>> [ 3.663695] module raid1: unsupported RELA relocation: 275
>> [ 3.713964] module raid6_pq: unsupported RELA relocation: 275
>> [ 3.763983] module raid6_pq: unsupported RELA relocation: 275
>> [ 3.803975] module raid6_pq: unsupported RELA relocation: 275
>> [ 3.853881] module raid10: unsupported RELA relocation: 275
>> [ 3.924962] module raid6_pq: unsupported RELA relocation: 275
>>
>
> RELA #275 is the relocation against ADRP instructions, which GCC
> should not emit anymore when -mcmodel=large is in effect.
>
> Can you confirm that the modules have been rebuilt with this config as
> well?

Yeah, it was.

> Can you double check the GCC command line (with V=1) when doing
> 'make modules' to ensure that '-mcmodel=large' is being passed?

I did, and I don't see -mcmodel at all. On a whim I changed
CFLAGS_MODULE in the patch to KBUILD_CFLAGS_MODULE, and V=1 now shows
-mcmodel=large. I haven't had time yet to figure out why the KBUILD
variant is important, nor time to boot test such a build (travel day).

> Can
> you check with 'readelf -r' which objects still contain
> R_AARCH64_ADR_PREL_PG_HI21 relocations?

My readelf seems to truncate the type field (even w/ -W). Let me know
if you still need the list of objects after the above and I can try
fixing it.

  -dann

>
>
>> I haven't attempted to reproduce with a pure upstream kernel yet.
>>
>> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1502946
>>
>>    -dann
>>
>>> There is a linker fix to generate veneers for ADRP instructions, but
>>> this doesn't work for kernel modules which are built as unlinked ELF
>>> objects.
>>>
>>> This patch adds a new config option for the erratum which, when enabled,
>>> builds kernel modules with the mcmodel=large flag. This uses absolute
>>> addressing for all kernel symbols, thereby removing the use of ADRP as
>>> a PC-relative form of addressing. The ADRP relocs are removed from the
>>> module loader so that we fail to load any potentially affected modules.
>>>
>>> Signed-off-by: Will Deacon <will.deacon@arm.com>
>>> ---
>>>  arch/arm64/Kconfig         | 16 ++++++++++++++++
>>>  arch/arm64/Makefile        |  4 ++++
>>>  arch/arm64/kernel/module.c |  2 ++
>>>  3 files changed, 22 insertions(+)
>>>
>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>> index 7d95663c0160..11ff4d57c92a 100644
>>> --- a/arch/arm64/Kconfig
>>> +++ b/arch/arm64/Kconfig
>>> @@ -331,6 +331,22 @@ config ARM64_ERRATUM_845719
>>>
>>>           If unsure, say Y.
>>>
>>> +config ARM64_ERRATUM_843419
>>> +       bool "Cortex-A53: 843419: A load or store might access an incorrect address"
>>> +       depends on MODULES
>>> +       default y
>>> +       help
>>> +         This option builds kernel modules using the large memory model in
>>> +         order to avoid the use of the ADRP instruction, which can cause
>>> +         a subsequent memory access to use an incorrect address on Cortex-A53
>>> +         parts up to r0p4.
>>> +
>>> +         Note that the kernel itself must be linked with a version of ld
>>> +         which fixes potentially affected ADRP instructions through the
>>> +         use of veneers.
>>> +
>>> +         If unsure, say Y.
>>> +
>>>  endmenu
>>>
>>>
>>> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
>>> index 15ff5b4156fd..f9914d7c1bb0 100644
>>> --- a/arch/arm64/Makefile
>>> +++ b/arch/arm64/Makefile
>>> @@ -41,6 +41,10 @@ endif
>>>
>>>  CHECKFLAGS     += -D__aarch64__
>>>
>>> +ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
>>> +CFLAGS_MODULE  += -mcmodel=large
>>> +endif
>>> +
>>>  # Default value
>>>  head-y         := arch/arm64/kernel/head.o
>>>
>>> diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
>>> index 67bf4107f6ef..876eb8df50bf 100644
>>> --- a/arch/arm64/kernel/module.c
>>> +++ b/arch/arm64/kernel/module.c
>>> @@ -332,12 +332,14 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
>>>                         ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 0, 21,
>>>                                              AARCH64_INSN_IMM_ADR);
>>>                         break;
>>> +#ifndef CONFIG_ARM64_ERRATUM_843419
>>>                 case R_AARCH64_ADR_PREL_PG_HI21_NC:
>>>                         overflow_check = false;
>>>                 case R_AARCH64_ADR_PREL_PG_HI21:
>>>                         ovf = reloc_insn_imm(RELOC_OP_PAGE, loc, val, 12, 21,
>>>                                              AARCH64_INSN_IMM_ADR);
>>>                         break;
>>> +#endif
>>>                 case R_AARCH64_ADD_ABS_LO12_NC:
>>>                 case R_AARCH64_LDST8_ABS_LO12_NC:
>>>                         overflow_check = false;
>>> --
>>> 2.1.4
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel@lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon Oct. 8, 2015, 10:07 a.m. UTC | #7
On Thu, Oct 08, 2015 at 12:07:54AM -0600, Dann Frazier wrote:
> On Tue, Oct 6, 2015 at 4:29 PM, Ard Biesheuvel
> <ard.biesheuvel@linaro.org> wrote:
> > On 6 October 2015 at 22:44, Dann Frazier <dann.frazier@canonical.com> wrote:
> >> On Wed, Sep 16, 2015 at 5:16 AM, Will Deacon <will.deacon@arm.com> wrote:
> >>> Cortex-A53 processors <= r0p4 are affected by erratum #843419 which can
> >>> lead to a memory access using an incorrect address in certain sequences
> >>> headed by an ADRP instruction.
> >>
> >> Just a heads up that we're seeing a regression in the Ubuntu 4.2 kernel on
> >> X-Gene after this patch is applied and the CONFIG enabled.
> >>
> >> Modules loads fail with messages like:
> >>
> >> [ 2.192721] module gpio_xgene_sb: unsupported RELA relocation: 275
> >> [ 2.193609] module xgene_enet: unsupported RELA relocation: 275
> >> [ 2.249402] module libahci: unsupported RELA relocation: 275
> >> [ 2.249628] module xgene_enet: unsupported RELA relocation: 275
> >> [ 2.359451] module xgene_enet: unsupported RELA relocation: 275
> >> [ 2.389444] module xgene_enet: unsupported RELA relocation: 275
> >> [ 3.473766] module linear: unsupported RELA relocation: 275
> >> [ 3.543252] module multipath: unsupported RELA relocation: 275
> >> [ 3.593268] module raid0: unsupported RELA relocation: 275
> >> [ 3.663695] module raid1: unsupported RELA relocation: 275
> >> [ 3.713964] module raid6_pq: unsupported RELA relocation: 275
> >> [ 3.763983] module raid6_pq: unsupported RELA relocation: 275
> >> [ 3.803975] module raid6_pq: unsupported RELA relocation: 275
> >> [ 3.853881] module raid10: unsupported RELA relocation: 275
> >> [ 3.924962] module raid6_pq: unsupported RELA relocation: 275
> >>
> >
> > RELA #275 is the relocation against ADRP instructions, which GCC
> > should not emit anymore when -mcmodel=large is in effect.
> >
> > Can you confirm that the modules have been rebuilt with this config as
> > well?
> 
> Yeah, it was.
> 
> > Can you double check the GCC command line (with V=1) when doing
> > 'make modules' to ensure that '-mcmodel=large' is being passed?
> 
> I did, and I don't see -mcmodel at all. On a whim I changed
> CFLAGS_MODULE in the patch to KBUILD_CFLAGS_MODULE, and V=1 now shows
> -mcmodel=large. I haven't had time yet to figure out why the KBUILD
> variant is important, nor time to boot test such a build (travel day).

CFLAGS_MODULE is the environment variable (i.e. you can set it on the
cmdline), so we probably *should* be using KBUILD_CFLAGS_MODULE here
instead (and the thumb2 gas issue on arch/arm/ should be updated as
well).

However, I'd still like to understand how it's getting clobbered for
you. Are you overriding CFLAGS_MODULE someplace?

Will
dann frazier Oct. 8, 2015, 3:21 p.m. UTC | #8
On Thu, Oct 8, 2015 at 3:07 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Thu, Oct 08, 2015 at 12:07:54AM -0600, Dann Frazier wrote:
>> On Tue, Oct 6, 2015 at 4:29 PM, Ard Biesheuvel
>> <ard.biesheuvel@linaro.org> wrote:
>> > On 6 October 2015 at 22:44, Dann Frazier <dann.frazier@canonical.com> wrote:
>> >> On Wed, Sep 16, 2015 at 5:16 AM, Will Deacon <will.deacon@arm.com> wrote:
>> >>> Cortex-A53 processors <= r0p4 are affected by erratum #843419 which can
>> >>> lead to a memory access using an incorrect address in certain sequences
>> >>> headed by an ADRP instruction.
>> >>
>> >> Just a heads up that we're seeing a regression in the Ubuntu 4.2 kernel on
>> >> X-Gene after this patch is applied and the CONFIG enabled.
>> >>
>> >> Modules loads fail with messages like:
>> >>
>> >> [ 2.192721] module gpio_xgene_sb: unsupported RELA relocation: 275
>> >> [ 2.193609] module xgene_enet: unsupported RELA relocation: 275
>> >> [ 2.249402] module libahci: unsupported RELA relocation: 275
>> >> [ 2.249628] module xgene_enet: unsupported RELA relocation: 275
>> >> [ 2.359451] module xgene_enet: unsupported RELA relocation: 275
>> >> [ 2.389444] module xgene_enet: unsupported RELA relocation: 275
>> >> [ 3.473766] module linear: unsupported RELA relocation: 275
>> >> [ 3.543252] module multipath: unsupported RELA relocation: 275
>> >> [ 3.593268] module raid0: unsupported RELA relocation: 275
>> >> [ 3.663695] module raid1: unsupported RELA relocation: 275
>> >> [ 3.713964] module raid6_pq: unsupported RELA relocation: 275
>> >> [ 3.763983] module raid6_pq: unsupported RELA relocation: 275
>> >> [ 3.803975] module raid6_pq: unsupported RELA relocation: 275
>> >> [ 3.853881] module raid10: unsupported RELA relocation: 275
>> >> [ 3.924962] module raid6_pq: unsupported RELA relocation: 275
>> >>
>> >
>> > RELA #275 is the relocation against ADRP instructions, which GCC
>> > should not emit anymore when -mcmodel=large is in effect.
>> >
>> > Can you confirm that the modules have been rebuilt with this config as
>> > well?
>>
>> Yeah, it was.
>>
>> > Can you double check the GCC command line (with V=1) when doing
>> > 'make modules' to ensure that '-mcmodel=large' is being passed?
>>
>> I did, and I don't see -mcmodel at all. On a whim I changed
>> CFLAGS_MODULE in the patch to KBUILD_CFLAGS_MODULE, and V=1 now shows
>> -mcmodel=large. I haven't had time yet to figure out why the KBUILD
>> variant is important, nor time to boot test such a build (travel day).
>
> CFLAGS_MODULE is the environment variable (i.e. you can set it on the
> cmdline), so we probably *should* be using KBUILD_CFLAGS_MODULE here
> instead (and the thumb2 gas issue on arch/arm/ should be updated as
> well).
>
> However, I'd still like to understand how it's getting clobbered for
> you. Are you overriding CFLAGS_MODULE someplace?

Yep - apparently the Ubuntu kernel packaging uses it to pass the ABI number:

kmake = make ARCH=$(build_arch) \
        CROSS_COMPILE=$(CROSS_COMPILE) \
        KERNELVERSION=$(abi_release)-$(target_flavour) \
        CONFIG_DEBUG_SECTION_MISMATCH=y \
        KBUILD_BUILD_VERSION="$(uploadnum)" \
        LOCALVERSION= localver-extra= \
        CFLAGS_MODULE="-DPKG_ABI=$(abinum)"
diff mbox

Patch

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7d95663c0160..11ff4d57c92a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -331,6 +331,22 @@  config ARM64_ERRATUM_845719
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_843419
+	bool "Cortex-A53: 843419: A load or store might access an incorrect address"
+	depends on MODULES
+	default y
+	help
+	  This option builds kernel modules using the large memory model in
+	  order to avoid the use of the ADRP instruction, which can cause
+	  a subsequent memory access to use an incorrect address on Cortex-A53
+	  parts up to r0p4.
+
+	  Note that the kernel itself must be linked with a version of ld
+	  which fixes potentially affected ADRP instructions through the
+	  use of veneers.
+
+	  If unsure, say Y.
+
 endmenu
 
 
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 15ff5b4156fd..f9914d7c1bb0 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -41,6 +41,10 @@  endif
 
 CHECKFLAGS	+= -D__aarch64__
 
+ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
+CFLAGS_MODULE	+= -mcmodel=large
+endif
+
 # Default value
 head-y		:= arch/arm64/kernel/head.o
 
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 67bf4107f6ef..876eb8df50bf 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -332,12 +332,14 @@  int apply_relocate_add(Elf64_Shdr *sechdrs,
 			ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 0, 21,
 					     AARCH64_INSN_IMM_ADR);
 			break;
+#ifndef CONFIG_ARM64_ERRATUM_843419
 		case R_AARCH64_ADR_PREL_PG_HI21_NC:
 			overflow_check = false;
 		case R_AARCH64_ADR_PREL_PG_HI21:
 			ovf = reloc_insn_imm(RELOC_OP_PAGE, loc, val, 12, 21,
 					     AARCH64_INSN_IMM_ADR);
 			break;
+#endif
 		case R_AARCH64_ADD_ABS_LO12_NC:
 		case R_AARCH64_LDST8_ABS_LO12_NC:
 			overflow_check = false;