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