[PATCH v3 04/17] x86/efi: Defer sub-1M check from unmap to free stage

Ard Biesheuvel
2026-04-23T15:21:05Z

As a first step towards moving the free logic to a later stage
altogether, and only keeping the unmap and the realmode trampoline hack
during the early stage of freeing the boot service code and data
regions, move the logic that avoids freeing memory below 1M to the later
stage.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/x86/platform/efi/quirks.c | 28 +++++++++-----------
1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 4d8de7c6ce59..e2e57e9201a9 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -468,18 +468,6 @@ void __init efi_unmap_boot_services(void)
size -= rm_size;
}

- /*
- * Don't free memory under 1M for two reasons:
- * - BIOS might clobber it
- * - Crash kernel needs it to be reserved
- */
- if (start + size < SZ_1M)
- continue;
- if (start < SZ_1M) {
- size -= (SZ_1M - start);
- start = SZ_1M;
- }
-
/*
* With CONFIG_DEFERRED_STRUCT_PAGE_INIT parts of the memory
* map are still not initialized and we can't reliably free
@@ -537,12 +525,20 @@ static int __init efi_free_boot_services(void)
if (!ranges_to_free)
return 0;

- while (range->start) {
- void *start = phys_to_virt(range->start);
+ while (range->start || range->end) {
+ /*
+ * Don't free memory under 1M for two reasons:
+ * - BIOS might clobber it
+ * - Crash kernel needs it to be reserved
+ */
+ unsigned long s = max(range->start, SZ_1M);
+ void *start = phys_to_virt(s);
void *end = phys_to_virt(range->end);

- free_reserved_area(start, end, -1, NULL);
- freed += (end - start);
+ if (start < end) {
+ free_reserved_area(start, end, -1, NULL);
+ freed += (end - start);
+ }
range++;
}
kfree(ranges_to_free);