diff options
Diffstat (limited to 'arch/x86/platform/efi/efi.c')
-rw-r--r-- | arch/x86/platform/efi/efi.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index b30aa26a8df..0d3a4fa3456 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -304,6 +304,40 @@ static void __init print_efi_memmap(void) | |||
304 | } | 304 | } |
305 | #endif /* EFI_DEBUG */ | 305 | #endif /* EFI_DEBUG */ |
306 | 306 | ||
307 | void __init efi_reserve_boot_services(void) | ||
308 | { | ||
309 | void *p; | ||
310 | |||
311 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
312 | efi_memory_desc_t *md = p; | ||
313 | unsigned long long start = md->phys_addr; | ||
314 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
315 | |||
316 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
317 | md->type != EFI_BOOT_SERVICES_DATA) | ||
318 | continue; | ||
319 | |||
320 | memblock_x86_reserve_range(start, start + size, "EFI Boot"); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | static void __init efi_free_boot_services(void) | ||
325 | { | ||
326 | void *p; | ||
327 | |||
328 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
329 | efi_memory_desc_t *md = p; | ||
330 | unsigned long long start = md->phys_addr; | ||
331 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
332 | |||
333 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
334 | md->type != EFI_BOOT_SERVICES_DATA) | ||
335 | continue; | ||
336 | |||
337 | free_bootmem_late(start, size); | ||
338 | } | ||
339 | } | ||
340 | |||
307 | void __init efi_init(void) | 341 | void __init efi_init(void) |
308 | { | 342 | { |
309 | efi_config_table_t *config_tables; | 343 | efi_config_table_t *config_tables; |
@@ -536,7 +570,9 @@ void __init efi_enter_virtual_mode(void) | |||
536 | 570 | ||
537 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 571 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
538 | md = p; | 572 | md = p; |
539 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) | 573 | if (!(md->attribute & EFI_MEMORY_RUNTIME) && |
574 | md->type != EFI_BOOT_SERVICES_CODE && | ||
575 | md->type != EFI_BOOT_SERVICES_DATA) | ||
540 | continue; | 576 | continue; |
541 | 577 | ||
542 | size = md->num_pages << EFI_PAGE_SHIFT; | 578 | size = md->num_pages << EFI_PAGE_SHIFT; |
@@ -593,6 +629,13 @@ void __init efi_enter_virtual_mode(void) | |||
593 | } | 629 | } |
594 | 630 | ||
595 | /* | 631 | /* |
632 | * Thankfully, it does seem that no runtime services other than | ||
633 | * SetVirtualAddressMap() will touch boot services code, so we can | ||
634 | * get rid of it all at this point | ||
635 | */ | ||
636 | efi_free_boot_services(); | ||
637 | |||
638 | /* | ||
596 | * Now that EFI is in virtual mode, update the function | 639 | * Now that EFI is in virtual mode, update the function |
597 | * pointers in the runtime service table to the new virtual addresses. | 640 | * pointers in the runtime service table to the new virtual addresses. |
598 | * | 641 | * |