diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-02 19:25:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-02 19:25:50 -0400 |
commit | 4d6f843a38fa26035598f1f35181aa5f328db897 (patch) | |
tree | 0a2fa0b492ae121dc937f08efd5ba6ef9d110db3 /arch/x86/boot | |
parent | 55a0d3ff603a69ea4ec7677effd457f838390afc (diff) | |
parent | d3768d885c6ccbf8a137276843177d76c49033a7 (diff) |
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 EFI changes from Ingo Molnar:
"Two fixes that should in principle increase robustness of our
interaction with the EFI firmware, and a cleanup"
* 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86, efi: retry ExitBootServices() on failure
efi: Convert runtime services function ptrs
UEFI: Don't pass boot services regions to SetVirtualAddressMap()
Diffstat (limited to 'arch/x86/boot')
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c205035a6b96..d606463aa6d6 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -992,18 +992,20 @@ static efi_status_t exit_boot(struct boot_params *boot_params, | |||
992 | efi_memory_desc_t *mem_map; | 992 | efi_memory_desc_t *mem_map; |
993 | efi_status_t status; | 993 | efi_status_t status; |
994 | __u32 desc_version; | 994 | __u32 desc_version; |
995 | bool called_exit = false; | ||
995 | u8 nr_entries; | 996 | u8 nr_entries; |
996 | int i; | 997 | int i; |
997 | 998 | ||
998 | size = sizeof(*mem_map) * 32; | 999 | size = sizeof(*mem_map) * 32; |
999 | 1000 | ||
1000 | again: | 1001 | again: |
1001 | size += sizeof(*mem_map); | 1002 | size += sizeof(*mem_map) * 2; |
1002 | _size = size; | 1003 | _size = size; |
1003 | status = low_alloc(size, 1, (unsigned long *)&mem_map); | 1004 | status = low_alloc(size, 1, (unsigned long *)&mem_map); |
1004 | if (status != EFI_SUCCESS) | 1005 | if (status != EFI_SUCCESS) |
1005 | return status; | 1006 | return status; |
1006 | 1007 | ||
1008 | get_map: | ||
1007 | status = efi_call_phys5(sys_table->boottime->get_memory_map, &size, | 1009 | status = efi_call_phys5(sys_table->boottime->get_memory_map, &size, |
1008 | mem_map, &key, &desc_size, &desc_version); | 1010 | mem_map, &key, &desc_size, &desc_version); |
1009 | if (status == EFI_BUFFER_TOO_SMALL) { | 1011 | if (status == EFI_BUFFER_TOO_SMALL) { |
@@ -1029,8 +1031,20 @@ again: | |||
1029 | /* Might as well exit boot services now */ | 1031 | /* Might as well exit boot services now */ |
1030 | status = efi_call_phys2(sys_table->boottime->exit_boot_services, | 1032 | status = efi_call_phys2(sys_table->boottime->exit_boot_services, |
1031 | handle, key); | 1033 | handle, key); |
1032 | if (status != EFI_SUCCESS) | 1034 | if (status != EFI_SUCCESS) { |
1033 | goto free_mem_map; | 1035 | /* |
1036 | * ExitBootServices() will fail if any of the event | ||
1037 | * handlers change the memory map. In which case, we | ||
1038 | * must be prepared to retry, but only once so that | ||
1039 | * we're guaranteed to exit on repeated failures instead | ||
1040 | * of spinning forever. | ||
1041 | */ | ||
1042 | if (called_exit) | ||
1043 | goto free_mem_map; | ||
1044 | |||
1045 | called_exit = true; | ||
1046 | goto get_map; | ||
1047 | } | ||
1034 | 1048 | ||
1035 | /* Historic? */ | 1049 | /* Historic? */ |
1036 | boot_params->alt_mem_k = 32 * 1024; | 1050 | boot_params->alt_mem_k = 32 * 1024; |