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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 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 --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@xxxxxxxxx>
- *	Huang Ying <ying.huang@xxxxxxxxx>
- */
-
-#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)
-- 
2.39.2




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux