Instruct the compiler to realign the stack to 16 bytes, as required by the UEFI specification for x86_64. This will allow us to drop the asm helper that converts between MS and SysV calling conventions in a future patch. Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx> --- arch/x86/Makefile | 3 +++ arch/x86/include/asm/efi.h | 2 ++ arch/x86/platform/efi/Makefile | 2 ++ arch/x86/platform/efi/efi_64.c | 2 +- arch/x86/platform/uv/Makefile | 1 + arch/x86/platform/uv/bios_uv.c | 4 ++-- drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/runtime-wrappers.c | 17 ++++++++++------- 8 files changed, 22 insertions(+), 10 deletions(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index fdc2e3abd6152f53..debc43fb9a2e6d36 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -36,10 +36,13 @@ export RETPOLINE_VDSO_CFLAGS ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) cc_stack_align4 := -mpreferred-stack-boundary=2 cc_stack_align8 := -mpreferred-stack-boundary=3 + EFI_STACK_ALIGN := -mpreferred-stack-boundary=4 else ifneq ($(call cc-option, -mstack-alignment=16),) cc_stack_align4 := -mstack-alignment=4 cc_stack_align8 := -mstack-alignment=8 + EFI_STACK_ALIGN := -mstack-alignment=16 endif +export EFI_STACK_ALIGN # How to compile the 16-bit code. Note we always compile for -march=i386; # that way we can complain to the user if the CPU is insufficient. diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index c4555b269a1b2474..c47f2d49e6bc6a09 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -111,6 +111,8 @@ extern bool efi_disable_ibt_for_runtime; ret; \ }) +#define __efi_realign_stack __attribute__((force_align_arg_pointer)) + #ifdef CONFIG_KASAN /* * CONFIG_KASAN may redefine memset to __memset. __memset function is present diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index 543df9a1379d121c..684ac27cdf7cabfe 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile @@ -7,3 +7,5 @@ obj-$(CONFIG_EFI) += memmap.o quirks.o efi.o efi_$(BITS).o \ obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o + +CFLAGS_efi_64.o := $(EFI_STACK_ALIGN) diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 91d31ac422d6cde7..8033b4a338c4b431 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -846,7 +846,7 @@ void __init efi_thunk_runtime_setup(void) efi.query_capsule_caps = efi_thunk_query_capsule_caps; } -efi_status_t __init __no_sanitize_address +efi_status_t __init __no_sanitize_address __efi_realign_stack efi_set_virtual_address_map(unsigned long memory_map_size, unsigned long descriptor_size, u32 descriptor_version, diff --git a/arch/x86/platform/uv/Makefile b/arch/x86/platform/uv/Makefile index 1441dda8edf76879..cb4807ba4ef50f02 100644 --- a/arch/x86/platform/uv/Makefile +++ b/arch/x86/platform/uv/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_time.o uv_nmi.o +CFLAGS_bios_uv.o := $(EFI_STACK_ALIGN) diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c index bf31af3d32d69cbc..d6b69f363aa1f2a9 100644 --- a/arch/x86/platform/uv/bios_uv.c +++ b/arch/x86/platform/uv/bios_uv.c @@ -20,8 +20,8 @@ unsigned long uv_systab_phys __ro_after_init = EFI_INVALID_TABLE_ADDR; struct uv_systab *uv_systab; -static s64 __uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, - u64 a4, u64 a5) +static s64 __efi_realign_stack +__uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5) { struct uv_systab *tab = uv_systab; s64 ret; diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index e489fefd23dae0bc..db3f8c1fbc1d8a54 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -9,6 +9,7 @@ # in efi_call_virt() will cause crash if this code instrumented. # KASAN_SANITIZE_runtime-wrappers.o := n +CFLAGS_runtime-wrappers.o := $(EFI_STACK_ALIGN) obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o obj-$(CONFIG_EFI) += efi.o vars.o reboot.o memattr.o tpm.o diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index dfec5969dbaba417..2db9e0b3c2842e50 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -35,6 +35,10 @@ #include <asm/efi.h> +#ifndef __efi_realign_stack +#define __efi_realign_stack +#endif + /* * Wrap around the new efi_call_virt_generic() macros so that the * code doesn't get too cluttered: @@ -213,7 +217,7 @@ extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock); * Calls the appropriate efi_runtime_service() with the appropriate * arguments. */ -static void efi_call_rts(struct work_struct *work) +static void __efi_realign_stack efi_call_rts(struct work_struct *work) { const union efi_rts_args *args = efi_rts_work.args; efi_status_t status = EFI_NOT_FOUND; @@ -436,7 +440,7 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, return status; } -static efi_status_t +static efi_status_t __efi_realign_stack virt_efi_set_variable_nb(efi_char16_t *name, efi_guid_t *vendor, u32 attr, unsigned long data_size, void *data) { @@ -470,7 +474,7 @@ static efi_status_t virt_efi_query_variable_info(u32 attr, return status; } -static efi_status_t +static efi_status_t __efi_realign_stack virt_efi_query_variable_info_nb(u32 attr, u64 *storage_space, u64 *remaining_space, u64 *max_variable_size) { @@ -500,10 +504,9 @@ static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) return status; } -static void virt_efi_reset_system(int reset_type, - efi_status_t status, - unsigned long data_size, - efi_char16_t *data) +static void __efi_realign_stack +virt_efi_reset_system(int reset_type, efi_status_t status, + unsigned long data_size, efi_char16_t *data) { if (down_trylock(&efi_runtime_lock)) { pr_warn("failed to invoke the reset_system() runtime service:\n" -- 2.39.2