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 #define pr_fmt(fmt) "efi: " fmt
19 #include <linux/bug.h>
20 #include <linux/efi.h>
21 #include <linux/irqflags.h>
22 #include <linux/mutex.h>
23 #include <linux/semaphore.h>
24 #include <linux/stringify.h>
28 * Wrap around the new efi_call_virt_generic() macros so that the
29 * code doesn't get too cluttered:
31 #define efi_call_virt(f, args...) \
32 efi_call_virt_pointer(efi.systab->runtime, f, args)
33 #define __efi_call_virt(f, args...) \
34 __efi_call_virt_pointer(efi.systab->runtime, f, args)
36 void efi_call_virt_check_flags(unsigned long flags
, const char *call
)
38 unsigned long cur_flags
, mismatch
;
40 local_save_flags(cur_flags
);
42 mismatch
= flags
^ cur_flags
;
43 if (!WARN_ON_ONCE(mismatch
& ARCH_EFI_IRQ_FLAGS_MASK
))
46 add_taint(TAINT_FIRMWARE_WORKAROUND
, LOCKDEP_NOW_UNRELIABLE
);
47 pr_err_ratelimited(FW_BUG
"IRQ flags corrupted (0x%08lx=>0x%08lx) by EFI %s\n",
48 flags
, cur_flags
, call
);
49 local_irq_restore(flags
);
53 * According to section 7.1 of the UEFI spec, Runtime Services are not fully
54 * reentrant, and there are particular combinations of calls that need to be
55 * serialized. (source: UEFI Specification v2.4A)
57 * Table 31. Rules for Reentry Into Runtime Services
58 * +------------------------------------+-------------------------------+
59 * | If previous call is busy in | Forbidden to call |
60 * +------------------------------------+-------------------------------+
61 * | Any | SetVirtualAddressMap() |
62 * +------------------------------------+-------------------------------+
63 * | ConvertPointer() | ConvertPointer() |
64 * +------------------------------------+-------------------------------+
65 * | SetVariable() | ResetSystem() |
66 * | UpdateCapsule() | |
68 * | SetWakeupTime() | |
69 * | GetNextHighMonotonicCount() | |
70 * +------------------------------------+-------------------------------+
71 * | GetVariable() | GetVariable() |
72 * | GetNextVariableName() | GetNextVariableName() |
73 * | SetVariable() | SetVariable() |
74 * | QueryVariableInfo() | QueryVariableInfo() |
75 * | UpdateCapsule() | UpdateCapsule() |
76 * | QueryCapsuleCapabilities() | QueryCapsuleCapabilities() |
77 * | GetNextHighMonotonicCount() | GetNextHighMonotonicCount() |
78 * +------------------------------------+-------------------------------+
79 * | GetTime() | GetTime() |
80 * | SetTime() | SetTime() |
81 * | GetWakeupTime() | GetWakeupTime() |
82 * | SetWakeupTime() | SetWakeupTime() |
83 * +------------------------------------+-------------------------------+
85 * Due to the fact that the EFI pstore may write to the variable store in
86 * interrupt context, we need to use a lock for at least the groups that
87 * contain SetVariable() and QueryVariableInfo(). That leaves little else, as
88 * none of the remaining functions are actually ever called at runtime.
89 * So let's just use a single lock to serialize all Runtime Services calls.
91 static DEFINE_SEMAPHORE(efi_runtime_lock
);
93 static efi_status_t
virt_efi_get_time(efi_time_t
*tm
, efi_time_cap_t
*tc
)
97 if (down_interruptible(&efi_runtime_lock
))
99 status
= efi_call_virt(get_time
, tm
, tc
);
100 up(&efi_runtime_lock
);
104 static efi_status_t
virt_efi_set_time(efi_time_t
*tm
)
108 if (down_interruptible(&efi_runtime_lock
))
110 status
= efi_call_virt(set_time
, tm
);
111 up(&efi_runtime_lock
);
115 static efi_status_t
virt_efi_get_wakeup_time(efi_bool_t
*enabled
,
121 if (down_interruptible(&efi_runtime_lock
))
123 status
= efi_call_virt(get_wakeup_time
, enabled
, pending
, tm
);
124 up(&efi_runtime_lock
);
128 static efi_status_t
virt_efi_set_wakeup_time(efi_bool_t enabled
, efi_time_t
*tm
)
132 if (down_interruptible(&efi_runtime_lock
))
134 status
= efi_call_virt(set_wakeup_time
, enabled
, tm
);
135 up(&efi_runtime_lock
);
139 static efi_status_t
virt_efi_get_variable(efi_char16_t
*name
,
142 unsigned long *data_size
,
147 if (down_interruptible(&efi_runtime_lock
))
149 status
= efi_call_virt(get_variable
, name
, vendor
, attr
, data_size
,
151 up(&efi_runtime_lock
);
155 static efi_status_t
virt_efi_get_next_variable(unsigned long *name_size
,
161 if (down_interruptible(&efi_runtime_lock
))
163 status
= efi_call_virt(get_next_variable
, name_size
, name
, vendor
);
164 up(&efi_runtime_lock
);
168 static efi_status_t
virt_efi_set_variable(efi_char16_t
*name
,
171 unsigned long data_size
,
176 if (down_interruptible(&efi_runtime_lock
))
178 status
= efi_call_virt(set_variable
, name
, vendor
, attr
, data_size
,
180 up(&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 (down_trylock(&efi_runtime_lock
))
192 return EFI_NOT_READY
;
194 status
= efi_call_virt(set_variable
, name
, vendor
, attr
, data_size
,
196 up(&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 if (down_interruptible(&efi_runtime_lock
))
213 status
= efi_call_virt(query_variable_info
, attr
, storage_space
,
214 remaining_space
, max_variable_size
);
215 up(&efi_runtime_lock
);
220 virt_efi_query_variable_info_nonblocking(u32 attr
,
222 u64
*remaining_space
,
223 u64
*max_variable_size
)
227 if (efi
.runtime_version
< EFI_2_00_SYSTEM_TABLE_REVISION
)
228 return EFI_UNSUPPORTED
;
230 if (down_trylock(&efi_runtime_lock
))
231 return EFI_NOT_READY
;
233 status
= efi_call_virt(query_variable_info
, attr
, storage_space
,
234 remaining_space
, max_variable_size
);
235 up(&efi_runtime_lock
);
239 static efi_status_t
virt_efi_get_next_high_mono_count(u32
*count
)
243 if (down_interruptible(&efi_runtime_lock
))
245 status
= efi_call_virt(get_next_high_mono_count
, count
);
246 up(&efi_runtime_lock
);
250 static void virt_efi_reset_system(int reset_type
,
252 unsigned long data_size
,
255 if (down_interruptible(&efi_runtime_lock
)) {
256 pr_warn("failed to invoke the reset_system() runtime service:\n"
257 "could not get exclusive access to the firmware\n");
260 __efi_call_virt(reset_system
, reset_type
, status
, data_size
, data
);
261 up(&efi_runtime_lock
);
264 static efi_status_t
virt_efi_update_capsule(efi_capsule_header_t
**capsules
,
266 unsigned long sg_list
)
270 if (efi
.runtime_version
< EFI_2_00_SYSTEM_TABLE_REVISION
)
271 return EFI_UNSUPPORTED
;
273 if (down_interruptible(&efi_runtime_lock
))
275 status
= efi_call_virt(update_capsule
, capsules
, count
, sg_list
);
276 up(&efi_runtime_lock
);
280 static efi_status_t
virt_efi_query_capsule_caps(efi_capsule_header_t
**capsules
,
287 if (efi
.runtime_version
< EFI_2_00_SYSTEM_TABLE_REVISION
)
288 return EFI_UNSUPPORTED
;
290 if (down_interruptible(&efi_runtime_lock
))
292 status
= efi_call_virt(query_capsule_caps
, capsules
, count
, max_size
,
294 up(&efi_runtime_lock
);
298 void efi_native_runtime_setup(void)
300 efi
.get_time
= virt_efi_get_time
;
301 efi
.set_time
= virt_efi_set_time
;
302 efi
.get_wakeup_time
= virt_efi_get_wakeup_time
;
303 efi
.set_wakeup_time
= virt_efi_set_wakeup_time
;
304 efi
.get_variable
= virt_efi_get_variable
;
305 efi
.get_next_variable
= virt_efi_get_next_variable
;
306 efi
.set_variable
= virt_efi_set_variable
;
307 efi
.set_variable_nonblocking
= virt_efi_set_variable_nonblocking
;
308 efi
.get_next_high_mono_count
= virt_efi_get_next_high_mono_count
;
309 efi
.reset_system
= virt_efi_reset_system
;
310 efi
.query_variable_info
= virt_efi_query_variable_info
;
311 efi
.query_variable_info_nonblocking
= virt_efi_query_variable_info_nonblocking
;
312 efi
.update_capsule
= virt_efi_update_capsule
;
313 efi
.query_capsule_caps
= virt_efi_query_capsule_caps
;