diff options
author | Mark Brown <broonie@linaro.org> | 2013-07-22 11:16:51 +0100 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-07-22 11:16:51 +0100 |
commit | 9f6772da061814c2962aeb7d79231f7510dba313 (patch) | |
tree | e0c4a856204af6adff125ee61fe1f3059cada71b /arch/x86/boot/compressed/eboot.c | |
parent | d998ec4860d366424a55059093bb022beb38a61d (diff) | |
parent | 0f4a56e16d5fc9028b62ba529177a3109513e111 (diff) |
Merge tag 'v3.10.2' into linux-linaro-lsk-androidlsk-android
This is the 3.10.2 stable release
Diffstat (limited to 'arch/x86/boot/compressed/eboot.c')
-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 c205035a6b9..d606463aa6d 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, efi_memory_desc_t *mem_map; efi_status_t status; __u32 desc_version; + bool called_exit = false; u8 nr_entries; int i; size = sizeof(*mem_map) * 32; again: - size += sizeof(*mem_map); + size += sizeof(*mem_map) * 2; _size = size; status = low_alloc(size, 1, (unsigned long *)&mem_map); if (status != EFI_SUCCESS) return status; +get_map: status = efi_call_phys5(sys_table->boottime->get_memory_map, &size, mem_map, &key, &desc_size, &desc_version); if (status == EFI_BUFFER_TOO_SMALL) { @@ -1029,8 +1031,20 @@ again: /* Might as well exit boot services now */ status = efi_call_phys2(sys_table->boottime->exit_boot_services, handle, key); - if (status != EFI_SUCCESS) - goto free_mem_map; + if (status != EFI_SUCCESS) { + /* + * ExitBootServices() will fail if any of the event + * handlers change the memory map. In which case, we + * must be prepared to retry, but only once so that + * we're guaranteed to exit on repeated failures instead + * of spinning forever. + */ + if (called_exit) + goto free_mem_map; + + called_exit = true; + goto get_map; + } /* Historic? */ boot_params->alt_mem_k = 32 * 1024; |