Re: [PATCH] efi: Allocate runtime workqueue before ACPI init
"Rafael J. Wysocki" <[email protected]> Tue, 19 May 2026 16:12:25 +0200
| Newsgroups | org.kernel.vger.linux-efi,org.kernel.vger.linux-acpi |
|---|---|
| Message-ID | <CAJZ5v0h5NvLK3Fs9Fw+GoKCs82SXP1_oRggiG_aH3wiuMkdnJA@mail.gmail.com> |
On Tue, May 19, 2026 at 10:23 AM Ard Biesheuvel <[email protected]> wrote: > > From: Ard Biesheuvel <[email protected]> > > Since commit > > 5894cf571e14 ("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. > > Fixes: 5894cf571e14 ("acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers") > Reported-by: "Rafael J. Wysocki" <[email protected]> > Signed-off-by: Ard Biesheuvel <[email protected]> This should work AFAICS, so Reviewed-by: Rafael J. Wysocki (Intel) <[email protected]> > --- > drivers/firmware/efi/efi.c | 28 ++++++++++++++++------------ > 1 file changed, 16 insertions(+), 12 deletions(-) > > diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c > index d04be38f1750..318d1cc9a066 100644 > --- a/drivers/firmware/efi/efi.c > +++ b/drivers/firmware/efi/efi.c > @@ -402,21 +402,11 @@ static void __init efi_debugfs_init(void) > static inline void efi_debugfs_init(void) {} > #endif > > -/* > - * We register the efi subsystem with the firmware subsystem and the > - * efivars subsystem with the efi subsystem, if the system was booted with > - * EFI. > - */ > -static int __init efisubsys_init(void) > +static int __init efipostcore_init(void) > { > - int error; > - > if (!efi_enabled(EFI_RUNTIME_SERVICES)) > efi.runtime_supported_mask = 0; > > - if (!efi_enabled(EFI_BOOT)) > - return 0; > - > if (efi.runtime_supported_mask) { > /* > * Since we process only one efi_runtime_service() at a time, an > @@ -428,9 +418,23 @@ static int __init efisubsys_init(void) > pr_err("Creating efi_rts_wq failed, EFI runtime services disabled.\n"); > clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); > efi.runtime_supported_mask = 0; > - return 0; > } > } > + return 0; > +} > +postcore_initcall(efipostcore_init); > + > +/* > + * We register the efi subsystem with the firmware subsystem and the > + * efivars subsystem with the efi subsystem, if the system was booted with > + * EFI. > + */ > +static int __init efisubsys_init(void) > +{ > + int error; > + > + if (!efi_enabled(EFI_BOOT)) > + return 0; > > if (efi_rt_services_supported(EFI_RT_SUPPORTED_TIME_SERVICES)) > platform_device_register_simple("rtc-efi", 0, NULL, 0); > --