[PATCH] arm64: entry: simplify trampoline data page
Ard Biesheuvel
ardb at kernel.org
Wed Jun 22 07:41:41 PDT 2022
On Wed, 27 Apr 2022 at 12:23, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> Get rid of some clunky open coded arithmetic on section addresses, by
> emitting the trampoline data variables into a separate, dedicated r/o
> data section, and putting it at the next page boundary. This way, we can
> access the literals via single LDR instruction.
>
> While at it, get rid of other, implicit literals, and use ADRP/ADD or
> MOVZ/MOVK sequences, as appropriate. Note that the latter are only
> supported for CONFIG_RELOCATABLE=n (which is usually the case if
> CONFIG_RANDOMIZE_BASE=n), so update the CPP conditionals to reflect
> this.
>
> Cc: James Morse <james.morse at arm.com>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Ping, in case this one slipped behind the desk.
> ---
> arch/arm64/include/asm/fixmap.h | 4 +-
> arch/arm64/kernel/entry.S | 45 ++++++--------------
> arch/arm64/kernel/vmlinux.lds.S | 3 +-
> arch/arm64/mm/mmu.c | 10 ++---
> 4 files changed, 22 insertions(+), 40 deletions(-)
>
> diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
> index daff882883f9..71ed5fdf718b 100644
> --- a/arch/arm64/include/asm/fixmap.h
> +++ b/arch/arm64/include/asm/fixmap.h
> @@ -62,10 +62,12 @@ enum fixed_addresses {
> #endif /* CONFIG_ACPI_APEI_GHES */
>
> #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
> +#ifdef CONFIG_RELOCATABLE
> + FIX_ENTRY_TRAMP_TEXT4, /* one extra slot for the data page */
> +#endif
> FIX_ENTRY_TRAMP_TEXT3,
> FIX_ENTRY_TRAMP_TEXT2,
> FIX_ENTRY_TRAMP_TEXT1,
> - FIX_ENTRY_TRAMP_DATA,
> #define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT1))
> #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
> __end_of_permanent_fixed_addresses,
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index ede028dee81b..aed2b41e05aa 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -636,18 +636,20 @@ alternative_else_nop_endif
> */
> .endm
>
> - .macro tramp_data_page dst
> - adr_l \dst, .entry.tramp.text
> - sub \dst, \dst, PAGE_SIZE
> - .endm
> -
> - .macro tramp_data_read_var dst, var
> -#ifdef CONFIG_RANDOMIZE_BASE
> - tramp_data_page \dst
> - add \dst, \dst, #:lo12:__entry_tramp_data_\var
> - ldr \dst, [\dst]
> + .macro tramp_data_read_var dst, var
> +#ifdef CONFIG_RELOCATABLE
> + ldr \dst, .L__tramp_data_\var
> + .ifndef .L__tramp_data_\var
> + .pushsection ".entry.tramp.rodata", "a", %progbits
> + .align 3
> +.L__tramp_data_\var:
> + .quad \var
> + .popsection
> + .endif
> #else
> - ldr \dst, =\var
> + movz \dst, :abs_g2_s:\var
> + movk \dst, :abs_g1_nc:\var
> + movk \dst, :abs_g0_nc:\var
> #endif
> .endm
>
> @@ -695,7 +697,7 @@ alternative_else_nop_endif
> msr vbar_el1, x30
> isb
> .else
> - ldr x30, =vectors
> + adr_l x30, vectors
> .endif // \kpti == 1
>
> .if \bhb == BHB_MITIGATION_FW
> @@ -764,24 +766,7 @@ SYM_CODE_END(tramp_exit_native)
> SYM_CODE_START(tramp_exit_compat)
> tramp_exit 32
> SYM_CODE_END(tramp_exit_compat)
> -
> - .ltorg
> .popsection // .entry.tramp.text
> -#ifdef CONFIG_RANDOMIZE_BASE
> - .pushsection ".rodata", "a"
> - .align PAGE_SHIFT
> -SYM_DATA_START(__entry_tramp_data_start)
> -__entry_tramp_data_vectors:
> - .quad vectors
> -#ifdef CONFIG_ARM_SDE_INTERFACE
> -__entry_tramp_data___sdei_asm_handler:
> - .quad __sdei_asm_handler
> -#endif /* CONFIG_ARM_SDE_INTERFACE */
> -__entry_tramp_data_this_cpu_vector:
> - .quad this_cpu_vector
> -SYM_DATA_END(__entry_tramp_data_start)
> - .popsection // .rodata
> -#endif /* CONFIG_RANDOMIZE_BASE */
> #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
>
> /*
> @@ -932,7 +917,6 @@ NOKPROBE(call_on_irq_stack)
> * This clobbers x4, __sdei_handler() will restore this from firmware's
> * copy.
> */
> -.ltorg
> .pushsection ".entry.tramp.text", "ax"
> SYM_CODE_START(__sdei_asm_entry_trampoline)
> mrs x4, ttbr1_el1
> @@ -967,7 +951,6 @@ SYM_CODE_START(__sdei_asm_exit_trampoline)
> 1: sdei_handler_exit exit_mode=x2
> SYM_CODE_END(__sdei_asm_exit_trampoline)
> NOKPROBE(__sdei_asm_exit_trampoline)
> - .ltorg
> .popsection // .entry.tramp.text
> #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
>
> diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
> index edaf0faf766f..17e554be9198 100644
> --- a/arch/arm64/kernel/vmlinux.lds.S
> +++ b/arch/arm64/kernel/vmlinux.lds.S
> @@ -117,7 +117,8 @@ jiffies = jiffies_64;
> __entry_tramp_text_start = .; \
> *(.entry.tramp.text) \
> . = ALIGN(PAGE_SIZE); \
> - __entry_tramp_text_end = .;
> + __entry_tramp_text_end = .; \
> + *(.entry.tramp.rodata)
> #else
> #define TRAMP_TEXT
> #endif
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 626ec32873c6..be4d6c3f5692 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -665,13 +665,9 @@ static int __init map_entry_trampoline(void)
> __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i,
> pa_start + i * PAGE_SIZE, prot);
>
> - if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
> - extern char __entry_tramp_data_start[];
> -
> - __set_fixmap(FIX_ENTRY_TRAMP_DATA,
> - __pa_symbol(__entry_tramp_data_start),
> - PAGE_KERNEL_RO);
> - }
> + if (IS_ENABLED(CONFIG_RELOCATABLE))
> + __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i,
> + pa_start + i * PAGE_SIZE, PAGE_KERNEL_RO);
>
> return 0;
> }
> --
> 2.30.2
>
More information about the linux-arm-kernel
mailing list