efi/runtime-wrappers: Add {__,}efi_call_virt() templates
[cascardo/linux.git] / drivers / firmware / efi / runtime-wrappers.c
1 /*
2  * runtime-wrappers.c - Runtime Services function call wrappers
3  *
4  * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
5  *
6  * Split off from arch/x86/platform/efi/efi.c
7  *
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
13  *
14  * This file is released under the GPLv2.
15  */
16
17 #include <linux/bug.h>
18 #include <linux/efi.h>
19 #include <linux/mutex.h>
20 #include <linux/spinlock.h>
21 #include <asm/efi.h>
22
23 /*
24  * Arch code can implement the following three template macros, avoiding
25  * reptition for the void/non-void return cases of {__,}efi_call_virt:
26  *
27  *  * arch_efi_call_virt_setup
28  *
29  *    Sets up the environment for the call (e.g. switching page tables,
30  *    allowing kernel-mode use of floating point, if required).
31  *
32  *  * arch_efi_call_virt
33  *
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
36  *    cases.
37  *
38  *  * arch_efi_call_virt_teardown
39  *
40  *    Restores the usual kernel environment once the call has returned.
41  */
42
43 #ifndef efi_call_virt
44 #define efi_call_virt(f, args...)                                       \
45 ({                                                                      \
46         efi_status_t __s;                                               \
47         arch_efi_call_virt_setup();                                     \
48         __s = arch_efi_call_virt(f, args);                              \
49         arch_efi_call_virt_teardown();                                  \
50         __s;                                                            \
51 })
52 #endif
53
54 #ifndef __efi_call_virt
55 #define __efi_call_virt(f, args...)                                     \
56 ({                                                                      \
57         arch_efi_call_virt_setup();                                     \
58         arch_efi_call_virt(f, args);                                    \
59         arch_efi_call_virt_teardown();                                  \
60 })
61 #endif
62
63 /*
64  * According to section 7.1 of the UEFI spec, Runtime Services are not fully
65  * reentrant, and there are particular combinations of calls that need to be
66  * serialized. (source: UEFI Specification v2.4A)
67  *
68  * Table 31. Rules for Reentry Into Runtime Services
69  * +------------------------------------+-------------------------------+
70  * | If previous call is busy in        | Forbidden to call             |
71  * +------------------------------------+-------------------------------+
72  * | Any                                | SetVirtualAddressMap()        |
73  * +------------------------------------+-------------------------------+
74  * | ConvertPointer()                   | ConvertPointer()              |
75  * +------------------------------------+-------------------------------+
76  * | SetVariable()                      | ResetSystem()                 |
77  * | UpdateCapsule()                    |                               |
78  * | SetTime()                          |                               |
79  * | SetWakeupTime()                    |                               |
80  * | GetNextHighMonotonicCount()        |                               |
81  * +------------------------------------+-------------------------------+
82  * | GetVariable()                      | GetVariable()                 |
83  * | GetNextVariableName()              | GetNextVariableName()         |
84  * | SetVariable()                      | SetVariable()                 |
85  * | QueryVariableInfo()                | QueryVariableInfo()           |
86  * | UpdateCapsule()                    | UpdateCapsule()               |
87  * | QueryCapsuleCapabilities()         | QueryCapsuleCapabilities()    |
88  * | GetNextHighMonotonicCount()        | GetNextHighMonotonicCount()   |
89  * +------------------------------------+-------------------------------+
90  * | GetTime()                          | GetTime()                     |
91  * | SetTime()                          | SetTime()                     |
92  * | GetWakeupTime()                    | GetWakeupTime()               |
93  * | SetWakeupTime()                    | SetWakeupTime()               |
94  * +------------------------------------+-------------------------------+
95  *
96  * Due to the fact that the EFI pstore may write to the variable store in
97  * interrupt context, we need to use a spinlock for at least the groups that
98  * contain SetVariable() and QueryVariableInfo(). That leaves little else, as
99  * none of the remaining functions are actually ever called at runtime.
100  * So let's just use a single spinlock to serialize all Runtime Services calls.
101  */
102 static DEFINE_SPINLOCK(efi_runtime_lock);
103
104 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
105 {
106         efi_status_t status;
107
108         spin_lock(&efi_runtime_lock);
109         status = efi_call_virt(get_time, tm, tc);
110         spin_unlock(&efi_runtime_lock);
111         return status;
112 }
113
114 static efi_status_t virt_efi_set_time(efi_time_t *tm)
115 {
116         efi_status_t status;
117
118         spin_lock(&efi_runtime_lock);
119         status = efi_call_virt(set_time, tm);
120         spin_unlock(&efi_runtime_lock);
121         return status;
122 }
123
124 static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
125                                              efi_bool_t *pending,
126                                              efi_time_t *tm)
127 {
128         efi_status_t status;
129
130         spin_lock(&efi_runtime_lock);
131         status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
132         spin_unlock(&efi_runtime_lock);
133         return status;
134 }
135
136 static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
137 {
138         efi_status_t status;
139
140         spin_lock(&efi_runtime_lock);
141         status = efi_call_virt(set_wakeup_time, enabled, tm);
142         spin_unlock(&efi_runtime_lock);
143         return status;
144 }
145
146 static efi_status_t virt_efi_get_variable(efi_char16_t *name,
147                                           efi_guid_t *vendor,
148                                           u32 *attr,
149                                           unsigned long *data_size,
150                                           void *data)
151 {
152         efi_status_t status;
153
154         spin_lock(&efi_runtime_lock);
155         status = efi_call_virt(get_variable, name, vendor, attr, data_size,
156                                data);
157         spin_unlock(&efi_runtime_lock);
158         return status;
159 }
160
161 static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
162                                                efi_char16_t *name,
163                                                efi_guid_t *vendor)
164 {
165         efi_status_t status;
166
167         spin_lock(&efi_runtime_lock);
168         status = efi_call_virt(get_next_variable, name_size, name, vendor);
169         spin_unlock(&efi_runtime_lock);
170         return status;
171 }
172
173 static efi_status_t virt_efi_set_variable(efi_char16_t *name,
174                                           efi_guid_t *vendor,
175                                           u32 attr,
176                                           unsigned long data_size,
177                                           void *data)
178 {
179         efi_status_t status;
180
181         spin_lock(&efi_runtime_lock);
182         status = efi_call_virt(set_variable, name, vendor, attr, data_size,
183                                data);
184         spin_unlock(&efi_runtime_lock);
185         return status;
186 }
187
188 static efi_status_t
189 virt_efi_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor,
190                                   u32 attr, unsigned long data_size,
191                                   void *data)
192 {
193         efi_status_t status;
194
195         if (!spin_trylock(&efi_runtime_lock))
196                 return EFI_NOT_READY;
197
198         status = efi_call_virt(set_variable, name, vendor, attr, data_size,
199                                data);
200         spin_unlock(&efi_runtime_lock);
201         return status;
202 }
203
204
205 static efi_status_t virt_efi_query_variable_info(u32 attr,
206                                                  u64 *storage_space,
207                                                  u64 *remaining_space,
208                                                  u64 *max_variable_size)
209 {
210         efi_status_t status;
211
212         if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
213                 return EFI_UNSUPPORTED;
214
215         spin_lock(&efi_runtime_lock);
216         status = efi_call_virt(query_variable_info, attr, storage_space,
217                                remaining_space, max_variable_size);
218         spin_unlock(&efi_runtime_lock);
219         return status;
220 }
221
222 static efi_status_t
223 virt_efi_query_variable_info_nonblocking(u32 attr,
224                                          u64 *storage_space,
225                                          u64 *remaining_space,
226                                          u64 *max_variable_size)
227 {
228         efi_status_t status;
229
230         if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
231                 return EFI_UNSUPPORTED;
232
233         if (!spin_trylock(&efi_runtime_lock))
234                 return EFI_NOT_READY;
235
236         status = efi_call_virt(query_variable_info, attr, storage_space,
237                                remaining_space, max_variable_size);
238         spin_unlock(&efi_runtime_lock);
239         return status;
240 }
241
242 static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
243 {
244         efi_status_t status;
245
246         spin_lock(&efi_runtime_lock);
247         status = efi_call_virt(get_next_high_mono_count, count);
248         spin_unlock(&efi_runtime_lock);
249         return status;
250 }
251
252 static void virt_efi_reset_system(int reset_type,
253                                   efi_status_t status,
254                                   unsigned long data_size,
255                                   efi_char16_t *data)
256 {
257         spin_lock(&efi_runtime_lock);
258         __efi_call_virt(reset_system, reset_type, status, data_size, data);
259         spin_unlock(&efi_runtime_lock);
260 }
261
262 static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
263                                             unsigned long count,
264                                             unsigned long sg_list)
265 {
266         efi_status_t status;
267
268         if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
269                 return EFI_UNSUPPORTED;
270
271         spin_lock(&efi_runtime_lock);
272         status = efi_call_virt(update_capsule, capsules, count, sg_list);
273         spin_unlock(&efi_runtime_lock);
274         return status;
275 }
276
277 static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
278                                                 unsigned long count,
279                                                 u64 *max_size,
280                                                 int *reset_type)
281 {
282         efi_status_t status;
283
284         if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
285                 return EFI_UNSUPPORTED;
286
287         spin_lock(&efi_runtime_lock);
288         status = efi_call_virt(query_capsule_caps, capsules, count, max_size,
289                                reset_type);
290         spin_unlock(&efi_runtime_lock);
291         return status;
292 }
293
294 void efi_native_runtime_setup(void)
295 {
296         efi.get_time = virt_efi_get_time;
297         efi.set_time = virt_efi_set_time;
298         efi.get_wakeup_time = virt_efi_get_wakeup_time;
299         efi.set_wakeup_time = virt_efi_set_wakeup_time;
300         efi.get_variable = virt_efi_get_variable;
301         efi.get_next_variable = virt_efi_get_next_variable;
302         efi.set_variable = virt_efi_set_variable;
303         efi.set_variable_nonblocking = virt_efi_set_variable_nonblocking;
304         efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
305         efi.reset_system = virt_efi_reset_system;
306         efi.query_variable_info = virt_efi_query_variable_info;
307         efi.query_variable_info_nonblocking = virt_efi_query_variable_info_nonblocking;
308         efi.update_capsule = virt_efi_update_capsule;
309         efi.query_capsule_caps = virt_efi_query_capsule_caps;
310 }