aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2014-09-30 10:03:38 -0400
committerMatt Fleming <matt.fleming@intel.com>2014-10-03 13:41:03 -0400
commit60b4dc7720a5251f5dbda69ad404e0bcb3cb6bfb (patch)
treefca7b787763f26f7e197fab447d00943fcd13439 /drivers/firmware
parent6d80dba1c9fe4316ef626980102b92fa30c7845a (diff)
efi: Delete the in_nmi() conditional runtime locking
commit 5dc3826d9f08 ("efi: Implement mandatory locking for UEFI Runtime Services") implemented some conditional locking when accessing variable runtime services that Ingo described as "pretty disgusting". The intention with the !efi_in_nmi() checks was to avoid live-locks when trying to write pstore crash data into an EFI variable. Such lockless accesses are allowed according to the UEFI specification when we're in a "non-recoverable" state, but whether or not things are implemented correctly in actual firmware implementations remains an unanswered question, and so it would seem sensible to avoid doing any kind of unsynchronized variable accesses. Furthermore, the efi_in_nmi() tests are inadequate because they don't account for the case where we call EFI variable services from panic or oops callbacks and aren't executing in NMI context. In other words, live-locking is still possible. Let's just remove the conditional locking altogether. Now we've got the ->set_variable_nonblocking() EFI variable operation we can abort if the runtime lock is already held. Aborting is by far the safest option. Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efi/runtime-wrappers.c17
1 files changed, 4 insertions, 13 deletions
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
index 4349206198b2..228bbf910461 100644
--- a/drivers/firmware/efi/runtime-wrappers.c
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -86,9 +86,6 @@ static DEFINE_SPINLOCK(efi_runtime_lock);
86 * for QueryVariableInfo() and SetVariable(), as these can be reached in NMI 86 * for QueryVariableInfo() and SetVariable(), as these can be reached in NMI
87 * context through efi_pstore_write(). 87 * context through efi_pstore_write().
88 */ 88 */
89#ifndef efi_in_nmi
90#define efi_in_nmi() (0)
91#endif
92 89
93/* 90/*
94 * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"), 91 * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"),
@@ -189,14 +186,11 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
189{ 186{
190 unsigned long flags; 187 unsigned long flags;
191 efi_status_t status; 188 efi_status_t status;
192 bool __in_nmi = efi_in_nmi();
193 189
194 if (!__in_nmi) 190 spin_lock_irqsave(&efi_runtime_lock, flags);
195 spin_lock_irqsave(&efi_runtime_lock, flags);
196 status = efi_call_virt(set_variable, name, vendor, attr, data_size, 191 status = efi_call_virt(set_variable, name, vendor, attr, data_size,
197 data); 192 data);
198 if (!__in_nmi) 193 spin_unlock_irqrestore(&efi_runtime_lock, flags);
199 spin_unlock_irqrestore(&efi_runtime_lock, flags);
200 return status; 194 return status;
201} 195}
202 196
@@ -225,17 +219,14 @@ static efi_status_t virt_efi_query_variable_info(u32 attr,
225{ 219{
226 unsigned long flags; 220 unsigned long flags;
227 efi_status_t status; 221 efi_status_t status;
228 bool __in_nmi = efi_in_nmi();
229 222
230 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) 223 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
231 return EFI_UNSUPPORTED; 224 return EFI_UNSUPPORTED;
232 225
233 if (!__in_nmi) 226 spin_lock_irqsave(&efi_runtime_lock, flags);
234 spin_lock_irqsave(&efi_runtime_lock, flags);
235 status = efi_call_virt(query_variable_info, attr, storage_space, 227 status = efi_call_virt(query_variable_info, attr, storage_space,
236 remaining_space, max_variable_size); 228 remaining_space, max_variable_size);
237 if (!__in_nmi) 229 spin_unlock_irqrestore(&efi_runtime_lock, flags);
238 spin_unlock_irqrestore(&efi_runtime_lock, flags);
239 return status; 230 return status;
240} 231}
241 232