[RFC PATCH 2/2] efi/x86: Allow translating 64-bit arguments for mixed mode calls

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

 



When an EFI call takes 64-bit arguments, the mixed-mode call must push
the two 32-bit halves as separate arguments onto the stack.

Introduce the ability to define macros to perform this translation for
the calls that need it, and use it for free_pages.

Signed-off-by: Arvind Sankar <nivedita@xxxxxxxxxxxx>
---
 arch/x86/boot/compressed/eboot.c              | 17 ------------
 arch/x86/include/asm/efi.h                    | 27 +++++++++++++++----
 .../firmware/efi/libstub/efi-stub-helper.c    |  5 +---
 3 files changed, 23 insertions(+), 26 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 98477f3529f6..4884483ec093 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -889,20 +889,3 @@ struct boot_params *efi_main(efi_handle_t handle,
 	for (;;)
 		asm("hlt");
 }
-
-#ifdef CONFIG_EFI_MIXED
-void efi_free_native(unsigned long size, unsigned long addr);
-
-void efi_free(unsigned long size, unsigned long addr)
-{
-	if (!size)
-		return;
-
-	if (efi_is_native())
-		efi_free_native(size, addr);
-	else
-		efi64_thunk(efi_table_attr(efi_system_table(),
-					   boottime)->mixed_mode.free_pages,
-			    addr, 0, DIV_ROUND_UP(size, EFI_PAGE_SIZE));
-}
-#endif
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index c9800802894f..5f70499803a1 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -258,22 +258,39 @@ static inline bool efi_is_native(void)
 		: (__typeof__(inst->attr))				\
 			efi_mixed_mode_cast(inst->mixed_mode.attr))
 
+#define __efi64_thunk(inst, func, ...)					\
+	efi64_thunk(inst->mixed_mode.func,				\
+		__efi64_argmap(__efi64_argmap_ ## func, __VA_ARGS__))
+
+#define __efi64_argmap(map, ...)					\
+	__PASTE(__efi64_argmap__,					\
+		__efi64_argmap_def_p(map(__VA_ARGS__)))(map, __VA_ARGS__)
+
+#define __efi64_argmap__undef(map, ...) __VA_ARGS__
+#define __efi64_argmap__def(map, ...) map(__VA_ARGS__)
+
+#define __efi64_argmap_def_p(...)					\
+	__efi64_argmap_def_p_(__VA_ARGS__, __efi_arg_sentinel(undef))
+#define __efi64_argmap_def_p_(_0, n, ...) __take_second_arg(n, def)
+
 #define efi_call_proto(inst, func, ...)					\
 	(efi_is_native()						\
 		? inst->func(inst, ##__VA_ARGS__)			\
-		: efi64_thunk(inst->mixed_mode.func, inst, ##__VA_ARGS__))
+		: __efi64_thunk(inst, func, inst, ##__VA_ARGS__))
 
 #define efi_bs_call(func, ...)						\
 	(efi_is_native()						\
 		? efi_system_table()->boottime->func(__VA_ARGS__)	\
-		: efi64_thunk(efi_table_attr(efi_system_table(),	\
-				boottime)->mixed_mode.func, __VA_ARGS__))
+		: __efi64_thunk(efi_table_attr(efi_system_table(),	\
+				boottime), func, __VA_ARGS__))
 
 #define efi_rt_call(func, ...)						\
 	(efi_is_native()						\
 		? efi_system_table()->runtime->func(__VA_ARGS__)	\
-		: efi64_thunk(efi_table_attr(efi_system_table(),	\
-				runtime)->mixed_mode.func, __VA_ARGS__))
+		: __efi64_thunk(efi_table_attr(efi_system_table(),	\
+				runtime), func, __VA_ARGS__))
+
+#define __efi64_argmap_free_pages(addr, size) (addr), 0, (size)
 
 extern bool efi_reboot_required(void);
 extern bool efi_is_table_address(unsigned long phys_addr);
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index f1b9c36934e9..fcc45ee94e02 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -344,9 +344,6 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
 }
 
 void efi_free(unsigned long size, unsigned long addr)
-	__weak __alias(efi_free_native);
-
-void efi_free_native(unsigned long size, unsigned long addr)
 {
 	unsigned long nr_pages;
 
@@ -354,7 +351,7 @@ void efi_free_native(unsigned long size, unsigned long addr)
 		return;
 
 	nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
-	efi_system_table()->boottime->free_pages(addr, nr_pages);
+	efi_bs_call(free_pages, addr, nr_pages);
 }
 
 static efi_status_t efi_file_size(void *__fh, efi_char16_t *filename_16,
-- 
2.24.1




[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