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)  }  #endif  /*  EFI_DEBUG  */ +void __init efi_reserve_boot_services(void) +{ +	void *p; + +	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { +		efi_memory_desc_t *md = p; +		unsigned long long start = md->phys_addr; +		unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; + +		if (md->type != EFI_BOOT_SERVICES_CODE && +		    md->type != EFI_BOOT_SERVICES_DATA) +			continue; + +		memblock_x86_reserve_range(start, start + size, "EFI Boot"); +	} +} + +static void __init efi_free_boot_services(void) +{ +	void *p; + +	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { +		efi_memory_desc_t *md = p; +		unsigned long long start = md->phys_addr; +		unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; + +		if (md->type != EFI_BOOT_SERVICES_CODE && +		    md->type != EFI_BOOT_SERVICES_DATA) +			continue; + +		free_bootmem_late(start, size); +	} +} +  void __init efi_init(void)  {  	efi_config_table_t *config_tables; @@ -536,7 +570,9 @@ void __init efi_enter_virtual_mode(void)  	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {  		md = p; -		if (!(md->attribute & EFI_MEMORY_RUNTIME)) +		if (!(md->attribute & EFI_MEMORY_RUNTIME) && +		    md->type != EFI_BOOT_SERVICES_CODE && +		    md->type != EFI_BOOT_SERVICES_DATA)  			continue;  		size = md->num_pages << EFI_PAGE_SHIFT; @@ -593,6 +629,13 @@ void __init efi_enter_virtual_mode(void)  	}  	/* +	 * Thankfully, it does seem that no runtime services other than +	 * SetVirtualAddressMap() will touch boot services code, so we can +	 * get rid of it all at this point +	 */ +	efi_free_boot_services(); + +	/*  	 * Now that EFI is in virtual mode, update the function  	 * pointers in the runtime service table to the new virtual addresses.  	 *  |