Skip to content

Commit 13c6da0

Browse files
committed
efi: Allocate runtime workqueue before ACPI init
Since commit 5894cf5 ("acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers") ACPI PRM calls are delegated to a workqueue which runs in a kernel thread, making it easier to detect and mitigate faulting memory accesses performed by the firmware. Rafael reports that such PRM accesses may occur before efisubsys_init() executes, which is where the workqueue is allocated, leading to NULL pointer dereferences. Since acpi_init() [which triggers the early PRM accesses] executes as a subsys_initcall() as well, and has its own dependencies that may be sensitive to initcall ordering, deferring acpi_init() is not an option. So instead, split off the workqueue allocation into its own postcore initcall, as this is the only missing piece to allow EFI runtime calls to be made. This ensures that EFI runtime call (including PRM calls) are accessible to all code running at subsys_initcall() level. Cc: <stable@vger.kernel.org> Fixes: 5894cf5 ("acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers") Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent 2c340aa commit 13c6da0

1 file changed

Lines changed: 16 additions & 12 deletions

File tree

  • drivers/firmware/efi

drivers/firmware/efi/efi.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -402,21 +402,11 @@ static void __init efi_debugfs_init(void)
402402
static inline void efi_debugfs_init(void) {}
403403
#endif
404404

405-
/*
406-
* We register the efi subsystem with the firmware subsystem and the
407-
* efivars subsystem with the efi subsystem, if the system was booted with
408-
* EFI.
409-
*/
410-
static int __init efisubsys_init(void)
405+
static int __init efipostcore_init(void)
411406
{
412-
int error;
413-
414407
if (!efi_enabled(EFI_RUNTIME_SERVICES))
415408
efi.runtime_supported_mask = 0;
416409

417-
if (!efi_enabled(EFI_BOOT))
418-
return 0;
419-
420410
if (efi.runtime_supported_mask) {
421411
/*
422412
* Since we process only one efi_runtime_service() at a time, an
@@ -428,9 +418,23 @@ static int __init efisubsys_init(void)
428418
pr_err("Creating efi_rts_wq failed, EFI runtime services disabled.\n");
429419
clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
430420
efi.runtime_supported_mask = 0;
431-
return 0;
432421
}
433422
}
423+
return 0;
424+
}
425+
postcore_initcall(efipostcore_init);
426+
427+
/*
428+
* We register the efi subsystem with the firmware subsystem and the
429+
* efivars subsystem with the efi subsystem, if the system was booted with
430+
* EFI.
431+
*/
432+
static int __init efisubsys_init(void)
433+
{
434+
int error;
435+
436+
if (!efi_enabled(EFI_BOOT))
437+
return 0;
434438

435439
if (efi_rt_services_supported(EFI_RT_SUPPORTED_TIME_SERVICES))
436440
platform_device_register_simple("rtc-efi", 0, NULL, 0);

0 commit comments

Comments
 (0)