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