Skip to content

Commit a286050

Browse files
ardbiesheuvelctmarinas
authored andcommitted
efi/runtime-wrappers: Keep track of the efi_runtime_lock owner
The EFI runtime wrappers use a file local semaphore to serialize access to the EFI runtime services. This means that any calls to the arch wrappers around the runtime services will also be serialized, removing the need for redundant locking. For robustness, add a facility that allows those arch wrappers to assert that the semaphore was taken by the current task. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent 40374d3 commit a286050

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

drivers/firmware/efi/runtime-wrappers.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ void efi_call_virt_check_flags(unsigned long flags, const void *caller)
202202
*/
203203
static DEFINE_SEMAPHORE(efi_runtime_lock, 1);
204204

205+
static struct task_struct *efi_runtime_lock_owner;
206+
205207
/*
206208
* Expose the EFI runtime lock to the UV platform
207209
*/
@@ -219,6 +221,8 @@ static void __nocfi efi_call_rts(struct work_struct *work)
219221
efi_status_t status = EFI_NOT_FOUND;
220222
unsigned long flags;
221223

224+
efi_runtime_lock_owner = current;
225+
222226
arch_efi_call_virt_setup();
223227
flags = efi_call_virt_save_flags();
224228

@@ -310,6 +314,7 @@ static void __nocfi efi_call_rts(struct work_struct *work)
310314

311315
efi_rts_work.status = status;
312316
complete(&efi_rts_work.efi_rts_comp);
317+
efi_runtime_lock_owner = NULL;
313318
}
314319

315320
static efi_status_t __efi_queue_work(enum efi_rts_ids id,
@@ -444,8 +449,10 @@ virt_efi_set_variable_nb(efi_char16_t *name, efi_guid_t *vendor, u32 attr,
444449
if (down_trylock(&efi_runtime_lock))
445450
return EFI_NOT_READY;
446451

452+
efi_runtime_lock_owner = current;
447453
status = efi_call_virt_pointer(efi.runtime, set_variable, name, vendor,
448454
attr, data_size, data);
455+
efi_runtime_lock_owner = NULL;
449456
up(&efi_runtime_lock);
450457
return status;
451458
}
@@ -481,9 +488,11 @@ virt_efi_query_variable_info_nb(u32 attr, u64 *storage_space,
481488
if (down_trylock(&efi_runtime_lock))
482489
return EFI_NOT_READY;
483490

491+
efi_runtime_lock_owner = current;
484492
status = efi_call_virt_pointer(efi.runtime, query_variable_info, attr,
485493
storage_space, remaining_space,
486494
max_variable_size);
495+
efi_runtime_lock_owner = NULL;
487496
up(&efi_runtime_lock);
488497
return status;
489498
}
@@ -509,12 +518,13 @@ virt_efi_reset_system(int reset_type, efi_status_t status,
509518
return;
510519
}
511520

521+
efi_runtime_lock_owner = current;
512522
arch_efi_call_virt_setup();
513523
efi_rts_work.efi_rts_id = EFI_RESET_SYSTEM;
514524
arch_efi_call_virt(efi.runtime, reset_system, reset_type, status,
515525
data_size, data);
516526
arch_efi_call_virt_teardown();
517-
527+
efi_runtime_lock_owner = NULL;
518528
up(&efi_runtime_lock);
519529
}
520530

@@ -587,3 +597,8 @@ efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *),
587597
}
588598

589599
#endif
600+
601+
void efi_runtime_assert_lock_held(void)
602+
{
603+
WARN_ON(efi_runtime_lock_owner != current);
604+
}

include/linux/efi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,8 @@ static inline bool efi_runtime_disabled(void) { return true; }
11261126
extern void efi_call_virt_check_flags(unsigned long flags, const void *caller);
11271127
extern unsigned long efi_call_virt_save_flags(void);
11281128

1129+
void efi_runtime_assert_lock_held(void);
1130+
11291131
enum efi_secureboot_mode {
11301132
efi_secureboot_mode_unset,
11311133
efi_secureboot_mode_unknown,

0 commit comments

Comments
 (0)