@@ -21,6 +21,46 @@
#include <asm/efi.h>
/*
+ * Arch code can implement the following three template macros, avoiding
+ * reptition for the void/non-void return cases of {__,}efi_call_virt:
+ *
+ * * arch_efi_call_virt_setup
+ *
+ * Sets up the environment for the call (e.g. switching page tables,
+ * allowing kernel-mode use of floating point, if required).
+ *
+ * * arch_efi_call_virt
+ *
+ * Performs the call. The last expression in the macro must be the call
+ * itself, allowing the logic to be shared by the void and non-void
+ * cases.
+ *
+ * * arch_efi_call_virt_teardown
+ *
+ * Restores the usual kernel environment once the call has returned.
+ */
+
+#ifndef efi_call_virt
+#define efi_call_virt(f, args...) \
+({ \
+ efi_status_t __s; \
+ arch_efi_call_virt_setup(); \
+ __s = arch_efi_call_virt(f, args); \
+ arch_efi_call_virt_teardown(); \
+ __s; \
+})
+#endif
+
+#ifndef __efi_call_virt
+#define __efi_call_virt(f, args...) \
+({ \
+ arch_efi_call_virt_setup(); \
+ arch_efi_call_virt(f, args); \
+ arch_efi_call_virt_teardown(); \
+})
+#endif
+
+/*
* According to section 7.1 of the UEFI spec, Runtime Services are not fully
* reentrant, and there are particular combinations of calls that need to be
* serialized. (source: UEFI Specification v2.4A)