efi/runtime-wrappers: Add {__,}efi_call_virt() templates
[cascardo/linux.git] / drivers / firmware / efi / runtime-wrappers.c
index de69530..0677577 100644 (file)
 #include <linux/spinlock.h>
 #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