efi/runtime-wrappers: factor out efi_rts_park_worker()

x86's efi_crash_gracefully_on_page_fault() ends in an infinite
schedule() loop so the kworker that faulted in firmware never runs
efi_rts_wq again. A later change needs the same "park this worker
forever" primitive on the runtime service timeout path, so factor the
loop into a shared efi_rts_park_worker() and call it from the x86
page-fault handler.

No functional change.

Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
Breno Leitao
2026-06-16 05:09:35 -07:00
committed by Ard Biesheuvel
parent 718ee46ba4
commit ecbccdbdab
4 changed files with 18 additions and 9 deletions

View File

@@ -832,12 +832,5 @@ void efi_crash_gracefully_on_page_fault(unsigned long phys_addr,
clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
pr_info("Froze efi_rts_wq and disabled EFI Runtime Services\n");
/*
* Call schedule() in an infinite loop, so that any spurious wake ups
* will never run efi_rts_wq again.
*/
for (;;) {
set_current_state(TASK_IDLE);
schedule();
}
efi_rts_park_worker();
}

View File

@@ -202,7 +202,7 @@ void efi_call_virt_check_flags(unsigned long flags, const void *caller)
*/
static DEFINE_SEMAPHORE(efi_runtime_lock, 1);
static struct task_struct *efi_runtime_lock_owner;
static struct task_struct *efi_runtime_lock_owner __used;
/*
* Expose the EFI runtime lock to the UV platform
@@ -211,6 +211,19 @@ static struct task_struct *efi_runtime_lock_owner;
extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock);
#endif
/*
* Park a worker that must never run efi_rts_wq again: EFI runtime services
* have been disabled and its efi_rts_work is abandoned. Loop in schedule()
* so a spurious wakeup cannot resume it.
*/
void __noreturn efi_rts_park_worker(void)
{
for (;;) {
set_current_state(TASK_IDLE);
schedule();
}
}
/*
* Calls the appropriate efi_runtime_service() with the appropriate
* arguments.

View File

@@ -1256,6 +1256,8 @@ extern struct efi_runtime_work efi_rts_work;
/* Workqueue to queue EFI Runtime Services */
extern struct workqueue_struct *efi_rts_wq;
void __noreturn efi_rts_park_worker(void);
struct linux_efi_memreserve {
int size; // allocated size of the array
atomic_t count; // number of entries used

View File

@@ -26,6 +26,7 @@ NORETURN(cpu_startup_entry)
NORETURN(do_exit)
NORETURN(do_group_exit)
NORETURN(do_task_dead)
NORETURN(efi_rts_park_worker)
NORETURN(ex_handler_msr_mce)
NORETURN(hlt_play_dead)
NORETURN(hv_ghcb_terminate)