diff options
Diffstat (limited to 'arch/x86/platform/efi/efi.c')
-rw-r--r-- | arch/x86/platform/efi/efi.c | 198 |
1 files changed, 90 insertions, 108 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 1fbb408e2e72..0955c70897ae 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -172,7 +172,9 @@ static void __init do_add_efi_memmap(void) | |||
172 | int __init efi_memblock_x86_reserve_range(void) | 172 | int __init efi_memblock_x86_reserve_range(void) |
173 | { | 173 | { |
174 | struct efi_info *e = &boot_params.efi_info; | 174 | struct efi_info *e = &boot_params.efi_info; |
175 | struct efi_memory_map_data data; | ||
175 | phys_addr_t pmap; | 176 | phys_addr_t pmap; |
177 | int rv; | ||
176 | 178 | ||
177 | if (efi_enabled(EFI_PARAVIRT)) | 179 | if (efi_enabled(EFI_PARAVIRT)) |
178 | return 0; | 180 | return 0; |
@@ -187,11 +189,17 @@ int __init efi_memblock_x86_reserve_range(void) | |||
187 | #else | 189 | #else |
188 | pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32)); | 190 | pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32)); |
189 | #endif | 191 | #endif |
190 | efi.memmap.phys_map = pmap; | 192 | data.phys_map = pmap; |
191 | efi.memmap.nr_map = e->efi_memmap_size / | 193 | data.size = e->efi_memmap_size; |
192 | e->efi_memdesc_size; | 194 | data.desc_size = e->efi_memdesc_size; |
193 | efi.memmap.desc_size = e->efi_memdesc_size; | 195 | data.desc_version = e->efi_memdesc_version; |
194 | efi.memmap.desc_version = e->efi_memdesc_version; | 196 | |
197 | rv = efi_memmap_init_early(&data); | ||
198 | if (rv) | ||
199 | return rv; | ||
200 | |||
201 | if (add_efi_memmap) | ||
202 | do_add_efi_memmap(); | ||
195 | 203 | ||
196 | WARN(efi.memmap.desc_version != 1, | 204 | WARN(efi.memmap.desc_version != 1, |
197 | "Unexpected EFI_MEMORY_DESCRIPTOR version %ld", | 205 | "Unexpected EFI_MEMORY_DESCRIPTOR version %ld", |
@@ -218,19 +226,6 @@ void __init efi_print_memmap(void) | |||
218 | } | 226 | } |
219 | } | 227 | } |
220 | 228 | ||
221 | void __init efi_unmap_memmap(void) | ||
222 | { | ||
223 | unsigned long size; | ||
224 | |||
225 | clear_bit(EFI_MEMMAP, &efi.flags); | ||
226 | |||
227 | size = efi.memmap.nr_map * efi.memmap.desc_size; | ||
228 | if (efi.memmap.map) { | ||
229 | early_memunmap(efi.memmap.map, size); | ||
230 | efi.memmap.map = NULL; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | static int __init efi_systab_init(void *phys) | 229 | static int __init efi_systab_init(void *phys) |
235 | { | 230 | { |
236 | if (efi_enabled(EFI_64BIT)) { | 231 | if (efi_enabled(EFI_64BIT)) { |
@@ -414,33 +409,6 @@ static int __init efi_runtime_init(void) | |||
414 | return 0; | 409 | return 0; |
415 | } | 410 | } |
416 | 411 | ||
417 | static int __init efi_memmap_init(void) | ||
418 | { | ||
419 | unsigned long addr, size; | ||
420 | |||
421 | if (efi_enabled(EFI_PARAVIRT)) | ||
422 | return 0; | ||
423 | |||
424 | /* Map the EFI memory map */ | ||
425 | size = efi.memmap.nr_map * efi.memmap.desc_size; | ||
426 | addr = (unsigned long)efi.memmap.phys_map; | ||
427 | |||
428 | efi.memmap.map = early_memremap(addr, size); | ||
429 | if (efi.memmap.map == NULL) { | ||
430 | pr_err("Could not map the memory map!\n"); | ||
431 | return -ENOMEM; | ||
432 | } | ||
433 | |||
434 | efi.memmap.map_end = efi.memmap.map + size; | ||
435 | |||
436 | if (add_efi_memmap) | ||
437 | do_add_efi_memmap(); | ||
438 | |||
439 | set_bit(EFI_MEMMAP, &efi.flags); | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | void __init efi_init(void) | 412 | void __init efi_init(void) |
445 | { | 413 | { |
446 | efi_char16_t *c16; | 414 | efi_char16_t *c16; |
@@ -498,16 +466,14 @@ void __init efi_init(void) | |||
498 | if (!efi_runtime_supported()) | 466 | if (!efi_runtime_supported()) |
499 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); | 467 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); |
500 | else { | 468 | else { |
501 | if (efi_runtime_disabled() || efi_runtime_init()) | 469 | if (efi_runtime_disabled() || efi_runtime_init()) { |
470 | efi_memmap_unmap(); | ||
502 | return; | 471 | return; |
472 | } | ||
503 | } | 473 | } |
504 | if (efi_memmap_init()) | ||
505 | return; | ||
506 | 474 | ||
507 | if (efi_enabled(EFI_DBG)) | 475 | if (efi_enabled(EFI_DBG)) |
508 | efi_print_memmap(); | 476 | efi_print_memmap(); |
509 | |||
510 | efi_esrt_init(); | ||
511 | } | 477 | } |
512 | 478 | ||
513 | void __init efi_late_init(void) | 479 | void __init efi_late_init(void) |
@@ -624,42 +590,6 @@ static void __init get_systab_virt_addr(efi_memory_desc_t *md) | |||
624 | } | 590 | } |
625 | } | 591 | } |
626 | 592 | ||
627 | static void __init save_runtime_map(void) | ||
628 | { | ||
629 | #ifdef CONFIG_KEXEC_CORE | ||
630 | unsigned long desc_size; | ||
631 | efi_memory_desc_t *md; | ||
632 | void *tmp, *q = NULL; | ||
633 | int count = 0; | ||
634 | |||
635 | if (efi_enabled(EFI_OLD_MEMMAP)) | ||
636 | return; | ||
637 | |||
638 | desc_size = efi.memmap.desc_size; | ||
639 | |||
640 | for_each_efi_memory_desc(md) { | ||
641 | if (!(md->attribute & EFI_MEMORY_RUNTIME) || | ||
642 | (md->type == EFI_BOOT_SERVICES_CODE) || | ||
643 | (md->type == EFI_BOOT_SERVICES_DATA)) | ||
644 | continue; | ||
645 | tmp = krealloc(q, (count + 1) * desc_size, GFP_KERNEL); | ||
646 | if (!tmp) | ||
647 | goto out; | ||
648 | q = tmp; | ||
649 | |||
650 | memcpy(q + count * desc_size, md, desc_size); | ||
651 | count++; | ||
652 | } | ||
653 | |||
654 | efi_runtime_map_setup(q, count, desc_size); | ||
655 | return; | ||
656 | |||
657 | out: | ||
658 | kfree(q); | ||
659 | pr_err("Error saving runtime map, efi runtime on kexec non-functional!!\n"); | ||
660 | #endif | ||
661 | } | ||
662 | |||
663 | static void *realloc_pages(void *old_memmap, int old_shift) | 593 | static void *realloc_pages(void *old_memmap, int old_shift) |
664 | { | 594 | { |
665 | void *ret; | 595 | void *ret; |
@@ -745,6 +675,46 @@ static void *efi_map_next_entry(void *entry) | |||
745 | return entry; | 675 | return entry; |
746 | } | 676 | } |
747 | 677 | ||
678 | static bool should_map_region(efi_memory_desc_t *md) | ||
679 | { | ||
680 | /* | ||
681 | * Runtime regions always require runtime mappings (obviously). | ||
682 | */ | ||
683 | if (md->attribute & EFI_MEMORY_RUNTIME) | ||
684 | return true; | ||
685 | |||
686 | /* | ||
687 | * 32-bit EFI doesn't suffer from the bug that requires us to | ||
688 | * reserve boot services regions, and mixed mode support | ||
689 | * doesn't exist for 32-bit kernels. | ||
690 | */ | ||
691 | if (IS_ENABLED(CONFIG_X86_32)) | ||
692 | return false; | ||
693 | |||
694 | /* | ||
695 | * Map all of RAM so that we can access arguments in the 1:1 | ||
696 | * mapping when making EFI runtime calls. | ||
697 | */ | ||
698 | if (IS_ENABLED(CONFIG_EFI_MIXED) && !efi_is_native()) { | ||
699 | if (md->type == EFI_CONVENTIONAL_MEMORY || | ||
700 | md->type == EFI_LOADER_DATA || | ||
701 | md->type == EFI_LOADER_CODE) | ||
702 | return true; | ||
703 | } | ||
704 | |||
705 | /* | ||
706 | * Map boot services regions as a workaround for buggy | ||
707 | * firmware that accesses them even when they shouldn't. | ||
708 | * | ||
709 | * See efi_{reserve,free}_boot_services(). | ||
710 | */ | ||
711 | if (md->type == EFI_BOOT_SERVICES_CODE || | ||
712 | md->type == EFI_BOOT_SERVICES_DATA) | ||
713 | return true; | ||
714 | |||
715 | return false; | ||
716 | } | ||
717 | |||
748 | /* | 718 | /* |
749 | * Map the efi memory ranges of the runtime services and update new_mmap with | 719 | * Map the efi memory ranges of the runtime services and update new_mmap with |
750 | * virtual addresses. | 720 | * virtual addresses. |
@@ -761,13 +731,9 @@ static void * __init efi_map_regions(int *count, int *pg_shift) | |||
761 | p = NULL; | 731 | p = NULL; |
762 | while ((p = efi_map_next_entry(p))) { | 732 | while ((p = efi_map_next_entry(p))) { |
763 | md = p; | 733 | md = p; |
764 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) { | 734 | |
765 | #ifdef CONFIG_X86_64 | 735 | if (!should_map_region(md)) |
766 | if (md->type != EFI_BOOT_SERVICES_CODE && | 736 | continue; |
767 | md->type != EFI_BOOT_SERVICES_DATA) | ||
768 | #endif | ||
769 | continue; | ||
770 | } | ||
771 | 737 | ||
772 | efi_map_region(md); | 738 | efi_map_region(md); |
773 | get_systab_virt_addr(md); | 739 | get_systab_virt_addr(md); |
@@ -803,7 +769,7 @@ static void __init kexec_enter_virtual_mode(void) | |||
803 | * non-native EFI | 769 | * non-native EFI |
804 | */ | 770 | */ |
805 | if (!efi_is_native()) { | 771 | if (!efi_is_native()) { |
806 | efi_unmap_memmap(); | 772 | efi_memmap_unmap(); |
807 | clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); | 773 | clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); |
808 | return; | 774 | return; |
809 | } | 775 | } |
@@ -823,7 +789,18 @@ static void __init kexec_enter_virtual_mode(void) | |||
823 | get_systab_virt_addr(md); | 789 | get_systab_virt_addr(md); |
824 | } | 790 | } |
825 | 791 | ||
826 | save_runtime_map(); | 792 | /* |
793 | * Unregister the early EFI memmap from efi_init() and install | ||
794 | * the new EFI memory map. | ||
795 | */ | ||
796 | efi_memmap_unmap(); | ||
797 | |||
798 | if (efi_memmap_init_late(efi.memmap.phys_map, | ||
799 | efi.memmap.desc_size * efi.memmap.nr_map)) { | ||
800 | pr_err("Failed to remap late EFI memory map\n"); | ||
801 | clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); | ||
802 | return; | ||
803 | } | ||
827 | 804 | ||
828 | BUG_ON(!efi.systab); | 805 | BUG_ON(!efi.systab); |
829 | 806 | ||
@@ -884,6 +861,7 @@ static void __init __efi_enter_virtual_mode(void) | |||
884 | int count = 0, pg_shift = 0; | 861 | int count = 0, pg_shift = 0; |
885 | void *new_memmap = NULL; | 862 | void *new_memmap = NULL; |
886 | efi_status_t status; | 863 | efi_status_t status; |
864 | phys_addr_t pa; | ||
887 | 865 | ||
888 | efi.systab = NULL; | 866 | efi.systab = NULL; |
889 | 867 | ||
@@ -901,11 +879,24 @@ static void __init __efi_enter_virtual_mode(void) | |||
901 | return; | 879 | return; |
902 | } | 880 | } |
903 | 881 | ||
904 | save_runtime_map(); | 882 | pa = __pa(new_memmap); |
883 | |||
884 | /* | ||
885 | * Unregister the early EFI memmap from efi_init() and install | ||
886 | * the new EFI memory map that we are about to pass to the | ||
887 | * firmware via SetVirtualAddressMap(). | ||
888 | */ | ||
889 | efi_memmap_unmap(); | ||
890 | |||
891 | if (efi_memmap_init_late(pa, efi.memmap.desc_size * count)) { | ||
892 | pr_err("Failed to remap late EFI memory map\n"); | ||
893 | clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); | ||
894 | return; | ||
895 | } | ||
905 | 896 | ||
906 | BUG_ON(!efi.systab); | 897 | BUG_ON(!efi.systab); |
907 | 898 | ||
908 | if (efi_setup_page_tables(__pa(new_memmap), 1 << pg_shift)) { | 899 | if (efi_setup_page_tables(pa, 1 << pg_shift)) { |
909 | clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); | 900 | clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); |
910 | return; | 901 | return; |
911 | } | 902 | } |
@@ -917,14 +908,14 @@ static void __init __efi_enter_virtual_mode(void) | |||
917 | efi.memmap.desc_size * count, | 908 | efi.memmap.desc_size * count, |
918 | efi.memmap.desc_size, | 909 | efi.memmap.desc_size, |
919 | efi.memmap.desc_version, | 910 | efi.memmap.desc_version, |
920 | (efi_memory_desc_t *)__pa(new_memmap)); | 911 | (efi_memory_desc_t *)pa); |
921 | } else { | 912 | } else { |
922 | status = efi_thunk_set_virtual_address_map( | 913 | status = efi_thunk_set_virtual_address_map( |
923 | efi_phys.set_virtual_address_map, | 914 | efi_phys.set_virtual_address_map, |
924 | efi.memmap.desc_size * count, | 915 | efi.memmap.desc_size * count, |
925 | efi.memmap.desc_size, | 916 | efi.memmap.desc_size, |
926 | efi.memmap.desc_version, | 917 | efi.memmap.desc_version, |
927 | (efi_memory_desc_t *)__pa(new_memmap)); | 918 | (efi_memory_desc_t *)pa); |
928 | } | 919 | } |
929 | 920 | ||
930 | if (status != EFI_SUCCESS) { | 921 | if (status != EFI_SUCCESS) { |
@@ -956,15 +947,6 @@ static void __init __efi_enter_virtual_mode(void) | |||
956 | efi_runtime_update_mappings(); | 947 | efi_runtime_update_mappings(); |
957 | efi_dump_pagetable(); | 948 | efi_dump_pagetable(); |
958 | 949 | ||
959 | /* | ||
960 | * We mapped the descriptor array into the EFI pagetable above | ||
961 | * but we're not unmapping it here because if we're running in | ||
962 | * EFI mixed mode we need all of memory to be accessible when | ||
963 | * we pass parameters to the EFI runtime services in the | ||
964 | * thunking code. | ||
965 | */ | ||
966 | free_pages((unsigned long)new_memmap, pg_shift); | ||
967 | |||
968 | /* clean DUMMY object */ | 950 | /* clean DUMMY object */ |
969 | efi_delete_dummy_variable(); | 951 | efi_delete_dummy_variable(); |
970 | } | 952 | } |