[PATCH v3 1/3] arm64: unwind: add asynchronous unwind tables to kernel and modules

Sami Tolvanen samitolvanen at google.com
Wed Jun 15 09:50:36 PDT 2022


On Mon, Jun 13, 2022 at 03:40:06PM +0200, Ard Biesheuvel wrote:
> Enable asynchronous unwind table generation for both the core kernel as
> well as modules, and emit the resulting .eh_frame sections as init code
> so we can use the unwind directives for code patching at boot or module
> load time.
> 
> This will be used by dynamic shadow call stack support, which will rely
> on code patching rather than compiler codegen to emit the shadow call
> stack push and pop instructions.
> 
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>
> ---
>  arch/arm64/Kconfig                    |  3 +++
>  arch/arm64/Makefile                   |  5 +++++
>  arch/arm64/include/asm/module.lds.h   |  8 ++++++++
>  arch/arm64/kernel/vmlinux.lds.S       | 13 +++++++++++++
>  arch/arm64/kvm/hyp/nvhe/Makefile      |  1 +
>  drivers/firmware/efi/libstub/Makefile |  1 +
>  6 files changed, 31 insertions(+)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 1652a9800ebe..5f92344edff5 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -366,6 +366,9 @@ config KASAN_SHADOW_OFFSET
>  	default 0xeffffff800000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS
>  	default 0xffffffffffffffff
>  
> +config UNWIND_TABLES
> +	bool
> +
>  source "arch/arm64/Kconfig.platforms"
>  
>  menu "Kernel Features"
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index 6d9d4a58b898..4fbca56fa602 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -45,8 +45,13 @@ KBUILD_CFLAGS	+= $(call cc-option,-mabi=lp64)
>  KBUILD_AFLAGS	+= $(call cc-option,-mabi=lp64)
>  
>  # Avoid generating .eh_frame* sections.
> +ifneq ($(CONFIG_UNWIND_TABLES),y)
>  KBUILD_CFLAGS	+= -fno-asynchronous-unwind-tables -fno-unwind-tables
>  KBUILD_AFLAGS	+= -fno-asynchronous-unwind-tables -fno-unwind-tables
> +else
> +KBUILD_CFLAGS	+= -fasynchronous-unwind-tables
> +KBUILD_AFLAGS	+= -fasynchronous-unwind-tables
> +endif
>  
>  ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y)
>  prepare: stack_protector_prepare
> diff --git a/arch/arm64/include/asm/module.lds.h b/arch/arm64/include/asm/module.lds.h
> index 094701ec5500..dbba4b7559aa 100644
> --- a/arch/arm64/include/asm/module.lds.h
> +++ b/arch/arm64/include/asm/module.lds.h
> @@ -17,4 +17,12 @@ SECTIONS {
>  	 */
>  	.text.hot : { *(.text.hot) }
>  #endif
> +
> +#ifdef CONFIG_UNWIND_TABLES
> +	/*
> +	 * Currently, we only use unwind info at module load time, so we can
> +	 * put it into the .init allocation.
> +	 */
> +	.init.eh_frame : { *(.eh_frame) }
> +#endif
>  }
> diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
> index 2d4a8f995175..7bf4809f523d 100644
> --- a/arch/arm64/kernel/vmlinux.lds.S
> +++ b/arch/arm64/kernel/vmlinux.lds.S
> @@ -120,6 +120,17 @@ jiffies = jiffies_64;
>  #define TRAMP_TEXT
>  #endif
>  
> +#ifdef CONFIG_UNWIND_TABLES
> +#define UNWIND_DATA_SECTIONS				\
> +	.eh_frame : {					\
> +		__eh_frame_start = .;			\
> +		*(.eh_frame)				\
> +		__eh_frame_end = .;			\
> +	}
> +#else
> +#define UNWIND_DATA_SECTIONS
> +#endif

How does this work with SANITIZER_DISCARDS dropping .eh_frame in
include/asm-generic/vmlinux.lds.h and scripts/module.lds.S? We would
definitely want to enable this together with CONFIG_CFI_CLANG, so it
seems like we'd have to drop the discard rules as well.

Sami



More information about the linux-arm-kernel mailing list