[PATCH] arm64: errata: add module build workaround for erratum #843419
Ard Biesheuvel
ard.biesheuvel at linaro.org
Thu Sep 17 07:24:01 PDT 2015
Hi Will,
On 16 September 2015 at 13:16, Will Deacon <will.deacon at 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 at 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 at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
More information about the linux-arm-kernel
mailing list