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

Nick Desaulniers ndesaulniers at google.com
Thu May 5 13:19:58 PDT 2022


On Thu, May 5, 2022 at 9:10 AM Ard Biesheuvel <ardb at kernel.org> 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>

Two minor nits inline below; I don't feel strongly about them either way.
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       | 16 ++++++++++++++++
>  drivers/firmware/efi/libstub/Makefile |  1 +
>  5 files changed, 33 insertions(+)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 57c4c995965f..b6302f7cd73f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -354,6 +354,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 2f1de88651e6..a4c6807ecbaf 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)

You know how I feel about negated conditions when there's an else branch...

>  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 edaf0faf766f..2f4908c8d152 100644
> --- a/arch/arm64/kernel/vmlinux.lds.S
> +++ b/arch/arm64/kernel/vmlinux.lds.S
> @@ -122,6 +122,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
> +
>  /*
>   * The size of the PE/COFF section that covers the kernel image, which
>   * runs from _stext to _edata, must be a round multiple of the PE/COFF
> @@ -150,6 +161,9 @@ SECTIONS
>         /DISCARD/ : {
>                 *(.interp .dynamic)
>                 *(.dynsym .dynstr .hash .gnu.hash)
> +#ifndef CONFIG_UNWIND_TABLES
> +               *(.eh_frame)
> +#endif

If CONFIG_UNWIND_TABLES is unset, then
`-fno-asynchronous-unwind-tables -fno-unwind-tables` should be set; it
would be anomalous otherwise.  We could leave this hunk out and we
should get a warning from `--orphan-handling=warn` linker flag which
would warn explicitly about such anomalies, rather than produce but
then silently discard them.

>         }
>
>         . = KIMAGE_VADDR;
> @@ -228,6 +242,8 @@ SECTIONS
>                 __alt_instructions_end = .;
>         }
>
> +       UNWIND_DATA_SECTIONS
> +
>         . = ALIGN(SEGMENT_ALIGN);
>         __inittext_end = .;
>         __initdata_begin = .;
> diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
> index d0537573501e..78c46638707a 100644
> --- a/drivers/firmware/efi/libstub/Makefile
> +++ b/drivers/firmware/efi/libstub/Makefile
> @@ -20,6 +20,7 @@ cflags-$(CONFIG_X86)          += -m$(BITS) -D__KERNEL__ \
>  # disable the stackleak plugin
>  cflags-$(CONFIG_ARM64)         := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
>                                    -fpie $(DISABLE_STACKLEAK_PLUGIN) \
> +                                  -fno-unwind-tables -fno-asynchronous-unwind-tables \
>                                    $(call cc-option,-mbranch-protection=none)
>  cflags-$(CONFIG_ARM)           := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
>                                    -fno-builtin -fpic \
> --
> 2.30.2
>


-- 
Thanks,
~Nick Desaulniers



More information about the linux-arm-kernel mailing list