aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/kernel/efi.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 56c3327bbf79..e72f3100958f 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -414,13 +414,24 @@ static int __init arm64_enter_virtual_mode(void)
414 for_each_efi_memory_desc(&memmap, md) { 414 for_each_efi_memory_desc(&memmap, md) {
415 if (!(md->attribute & EFI_MEMORY_RUNTIME)) 415 if (!(md->attribute & EFI_MEMORY_RUNTIME))
416 continue; 416 continue;
417 if (remap_region(md, &virt_md)) 417 if (!remap_region(md, &virt_md))
418 ++count; 418 goto err_unmap;
419 ++count;
419 } 420 }
420 421
421 efi.systab = (__force void *)efi_lookup_mapped_addr(efi_system_table); 422 efi.systab = (__force void *)efi_lookup_mapped_addr(efi_system_table);
422 if (efi.systab) 423 if (!efi.systab) {
423 set_bit(EFI_SYSTEM_TABLES, &efi.flags); 424 /*
425 * If we have no virtual mapping for the System Table at this
426 * point, the memory map doesn't cover the physical offset where
427 * it resides. This means the System Table will be inaccessible
428 * to Runtime Services themselves once the virtual mapping is
429 * installed.
430 */
431 pr_err("Failed to remap EFI System Table -- buggy firmware?\n");
432 goto err_unmap;
433 }
434 set_bit(EFI_SYSTEM_TABLES, &efi.flags);
424 435
425 local_irq_save(flags); 436 local_irq_save(flags);
426 cpu_switch_mm(idmap_pg_dir, &init_mm); 437 cpu_switch_mm(idmap_pg_dir, &init_mm);
@@ -453,5 +464,14 @@ static int __init arm64_enter_virtual_mode(void)
453 set_bit(EFI_RUNTIME_SERVICES, &efi.flags); 464 set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
454 465
455 return 0; 466 return 0;
467
468err_unmap:
469 /* unmap all mappings that succeeded: there are 'count' of those */
470 for (virt_md = virtmap; count--; virt_md += memmap.desc_size) {
471 md = virt_md;
472 iounmap((__force void __iomem *)md->virt_addr);
473 }
474 kfree(virtmap);
475 return -1;
456} 476}
457early_initcall(arm64_enter_virtual_mode); 477early_initcall(arm64_enter_virtual_mode);