2 * runtime-wrappers.c - Runtime Services function call wrappers
4 * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
6 * Split off from arch/x86/platform/efi/efi.c
8 * Copyright (C) 1999 VA Linux Systems
9 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
10 * Copyright (C) 1999-2002 Hewlett-Packard Co.
11 * Copyright (C) 2005-2008 Intel Co.
12 * Copyright (C) 2013 SuSE Labs
14 * This file is released under the GPLv2.
17 #include <linux/bug.h>
18 #include <linux/efi.h>
19 #include <linux/mutex.h>
20 #include <linux/spinlock.h>
24 * Arch code can implement the following three template macros, avoiding
25 * reptition for the void/non-void return cases of {__,}efi_call_virt:
27 * * arch_efi_call_virt_setup
29 * Sets up the environment for the call (e.g. switching page tables,
30 * allowing kernel-mode use of floating point, if required).
32 * * arch_efi_call_virt
34 * Performs the call. The last expression in the macro must be the call
35 * itself, allowing the logic to be shared by the void and non-void
38 * * arch_efi_call_virt_teardown
40 * Restores the usual kernel environment once the call has returned.
43 #define efi_call_virt(f, args...) \
46 arch_efi_call_virt_setup(); \
47 __s = arch_efi_call_virt(f, args); \
48 arch_efi_call_virt_teardown(); \
52 #define __efi_call_virt(f, args...) \
54 arch_efi_call_virt_setup(); \
55 arch_efi_call_virt(f, args); \
56 arch_efi_call_virt_teardown(); \
60 * According to section 7.1 of the UEFI spec, Runtime Services are not fully
61 * reentrant, and there are particular combinations of calls that need to be
62 * serialized. (source: UEFI Specification v2.4A)
64 * Table 31. Rules for Reentry Into Runtime Services
65 * +------------------------------------+-------------------------------+
66 * | If previous call is busy in | Forbidden to call |
67 * +------------------------------------+-------------------------------+
68 * | Any | SetVirtualAddressMap() |
69 * +------------------------------------+-------------------------------+
70 * | ConvertPointer() | ConvertPointer() |
71 * +------------------------------------+-------------------------------+
72 * | SetVariable() | ResetSystem() |
73 * | UpdateCapsule() | |
75 * | SetWakeupTime() | |
76 * | GetNextHighMonotonicCount() | |
77 * +------------------------------------+-------------------------------+
78 * | GetVariable() | GetVariable() |
79 * | GetNextVariableName() | GetNextVariableName() |
80 * | SetVariable() | SetVariable() |
81 * | QueryVariableInfo() | QueryVariableInfo() |
82 * | UpdateCapsule() | UpdateCapsule() |
83 * | QueryCapsuleCapabilities() | QueryCapsuleCapabilities() |
84 * | GetNextHighMonotonicCount() | GetNextHighMonotonicCount() |
85 * +------------------------------------+-------------------------------+
86 * | GetTime() | GetTime() |
87 * | SetTime() | SetTime() |
88 * | GetWakeupTime() | GetWakeupTime() |
89 * | SetWakeupTime() | SetWakeupTime() |
90 * +------------------------------------+-------------------------------+
92 * Due to the fact that the EFI pstore may write to the variable store in
93 * interrupt context, we need to use a spinlock for at least the groups that
94 * contain SetVariable() and QueryVariableInfo(). That leaves little else, as
95 * none of the remaining functions are actually ever called at runtime.
96 * So let's just use a single spinlock to serialize all Runtime Services calls.
98 static DEFINE_SPINLOCK(efi_runtime_lock);
100 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
104 spin_lock(&efi_runtime_lock);
105 status = efi_call_virt(get_time, tm, tc);
106 spin_unlock(&efi_runtime_lock);
110 static efi_status_t virt_efi_set_time(efi_time_t *tm)
114 spin_lock(&efi_runtime_lock);
115 status = efi_call_virt(set_time, tm);
116 spin_unlock(&efi_runtime_lock);
120 static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
126 spin_lock(&efi_runtime_lock);
127 status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
128 spin_unlock(&efi_runtime_lock);
132 static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
136 spin_lock(&efi_runtime_lock);
137 status = efi_call_virt(set_wakeup_time, enabled, tm);
138 spin_unlock(&efi_runtime_lock);
142 static efi_status_t virt_efi_get_variable(efi_char16_t *name,
145 unsigned long *data_size,
150 spin_lock(&efi_runtime_lock);
151 status = efi_call_virt(get_variable, name, vendor, attr, data_size,
153 spin_unlock(&efi_runtime_lock);
157 static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
163 spin_lock(&efi_runtime_lock);
164 status = efi_call_virt(get_next_variable, name_size, name, vendor);
165 spin_unlock(&efi_runtime_lock);
169 static efi_status_t virt_efi_set_variable(efi_char16_t *name,
172 unsigned long data_size,
177 spin_lock(&efi_runtime_lock);
178 status = efi_call_virt(set_variable, name, vendor, attr, data_size,
180 spin_unlock(&efi_runtime_lock);
185 virt_efi_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor,
186 u32 attr, unsigned long data_size,
191 if (!spin_trylock(&efi_runtime_lock))
192 return EFI_NOT_READY;
194 status = efi_call_virt(set_variable, name, vendor, attr, data_size,
196 spin_unlock(&efi_runtime_lock);
201 static efi_status_t virt_efi_query_variable_info(u32 attr,
203 u64 *remaining_space,
204 u64 *max_variable_size)
208 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
209 return EFI_UNSUPPORTED;
211 spin_lock(&efi_runtime_lock);
212 status = efi_call_virt(query_variable_info, attr, storage_space,
213 remaining_space, max_variable_size);
214 spin_unlock(&efi_runtime_lock);
219 virt_efi_query_variable_info_nonblocking(u32 attr,
221 u64 *remaining_space,
222 u64 *max_variable_size)
226 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
227 return EFI_UNSUPPORTED;
229 if (!spin_trylock(&efi_runtime_lock))
230 return EFI_NOT_READY;
232 status = efi_call_virt(query_variable_info, attr, storage_space,
233 remaining_space, max_variable_size);
234 spin_unlock(&efi_runtime_lock);
238 static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
242 spin_lock(&efi_runtime_lock);
243 status = efi_call_virt(get_next_high_mono_count, count);
244 spin_unlock(&efi_runtime_lock);
248 static void virt_efi_reset_system(int reset_type,
250 unsigned long data_size,
253 spin_lock(&efi_runtime_lock);
254 __efi_call_virt(reset_system, reset_type, status, data_size, data);
255 spin_unlock(&efi_runtime_lock);
258 static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
260 unsigned long sg_list)
264 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
265 return EFI_UNSUPPORTED;
267 spin_lock(&efi_runtime_lock);
268 status = efi_call_virt(update_capsule, capsules, count, sg_list);
269 spin_unlock(&efi_runtime_lock);
273 static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
280 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
281 return EFI_UNSUPPORTED;
283 spin_lock(&efi_runtime_lock);
284 status = efi_call_virt(query_capsule_caps, capsules, count, max_size,
286 spin_unlock(&efi_runtime_lock);
290 void efi_native_runtime_setup(void)
292 efi.get_time = virt_efi_get_time;
293 efi.set_time = virt_efi_set_time;
294 efi.get_wakeup_time = virt_efi_get_wakeup_time;
295 efi.set_wakeup_time = virt_efi_set_wakeup_time;
296 efi.get_variable = virt_efi_get_variable;
297 efi.get_next_variable = virt_efi_get_next_variable;
298 efi.set_variable = virt_efi_set_variable;
299 efi.set_variable_nonblocking = virt_efi_set_variable_nonblocking;
300 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
301 efi.reset_system = virt_efi_reset_system;
302 efi.query_variable_info = virt_efi_query_variable_info;
303 efi.query_variable_info_nonblocking = virt_efi_query_variable_info_nonblocking;
304 efi.update_capsule = virt_efi_update_capsule;
305 efi.query_capsule_caps = virt_efi_query_capsule_caps;