diff mbox series

[RFC,v2,11/11] efi/x86: Rely on compiler to emit MS ABI calls

Message ID 20230818113724.368492-12-ardb@kernel.org
State New
Headers show
Series efi: Clean up runtime wrapper and wire it up for PRM | expand

Commit Message

Ard Biesheuvel Aug. 18, 2023, 11:37 a.m. UTC
When EFI support was added to the x86_64 port originally, GCC did not
implement support for emitting procedure calls using the MS calling
convention, which deviates from the SysV one used in Linux.

However, this support has been added a long time ago, and the EFI stub
(which runs in a different execution context) has already been updated
to simply rely on the __attribute__((ms_abi)) annotations of the EFI
function pointers, resulting in both GCC and Clang doing the right
thing, as long as the correct stack alignment is being used.

The EFI stub runs on the stack provided by the firmware, and maintains
16 byte alignment internally, but the core x86_64 code does not, so
explicit stack realignment is needed, and this has been dealt with in
a previous patch. So the asm wrapper has become redundant, and can be
dropped.

Note that one of the EFI runtime services returns void so a trick is
needed to make the compiler ignore the return value in that case, or an
error will be triggered.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/x86/include/asm/efi.h          | 11 +++-----
 arch/x86/platform/efi/Makefile      |  4 +--
 arch/x86/platform/efi/efi_stub_64.S | 27 --------------------
 3 files changed, 5 insertions(+), 37 deletions(-)
diff mbox series

Patch

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index c47f2d49e6bc6a09..f5ac4dbecafe7f37 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -94,19 +94,14 @@  static inline void efi_fpu_end(void)
 #else /* !CONFIG_X86_32 */
 #define EFI_X86_KERNEL_ALLOC_LIMIT		EFI_ALLOC_LIMIT
 
-extern asmlinkage u64 __efi_call(void *fp, ...);
-
 extern bool efi_disable_ibt_for_runtime;
 
-#define efi_call(...) ({						\
-	__efi_nargs_check(efi_call, 7, __VA_ARGS__);			\
-	__efi_call(__VA_ARGS__);					\
-})
-
 #undef arch_efi_call_virt
 #define arch_efi_call_virt(p, f, args...) ({				\
 	u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime);		\
-	ret = efi_call((void *)p->f, args);				\
+	ret = __builtin_choose_expr(					\
+		__builtin_types_compatible_p(typeof((p)->f(args)),void),\
+			((p)->f(args), EFI_ABORTED), (p)->f(args));	\
 	ibt_restore(ibt);						\
 	ret;								\
 })
diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile
index 684ac27cdf7cabfe..6dbd9533c4ce088c 100644
--- a/arch/x86/platform/efi/Makefile
+++ b/arch/x86/platform/efi/Makefile
@@ -2,8 +2,8 @@ 
 KASAN_SANITIZE := n
 GCOV_PROFILE := n
 
-obj-$(CONFIG_EFI) 		+= memmap.o quirks.o efi.o efi_$(BITS).o \
-				   efi_stub_$(BITS).o
+obj-$(CONFIG_EFI) 		+= memmap.o quirks.o efi.o efi_$(BITS).o
+obj-$(CONFIG_X86_32)		+= efi_stub_32.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
diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S
deleted file mode 100644
index 2206b8bc47b8a757..0000000000000000
--- a/arch/x86/platform/efi/efi_stub_64.S
+++ /dev/null
@@ -1,27 +0,0 @@ 
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Function calling ABI conversion from Linux to EFI for x86_64
- *
- * Copyright (C) 2007 Intel Corp
- *	Bibo Mao <bibo.mao@intel.com>
- *	Huang Ying <ying.huang@intel.com>
- */
-
-#include <linux/linkage.h>
-#include <asm/nospec-branch.h>
-
-SYM_FUNC_START(__efi_call)
-	pushq %rbp
-	movq %rsp, %rbp
-	and $~0xf, %rsp
-	mov 16(%rbp), %rax
-	subq $48, %rsp
-	mov %r9, 32(%rsp)
-	mov %rax, 40(%rsp)
-	mov %r8, %r9
-	mov %rcx, %r8
-	mov %rsi, %rcx
-	CALL_NOSPEC rdi
-	leave
-	RET
-SYM_FUNC_END(__efi_call)