diff options
| -rw-r--r-- | arch/arm64/kernel/efi.c | 28 |
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 | |||
| 468 | err_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 | } |
| 457 | early_initcall(arm64_enter_virtual_mode); | 477 | early_initcall(arm64_enter_virtual_mode); |
