Skip to content

Commit 4e78921

Browse files
zhanggenexIngo Molnar
authored andcommitted
efi/x86/Add missing error handling to old_memmap 1:1 mapping code
The old_memmap flow in efi_call_phys_prolog() performs numerous memory allocations, and either does not check for failure at all, or it does but fails to propagate it back to the caller, which may end up calling into the firmware with an incomplete 1:1 mapping. So let's fix this by returning NULL from efi_call_phys_prolog() on memory allocation failures only, and by handling this condition in the caller. Also, clean up any half baked sets of page tables that we may have created before returning with a NULL return value. Note that any failure at this level will trigger a panic() two levels up, so none of this makes a huge difference, but it is a nice cleanup nonetheless. [ardb: update commit log, add efi_call_phys_epilog() call on error path] Signed-off-by: Gen Zhang <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Rob Bradford <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 2409207 commit 4e78921

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

arch/x86/platform/efi/efi.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
8585
pgd_t *save_pgd;
8686

8787
save_pgd = efi_call_phys_prolog();
88+
if (!save_pgd)
89+
return EFI_ABORTED;
8890

8991
/* Disable interrupts around EFI calls: */
9092
local_irq_save(flags);

arch/x86/platform/efi/efi_64.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,15 @@ pgd_t * __init efi_call_phys_prolog(void)
8484

8585
if (!efi_enabled(EFI_OLD_MEMMAP)) {
8686
efi_switch_mm(&efi_mm);
87-
return NULL;
87+
return efi_mm.pgd;
8888
}
8989

9090
early_code_mapping_set_exec(1);
9191

9292
n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
9393
save_pgd = kmalloc_array(n_pgds, sizeof(*save_pgd), GFP_KERNEL);
94+
if (!save_pgd)
95+
return NULL;
9496

9597
/*
9698
* Build 1:1 identity mapping for efi=old_map usage. Note that
@@ -138,10 +140,11 @@ pgd_t * __init efi_call_phys_prolog(void)
138140
pgd_offset_k(pgd * PGDIR_SIZE)->pgd &= ~_PAGE_NX;
139141
}
140142

141-
out:
142143
__flush_tlb_all();
143-
144144
return save_pgd;
145+
out:
146+
efi_call_phys_epilog(save_pgd);
147+
return NULL;
145148
}
146149

147150
void __init efi_call_phys_epilog(pgd_t *save_pgd)

0 commit comments

Comments
 (0)