linux/drivers/firmware
Mike Rapoport (Microsoft) 6d8ba221e7 x86/efi: defer freeing of boot services memory
commit a4b0bf6a40 upstream.

efi_free_boot_services() frees memory occupied by EFI_BOOT_SERVICES_CODE
and EFI_BOOT_SERVICES_DATA using memblock_free_late().

There are two issue with that: memblock_free_late() should be used for
memory allocated with memblock_alloc() while the memory reserved with
memblock_reserve() should be freed with free_reserved_area().

More acutely, with CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
efi_free_boot_services() is called before deferred initialization of the
memory map is complete.

Benjamin Herrenschmidt reports that this causes a leak of ~140MB of
RAM on EC2 t3a.nano instances which only have 512MB or RAM.

If the freed memory resides in the areas that memory map for them is
still uninitialized, they won't be actually freed because
memblock_free_late() calls memblock_free_pages() and the latter skips
uninitialized pages.

Using free_reserved_area() at this point is also problematic because
__free_page() accesses the buddy of the freed page and that again might
end up in uninitialized part of the memory map.

Delaying the entire efi_free_boot_services() could be problematic
because in addition to freeing boot services memory it updates
efi.memmap without any synchronization and that's undesirable late in
boot when there is concurrency.

More robust approach is to only defer freeing of the EFI boot services
memory.

Split efi_free_boot_services() in two. First efi_unmap_boot_services()
collects ranges that should be freed into an array then
efi_free_boot_services() later frees them after deferred init is complete.

Link: https://lore.kernel.org/all/ec2aaef14783869b3be6e3c253b2dcbf67dbc12a.camel@kernel.crashing.org
Fixes: 916f676f8d ("x86, efi: Retain boot service code until after switching to virtual mode")
Cc: <stable@vger.kernel.org>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2026-04-18 10:33:08 +02:00
..
arm_ffa firmware: arm_ffa: Set dma_mask for ffa devices 2025-06-04 14:37:59 +02:00
arm_scmi firmware: arm_scmi: Fix unused notifier-block in unregister 2026-01-19 13:10:13 +01:00
broadcom firmware: tee_bnxt: Release TEE shm, session, and context during kexec 2021-07-21 07:55:50 +02:00
efi x86/efi: defer freeing of boot services memory 2026-04-18 10:33:08 +02:00
google firmware: google: Unregister driver_info on failure 2024-12-14 19:50:44 +01:00
imx firmware: imx: scu-irq: Set mu_resource_id before get handle 2026-01-19 13:10:19 +01:00
meson firmware: meson_sm: fix device leak at probe 2025-10-19 16:21:44 +02:00
psci firmware: psci: Fix refcount leak in psci_dt_init 2025-06-27 11:05:11 +01:00
smccc arm64: smccc: Remove broken support for SMCCCv1.3 SVE discard hint 2024-12-14 19:51:46 +01:00
tegra firmware: tegra: bpmp: Drop unused mbox_client_to_bpmp() 2024-10-17 15:11:35 +02:00
xilinx firmware: xilinx: don't make a sleepable memory allocation from an atomic context 2023-03-22 13:31:32 +01:00
arm_scpi.c firmware: arm_scpi: Check the DVFS OPP count returned by the firmware 2024-12-14 19:50:50 +01:00
arm_sdei.c firmware: SDEI: Allow sdei initialization without ACPI_APEI_GHES 2025-06-27 11:05:11 +01:00
dmi-id.c firmware: dmi-id: add a release callback function 2024-06-16 13:39:34 +02:00
dmi-sysfs.c firmware: dmi-sysfs: Fix null-ptr-deref in dmi_sysfs_register_handle 2023-03-10 09:39:39 +01:00
dmi_scan.c firmware: dmi: Stop decoding on broken entry 2024-07-18 13:07:28 +02:00
edd.c edd: Use scnprintf() for avoiding potential buffer overflow 2020-04-02 20:42:29 +02:00
iscsi_ibft.c iscsi_ibft: Fix UBSAN shift-out-of-bounds warning in ibft_attr_show_nic() 2025-04-10 14:31:50 +02:00
iscsi_ibft_find.c iscsi_ibft: fix warning in reserve_ibft_region() 2021-08-05 19:47:57 -04:00
Kconfig firmware: SDEI: Allow sdei initialization without ACPI_APEI_GHES 2025-06-27 11:05:11 +01:00
Makefile ARM: SoC drivers for 5.15 2021-09-01 15:25:28 -07:00
memmap.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 287 2019-06-05 17:36:37 +02:00
pcdp.c efi/ia64: Move HCDP and MPS table handling into IA64 arch code 2020-02-23 21:59:42 +01:00
pcdp.h firmware: pcdp: Replace zero-length array with flexible-array 2020-06-15 23:08:32 -05:00
qcom_scm-legacy.c firmware: qcom_scm: Fix kernel-doc function names to match 2021-04-06 21:25:49 -05:00
qcom_scm-smc.c firmware: qcom_scm: Reduce locking section for __get_convention() 2021-04-06 21:25:23 -05:00
qcom_scm.c firmware: qcom_scm: use 64-bit calling convention only when client is 64-bit 2023-11-28 16:56:29 +00:00
qcom_scm.h firmware: qcom_scm: Introduce SCM calls to access LMh 2021-08-18 09:31:53 +02:00
qemu_fw_cfg.c firmware: qemu_fw_cfg: fix kobject leak in probe error path 2022-01-20 09:13:15 +01:00
raspberrypi.c firmware: raspberrypi: Use correct device for DMA mappings 2024-06-16 13:39:16 +02:00
scpi_pm_domain.c firmware: arm_scpi: Fix string overflow in SCPI genpd driver 2021-12-22 09:32:35 +01:00
stratix10-rsu.c firmware: stratix10-rsu: fix warnings 2020-07-02 14:48:48 +02:00
stratix10-svc.c firmware: stratix10-svc: fix bug in saving controller data 2025-12-07 06:09:35 +09:00
sysfb.c efi: sysfb_efi: Fix DMI quirks not working for simpledrm 2023-03-30 12:47:55 +02:00
sysfb_simplefb.c efi: sysfb_efi: Fix DMI quirks not working for simpledrm 2023-03-30 12:47:55 +02:00
ti_sci.c firmware: ti_sci: Fix an off-by-one in ti_sci_debugfs_create() 2024-01-25 14:52:36 -08:00
ti_sci.h firmware: ti_sci: rm: Add new ops for ring configuration 2020-11-01 19:38:02 -08:00
trusted_foundations.c firmware: tf: Different way of L2 cache enabling after LP2 suspend 2020-05-06 18:27:26 +02:00
turris-mox-rwtm.c firmware: turris-mox-rwtm: Initialize completion before mailbox 2024-08-19 05:44:55 +02:00